feat(test-runner): friendly expect errors for typos (#13229)

If you typo'd an `expect` property, you got a cryptic error message:

```
Uncaught TypeError: Cannot create proxy with a non-object as target or handler
```

Now we get this nice friendly message:

```
  1) a.spec.ts:6:9 › explodes ======================================================================

    Error: expect: Property 'toBeLessThen' not found.

    Did you mean 'toBeLessThan'?

    See https://playwright.dev/docs/test-assertions for available options and documentation.

      5 |         const { test } = pwt;
      6 |         test('explodes', () => {
    > 7 |           expect.soft(1).toBeLessThen();
        |           ^
      8 |         });
      9 |

```

Fixes #13218
This commit is contained in:
Ross Wollman 2022-04-01 13:38:22 -07:00 committed by GitHub
parent fee9b6007f
commit 12abae7f31
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 70 additions and 1 deletions

View file

@ -168,6 +168,8 @@ class ExpectMetaInfoProxyHandler {
get(target: any, prop: any, receiver: any): any {
const value = Reflect.get(target, prop, receiver);
if (value === undefined)
throw new Error(`expect: Property '${prop}' not found.`);
if (typeof value !== 'function')
return new Proxy(value, this);
return (...args: any[]) => {

View file

@ -277,4 +277,3 @@ export function getPackageJsonPath(folderPath: string): string {
folderToPackageJsonPath.set(folderPath, result);
return result;
}

View file

@ -233,3 +233,71 @@ test('should propose only the relevant matchers when custom expect matcher class
});
expect(result.exitCode).toBe(0);
});
test.describe('helpful expect errors', () => {
test('top-level', async ({ runInlineTest }) => {
const result = await runInlineTest({
'a.spec.ts': `
const { test } = pwt;
test('explodes', () => {
expect(1).nope();
});
`
});
expect(result.output).toContain(`expect: Property 'nope' not found.`);
});
test('soft', async ({ runInlineTest }) => {
const result = await runInlineTest({
'a.spec.ts': `
const { test } = pwt;
test('explodes', () => {
expect.soft(1).nope();
});
`
});
expect(result.output).toContain(`expect: Property 'nope' not found.`);
});
test('poll', async ({ runInlineTest }) => {
const result = await runInlineTest({
'a.spec.ts': `
const { test } = pwt;
test('explodes', () => {
expect.poll(() => {}).nope();
});
`
});
expect(result.output).toContain(`expect: Property 'nope' not found.`);
});
test('not', async ({ runInlineTest }) => {
const result = await runInlineTest({
'a.spec.ts': `
const { test } = pwt;
test('explodes', () => {
expect(1).not.nope();
});
`
});
expect(result.output).toContain(`expect: Property 'nope' not found.`);
});
test('bare', async ({ runInlineTest }) => {
const result = await runInlineTest({
'a.spec.ts': `
const { test } = pwt;
test('explodes', () => {
expect('');
});
`
});
expect(result.exitCode).toBe(0);
expect(result.passed).toBe(1);
});
});