fix(reporter): fix locator stacks to hide internal detail (#9693)

This commit is contained in:
Pavel Feldman 2021-10-21 15:10:47 -08:00 committed by GitHub
parent 299dffbdb3
commit 6a3e08d1ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 8 deletions

View File

@ -36,14 +36,18 @@ export class Locator implements api.Locator {
private async _withElement<R>(task: (handle: ElementHandle<SVGElement | HTMLElement>, timeout?: number) => Promise<R>, timeout?: number): Promise<R> {
timeout = this._frame.page()._timeoutSettings.timeout({ timeout });
const deadline = timeout ? monotonicTime() + timeout : 0;
const handle = await this.elementHandle({ timeout });
if (!handle)
throw new Error(`Could not resolve ${this._selector} to DOM Element`);
try {
return await task(handle, deadline ? deadline - monotonicTime() : 0);
} finally {
await handle.dispose();
}
return this._frame._wrapApiCall<R>(async (channel: channels.FrameChannel) => {
const result = await channel.waitForSelector({ selector: this._selector, strict: true, state: 'attached', timeout });
const handle = ElementHandle.fromNullable(result.element) as ElementHandle<SVGElement | HTMLElement> | null;
if (!handle)
throw new Error(`Could not resolve ${this._selector} to DOM Element`);
try {
return await task(handle, deadline ? deadline - monotonicTime() : 0);
} finally {
await handle.dispose();
}
});
}
async boundingBox(options?: TimeoutOptions): Promise<Rect | null> {

View File

@ -368,6 +368,43 @@ test('should not have internal error when steps are finished after timeout', asy
expect(result.output).not.toContain('Internal error');
});
test('should show nice stacks for locators', async ({ runInlineTest }) => {
const result = await runInlineTest({
'reporter.ts': stepsReporterJS,
'playwright.config.ts': `
module.exports = {
reporter: './reporter',
};
`,
'a.test.ts': `
const { test } = pwt;
test('pass', async ({ page }) => {
await page.setContent('<button></button>');
const locator = page.locator('button');
await locator.evaluate(e => e.innerText);
});
`
}, { reporter: '', workers: 1 });
expect(result.exitCode).toBe(0);
expect(result.passed).toBe(0);
expect(result.output).not.toContain('Internal error');
expect(result.output.split('\n').filter(line => line.startsWith('%%')).map(stripEscapedAscii)).toEqual([
`%% begin {"title":"Before Hooks","category":"hook"}`,
`%% begin {"title":"browserContext.newPage","category":"pw:api"}`,
`%% end {"title":"browserContext.newPage","category":"pw:api"}`,
`%% end {"title":"Before Hooks","category":"hook","steps":[{"title":"browserContext.newPage","category":"pw:api"}]}`,
`%% begin {"title":"page.setContent","category":"pw:api"}`,
`%% end {"title":"page.setContent","category":"pw:api"}`,
`%% begin {"title":"locator.evaluate(button)","category":"pw:api"}`,
`%% end {"title":"locator.evaluate(button)","category":"pw:api"}`,
`%% begin {"title":"After Hooks","category":"hook"}`,
`%% begin {"title":"browserContext.close","category":"pw:api"}`,
`%% end {"title":"browserContext.close","category":"pw:api"}`,
`%% end {"title":"After Hooks","category":"hook","steps":[{"title":"browserContext.close","category":"pw:api"}]}`,
]);
});
function stripEscapedAscii(str: string) {
return str.replace(/\\u00[a-z0-9][a-z0-9]\[[^m]+m/g, '');
}