fix(expect): properly handle custom asymmetric matcher regression (#35149)
This commit is contained in:
parent
629f5f2a9a
commit
a98075085e
|
@ -209,10 +209,12 @@ function setMatcherCallContext(context: MatcherCallContext) {
|
|||
matcherCallContext = context;
|
||||
}
|
||||
|
||||
function takeMatcherCallContext(): MatcherCallContext {
|
||||
function takeMatcherCallContext(): MatcherCallContext | undefined {
|
||||
try {
|
||||
return matcherCallContext!;
|
||||
return matcherCallContext;
|
||||
} finally {
|
||||
// Any subsequent matcher following the first is assumed to be an unsupported legacy asymmetric matcher.
|
||||
// Lacking call context in these scenarios is not particularly important.
|
||||
matcherCallContext = undefined;
|
||||
}
|
||||
}
|
||||
|
@ -223,13 +225,13 @@ function wrapPlaywrightMatcherToPassNiceThis(matcher: any) {
|
|||
return function(this: any, ...args: any[]) {
|
||||
const { isNot, promise, utils } = this;
|
||||
const context = takeMatcherCallContext();
|
||||
const timeout = context.expectInfo.timeout ?? context.testInfo?._projectInternal?.expect?.timeout ?? defaultExpectTimeout;
|
||||
const timeout = context?.expectInfo.timeout ?? context?.testInfo?._projectInternal?.expect?.timeout ?? defaultExpectTimeout;
|
||||
const newThis: ExpectMatcherStateInternal = {
|
||||
isNot,
|
||||
promise,
|
||||
utils,
|
||||
timeout,
|
||||
_stepInfo: context.step,
|
||||
_stepInfo: context?.step,
|
||||
};
|
||||
(newThis as any).equals = throwUnsupportedExpectMatcherError;
|
||||
return matcher.call(newThis, ...args);
|
||||
|
|
|
@ -1186,3 +1186,104 @@ test('custom asymmetric matchers should work with expect.extend', async ({ runIn
|
|||
expect(result.passed).toBe(1);
|
||||
expect(result.output).not.toContain('should not run');
|
||||
});
|
||||
|
||||
test('custom asymmetric matchers should function', { annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/35138' } }, async ({ runInlineTest }) => {
|
||||
const result = await runInlineTest({
|
||||
'expect-test.spec.ts': `
|
||||
import { test, expect } from '@playwright/test';
|
||||
expect.extend({
|
||||
isUndefined(received: unknown, expected: string) {
|
||||
return { pass: received === undefined, message: () => '' };
|
||||
}
|
||||
});
|
||||
test('example', () => {
|
||||
expect(undefined).toEqual(expect.isUndefined());
|
||||
});
|
||||
test('example2', () => {
|
||||
expect({
|
||||
aProperty: undefined,
|
||||
bProperty: 'foo',
|
||||
}).toEqual({
|
||||
aProperty: expect.isUndefined(),
|
||||
bProperty: 'foo',
|
||||
cProperty: expect.isUndefined(),
|
||||
});
|
||||
});
|
||||
`,
|
||||
});
|
||||
expect(result.exitCode).toBe(0);
|
||||
expect(result.passed).toBe(2);
|
||||
});
|
||||
|
||||
test('single custom asymmetric matcher should present the correct error', { annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/35138' } }, async ({ runInlineTest }) => {
|
||||
const result = await runInlineTest({
|
||||
'expect-test.spec.ts': `
|
||||
import { test, expect } from '@playwright/test';
|
||||
expect.extend({
|
||||
isUndefined(received: unknown, expected: string) {
|
||||
return { pass: received === undefined, message: () => '' };
|
||||
}
|
||||
});
|
||||
test('example', () => {
|
||||
expect({
|
||||
aProperty: 'foo'
|
||||
}).toEqual({
|
||||
aProperty: expect.isUndefined()
|
||||
});
|
||||
});
|
||||
`,
|
||||
});
|
||||
expect(result.exitCode).toBe(1);
|
||||
expect(result.passed).toBe(0);
|
||||
expect(result.output).toContain('- \"aProperty\": isUndefined<>');
|
||||
expect(result.output).toContain('+ \"aProperty\": \"foo\"');
|
||||
});
|
||||
|
||||
test('multiple custom asymmetric matchers should present the correct error', { annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/35138' } }, async ({ runInlineTest }) => {
|
||||
const result = await runInlineTest({
|
||||
'expect-test.spec.ts': `
|
||||
import { test, expect } from '@playwright/test';
|
||||
expect.extend({
|
||||
isUndefined(received: unknown, expected: string) {
|
||||
return { pass: received === undefined, message: () => '' };
|
||||
}
|
||||
});
|
||||
test('example', () => {
|
||||
expect({
|
||||
aProperty: undefined,
|
||||
bProperty: 'foo',
|
||||
}).toEqual({
|
||||
aProperty: expect.isUndefined(),
|
||||
bProperty: expect.isUndefined()
|
||||
});
|
||||
});
|
||||
`,
|
||||
});
|
||||
expect(result.exitCode).toBe(1);
|
||||
expect(result.passed).toBe(0);
|
||||
expect(result.output).toContain('- \"bProperty\": isUndefined<>');
|
||||
expect(result.output).toContain('+ \"bProperty\": \"foo\"');
|
||||
});
|
||||
|
||||
test('multiple custom asymmetric matchers in async expect should present the correct error', { annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/35138' } }, async ({ runInlineTest }) => {
|
||||
const result = await runInlineTest({
|
||||
'expect-test.spec.ts': `
|
||||
import { test, expect } from '@playwright/test';
|
||||
expect.extend({
|
||||
isUndefined(received: unknown, expected: string) {
|
||||
return { pass: received === undefined, message: () => '' };
|
||||
}
|
||||
});
|
||||
test('example', async () => {
|
||||
await expect.poll(() => ({ aProperty: 'foo', bProperty: undefined })).toEqual({
|
||||
aProperty: expect.isUndefined(),
|
||||
bProperty: expect.isUndefined(),
|
||||
});
|
||||
});
|
||||
`,
|
||||
});
|
||||
expect(result.exitCode).toBe(1);
|
||||
expect(result.passed).toBe(0);
|
||||
expect(result.output).toContain('- \"aProperty\": isUndefined<>');
|
||||
expect(result.output).toContain('+ \"aProperty\": \"foo\"');
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue