fix(error): create a step for raw runtime error (#24057)

Fix https://github.com/microsoft/playwright/issues/23850
This commit is contained in:
Pavel Feldman 2023-07-06 10:48:12 -07:00 committed by GitHub
parent 88010333f3
commit 608e336dba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 51 additions and 3 deletions

View File

@ -23,7 +23,7 @@ import { ConfigLoader } from '../common/configLoader';
import type { Suite, TestCase } from '../common/test';
import type { Annotation, FullConfigInternal, FullProjectInternal } from '../common/config';
import { FixtureRunner } from './fixtureRunner';
import { ManualPromise } from 'playwright-core/lib/utils';
import { ManualPromise, captureLibraryStackTrace } from 'playwright-core/lib/utils';
import { TestInfoImpl } from './testInfo';
import { TimeoutManager, type TimeSlot } from './timeoutManager';
import { ProcessRunner } from '../common/process';
@ -369,13 +369,25 @@ export class WorkerMain extends ProcessRunner {
return;
}
await testInfo._runAndFailOnError(async () => {
const error = await testInfo._runAndFailOnError(async () => {
// Now run the test itself.
debugTest(`test function started`);
const fn = test.fn; // Extract a variable to get a better stack trace ("myTest" vs "TestCase.myTest [as fn]").
await fn(testFunctionParams, testInfo);
debugTest(`test function finished`);
}, 'allowSkips');
// If there are no steps with errors in the test, but the test has an error - append artificial trace entry.
if (error && !testInfo._steps.some(s => !!s.error)) {
const frames = error.stack ? captureLibraryStackTrace(error.stack.split('\n')).frames : [];
const step = testInfo._addStep({
wallTime: Date.now(),
title: error.message || 'error',
category: 'hook',
location: frames[0],
});
step.complete({ error });
}
});
if (didFailBeforeAllForSuite) {

View File

@ -331,6 +331,7 @@ test('should not override trace file in afterAll', async ({ runInlineTest, serve
' fixture: page',
' browserContext.newPage',
'page.goto',
'error',
'After Hooks',
' fixture: page',
' fixture: context',
@ -650,3 +651,38 @@ test('should expand expect.toPass', async ({ runInlineTest }, testInfo) => {
' fixture: context',
]);
});
test('should show non-expect error in trace', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({
'playwright.config.ts': `
module.exports = { use: { trace: { mode: 'on' } } };
`,
'a.spec.ts': `
import { test, expect } from '@playwright/test';
test('fail', async ({ page }) => {
expect(1).toBe(1);
undefinedVariable1 = 'this throws an exception';
expect(1).toBe(2);
});
`,
}, { workers: 1 });
expect(result.exitCode).toBe(1);
expect(result.failed).toBe(1);
const trace = await parseTrace(testInfo.outputPath('test-results', 'a-fail', 'trace.zip'));
expect(trace.actionTree).toEqual([
'Before Hooks',
' fixture: browser',
' browserType.launch',
' fixture: context',
' browser.newContext',
' tracing.start',
' fixture: page',
' browserContext.newPage',
'expect.toBe',
'undefinedVariable1 is not defined',
'After Hooks',
' fixture: page',
' fixture: context',
]);
});

View File

@ -780,7 +780,7 @@ for (const useIntermediateMergeReport of [false, true] as const) {
await showReport();
await page.locator('text=sample').first().click();
await expect(page.locator('text=ouch')).toBeVisible();
await expect(page.locator('text=ouch')).toHaveCount(2);
await page.locator('text=All').first().click();
await page.locator('text=sample').nth(1).click();