feat(hooks): add a step per hook (#12867)
It is now possible to see which hooks were run in the html report.
This commit is contained in:
parent
c7d6f96328
commit
3a009531b1
|
|
@ -214,6 +214,18 @@ export class TestInfoImpl implements TestInfo {
|
|||
this.errors.push(error);
|
||||
}
|
||||
|
||||
async _runAsStep<T>(cb: () => Promise<T>, stepInfo: Omit<TestStepInternal, 'complete'>): Promise<T> {
|
||||
const step = this._addStep(stepInfo);
|
||||
try {
|
||||
const result = await cb();
|
||||
step.complete();
|
||||
return result;
|
||||
} catch (e) {
|
||||
step.complete(e instanceof SkipError ? undefined : serializeError(e));
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------ TestInfo methods ------------
|
||||
|
||||
async attach(name: string, options: { path?: string, body?: string | Buffer, contentType?: string } = {}) {
|
||||
|
|
|
|||
|
|
@ -418,7 +418,13 @@ export class WorkerRunner extends EventEmitter {
|
|||
if (actualScope !== scope)
|
||||
continue;
|
||||
testInfo._timeoutManager.setCurrentRunnable({ type: modifier.type, location: modifier.location, slot: timeSlot });
|
||||
const result = await this._fixtureRunner.resolveParametersAndRunFunction(modifier.fn, testInfo);
|
||||
const result = await testInfo._runAsStep(() => this._fixtureRunner.resolveParametersAndRunFunction(modifier.fn, testInfo), {
|
||||
category: 'hook',
|
||||
title: `${modifier.type} modifier`,
|
||||
canHaveChildren: true,
|
||||
forceNoParent: false,
|
||||
location: modifier.location,
|
||||
});
|
||||
if (result && extraAnnotations)
|
||||
extraAnnotations.push({ type: modifier.type, description: modifier.description });
|
||||
testInfo[modifier.type](!!result, modifier.description);
|
||||
|
|
@ -437,7 +443,13 @@ export class WorkerRunner extends EventEmitter {
|
|||
// Separate time slot for each "beforeAll" hook.
|
||||
const timeSlot = { timeout: this._project.config.timeout, elapsed: 0 };
|
||||
testInfo._timeoutManager.setCurrentRunnable({ type: 'beforeAll', location: hook.location, slot: timeSlot });
|
||||
await this._fixtureRunner.resolveParametersAndRunFunction(hook.fn, testInfo);
|
||||
await testInfo._runAsStep(() => this._fixtureRunner.resolveParametersAndRunFunction(hook.fn, testInfo), {
|
||||
category: 'hook',
|
||||
title: `${hook.type} hook`,
|
||||
canHaveChildren: true,
|
||||
forceNoParent: false,
|
||||
location: hook.location,
|
||||
});
|
||||
} catch (e) {
|
||||
// Always run all the hooks, and capture the first error.
|
||||
beforeAllError = beforeAllError || e;
|
||||
|
|
@ -459,7 +471,13 @@ export class WorkerRunner extends EventEmitter {
|
|||
// Separate time slot for each "afterAll" hook.
|
||||
const timeSlot = { timeout: this._project.config.timeout, elapsed: 0 };
|
||||
testInfo._timeoutManager.setCurrentRunnable({ type: 'afterAll', location: hook.location, slot: timeSlot });
|
||||
await this._fixtureRunner.resolveParametersAndRunFunction(hook.fn, testInfo);
|
||||
await testInfo._runAsStep(() => this._fixtureRunner.resolveParametersAndRunFunction(hook.fn, testInfo), {
|
||||
category: 'hook',
|
||||
title: `${hook.type} hook`,
|
||||
canHaveChildren: true,
|
||||
forceNoParent: false,
|
||||
location: hook.location,
|
||||
});
|
||||
});
|
||||
firstError = firstError || afterAllError;
|
||||
}
|
||||
|
|
@ -472,7 +490,13 @@ export class WorkerRunner extends EventEmitter {
|
|||
for (const hook of hooks) {
|
||||
try {
|
||||
testInfo._timeoutManager.setCurrentRunnable({ type, location: hook.location, slot: timeSlot });
|
||||
await this._fixtureRunner.resolveParametersAndRunFunction(hook.fn, testInfo);
|
||||
await testInfo._runAsStep(() => this._fixtureRunner.resolveParametersAndRunFunction(hook.fn, testInfo), {
|
||||
category: 'hook',
|
||||
title: `${hook.type} hook`,
|
||||
canHaveChildren: true,
|
||||
forceNoParent: false,
|
||||
location: hook.location,
|
||||
});
|
||||
} catch (e) {
|
||||
// Always run all the hooks, and capture the first error.
|
||||
error = error || e;
|
||||
|
|
|
|||
|
|
@ -392,13 +392,31 @@ test('should show multi trace source', async ({ runInlineTest, page, server, sho
|
|||
await expect(page.locator('.source-line-running')).toContainText('request.get');
|
||||
});
|
||||
|
||||
test('should show timed out steps', async ({ runInlineTest, page, showReport }) => {
|
||||
test('should show timed out steps and hooks', async ({ runInlineTest, page, showReport }) => {
|
||||
const result = await runInlineTest({
|
||||
'playwright.config.js': `
|
||||
module.exports = { timeout: 3000 };
|
||||
`,
|
||||
'a.test.js': `
|
||||
const { test } = pwt;
|
||||
test.beforeAll(() => {
|
||||
console.log('beforeAll 1');
|
||||
});
|
||||
test.beforeAll(() => {
|
||||
console.log('beforeAll 2');
|
||||
});
|
||||
test.beforeEach(() => {
|
||||
console.log('beforeEach 1');
|
||||
});
|
||||
test.beforeEach(() => {
|
||||
console.log('beforeEach 2');
|
||||
});
|
||||
test.afterEach(() => {
|
||||
console.log('afterEach 1');
|
||||
});
|
||||
test.afterAll(() => {
|
||||
console.log('afterAll 1');
|
||||
});
|
||||
test('fails', async ({ page }) => {
|
||||
await test.step('outer step', async () => {
|
||||
await test.step('inner step', async () => {
|
||||
|
|
@ -416,6 +434,20 @@ test('should show timed out steps', async ({ runInlineTest, page, showReport })
|
|||
await page.click('text=outer step');
|
||||
await expect(page.locator('.tree-item:has-text("outer step") svg.color-text-danger')).toHaveCount(2);
|
||||
await expect(page.locator('.tree-item:has-text("inner step") svg.color-text-danger')).toHaveCount(2);
|
||||
await page.click('text=Before Hooks');
|
||||
await expect(page.locator('.tree-item:has-text("Before Hooks") .tree-item')).toContainText([
|
||||
/beforeAll hook/,
|
||||
/beforeAll hook/,
|
||||
/beforeEach hook/,
|
||||
/beforeEach hook/,
|
||||
]);
|
||||
await page.locator('text=beforeAll hook').nth(1).click();
|
||||
await expect(page.locator('text=console.log(\'beforeAll 2\');')).toBeVisible();
|
||||
await page.click('text=After Hooks');
|
||||
await expect(page.locator('.tree-item:has-text("After Hooks") .tree-item')).toContainText([
|
||||
/afterEach hook/,
|
||||
/afterAll hook/,
|
||||
]);
|
||||
});
|
||||
|
||||
test('should render annotations', async ({ runInlineTest, page, showReport }) => {
|
||||
|
|
|
|||
|
|
@ -343,11 +343,13 @@ test('should report api steps', async ({ runInlineTest }) => {
|
|||
`%% end {\"title\":\"browserContext.close\",\"category\":\"pw:api\"}`,
|
||||
`%% end {\"title\":\"After Hooks\",\"category\":\"hook\",\"steps\":[{\"title\":\"apiRequestContext.dispose\",\"category\":\"pw:api\"},{\"title\":\"browserContext.close\",\"category\":\"pw:api\"}]}`,
|
||||
`%% begin {\"title\":\"Before Hooks\",\"category\":\"hook\"}`,
|
||||
`%% begin {\"title\":\"beforeAll hook\",\"category\":\"hook\"}`,
|
||||
`%% begin {\"title\":\"browser.newPage\",\"category\":\"pw:api\"}`,
|
||||
`%% end {\"title\":\"browser.newPage\",\"category\":\"pw:api\"}`,
|
||||
`%% begin {\"title\":\"page.setContent\",\"category\":\"pw:api\"}`,
|
||||
`%% end {\"title\":\"page.setContent\",\"category\":\"pw:api\"}`,
|
||||
`%% end {\"title\":\"Before Hooks\",\"category\":\"hook\",\"steps\":[{\"title\":\"browser.newPage\",\"category\":\"pw:api\"},{\"title\":\"page.setContent\",\"category\":\"pw:api\"}]}`,
|
||||
`%% end {\"title\":\"beforeAll hook\",\"category\":\"hook\",\"steps\":[{\"title\":\"browser.newPage\",\"category\":\"pw:api\"},{\"title\":\"page.setContent\",\"category\":\"pw:api\"}]}`,
|
||||
`%% end {\"title\":\"Before Hooks\",\"category\":\"hook\",\"steps\":[{\"title\":\"beforeAll hook\",\"category\":\"hook\",\"steps\":[{\"title\":\"browser.newPage\",\"category\":\"pw:api\"},{\"title\":\"page.setContent\",\"category\":\"pw:api\"}]}]}`,
|
||||
`%% begin {\"title\":\"page.click(button)\",\"category\":\"pw:api\"}`,
|
||||
`%% end {\"title\":\"page.click(button)\",\"category\":\"pw:api\"}`,
|
||||
`%% begin {\"title\":\"After Hooks\",\"category\":\"hook\"}`,
|
||||
|
|
@ -357,9 +359,11 @@ test('should report api steps', async ({ runInlineTest }) => {
|
|||
`%% begin {\"title\":\"page.click(button)\",\"category\":\"pw:api\"}`,
|
||||
`%% end {\"title\":\"page.click(button)\",\"category\":\"pw:api\"}`,
|
||||
`%% begin {\"title\":\"After Hooks\",\"category\":\"hook\"}`,
|
||||
`%% begin {\"title\":\"afterAll hook\",\"category\":\"hook\"}`,
|
||||
`%% begin {\"title\":\"page.close\",\"category\":\"pw:api\"}`,
|
||||
`%% end {\"title\":\"page.close\",\"category\":\"pw:api\"}`,
|
||||
`%% end {\"title\":\"After Hooks\",\"category\":\"hook\",\"steps\":[{\"title\":\"page.close\",\"category\":\"pw:api\"}]}`,
|
||||
`%% end {\"title\":\"afterAll hook\",\"category\":\"hook\",\"steps\":[{\"title\":\"page.close\",\"category\":\"pw:api\"}]}`,
|
||||
`%% end {\"title\":\"After Hooks\",\"category\":\"hook\",\"steps\":[{\"title\":\"afterAll hook\",\"category\":\"hook\",\"steps\":[{\"title\":\"page.close\",\"category\":\"pw:api\"}]}]}`,
|
||||
]);
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue