From 4cdf5b782d26d8e37a8d9aaff59128815e1f6893 Mon Sep 17 00:00:00 2001 From: Simon Knott Date: Mon, 2 Sep 2024 10:31:01 +0200 Subject: [PATCH] fix(test runner): fix types to allow `expect.extend` matchers to be used from `.poll` --- packages/playwright/types/test.d.ts | 14 ++++++++------ tests/playwright-test/expect-poll.spec.ts | 6 +++++- utils/generate_types/overrides-test.d.ts | 14 ++++++++------ 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/packages/playwright/types/test.d.ts b/packages/playwright/types/test.d.ts index 5efdca4658..84fd21453d 100644 --- a/packages/playwright/types/test.d.ts +++ b/packages/playwright/types/test.d.ts @@ -6567,15 +6567,17 @@ type MakeMatchers = { rejects: MakeMatchers, any, ExtendedMatchers>; } & IfAny, SpecificMatchers & ToUserMatcherObject>; +type PollMatchers = { + /** + * If you know how to test something, `.not` lets you test its opposite. + */ + not: PollMatchers; +} & BaseMatchers & ToUserMatcherObject; + export type Expect = { (actual: T, messageOrOptions?: string | { message?: string }): MakeMatchers; soft: (actual: T, messageOrOptions?: string | { message?: string }) => MakeMatchers; - poll: (actual: () => T | Promise, messageOrOptions?: string | { message?: string, timeout?: number, intervals?: number[] }) => BaseMatchers, T> & { - /** - * If you know how to test something, `.not` lets you test its opposite. - */ - not: BaseMatchers, T>; - }; + poll: (actual: () => T | Promise, messageOrOptions?: string | { message?: string, timeout?: number, intervals?: number[] }) => PollMatchers,T, ExtendedMatchers> extend MatcherReturnType | Promise>>(matchers: MoreMatchers): Expect; configure: (configuration: { message?: string, diff --git a/tests/playwright-test/expect-poll.spec.ts b/tests/playwright-test/expect-poll.spec.ts index aa8bbde79d..9a6e9d6771 100644 --- a/tests/playwright-test/expect-poll.spec.ts +++ b/tests/playwright-test/expect-poll.spec.ts @@ -44,7 +44,10 @@ test('should poll predicate', async ({ runInlineTest }) => { test('should compile', async ({ runTSC }) => { const result = await runTSC({ 'a.spec.ts': ` - import { test, expect } from '@playwright/test'; + import { test, expect as baseExpect } from '@playwright/test'; + const expect = baseExpect.extend({ + toBeWithinRange() { return { message: () => "is within range", pass: true }; }, + }) test('should poll sync predicate', async ({ page }) => { let i = 0; test.expect.poll(() => ++i).toBe(3); @@ -57,6 +60,7 @@ test('should compile', async ({ runTSC }) => { return ++i; }).toBe(3); test.expect.poll(() => Promise.resolve(++i)).toBe(3); + expect.poll(() => Promise.resolve(++i)).toBeWithinRange(); // @ts-expect-error await test.expect.poll(() => page.locator('foo')).toBeEnabled(); diff --git a/utils/generate_types/overrides-test.d.ts b/utils/generate_types/overrides-test.d.ts index 76fecc524a..98a71e7f99 100644 --- a/utils/generate_types/overrides-test.d.ts +++ b/utils/generate_types/overrides-test.d.ts @@ -405,15 +405,17 @@ type MakeMatchers = { rejects: MakeMatchers, any, ExtendedMatchers>; } & IfAny, SpecificMatchers & ToUserMatcherObject>; +type PollMatchers = { + /** + * If you know how to test something, `.not` lets you test its opposite. + */ + not: PollMatchers; +} & BaseMatchers & ToUserMatcherObject; + export type Expect = { (actual: T, messageOrOptions?: string | { message?: string }): MakeMatchers; soft: (actual: T, messageOrOptions?: string | { message?: string }) => MakeMatchers; - poll: (actual: () => T | Promise, messageOrOptions?: string | { message?: string, timeout?: number, intervals?: number[] }) => BaseMatchers, T> & { - /** - * If you know how to test something, `.not` lets you test its opposite. - */ - not: BaseMatchers, T>; - }; + poll: (actual: () => T | Promise, messageOrOptions?: string | { message?: string, timeout?: number, intervals?: number[] }) => PollMatchers,T, ExtendedMatchers> extend MatcherReturnType | Promise>>(matchers: MoreMatchers): Expect; configure: (configuration: { message?: string,