From bd06d1604f9fe8376c0062f5a95738531778524e Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Mon, 15 Aug 2022 09:28:55 -0700 Subject: [PATCH] chore: render original exception location in error frame (#16515) --- packages/playwright-test/src/reporters/base.ts | 16 ++++++---------- packages/playwright-test/src/reporters/json.ts | 2 +- tests/playwright-test/reporter-base.spec.ts | 8 ++++---- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/packages/playwright-test/src/reporters/base.ts b/packages/playwright-test/src/reporters/base.ts index 6c1d34a698..7c3020c5ea 100644 --- a/packages/playwright-test/src/reporters/base.ts +++ b/packages/playwright-test/src/reporters/base.ts @@ -375,7 +375,9 @@ export function formatError(config: FullConfig, error: TestError, highlightCode: const tokens = []; let location: Location | undefined; if (stack) { - const parsed = prepareErrorStack(stack, file); + // Now that we filter out internals from our stack traces, we can safely render + // the helper / original exception locations. + const parsed = prepareErrorStack(stack); tokens.push(parsed.message); location = parsed.location; if (location) { @@ -416,15 +418,11 @@ function indent(lines: string, tab: string) { return lines.replace(/^(?=.+$)/gm, tab); } -export function prepareErrorStack(stack: string, file?: string): { +export function prepareErrorStack(stack: string): { message: string; stackLines: string[]; location?: Location; } { - if (file) { - // Stack will have /private/var/folders instead of /var/folders on Mac. - file = fs.realpathSync(file); - } const lines = stack.split('\n'); let firstStackLine = lines.findIndex(line => line.startsWith(' at ')); if (firstStackLine === -1) @@ -436,10 +434,8 @@ export function prepareErrorStack(stack: string, file?: string): { const { frame: parsed, fileName: resolvedFile } = parseStackTraceLine(line); if (!parsed || !resolvedFile) continue; - if (!file || resolvedFile === file) { - location = { file: resolvedFile, column: parsed.column || 0, line: parsed.line || 0 }; - break; - } + location = { file: resolvedFile, column: parsed.column || 0, line: parsed.line || 0 }; + break; } return { message, stackLines, location }; } diff --git a/packages/playwright-test/src/reporters/json.ts b/packages/playwright-test/src/reporters/json.ts index 36fd5495b0..c5b21a695a 100644 --- a/packages/playwright-test/src/reporters/json.ts +++ b/packages/playwright-test/src/reporters/json.ts @@ -185,7 +185,7 @@ class JSONReporter implements Reporter { })), }; if (result.error?.stack) - jsonResult.errorLocation = prepareErrorStack(result.error.stack, test.location.file).location; + jsonResult.errorLocation = prepareErrorStack(result.error.stack).location; return jsonResult; } diff --git a/tests/playwright-test/reporter-base.spec.ts b/tests/playwright-test/reporter-base.spec.ts index 7ca35ab95f..d044c1a8a2 100644 --- a/tests/playwright-test/reporter-base.spec.ts +++ b/tests/playwright-test/reporter-base.spec.ts @@ -85,7 +85,7 @@ test('should print an error in a codeframe', async ({ runInlineTest }) => { expect(result.output).toContain(`> 7 | const error = new Error('my-message');`); }); -test('should not print codeframe from a helper', async ({ runInlineTest }) => { +test('should print codeframe from a helper', async ({ runInlineTest }) => { const result = await runInlineTest({ 'helper.ts': ` export function ohMy() { @@ -105,9 +105,9 @@ test('should not print codeframe from a helper', async ({ runInlineTest }) => { expect(result.exitCode).toBe(1); expect(result.failed).toBe(1); expect(result.output).toContain('Error: oh my'); - expect(result.output).toContain(` 7 | test('foobar', async ({}) => {`); - expect(result.output).toContain(`> 8 | ohMy();`); - expect(result.output).toContain(` | ^`); + expect(result.output).toContain(` 4 | export function ohMy() {`); + expect(result.output).toContain(` > 5 | throw new Error('oh my');`); + expect(result.output).toContain(` | ^`); }); test('should print slow tests', async ({ runInlineTest }) => {