fix(test runner): fix types to allow expect.extend matchers to be used from .poll

This commit is contained in:
Simon Knott 2024-09-02 10:31:01 +02:00
parent 5c2e9962b4
commit 4cdf5b782d
No known key found for this signature in database
GPG key ID: 8CEDC00028084AEC
3 changed files with 21 additions and 13 deletions

View file

@ -6567,15 +6567,17 @@ type MakeMatchers<R, T, ExtendedMatchers> = {
rejects: MakeMatchers<Promise<R>, any, ExtendedMatchers>;
} & IfAny<T, AllMatchers<R, T>, SpecificMatchers<R, T> & ToUserMatcherObject<ExtendedMatchers, T>>;
type PollMatchers<R, T, ExtendedMatchers> = {
/**
* If you know how to test something, `.not` lets you test its opposite.
*/
not: PollMatchers<R, T, ExtendedMatchers>;
} & BaseMatchers<R, T> & ToUserMatcherObject<ExtendedMatchers, T>;
export type Expect<ExtendedMatchers = {}> = {
<T = unknown>(actual: T, messageOrOptions?: string | { message?: string }): MakeMatchers<void, T, ExtendedMatchers>;
soft: <T = unknown>(actual: T, messageOrOptions?: string | { message?: string }) => MakeMatchers<void, T, ExtendedMatchers>;
poll: <T = unknown>(actual: () => T | Promise<T>, messageOrOptions?: string | { message?: string, timeout?: number, intervals?: number[] }) => BaseMatchers<Promise<void>, T> & {
/**
* If you know how to test something, `.not` lets you test its opposite.
*/
not: BaseMatchers<Promise<void>, T>;
};
poll: <T = unknown>(actual: () => T | Promise<T>, messageOrOptions?: string | { message?: string, timeout?: number, intervals?: number[] }) => PollMatchers<Promise<void>,T, ExtendedMatchers>
extend<MoreMatchers extends Record<string, (this: ExpectMatcherState, receiver: any, ...args: any[]) => MatcherReturnType | Promise<MatcherReturnType>>>(matchers: MoreMatchers): Expect<ExtendedMatchers & MoreMatchers>;
configure: (configuration: {
message?: string,

View file

@ -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();

View file

@ -405,15 +405,17 @@ type MakeMatchers<R, T, ExtendedMatchers> = {
rejects: MakeMatchers<Promise<R>, any, ExtendedMatchers>;
} & IfAny<T, AllMatchers<R, T>, SpecificMatchers<R, T> & ToUserMatcherObject<ExtendedMatchers, T>>;
type PollMatchers<R, T, ExtendedMatchers> = {
/**
* If you know how to test something, `.not` lets you test its opposite.
*/
not: PollMatchers<R, T, ExtendedMatchers>;
} & BaseMatchers<R, T> & ToUserMatcherObject<ExtendedMatchers, T>;
export type Expect<ExtendedMatchers = {}> = {
<T = unknown>(actual: T, messageOrOptions?: string | { message?: string }): MakeMatchers<void, T, ExtendedMatchers>;
soft: <T = unknown>(actual: T, messageOrOptions?: string | { message?: string }) => MakeMatchers<void, T, ExtendedMatchers>;
poll: <T = unknown>(actual: () => T | Promise<T>, messageOrOptions?: string | { message?: string, timeout?: number, intervals?: number[] }) => BaseMatchers<Promise<void>, T> & {
/**
* If you know how to test something, `.not` lets you test its opposite.
*/
not: BaseMatchers<Promise<void>, T>;
};
poll: <T = unknown>(actual: () => T | Promise<T>, messageOrOptions?: string | { message?: string, timeout?: number, intervals?: number[] }) => PollMatchers<Promise<void>,T, ExtendedMatchers>
extend<MoreMatchers extends Record<string, (this: ExpectMatcherState, receiver: any, ...args: any[]) => MatcherReturnType | Promise<MatcherReturnType>>>(matchers: MoreMatchers): Expect<ExtendedMatchers & MoreMatchers>;
configure: (configuration: {
message?: string,