mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-14 05:37:20 +03:00
fix(steps): do not show unnecessary steps for internal waitForEventInfo (#10889)
This commit is contained in:
parent
c27491cd4d
commit
9491f6652d
@ -200,7 +200,7 @@ export class AndroidDevice extends ChannelOwner<channels.AndroidDeviceChannel> i
|
||||
return this._wrapApiCall(async () => {
|
||||
const timeout = this._timeoutSettings.timeout(typeof optionsOrPredicate === 'function' ? {} : optionsOrPredicate);
|
||||
const predicate = typeof optionsOrPredicate === 'function' ? optionsOrPredicate : optionsOrPredicate.predicate;
|
||||
const waiter = Waiter.createForEvent(this._channel, event);
|
||||
const waiter = Waiter.createForEvent(this, event);
|
||||
waiter.rejectOnTimeout(timeout, `Timeout ${timeout}ms exceeded while waiting for event "${event}"`);
|
||||
if (event !== Events.AndroidDevice.Close)
|
||||
waiter.rejectOnEvent(this, Events.AndroidDevice.Close, new Error('Device closed'));
|
||||
|
@ -268,7 +268,7 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel>
|
||||
return this._wrapApiCall(async () => {
|
||||
const timeout = this._timeoutSettings.timeout(typeof optionsOrPredicate === 'function' ? {} : optionsOrPredicate);
|
||||
const predicate = typeof optionsOrPredicate === 'function' ? optionsOrPredicate : optionsOrPredicate.predicate;
|
||||
const waiter = Waiter.createForEvent(this._channel, event);
|
||||
const waiter = Waiter.createForEvent(this, event);
|
||||
waiter.rejectOnTimeout(timeout, `Timeout ${timeout}ms exceeded while waiting for event "${event}"`);
|
||||
if (event !== Events.BrowserContext.Close)
|
||||
waiter.rejectOnEvent(this, Events.BrowserContext.Close, new Error('Context closed'));
|
||||
|
@ -104,7 +104,7 @@ export class ElectronApplication extends ChannelOwner<channels.ElectronApplicati
|
||||
return this._wrapApiCall(async () => {
|
||||
const timeout = this._timeoutSettings.timeout(typeof optionsOrPredicate === 'function' ? {} : optionsOrPredicate);
|
||||
const predicate = typeof optionsOrPredicate === 'function' ? optionsOrPredicate : optionsOrPredicate.predicate;
|
||||
const waiter = Waiter.createForEvent(this._channel, event);
|
||||
const waiter = Waiter.createForEvent(this, event);
|
||||
waiter.rejectOnTimeout(timeout, `Timeout ${timeout}ms exceeded while waiting for event "${event}"`);
|
||||
if (event !== Events.ElectronApplication.Close)
|
||||
waiter.rejectOnEvent(this, Events.ElectronApplication.Close, new Error('Electron application closed'));
|
||||
|
@ -93,7 +93,7 @@ export class Frame extends ChannelOwner<channels.FrameChannel> implements api.Fr
|
||||
}
|
||||
|
||||
private _setupNavigationWaiter(options: { timeout?: number }): Waiter {
|
||||
const waiter = new Waiter(this._page!._channel, '');
|
||||
const waiter = new Waiter(this._page!, '');
|
||||
if (this._page!.isClosed())
|
||||
waiter.rejectImmediately(new Error('Navigation failed because page was closed!'));
|
||||
waiter.rejectOnEvent(this._page!, Events.Page.Close, new Error('Navigation failed because page was closed!'));
|
||||
|
@ -474,7 +474,7 @@ export class WebSocket extends ChannelOwner<channels.WebSocketChannel> implement
|
||||
return this._wrapApiCall(async () => {
|
||||
const timeout = this._page._timeoutSettings.timeout(typeof optionsOrPredicate === 'function' ? {} : optionsOrPredicate);
|
||||
const predicate = typeof optionsOrPredicate === 'function' ? optionsOrPredicate : optionsOrPredicate.predicate;
|
||||
const waiter = Waiter.createForEvent(this._channel, event);
|
||||
const waiter = Waiter.createForEvent(this, event);
|
||||
waiter.rejectOnTimeout(timeout, `Timeout ${timeout}ms exceeded while waiting for event "${event}"`);
|
||||
if (event !== Events.WebSocket.Error)
|
||||
waiter.rejectOnEvent(this, Events.WebSocket.Error, new Error('Socket error'));
|
||||
|
@ -359,7 +359,7 @@ export class Page extends ChannelOwner<channels.PageChannel> implements api.Page
|
||||
};
|
||||
const trimmedUrl = trimUrl(urlOrPredicate);
|
||||
const logLine = trimmedUrl ? `waiting for request ${trimmedUrl}` : undefined;
|
||||
return this._waitForEvent(this._channel, Events.Page.Request, { predicate, timeout: options.timeout }, logLine);
|
||||
return this._waitForEvent(Events.Page.Request, { predicate, timeout: options.timeout }, logLine);
|
||||
}
|
||||
|
||||
async waitForResponse(urlOrPredicate: string | RegExp | ((r: Response) => boolean | Promise<boolean>), options: { timeout?: number } = {}): Promise<Response> {
|
||||
@ -370,17 +370,17 @@ export class Page extends ChannelOwner<channels.PageChannel> implements api.Page
|
||||
};
|
||||
const trimmedUrl = trimUrl(urlOrPredicate);
|
||||
const logLine = trimmedUrl ? `waiting for response ${trimmedUrl}` : undefined;
|
||||
return this._waitForEvent(this._channel, Events.Page.Response, { predicate, timeout: options.timeout }, logLine);
|
||||
return this._waitForEvent(Events.Page.Response, { predicate, timeout: options.timeout }, logLine);
|
||||
}
|
||||
|
||||
async waitForEvent(event: string, optionsOrPredicate: WaitForEventOptions = {}): Promise<any> {
|
||||
return this._waitForEvent(this._channel, event, optionsOrPredicate, `waiting for event "${event}"`);
|
||||
return this._waitForEvent(event, optionsOrPredicate, `waiting for event "${event}"`);
|
||||
}
|
||||
|
||||
private async _waitForEvent(channel: channels.EventTargetChannel, event: string, optionsOrPredicate: WaitForEventOptions, logLine?: string): Promise<any> {
|
||||
private async _waitForEvent(event: string, optionsOrPredicate: WaitForEventOptions, logLine?: string): Promise<any> {
|
||||
const timeout = this._timeoutSettings.timeout(typeof optionsOrPredicate === 'function' ? {} : optionsOrPredicate);
|
||||
const predicate = typeof optionsOrPredicate === 'function' ? optionsOrPredicate : optionsOrPredicate.predicate;
|
||||
const waiter = Waiter.createForEvent(channel, event);
|
||||
const waiter = Waiter.createForEvent(this, event);
|
||||
if (logLine)
|
||||
waiter.log(logLine);
|
||||
waiter.rejectOnTimeout(timeout, `Timeout ${timeout}ms exceeded while waiting for event "${event}"`);
|
||||
|
@ -19,28 +19,30 @@ import { rewriteErrorMessage } from '../utils/stackTrace';
|
||||
import { TimeoutError } from '../utils/errors';
|
||||
import { createGuid } from '../utils/utils';
|
||||
import * as channels from '../protocol/channels';
|
||||
import { ChannelOwner } from './channelOwner';
|
||||
|
||||
export class Waiter {
|
||||
private _dispose: (() => void)[];
|
||||
private _failures: Promise<any>[] = [];
|
||||
private _immediateError?: Error;
|
||||
// TODO: can/should we move these logs into wrapApiCall?
|
||||
private _logs: string[] = [];
|
||||
private _channel: channels.EventTargetChannel;
|
||||
private _channelOwner: ChannelOwner<channels.EventTargetChannel>;
|
||||
private _waitId: string;
|
||||
private _error: string | undefined;
|
||||
|
||||
constructor(channel: channels.EventTargetChannel, event: string) {
|
||||
constructor(channelOwner: ChannelOwner<channels.EventTargetChannel>, event: string) {
|
||||
this._waitId = createGuid();
|
||||
this._channel = channel;
|
||||
this._channel.waitForEventInfo({ info: { waitId: this._waitId, phase: 'before', event } }).catch(() => {});
|
||||
this._channelOwner = channelOwner;
|
||||
this._channelOwner._channel.waitForEventInfo({ info: { waitId: this._waitId, phase: 'before', event } }).catch(() => {});
|
||||
this._dispose = [
|
||||
() => this._channel.waitForEventInfo({ info: { waitId: this._waitId, phase: 'after', error: this._error } }).catch(() => {})
|
||||
() => this._channelOwner._wrapApiCall(async () => {
|
||||
await this._channelOwner._channel.waitForEventInfo({ info: { waitId: this._waitId, phase: 'after', error: this._error } });
|
||||
}, true).catch(() => {}),
|
||||
];
|
||||
}
|
||||
|
||||
static createForEvent(channel: channels.EventTargetChannel, event: string) {
|
||||
return new Waiter(channel, event);
|
||||
static createForEvent(channelOwner: ChannelOwner<channels.EventTargetChannel>, event: string) {
|
||||
return new Waiter(channelOwner, event);
|
||||
}
|
||||
|
||||
async waitForEvent<T = void>(emitter: EventEmitter, event: string, predicate?: (arg: T) => boolean | Promise<boolean>): Promise<T> {
|
||||
@ -89,7 +91,9 @@ export class Waiter {
|
||||
|
||||
log(s: string) {
|
||||
this._logs.push(s);
|
||||
this._channel.waitForEventInfo({ info: { waitId: this._waitId, phase: 'log', message: s } }).catch(() => {});
|
||||
this._channelOwner._wrapApiCall(async () => {
|
||||
await this._channelOwner._channel.waitForEventInfo({ info: { waitId: this._waitId, phase: 'log', message: s } }).catch(() => {});
|
||||
}, true);
|
||||
}
|
||||
|
||||
private _rejectOn(promise: Promise<any>, dispose?: () => void) {
|
||||
|
@ -252,7 +252,7 @@ test('should show trace title', async ({ runInlineTest, page, showReport }) => {
|
||||
test('should show timed out steps', async ({ runInlineTest, page, showReport }) => {
|
||||
const result = await runInlineTest({
|
||||
'playwright.config.js': `
|
||||
module.exports = { timeout: 500 };
|
||||
module.exports = { timeout: 3000 };
|
||||
`,
|
||||
'a.test.js': `
|
||||
const { test } = pwt;
|
||||
|
@ -259,7 +259,10 @@ test('should report api steps', async ({ runInlineTest }) => {
|
||||
'a.test.ts': `
|
||||
const { test } = pwt;
|
||||
test('pass', async ({ page }) => {
|
||||
await page.setContent('<button></button>');
|
||||
await Promise.all([
|
||||
page.waitForNavigation(),
|
||||
page.goto('data:text/html,<button></button>'),
|
||||
]);
|
||||
await page.click('button');
|
||||
});
|
||||
|
||||
@ -290,8 +293,10 @@ test('should report api steps', async ({ runInlineTest }) => {
|
||||
`%% 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\":\"page.waitForNavigation\",\"category\":\"pw:api\"}`,
|
||||
`%% begin {\"title\":\"page.goto(data:text/html,<button></button>)\",\"category\":\"pw:api\"}`,
|
||||
`%% end {\"title\":\"page.waitForNavigation\",\"category\":\"pw:api\"}`,
|
||||
`%% end {\"title\":\"page.goto(data:text/html,<button></button>)\",\"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\"}`,
|
||||
|
Loading…
Reference in New Issue
Block a user