From f469e4b1ebad4a9c3de91fab626f36df5a28d6d1 Mon Sep 17 00:00:00 2001 From: Dmitry Gozman Date: Mon, 15 May 2023 19:37:12 -0700 Subject: [PATCH] fix(expect): mark step as failed when async custom matcher throws (#23035) Fixes #23021. --- .../playwright-test/src/matchers/expect.ts | 2 ++ tests/playwright-test/test-step.spec.ts | 27 ++++++++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/packages/playwright-test/src/matchers/expect.ts b/packages/playwright-test/src/matchers/expect.ts index 11c4d1b23b..4b4e143886 100644 --- a/packages/playwright-test/src/matchers/expect.ts +++ b/packages/playwright-test/src/matchers/expect.ts @@ -312,6 +312,8 @@ class ExpectMetaInfoProxyHandler implements ProxyHandler { } else { try { const result = matcher.call(target, ...args); + if (result instanceof Promise) + return result.then(finalizer).catch(reportStepError); finalizer(); return result; } catch (e) { diff --git a/tests/playwright-test/test-step.spec.ts b/tests/playwright-test/test-step.spec.ts index 2f194b1a32..3596e1ba13 100644 --- a/tests/playwright-test/test-step.spec.ts +++ b/tests/playwright-test/test-step.spec.ts @@ -480,7 +480,7 @@ test('should report custom expect steps', async ({ runInlineTest }) => { 'reporter.ts': stepHierarchyReporter, 'playwright.config.ts': ` module.exports = { - reporter: './reporter', + reporter: [['./reporter'], ['line']], }; `, 'a.test.ts': ` @@ -501,16 +501,27 @@ test('should report custom expect steps', async ({ runInlineTest }) => { }; } }, + + async toBeFailingAsync(received) { + await new Promise(f => setTimeout(f, 0)); + return { + message: () => "It fails!", + pass: false, + }; + }, }); import { test, expect } from '@playwright/test'; - test('pass', async ({}) => { + test('fail', async ({}) => { expect(15).toBeWithinRange(10, 20); + await expect(1).toBeFailingAsync(22); }); ` }, { reporter: '', workers: 1 }); - expect(result.exitCode).toBe(0); + expect(result.exitCode).toBe(1); + expect(result.failed).toBe(1); + expect(result.output).toContain('It fails!'); const objects = result.outputLines.map(line => JSON.parse(line)); expect(objects).toEqual([ { @@ -526,6 +537,16 @@ test('should report custom expect steps', async ({ runInlineTest }) => { }, title: 'expect.toBeWithinRange', }, + { + category: 'expect', + location: { + column: 'number', + file: 'a.test.ts', + line: 'number', + }, + title: 'expect.toBeFailingAsync', + error: '', + }, { category: 'hook', title: 'After Hooks',