Skip to content

Commit 4c66f8a

Browse files
authored
cherry-pick(#31970): fix(trace): do not place expect into unfinished … (#31974)
…api calls based on time Fixes #31959
1 parent deba37b commit 4c66f8a

3 files changed

Lines changed: 54 additions & 2 deletions

File tree

packages/playwright/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ const playwrightFixtures: Fixtures<TestFixtures, WorkerFixtures> = ({
261261
title: renderApiCall(apiName, params),
262262
apiName,
263263
params,
264+
canNestByTime: true,
264265
});
265266
userData.userObject = step;
266267
out.stepId = step.stepId;

packages/playwright/src/worker/testInfo.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export interface TestStepInternal {
3333
complete(result: { error?: Error, attachments?: Attachment[] }): void;
3434
stepId: string;
3535
title: string;
36-
category: 'hook' | 'fixture' | 'test.step' | 'expect' | string;
36+
category: 'hook' | 'fixture' | 'test.step' | 'expect' | 'attach' | string;
3737
location?: Location;
3838
boxedStack?: StackFrame[];
3939
steps: TestStepInternal[];
@@ -44,6 +44,9 @@ export interface TestStepInternal {
4444
infectParentStepsWithError?: boolean;
4545
box?: boolean;
4646
isStage?: boolean;
47+
// TODO: this сould be decided based on the category, but pw:api
48+
// is from a different abstraction layer.
49+
canNestByTime?: boolean;
4750
}
4851

4952
export type TestStage = {
@@ -252,7 +255,7 @@ export class TestInfoImpl implements TestInfo {
252255
parentStep = this._findLastStageStep();
253256
} else {
254257
parentStep = zones.zoneData<TestStepInternal>('stepZone');
255-
if (!parentStep && data.category !== 'test.step') {
258+
if (!parentStep && data.canNestByTime) {
256259
// API steps (but not test.step calls) can be nested by time, instead of by stack.
257260
// However, do not nest chains of route.continue by checking the title.
258261
parentStep = this._findLastNonFinishedStep(step => step.title !== data.title);

tests/playwright-test/playwright.trace.spec.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1178,3 +1178,51 @@ test('should record trace for manually created context in a failed test', async
11781178
// Check console events to make sure that library trace is recorded.
11791179
expect(trace.events).toContainEqual(expect.objectContaining({ type: 'console', text: 'from the page' }));
11801180
});
1181+
1182+
test('should not nest top level expect into unfinished api calls ', {
1183+
annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/31959' }
1184+
}, async ({ runInlineTest, server }) => {
1185+
server.setRoute('/index', (req, res) => {
1186+
res.writeHead(200, { 'Content-Type': 'text/html' });
1187+
res.end(`<script>fetch('/api')</script><div>Hello!</div>`);
1188+
});
1189+
server.setRoute('/hang', () => {});
1190+
const result = await runInlineTest({
1191+
'a.spec.ts': `
1192+
import { test, expect } from '@playwright/test';
1193+
test('pass', async ({ page }) => {
1194+
await page.route('**/api', async route => {
1195+
const response = await route.fetch({ url: '${server.PREFIX}/hang' });
1196+
await route.fulfill({ response });
1197+
});
1198+
await page.goto('${server.PREFIX}/index');
1199+
await expect(page.getByText('Hello!')).toBeVisible();
1200+
await page.unrouteAll({ behavior: 'ignoreErrors' });
1201+
});
1202+
`,
1203+
}, { trace: 'on' });
1204+
expect(result.exitCode).toBe(0);
1205+
expect(result.failed).toBe(0);
1206+
1207+
const tracePath = test.info().outputPath('test-results', 'a-pass', 'trace.zip');
1208+
const trace = await parseTrace(tracePath);
1209+
expect(trace.actionTree).toEqual([
1210+
'Before Hooks',
1211+
' fixture: browser',
1212+
' browserType.launch',
1213+
' fixture: context',
1214+
' browser.newContext',
1215+
' fixture: page',
1216+
' browserContext.newPage',
1217+
'page.route',
1218+
'page.goto',
1219+
' route.fetch',
1220+
' page.unrouteAll',
1221+
'expect.toBeVisible',
1222+
'After Hooks',
1223+
' fixture: page',
1224+
' fixture: context',
1225+
]);
1226+
});
1227+
1228+

0 commit comments

Comments
 (0)