diff --git a/packages/playwright/types/test.d.ts b/packages/playwright/types/test.d.ts index 2556336b3d..3c7c8db0e4 100644 --- a/packages/playwright/types/test.d.ts +++ b/packages/playwright/types/test.d.ts @@ -31,8 +31,8 @@ export type ReporterDescription = Readonly< [string] | [string, any] >; -type PartialDeep = { - [P in keyof T]?: PartialDeep +type DeepPartial = { + [P in keyof T]?: DeepPartial } type UseOptions = Partial & Partial; @@ -6479,6 +6479,28 @@ interface GenericAssertions { * @param expected The expected object value to match against. */ toMatchObject(expected: Record | Array): R; + /** + * Compares contents of the value with contents of + * [`expected`](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-strict-equal-option-expected) + * **and** their types. + * + * Differences from + * [expect(value).toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal): + * - Keys with undefined properties are checked. For example, `{ a: undefined, b: 2 }` does not match `{ b: 2 }`. + * - Array sparseness is checked. For example, `[, 1]` does not match `[undefined, 1]`. + * - Object types are checked to be equal. For example, a class instance with fields `a` and `b` will not equal a + * literal object with fields `a` and `b`. + * + * **Usage** + * + * ```js + * const value = { prop: 1 }; + * expect(value).toStrictEqual({ prop: 1 }); + * ``` + * + * @param expected Expected value. + */ + toStrictEqual(expected: K): R; /** * Compares contents of the value with contents of * [`expected`](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-strict-equal-option-expected) diff --git a/tests/playwright-test/types.spec.ts b/tests/playwright-test/types.spec.ts index 83db925f1d..6e19bbe305 100644 --- a/tests/playwright-test/types.spec.ts +++ b/tests/playwright-test/types.spec.ts @@ -360,3 +360,41 @@ test.fixme('should check types of overloaded toMatchObject with generic paramete }); expect(result.exitCode).toBe(0); }); + +test.fixme('should check types of overloaded toStrictEqual with generic parameter', async ({ runTSC }) => { + const result = await runTSC({ + 'playwright.config.ts': ` + import { defineConfig } from '@playwright/test'; + + export default defineConfig({ + }); + `, + 'a.spec.ts': ` + import { test, expect } from '@playwright/test'; + test('my test', async () => { + const value = { a: 1, b: 'foo', c: { d: 2, e: 'bar' } }; + + expect.soft(value).toStrictEqual({ a: 1, b: 'foo', c: { d: 2, e: 'bar' } }); + expect.soft([value]).toStrictEqual>([{ a: 1, b: 'foo', c: { d: 2, e: 'bar' } }]); + + expect.soft(new Date()).toStrictEqual(new Date()); + + // @ts-expect-error + expect.soft(value).toStrictEqual({ a: 1 }); + + // @ts-expect-error + expect.soft(value).toStrictEqual({ a: 'a' }); + + // @ts-expect-error + expect.soft(value).toStrictEqual({ c: { e: 2 } }); + + // @ts-expect-error + expect.soft([value]).toStrictEqual([{ a: 'a' }]); + + // @ts-expect-error + expect.soft([value]).toStrictEqual([{ c: { e: 2 } }]); + }); + ` + }); + expect(result.exitCode).toBe(0); +}); \ No newline at end of file diff --git a/utils/generate_types/overrides-test.d.ts b/utils/generate_types/overrides-test.d.ts index 772c704494..6979c11cf9 100644 --- a/utils/generate_types/overrides-test.d.ts +++ b/utils/generate_types/overrides-test.d.ts @@ -295,6 +295,7 @@ interface GenericAssertions { toMatch(expected: RegExp | string): R; toMatchObject>(expected: DeepPartial | Array>): R; toMatchObject(expected: Record | Array): R; + toStrictEqual(expected: K): R; toStrictEqual(expected: unknown): R; toThrow(error?: unknown): R; toThrowError(error?: unknown): R;