diff --git a/packages/playwright-test/types/expect-types.d.ts b/packages/playwright-test/types/expect-types.d.ts deleted file mode 100644 index 272488eb1f..0000000000 --- a/packages/playwright-test/types/expect-types.d.ts +++ /dev/null @@ -1,111 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - */ - -// -------------- Playwright ------------- -// - Matcher types are relaxed in the overrides. -// -// import type { Config } from '@jest/types'; -// import type * as jestMatcherUtils from 'jest-matcher-utils'; -// import { INTERNAL_MATCHER_FLAG } from './jestMatchersObject'; -// -// export declare type SyncExpectationResult = { -// pass: boolean; -// message: () => string; -// }; -// export declare type AsyncExpectationResult = Promise; -// export declare type ExpectationResult = SyncExpectationResult | AsyncExpectationResult; -// export declare type RawMatcherFn = { -// (this: T, received: any, expected: any, options?: any): ExpectationResult; -// [INTERNAL_MATCHER_FLAG]?: boolean; -// }; -// export declare type ThrowingMatcherFn = (actual: any) => void; -// export declare type PromiseMatcherFn = (actual: any) => Promise; -// --------------------------------------- - -export declare type Tester = (a: any, b: any) => boolean | undefined; -export declare type MatcherState = { - assertionCalls: number; - currentTestName?: string; - dontThrow?: () => void; - error?: Error; - equals: (a: unknown, b: unknown, customTesters?: Array, strictCheck?: boolean) => boolean; - expand?: boolean; - expectedAssertionsNumber?: number | null; - expectedAssertionsNumberError?: Error; - isExpectingAssertions?: boolean; - isExpectingAssertionsError?: Error; - isNot: boolean; - promise: string; - suppressedErrors: Array; - - // -------------- Playwright ------------- - // - Inline type - // testPath?: Config.Path; - testPath?: string; - // --------------------------------------- - - // -------------- Playwright ------------- - // - Further relax type in order to not drag the dependencies. - // utils: typeof jestMatcherUtils & { - // iterableEquality: Tester; - // subsetEquality: Tester; - // }; - utils: any; - // --------------------------------------- -}; - -// -------------- Playwright ------------- -// - Matcher types are relaxed in the override. -// -// export interface AsymmetricMatcher { -// asymmetricMatch(other: unknown): boolean; -// toString(): string; -// getExpectedType?(): string; -// toAsymmetricMatcher?(): string; -// } -// -// export declare type MatchersObject = { -// [id: string]: RawMatcherFn; -// }; -// export declare type ExpectedAssertionsErrors = Array<{ -// actual: string | number; -// error: Error; -// expected: string; -// }>; -// --------------------------------------- - -// -------------- Playwright ------------- -// Following are inlined in the expect override. -// interface InverseAsymmetricMatchers { -// arrayContaining(sample: Array): AsymmetricMatcher; -// objectContaining(sample: Record): AsymmetricMatcher; -// stringContaining(expected: string): AsymmetricMatcher; -// stringMatching(expected: string | RegExp): AsymmetricMatcher; -// } -// interface AsymmetricMatchers extends InverseAsymmetricMatchers { -// any(expectedObject: unknown): AsymmetricMatcher; -// anything(): AsymmetricMatcher; -// } -// interface ExtraAsymmetricMatchers { -// [id: string]: (...sample: [unknown, ...Array]) => AsymmetricMatcher; -// } -// export declare type Expect = { -// (actual: T): Matchers; -// addSnapshotSerializer(serializer: unknown): void; -// assertions(numberOfAssertions: number): void; -// extend(matchers: MatchersObject): void; -// extractExpectedAssertionsErrors: () => ExpectedAssertionsErrors; -// getState(): State; -// hasAssertions(): void; -// setState(state: Partial): void; -// } & AsymmetricMatchers & ExtraAsymmetricMatchers & { -// not: InverseAsymmetricMatchers & ExtraAsymmetricMatchers; -// }; -// --------------------------------------- - -export {}; diff --git a/packages/playwright-test/types/test.d.ts b/packages/playwright-test/types/test.d.ts index 650b8439c4..9ba86ad4fc 100644 --- a/packages/playwright-test/types/test.d.ts +++ b/packages/playwright-test/types/test.d.ts @@ -3755,9 +3755,6 @@ type CustomProperties = ExcludeProps = Project, PlaywrightWorkerOptions & CustomProperties>; export type PlaywrightTestConfig = Config, PlaywrightWorkerOptions & CustomProperties>; -import type * as expectType from './expect-types'; -import type { Suite } from './testReporter'; - type AsymmetricMatcher = Record; type AsymmetricMatchers = { @@ -3770,13 +3767,6 @@ type AsymmetricMatchers = { stringMatching(sample: string | RegExp): AsymmetricMatcher; } -type Inverse = { - /** - * Inverse next matcher. If you know how to test something, `.not` lets you test its opposite. - */ - not: Matchers; -}; - type IfAny = 0 extends (1 & T) ? Y : N; type ExtraMatchers = T extends Type ? Matchers : IfAny; @@ -4222,16 +4212,6 @@ type MakeMatchers = BaseMatchers & { toPass(options?: { timeout?: number, intervals?: number[] }): Promise; }>; -type BaseExpect = { - // Removed following methods because they rely on a test-runner integration from Jest which we don't support: - // assertions(numberOfAssertions: number): void; - // extractExpectedAssertionsErrors(): ExpectedAssertionsErrors; - // hasAssertions(): void; - extend(matchers: any): void; - getState(): expectType.MatcherState; - setState(state: Partial): void; -} - export type Expect = { (actual: T, messageOrOptions?: string | { message?: string }): MakeMatchers; soft: (actual: T, messageOrOptions?: string | { message?: string }) => MakeMatchers; @@ -4241,9 +4221,15 @@ export type Expect = { */ not: BaseMatchers, T>; }; -} & BaseExpect & - AsymmetricMatchers & - Inverse>; + extend(matchers: any): void; + getState(): { + expand?: boolean; + isNot: boolean; + promise: string; + utils: any; + }; + not: Omit; +} & AsymmetricMatchers; type Awaited = T extends PromiseLike ? U : T; diff --git a/tests/playwright-test/expect.spec.ts b/tests/playwright-test/expect.spec.ts index a86be8af53..cda917552c 100644 --- a/tests/playwright-test/expect.spec.ts +++ b/tests/playwright-test/expect.spec.ts @@ -159,6 +159,23 @@ test('should work with generic matchers', async ({ runTSC }) => { expect({}).toStrictEqual({}); expect(() => { throw new Error('Something bad'); }).toThrow('something'); expect(() => { throw new Error('Something bad'); }).toThrowError('something'); + + expect(['Bob', 'Eve']).not.toEqual(expect.arrayContaining(['Alice', 'Bob'])); + expect({}).toEqual(expect.anything()); + expect({ sum: 0.1 + 0.2 }).toEqual({ sum: expect.closeTo(0.3, 5) }); + class Cat {} + expect(new Cat()).toEqual(expect.any(Cat)); + expect({ x: 2, y: 3, foo: 'bar' }).toEqual(expect.objectContaining({ + x: expect.any(Number), + y: expect.any(Number), + })); + expect('abc').toEqual(expect.stringContaining('bc')); + expect(['Alicia', 'Roberto', 'Evelina']).toEqual( + expect.arrayContaining([ + expect.stringMatching(/^Alic/), + expect.stringMatching('Roberto'), + ]), + ); ` }); expect(result.exitCode).toBe(0); @@ -200,6 +217,23 @@ test('should compile generic matchers', async ({ runTSC }) => { expect(() => { throw new Error('Something bad'); }).toThrowError('something'); expect(() => { throw new Error('Something bad'); }).toThrowError(); + expect(['Bob', 'Eve']).not.toEqual(expect.arrayContaining(['Alice', 'Bob'])); + expect({}).toEqual(expect.anything()); + expect({ sum: 0.1 + 0.2 }).toEqual({ sum: expect.closeTo(0.3, 5) }); + class Cat {} + expect(new Cat()).toEqual(expect.any(Cat)); + expect({ x: 2, y: 3, foo: 'bar' }).toEqual(expect.objectContaining({ + x: expect.any(Number), + y: expect.any(Number), + })); + expect('abc').toEqual(expect.stringContaining('bc')); + expect(['Alicia', 'Roberto', 'Evelina']).toEqual( + expect.arrayContaining([ + expect.stringMatching(/^Alic/), + expect.stringMatching('Roberto'), + ]), + ); + // @ts-expect-error expect(42).toBe(123, 456); // @ts-expect-error diff --git a/utils/generate_types/overrides-test.d.ts b/utils/generate_types/overrides-test.d.ts index 8635cc6a11..f1a009153a 100644 --- a/utils/generate_types/overrides-test.d.ts +++ b/utils/generate_types/overrides-test.d.ts @@ -261,9 +261,6 @@ type CustomProperties = ExcludeProps = Project, PlaywrightWorkerOptions & CustomProperties>; export type PlaywrightTestConfig = Config, PlaywrightWorkerOptions & CustomProperties>; -import type * as expectType from './expect-types'; -import type { Suite } from './testReporter'; - type AsymmetricMatcher = Record; type AsymmetricMatchers = { @@ -276,13 +273,6 @@ type AsymmetricMatchers = { stringMatching(sample: string | RegExp): AsymmetricMatcher; } -type Inverse = { - /** - * Inverse next matcher. If you know how to test something, `.not` lets you test its opposite. - */ - not: Matchers; -}; - type IfAny = 0 extends (1 & T) ? Y : N; type ExtraMatchers = T extends Type ? Matchers : IfAny; @@ -342,16 +332,6 @@ type MakeMatchers = BaseMatchers & { toPass(options?: { timeout?: number, intervals?: number[] }): Promise; }>; -type BaseExpect = { - // Removed following methods because they rely on a test-runner integration from Jest which we don't support: - // assertions(numberOfAssertions: number): void; - // extractExpectedAssertionsErrors(): ExpectedAssertionsErrors; - // hasAssertions(): void; - extend(matchers: any): void; - getState(): expectType.MatcherState; - setState(state: Partial): void; -} - export type Expect = { (actual: T, messageOrOptions?: string | { message?: string }): MakeMatchers; soft: (actual: T, messageOrOptions?: string | { message?: string }) => MakeMatchers; @@ -361,9 +341,15 @@ export type Expect = { */ not: BaseMatchers, T>; }; -} & BaseExpect & - AsymmetricMatchers & - Inverse>; + extend(matchers: any): void; + getState(): { + expand?: boolean; + isNot: boolean; + promise: string; + utils: any; + }; + not: Omit; +} & AsymmetricMatchers; type Awaited = T extends PromiseLike ? U : T;