mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-11 12:33:45 +03:00
fix(error): create a step for raw runtime error (#24057)
Fix https://github.com/microsoft/playwright/issues/23850
This commit is contained in:
parent
88010333f3
commit
608e336dba
@ -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) {
|
||||
|
@ -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',
|
||||
]);
|
||||
});
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user