fix(test runner): update TestInfo.duration before running afterEach hooks (#10228)

This commit is contained in:
Dmitry Gozman 2021-11-10 16:02:27 -08:00 committed by GitHub
parent 9ec3e7cd52
commit 9622704a8a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 8 additions and 9 deletions

View file

@ -81,7 +81,7 @@ Processed configuration from the [configuration file](./test-configuration.md).
## property: TestInfo.duration
- type: <[int]>
The number of milliseconds the test took to finish. Always zero before the test finishes, either successfully or not.
The number of milliseconds the test took to finish. Always zero before the test finishes, either successfully or not. Can be used in [`method: Test.afterEach`] hook.
## property: TestInfo.error

View file

@ -35,6 +35,5 @@ export interface TestStepInternal {
}
export interface TestInfoImpl extends TestInfo {
_testFinished: Promise<void>;
_addStep: (data: Omit<TestStepInternal, 'complete'>) => TestStepInternal;
}

View file

@ -246,7 +246,6 @@ export class WorkerRunner extends EventEmitter {
return path.join(this._project.config.snapshotDir, relativeTestFilePath + '-snapshots');
})();
let testFinishedCallback = () => {};
let lastStepId = 0;
const testInfo: TestInfoImpl = {
workerIndex: this._params.workerIndex,
@ -299,7 +298,6 @@ export class WorkerRunner extends EventEmitter {
if (deadlineRunner)
deadlineRunner.updateDeadline(deadline());
},
_testFinished: new Promise(f => testFinishedCallback = f),
_addStep: data => {
const stepId = `${data.category}@${data.title}@${++lastStepId}`;
let callbackHandled = false;
@ -389,7 +387,7 @@ export class WorkerRunner extends EventEmitter {
// Do not overwrite test failure upon hook timeout.
if (result.timedOut && testInfo.status === 'passed')
testInfo.status = 'timedOut';
testFinishedCallback();
testInfo.duration = monotonicTime() - startTime;
if (!result.timedOut) {
this._currentDeadlineRunner = deadlineRunner = new DeadlineRunner(this._runAfterHooks(test, testInfo), deadline());

View file

@ -1329,6 +1329,7 @@ export interface TestInfo {
retry: number;
/**
* The number of milliseconds the test took to finish. Always zero before the test finishes, either successfully or not.
* Can be used in [test.afterEach(hookFunction)](https://playwright.dev/docs/api/class-test#test-after-each) hook.
*/
duration: number;
/**

View file

@ -494,12 +494,13 @@ test('beforeAll and afterAll timeouts at the same time should be reported', asyn
expect(result.output).toContain('Timeout of 1000ms exceeded in beforeAll hook.');
});
test('afterEach should get the test status right away', async ({ runInlineTest }) => {
test('afterEach should get the test status and duration right away', async ({ runInlineTest }) => {
const result = await runInlineTest({
'a.test.js': `
const { test } = pwt;
test.afterEach(({}, testInfo) => {
console.log('\\n%%' + testInfo.title + ': ' + testInfo.status);
const duration = testInfo.duration ? 'XXms' : 'none';
console.log('\\n%%' + testInfo.title + ': ' + testInfo.status + '; ' + duration);
});
test('failing', () => {
throw new Error('Oh my!');
@ -513,8 +514,8 @@ test('afterEach should get the test status right away', async ({ runInlineTest }
expect(result.exitCode).toBe(1);
expect(result.failed).toBe(2);
expect(result.output.split('\n').filter(line => line.startsWith('%%'))).toEqual([
'%%failing: failed',
'%%timing out: timedOut',
'%%failing: failed; XXms',
'%%timing out: timedOut; XXms',
]);
});