chore: remove apiName plumbing and some unused methods from server side (#3481)
We append apiName where needed on the client instead.
This commit is contained in:
parent
244c2f37b6
commit
bc23324878
|
|
@ -86,7 +86,7 @@ export abstract class BrowserContextBase extends EventEmitter implements Browser
|
|||
|
||||
async waitForEvent(event: string, optionsOrPredicate: types.WaitForEventOptions = {}): Promise<any> {
|
||||
const options = typeof optionsOrPredicate === 'function' ? { predicate: optionsOrPredicate } : optionsOrPredicate;
|
||||
const progressController = new ProgressController(this._apiLogger, this._timeoutSettings.timeout(options), 'browserContext.waitForEvent');
|
||||
const progressController = new ProgressController(this._apiLogger, this._timeoutSettings.timeout(options));
|
||||
if (event !== Events.BrowserContext.Close)
|
||||
this._closePromise.then(error => progressController.abort(error));
|
||||
return progressController.run(progress => helper.waitForEvent(progress, this, event, options.predicate).promise);
|
||||
|
|
@ -191,9 +191,9 @@ export abstract class BrowserContextBase extends EventEmitter implements Browser
|
|||
if (!this.pages().length)
|
||||
await this.waitForEvent('page');
|
||||
const pages = this.pages();
|
||||
await pages[0].waitForLoadState();
|
||||
if (pages.length !== 1 || pages[0].url() !== 'about:blank')
|
||||
throw new Error(`Arguments can not specify page to be opened (first url is ${pages[0].url()})`);
|
||||
await pages[0].mainFrame().waitForLoadState();
|
||||
if (pages.length !== 1 || pages[0].mainFrame().url() !== 'about:blank')
|
||||
throw new Error(`Arguments can not specify page to be opened (first url is ${pages[0].mainFrame().url()})`);
|
||||
if (this._options.isMobile || this._options.locale) {
|
||||
// Workaround for:
|
||||
// - chromium fails to change isMobile for existing page;
|
||||
|
|
|
|||
30
src/dom.ts
30
src/dom.ts
|
|
@ -223,7 +223,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
|||
async scrollIntoViewIfNeeded(options: types.TimeoutOptions = {}) {
|
||||
return this._page._runAbortableTask(
|
||||
progress => this._waitAndScrollIntoViewIfNeeded(progress),
|
||||
this._page._timeoutSettings.timeout(options), 'elementHandle.scrollIntoViewIfNeeded');
|
||||
this._page._timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
private async _waitForVisible(progress: Progress): Promise<'error:notconnected' | 'done'> {
|
||||
|
|
@ -376,7 +376,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
|||
return this._page._runAbortableTask(async progress => {
|
||||
const result = await this._hover(progress, options);
|
||||
return assertDone(throwRetargetableDOMError(result));
|
||||
}, this._page._timeoutSettings.timeout(options), 'elementHandle.hover');
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
_hover(progress: Progress, options: types.PointerActionOptions & types.PointerActionWaitOptions): Promise<'error:notconnected' | 'done'> {
|
||||
|
|
@ -387,7 +387,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
|||
return this._page._runAbortableTask(async progress => {
|
||||
const result = await this._click(progress, options);
|
||||
return assertDone(throwRetargetableDOMError(result));
|
||||
}, this._page._timeoutSettings.timeout(options), 'elementHandle.click');
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
_click(progress: Progress, options: types.MouseClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions): Promise<'error:notconnected' | 'done'> {
|
||||
|
|
@ -398,7 +398,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
|||
return this._page._runAbortableTask(async progress => {
|
||||
const result = await this._dblclick(progress, options);
|
||||
return assertDone(throwRetargetableDOMError(result));
|
||||
}, this._page._timeoutSettings.timeout(options), 'elementHandle.dblclick');
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
_dblclick(progress: Progress, options: types.MouseMultiClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions): Promise<'error:notconnected' | 'done'> {
|
||||
|
|
@ -409,7 +409,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
|||
return this._page._runAbortableTask(async progress => {
|
||||
const result = await this._selectOption(progress, values, options);
|
||||
return throwRetargetableDOMError(result);
|
||||
}, this._page._timeoutSettings.timeout(options), 'elementHandle.selectOption');
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async _selectOption(progress: Progress, values: string | ElementHandle | types.SelectOption | string[] | ElementHandle[] | types.SelectOption[] | null, options: types.NavigatingActionWaitOptions): Promise<string[] | 'error:notconnected'> {
|
||||
|
|
@ -444,7 +444,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
|||
return this._page._runAbortableTask(async progress => {
|
||||
const result = await this._fill(progress, value, options);
|
||||
assertDone(throwRetargetableDOMError(result));
|
||||
}, this._page._timeoutSettings.timeout(options), 'elementHandle.fill');
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async _fill(progress: Progress, value: string, options: types.NavigatingActionWaitOptions): Promise<'error:notconnected' | 'done'> {
|
||||
|
|
@ -483,14 +483,14 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
|||
const pollHandler = new InjectedScriptPollHandler(progress, poll);
|
||||
const result = throwFatalDOMError(await pollHandler.finish());
|
||||
assertDone(throwRetargetableDOMError(result));
|
||||
}, this._page._timeoutSettings.timeout(options), 'elementHandle.selectText');
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async setInputFiles(files: string | types.FilePayload | string[] | types.FilePayload[], options: types.NavigatingActionWaitOptions = {}) {
|
||||
return this._page._runAbortableTask(async progress => {
|
||||
const result = await this._setInputFiles(progress, files, options);
|
||||
return assertDone(throwRetargetableDOMError(result));
|
||||
}, this._page._timeoutSettings.timeout(options), 'elementHandle.setInputFiles');
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async _setInputFiles(progress: Progress, files: string | types.FilePayload | string[] | types.FilePayload[], options: types.NavigatingActionWaitOptions): Promise<'error:notconnected' | 'done'> {
|
||||
|
|
@ -517,7 +517,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
|||
return this._page._runAbortableTask(async progress => {
|
||||
const result = await this._focus(progress);
|
||||
return assertDone(throwRetargetableDOMError(result));
|
||||
}, 0, 'elementHandle.focus');
|
||||
}, 0);
|
||||
}
|
||||
|
||||
async _focus(progress: Progress, resetSelectionIfNotFocused?: boolean): Promise<'error:notconnected' | 'done'> {
|
||||
|
|
@ -530,7 +530,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
|||
return this._page._runAbortableTask(async progress => {
|
||||
const result = await this._type(progress, text, options);
|
||||
return assertDone(throwRetargetableDOMError(result));
|
||||
}, this._page._timeoutSettings.timeout(options), 'elementHandle.type');
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async _type(progress: Progress, text: string, options: { delay?: number } & types.NavigatingActionWaitOptions): Promise<'error:notconnected' | 'done'> {
|
||||
|
|
@ -549,7 +549,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
|||
return this._page._runAbortableTask(async progress => {
|
||||
const result = await this._press(progress, key, options);
|
||||
return assertDone(throwRetargetableDOMError(result));
|
||||
}, this._page._timeoutSettings.timeout(options), 'elementHandle.press');
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async _press(progress: Progress, key: string, options: { delay?: number } & types.NavigatingActionWaitOptions): Promise<'error:notconnected' | 'done'> {
|
||||
|
|
@ -568,14 +568,14 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
|||
return this._page._runAbortableTask(async progress => {
|
||||
const result = await this._setChecked(progress, true, options);
|
||||
return assertDone(throwRetargetableDOMError(result));
|
||||
}, this._page._timeoutSettings.timeout(options), 'elementHandle.check');
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async uncheck(options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) {
|
||||
return this._page._runAbortableTask(async progress => {
|
||||
const result = await this._setChecked(progress, false, options);
|
||||
return assertDone(throwRetargetableDOMError(result));
|
||||
}, this._page._timeoutSettings.timeout(options), 'elementHandle.uncheck');
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async _setChecked(progress: Progress, state: boolean, options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions): Promise<'error:notconnected' | 'done'> {
|
||||
|
|
@ -596,7 +596,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
|||
async screenshot(options: types.ElementScreenshotOptions = {}): Promise<Buffer> {
|
||||
return this._page._runAbortableTask(
|
||||
progress => this._page._screenshotter.screenshotElement(progress, this, options),
|
||||
this._page._timeoutSettings.timeout(options), 'elementHandle.screenshot');
|
||||
this._page._timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async $(selector: string): Promise<ElementHandle | null> {
|
||||
|
|
@ -655,7 +655,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
|||
}
|
||||
const handle = result.asElement() as ElementHandle<Element>;
|
||||
return handle._adoptTo(await this._context.frame._mainContext());
|
||||
}, this._page._timeoutSettings.timeout(options), 'elementHandle.waitForSelector');
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async _adoptTo(context: FrameExecutionContext): Promise<ElementHandle<T>> {
|
||||
|
|
|
|||
|
|
@ -378,11 +378,6 @@ export class Frame {
|
|||
return this._page;
|
||||
}
|
||||
|
||||
private _apiName(method: string) {
|
||||
const subject = this._page._callingPageAPI ? 'page' : 'frame';
|
||||
return `${subject}.${method}`;
|
||||
}
|
||||
|
||||
_onLifecycleEvent(event: types.LifecycleEvent) {
|
||||
if (this._firedLifecycleEvents.has(event))
|
||||
return;
|
||||
|
|
@ -434,7 +429,7 @@ export class Frame {
|
|||
}
|
||||
|
||||
async goto(url: string, options: types.GotoOptions = {}): Promise<network.Response | null> {
|
||||
return runNavigationTask(this, options, this._apiName('goto'), async progress => {
|
||||
return runNavigationTask(this, options, async progress => {
|
||||
const waitUntil = verifyLifecycle('waitUntil', options.waitUntil === undefined ? 'load' : options.waitUntil);
|
||||
progress.logger.info(`navigating to "${url}", waiting until "${waitUntil}"`);
|
||||
const headers = (this._page._state.extraHTTPHeaders || {});
|
||||
|
|
@ -478,7 +473,7 @@ export class Frame {
|
|||
}
|
||||
|
||||
async waitForNavigation(options: types.WaitForNavigationOptions = {}): Promise<network.Response | null> {
|
||||
return runNavigationTask(this, options, this._apiName('waitForNavigation'), async progress => {
|
||||
return runNavigationTask(this, options, async progress => {
|
||||
const toUrl = typeof options.url === 'string' ? ` to "${options.url}"` : '';
|
||||
const waitUntil = verifyLifecycle('waitUntil', options.waitUntil === undefined ? 'load' : options.waitUntil);
|
||||
progress.logger.info(`waiting for navigation${toUrl} until "${waitUntil}"`);
|
||||
|
|
@ -502,7 +497,7 @@ export class Frame {
|
|||
}
|
||||
|
||||
async waitForLoadState(state: types.LifecycleEvent = 'load', options: types.TimeoutOptions = {}): Promise<void> {
|
||||
return runNavigationTask(this, options, this._apiName('waitForLoadState'), progress => this._waitForLoadState(progress, state));
|
||||
return runNavigationTask(this, options, progress => this._waitForLoadState(progress, state));
|
||||
}
|
||||
|
||||
async _waitForLoadState(progress: Progress, state: types.LifecycleEvent): Promise<void> {
|
||||
|
|
@ -578,7 +573,7 @@ export class Frame {
|
|||
}
|
||||
const handle = result.asElement() as dom.ElementHandle<Element>;
|
||||
return handle._adoptTo(await this._mainContext());
|
||||
}, this._page._timeoutSettings.timeout(options), this._apiName('waitForSelector'));
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async dispatchEvent(selector: string, type: string, eventInit?: Object, options: types.TimeoutOptions = {}): Promise<void> {
|
||||
|
|
@ -588,7 +583,7 @@ export class Frame {
|
|||
progress.logger.info(`Dispatching "${type}" event on selector "${selector}"...`);
|
||||
// Note: we always dispatch events in the main world.
|
||||
await this._scheduleRerunnableTask(progress, 'main', task);
|
||||
}, this._page._timeoutSettings.timeout(options), this._apiName('dispatchEvent'));
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async $eval<R, Arg>(selector: string, pageFunction: js.FuncOn<Element, Arg, R>, arg: Arg): Promise<R>;
|
||||
|
|
@ -638,7 +633,7 @@ export class Frame {
|
|||
}
|
||||
|
||||
async setContent(html: string, options: types.NavigateOptions = {}): Promise<void> {
|
||||
return runNavigationTask(this, options, this._apiName('setContent'), async progress => {
|
||||
return runNavigationTask(this, options, async progress => {
|
||||
const waitUntil = options.waitUntil === undefined ? 'load' : options.waitUntil;
|
||||
progress.logger.info(`setting frame content, waiting until "${waitUntil}"`);
|
||||
const tag = `--playwright--set--content--${this._id}--${++this._setContentCounter}--`;
|
||||
|
|
@ -823,8 +818,7 @@ export class Frame {
|
|||
|
||||
private async _retryWithSelectorIfNotConnected<R>(
|
||||
selector: string, options: types.TimeoutOptions,
|
||||
action: (progress: Progress, handle: dom.ElementHandle<Element>) => Promise<R | 'error:notconnected'>,
|
||||
apiName: string): Promise<R> {
|
||||
action: (progress: Progress, handle: dom.ElementHandle<Element>) => Promise<R | 'error:notconnected'>): Promise<R> {
|
||||
const info = selectors._parseSelector(selector);
|
||||
return this._page._runAbortableTask(async progress => {
|
||||
while (progress.isRunning()) {
|
||||
|
|
@ -846,23 +840,23 @@ export class Frame {
|
|||
return result;
|
||||
}
|
||||
return undefined as any;
|
||||
}, this._page._timeoutSettings.timeout(options), apiName);
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async click(selector: string, options: types.MouseClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) {
|
||||
await this._retryWithSelectorIfNotConnected(selector, options, (progress, handle) => handle._click(progress, options), this._apiName('click'));
|
||||
await this._retryWithSelectorIfNotConnected(selector, options, (progress, handle) => handle._click(progress, options));
|
||||
}
|
||||
|
||||
async dblclick(selector: string, options: types.MouseMultiClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) {
|
||||
await this._retryWithSelectorIfNotConnected(selector, options, (progress, handle) => handle._dblclick(progress, options), this._apiName('dblclick'));
|
||||
await this._retryWithSelectorIfNotConnected(selector, options, (progress, handle) => handle._dblclick(progress, options));
|
||||
}
|
||||
|
||||
async fill(selector: string, value: string, options: types.NavigatingActionWaitOptions = {}) {
|
||||
await this._retryWithSelectorIfNotConnected(selector, options, (progress, handle) => handle._fill(progress, value, options), this._apiName('fill'));
|
||||
await this._retryWithSelectorIfNotConnected(selector, options, (progress, handle) => handle._fill(progress, value, options));
|
||||
}
|
||||
|
||||
async focus(selector: string, options: types.TimeoutOptions = {}) {
|
||||
await this._retryWithSelectorIfNotConnected(selector, options, (progress, handle) => handle._focus(progress), this._apiName('focus'));
|
||||
await this._retryWithSelectorIfNotConnected(selector, options, (progress, handle) => handle._focus(progress));
|
||||
}
|
||||
|
||||
async textContent(selector: string, options: types.TimeoutOptions = {}): Promise<string | null> {
|
||||
|
|
@ -871,7 +865,7 @@ export class Frame {
|
|||
return this._page._runAbortableTask(async progress => {
|
||||
progress.logger.info(` retrieving textContent from "${selector}"`);
|
||||
return this._scheduleRerunnableTask(progress, info.world, task);
|
||||
}, this._page._timeoutSettings.timeout(options), this._apiName('textContent'));
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async innerText(selector: string, options: types.TimeoutOptions = {}): Promise<string> {
|
||||
|
|
@ -881,7 +875,7 @@ export class Frame {
|
|||
progress.logger.info(` retrieving innerText from "${selector}"`);
|
||||
const result = dom.throwFatalDOMError(await this._scheduleRerunnableTask(progress, info.world, task));
|
||||
return result.innerText;
|
||||
}, this._page._timeoutSettings.timeout(options), this._apiName('innerText'));
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async innerHTML(selector: string, options: types.TimeoutOptions = {}): Promise<string> {
|
||||
|
|
@ -890,7 +884,7 @@ export class Frame {
|
|||
return this._page._runAbortableTask(async progress => {
|
||||
progress.logger.info(` retrieving innerHTML from "${selector}"`);
|
||||
return this._scheduleRerunnableTask(progress, info.world, task);
|
||||
}, this._page._timeoutSettings.timeout(options), this._apiName('innerHTML'));
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async getAttribute(selector: string, name: string, options: types.TimeoutOptions = {}): Promise<string | null> {
|
||||
|
|
@ -899,35 +893,35 @@ export class Frame {
|
|||
return this._page._runAbortableTask(async progress => {
|
||||
progress.logger.info(` retrieving attribute "${name}" from "${selector}"`);
|
||||
return this._scheduleRerunnableTask(progress, info.world, task);
|
||||
}, this._page._timeoutSettings.timeout(options), this._apiName('getAttribute'));
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async hover(selector: string, options: types.PointerActionOptions & types.PointerActionWaitOptions = {}) {
|
||||
await this._retryWithSelectorIfNotConnected(selector, options, (progress, handle) => handle._hover(progress, options), this._apiName('hover'));
|
||||
await this._retryWithSelectorIfNotConnected(selector, options, (progress, handle) => handle._hover(progress, options));
|
||||
}
|
||||
|
||||
async selectOption(selector: string, values: string | dom.ElementHandle | types.SelectOption | string[] | dom.ElementHandle[] | types.SelectOption[] | null, options: types.NavigatingActionWaitOptions = {}): Promise<string[]> {
|
||||
return this._retryWithSelectorIfNotConnected(selector, options, (progress, handle) => handle._selectOption(progress, values, options), this._apiName('selectOption'));
|
||||
return this._retryWithSelectorIfNotConnected(selector, options, (progress, handle) => handle._selectOption(progress, values, options));
|
||||
}
|
||||
|
||||
async setInputFiles(selector: string, files: string | types.FilePayload | string[] | types.FilePayload[], options: types.NavigatingActionWaitOptions = {}): Promise<void> {
|
||||
await this._retryWithSelectorIfNotConnected(selector, options, (progress, handle) => handle._setInputFiles(progress, files, options), this._apiName('setInputFiles'));
|
||||
await this._retryWithSelectorIfNotConnected(selector, options, (progress, handle) => handle._setInputFiles(progress, files, options));
|
||||
}
|
||||
|
||||
async type(selector: string, text: string, options: { delay?: number } & types.NavigatingActionWaitOptions = {}) {
|
||||
await this._retryWithSelectorIfNotConnected(selector, options, (progress, handle) => handle._type(progress, text, options), this._apiName('type'));
|
||||
await this._retryWithSelectorIfNotConnected(selector, options, (progress, handle) => handle._type(progress, text, options));
|
||||
}
|
||||
|
||||
async press(selector: string, key: string, options: { delay?: number } & types.NavigatingActionWaitOptions = {}) {
|
||||
await this._retryWithSelectorIfNotConnected(selector, options, (progress, handle) => handle._press(progress, key, options), this._apiName('press'));
|
||||
await this._retryWithSelectorIfNotConnected(selector, options, (progress, handle) => handle._press(progress, key, options));
|
||||
}
|
||||
|
||||
async check(selector: string, options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) {
|
||||
await this._retryWithSelectorIfNotConnected(selector, options, (progress, handle) => handle._setChecked(progress, true, options), this._apiName('check'));
|
||||
await this._retryWithSelectorIfNotConnected(selector, options, (progress, handle) => handle._setChecked(progress, true, options));
|
||||
}
|
||||
|
||||
async uncheck(selector: string, options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) {
|
||||
await this._retryWithSelectorIfNotConnected(selector, options, (progress, handle) => handle._setChecked(progress, false, options), this._apiName('uncheck'));
|
||||
await this._retryWithSelectorIfNotConnected(selector, options, (progress, handle) => handle._setChecked(progress, false, options));
|
||||
}
|
||||
|
||||
async waitForTimeout(timeout: number) {
|
||||
|
|
@ -957,7 +951,7 @@ export class Frame {
|
|||
}, { predicateBody, polling, arg });
|
||||
return this._page._runAbortableTask(
|
||||
progress => this._scheduleRerunnableHandleTask(progress, 'main', task),
|
||||
this._page._timeoutSettings.timeout(options), this._apiName('waitForFunction'));
|
||||
this._page._timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async title(): Promise<string> {
|
||||
|
|
@ -1134,9 +1128,9 @@ class SignalBarrier {
|
|||
}
|
||||
}
|
||||
|
||||
async function runNavigationTask<T>(frame: Frame, options: types.TimeoutOptions, apiName: string, task: (progress: Progress) => Promise<T>): Promise<T> {
|
||||
async function runNavigationTask<T>(frame: Frame, options: types.TimeoutOptions, task: (progress: Progress) => Promise<T>): Promise<T> {
|
||||
const page = frame._page;
|
||||
const controller = new ProgressController(page._logger, page._timeoutSettings.navigationTimeout(options), apiName);
|
||||
const controller = new ProgressController(page._logger, page._timeoutSettings.navigationTimeout(options));
|
||||
page._disconnectedPromise.then(() => controller.abort(new Error('Navigation failed because page was closed!')));
|
||||
page._crashedPromise.then(() => controller.abort(new Error('Navigation failed because page crashed!')));
|
||||
frame._detachedPromise.then(() => controller.abort(new Error('Navigating frame was detached!')));
|
||||
|
|
|
|||
190
src/page.ts
190
src/page.ts
|
|
@ -117,7 +117,6 @@ export class Page extends EventEmitter {
|
|||
readonly coverage: any;
|
||||
_routes: { url: types.URLMatch, handler: network.RouteHandler }[] = [];
|
||||
_ownedContext: BrowserContext | undefined;
|
||||
_callingPageAPI = false;
|
||||
|
||||
constructor(delegate: PageDelegate, browserContext: BrowserContextBase) {
|
||||
super();
|
||||
|
|
@ -168,10 +167,10 @@ export class Page extends EventEmitter {
|
|||
this._disconnectedCallback(new Error('Page closed'));
|
||||
}
|
||||
|
||||
async _runAbortableTask<T>(task: (progress: Progress) => Promise<T>, timeout: number, apiName: string): Promise<T> {
|
||||
async _runAbortableTask<T>(task: (progress: Progress) => Promise<T>, timeout: number): Promise<T> {
|
||||
return runAbortableTask(async progress => {
|
||||
return task(progress);
|
||||
}, this._logger, timeout, apiName);
|
||||
}, this._logger, timeout);
|
||||
}
|
||||
|
||||
async _onFileChooserOpened(handle: dom.ElementHandle) {
|
||||
|
|
@ -219,63 +218,6 @@ export class Page extends EventEmitter {
|
|||
this._timeoutSettings.setDefaultTimeout(timeout);
|
||||
}
|
||||
|
||||
async $(selector: string): Promise<dom.ElementHandle<Element> | null> {
|
||||
return this._attributeToPage(() => this.mainFrame().$(selector));
|
||||
}
|
||||
|
||||
async waitForSelector(selector: string, options?: types.WaitForElementOptions): Promise<dom.ElementHandle<Element> | null> {
|
||||
return this._attributeToPage(() => this.mainFrame().waitForSelector(selector, options));
|
||||
}
|
||||
|
||||
async dispatchEvent(selector: string, type: string, eventInit?: Object, options?: types.TimeoutOptions): Promise<void> {
|
||||
return this._attributeToPage(() => this.mainFrame().dispatchEvent(selector, type, eventInit, options));
|
||||
}
|
||||
|
||||
async evaluateHandle<R, Arg>(pageFunction: js.Func1<Arg, R>, arg: Arg): Promise<js.SmartHandle<R>>;
|
||||
async evaluateHandle<R>(pageFunction: js.Func1<void, R>, arg?: any): Promise<js.SmartHandle<R>>;
|
||||
async evaluateHandle<R, Arg>(pageFunction: js.Func1<Arg, R>, arg: Arg): Promise<js.SmartHandle<R>> {
|
||||
assertMaxArguments(arguments.length, 2);
|
||||
return this._attributeToPage(() => this.mainFrame().evaluateHandle(pageFunction, arg));
|
||||
}
|
||||
|
||||
async _evaluateExpressionHandle(expression: string, isFunction: boolean, arg: any): Promise<any> {
|
||||
return this._attributeToPage(() => this.mainFrame()._evaluateExpressionHandle(expression, isFunction, arg));
|
||||
}
|
||||
|
||||
async $eval<R, Arg>(selector: string, pageFunction: js.FuncOn<Element, Arg, R>, arg: Arg): Promise<R>;
|
||||
async $eval<R>(selector: string, pageFunction: js.FuncOn<Element, void, R>, arg?: any): Promise<R>;
|
||||
async $eval<R, Arg>(selector: string, pageFunction: js.FuncOn<Element, Arg, R>, arg: Arg): Promise<R> {
|
||||
assertMaxArguments(arguments.length, 3);
|
||||
return this._attributeToPage(() => this.mainFrame().$eval(selector, pageFunction, arg));
|
||||
}
|
||||
|
||||
async _$evalExpression(selector: string, expression: string, isFunction: boolean, arg: any): Promise<any> {
|
||||
return this._attributeToPage(() => this.mainFrame()._$evalExpression(selector, expression, isFunction, arg));
|
||||
}
|
||||
|
||||
async $$eval<R, Arg>(selector: string, pageFunction: js.FuncOn<Element[], Arg, R>, arg: Arg): Promise<R>;
|
||||
async $$eval<R>(selector: string, pageFunction: js.FuncOn<Element[], void, R>, arg?: any): Promise<R>;
|
||||
async $$eval<R, Arg>(selector: string, pageFunction: js.FuncOn<Element[], Arg, R>, arg: Arg): Promise<R> {
|
||||
assertMaxArguments(arguments.length, 3);
|
||||
return this._attributeToPage(() => this.mainFrame().$$eval(selector, pageFunction, arg));
|
||||
}
|
||||
|
||||
async _$$evalExpression(selector: string, expression: string, isFunction: boolean, arg: any): Promise<any> {
|
||||
return this._attributeToPage(() => this.mainFrame()._$$evalExpression(selector, expression, isFunction, arg));
|
||||
}
|
||||
|
||||
async $$(selector: string): Promise<dom.ElementHandle<Element>[]> {
|
||||
return this._attributeToPage(() => this.mainFrame().$$(selector));
|
||||
}
|
||||
|
||||
async addScriptTag(options: { url?: string; path?: string; content?: string; type?: string; }): Promise<dom.ElementHandle> {
|
||||
return this._attributeToPage(() => this.mainFrame().addScriptTag(options));
|
||||
}
|
||||
|
||||
async addStyleTag(options: { url?: string; path?: string; content?: string; }): Promise<dom.ElementHandle> {
|
||||
return this._attributeToPage(() => this.mainFrame().addStyleTag(options));
|
||||
}
|
||||
|
||||
async exposeFunction(name: string, playwrightFunction: Function) {
|
||||
await this.exposeBinding(name, (options, ...args: any) => playwrightFunction(...args));
|
||||
}
|
||||
|
|
@ -310,36 +252,12 @@ export class Page extends EventEmitter {
|
|||
this.emit(Events.Page.Console, message);
|
||||
}
|
||||
|
||||
url(): string {
|
||||
return this._attributeToPage(() => this.mainFrame().url());
|
||||
}
|
||||
|
||||
async content(): Promise<string> {
|
||||
return this._attributeToPage(() => this.mainFrame().content());
|
||||
}
|
||||
|
||||
async setContent(html: string, options?: types.NavigateOptions): Promise<void> {
|
||||
return this._attributeToPage(() => this.mainFrame().setContent(html, options));
|
||||
}
|
||||
|
||||
async goto(url: string, options?: types.GotoOptions): Promise<network.Response | null> {
|
||||
return this._attributeToPage(() => this.mainFrame().goto(url, options));
|
||||
}
|
||||
|
||||
async reload(options?: types.NavigateOptions): Promise<network.Response | null> {
|
||||
const waitPromise = this.waitForNavigation(options);
|
||||
const waitPromise = this.mainFrame().waitForNavigation(options);
|
||||
await this._delegate.reload();
|
||||
return waitPromise;
|
||||
}
|
||||
|
||||
async waitForLoadState(state?: types.LifecycleEvent, options?: types.TimeoutOptions): Promise<void> {
|
||||
return this._attributeToPage(() => this.mainFrame().waitForLoadState(state, options));
|
||||
}
|
||||
|
||||
async waitForNavigation(options?: types.WaitForNavigationOptions): Promise<network.Response | null> {
|
||||
return this._attributeToPage(() => this.mainFrame().waitForNavigation(options));
|
||||
}
|
||||
|
||||
async waitForRequest(urlOrPredicate: string | RegExp | ((r: network.Request) => boolean), options: types.TimeoutOptions = {}): Promise<network.Request> {
|
||||
const predicate = (request: network.Request) => {
|
||||
if (helper.isString(urlOrPredicate) || helper.isRegExp(urlOrPredicate))
|
||||
|
|
@ -360,7 +278,7 @@ export class Page extends EventEmitter {
|
|||
|
||||
async waitForEvent(event: string, optionsOrPredicate: types.WaitForEventOptions = {}): Promise<any> {
|
||||
const options = typeof optionsOrPredicate === 'function' ? { predicate: optionsOrPredicate } : optionsOrPredicate;
|
||||
const progressController = new ProgressController(this._logger, this._timeoutSettings.timeout(options), 'page.waitForEvent');
|
||||
const progressController = new ProgressController(this._logger, this._timeoutSettings.timeout(options));
|
||||
this._disconnectedPromise.then(error => progressController.abort(error));
|
||||
if (event !== Events.Page.Crash)
|
||||
this._crashedPromise.then(error => progressController.abort(error));
|
||||
|
|
@ -368,7 +286,7 @@ export class Page extends EventEmitter {
|
|||
}
|
||||
|
||||
async goBack(options?: types.NavigateOptions): Promise<network.Response | null> {
|
||||
const waitPromise = this.waitForNavigation(options);
|
||||
const waitPromise = this.mainFrame().waitForNavigation(options);
|
||||
const result = await this._delegate.goBack();
|
||||
if (!result) {
|
||||
waitPromise.catch(() => {});
|
||||
|
|
@ -378,7 +296,7 @@ export class Page extends EventEmitter {
|
|||
}
|
||||
|
||||
async goForward(options?: types.NavigateOptions): Promise<network.Response | null> {
|
||||
const waitPromise = this.waitForNavigation(options);
|
||||
const waitPromise = this.mainFrame().waitForNavigation(options);
|
||||
const result = await this._delegate.goForward();
|
||||
if (!result) {
|
||||
waitPromise.catch(() => {});
|
||||
|
|
@ -412,17 +330,6 @@ export class Page extends EventEmitter {
|
|||
await this._delegate.bringToFront();
|
||||
}
|
||||
|
||||
async evaluate<R, Arg>(pageFunction: js.Func1<Arg, R>, arg: Arg): Promise<R>;
|
||||
async evaluate<R>(pageFunction: js.Func1<void, R>, arg?: any): Promise<R>;
|
||||
async evaluate<R, Arg>(pageFunction: js.Func1<Arg, R>, arg: Arg): Promise<R> {
|
||||
assertMaxArguments(arguments.length, 2);
|
||||
return this._attributeToPage(() => this.mainFrame().evaluate(pageFunction, arg));
|
||||
}
|
||||
|
||||
async _evaluateExpression(expression: string, isFunction: boolean, arg: any): Promise<any> {
|
||||
return this._attributeToPage(() => this.mainFrame()._evaluateExpression(expression, isFunction, arg));
|
||||
}
|
||||
|
||||
async addInitScript(script: Function | string | { path?: string, content?: string }, arg?: any) {
|
||||
const source = await helper.evaluationScript(script, arg);
|
||||
await this._addInitScriptExpression(source);
|
||||
|
|
@ -482,11 +389,7 @@ export class Page extends EventEmitter {
|
|||
async screenshot(options: types.ScreenshotOptions = {}): Promise<Buffer> {
|
||||
return this._runAbortableTask(
|
||||
progress => this._screenshotter.screenshotPage(progress, options),
|
||||
this._timeoutSettings.timeout(options), 'page.screenshot');
|
||||
}
|
||||
|
||||
async title(): Promise<string> {
|
||||
return this._attributeToPage(() => this.mainFrame().title());
|
||||
this._timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
async close(options?: { runBeforeUnload?: boolean }) {
|
||||
|
|
@ -513,89 +416,10 @@ export class Page extends EventEmitter {
|
|||
return this._closedState === 'closed';
|
||||
}
|
||||
|
||||
private _attributeToPage<T>(func: () => T): T {
|
||||
try {
|
||||
this._callingPageAPI = true;
|
||||
return func();
|
||||
} finally {
|
||||
this._callingPageAPI = false;
|
||||
}
|
||||
}
|
||||
|
||||
async click(selector: string, options?: types.MouseClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions) {
|
||||
return this._attributeToPage(() => this.mainFrame().click(selector, options));
|
||||
}
|
||||
|
||||
async dblclick(selector: string, options?: types.MouseMultiClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions) {
|
||||
return this._attributeToPage(() => this.mainFrame().dblclick(selector, options));
|
||||
}
|
||||
|
||||
async fill(selector: string, value: string, options?: types.NavigatingActionWaitOptions) {
|
||||
return this._attributeToPage(() => this.mainFrame().fill(selector, value, options));
|
||||
}
|
||||
|
||||
async focus(selector: string, options?: types.TimeoutOptions) {
|
||||
return this._attributeToPage(() => this.mainFrame().focus(selector, options));
|
||||
}
|
||||
|
||||
async textContent(selector: string, options?: types.TimeoutOptions): Promise<null|string> {
|
||||
return this._attributeToPage(() => this.mainFrame().textContent(selector, options));
|
||||
}
|
||||
|
||||
async innerText(selector: string, options?: types.TimeoutOptions): Promise<string> {
|
||||
return this._attributeToPage(() => this.mainFrame().innerText(selector, options));
|
||||
}
|
||||
|
||||
async innerHTML(selector: string, options?: types.TimeoutOptions): Promise<string> {
|
||||
return this._attributeToPage(() => this.mainFrame().innerHTML(selector, options));
|
||||
}
|
||||
|
||||
async getAttribute(selector: string, name: string, options?: types.TimeoutOptions): Promise<string | null> {
|
||||
return this._attributeToPage(() => this.mainFrame().getAttribute(selector, name, options));
|
||||
}
|
||||
|
||||
async hover(selector: string, options?: types.PointerActionOptions & types.PointerActionWaitOptions) {
|
||||
return this._attributeToPage(() => this.mainFrame().hover(selector, options));
|
||||
}
|
||||
|
||||
async selectOption(selector: string, values: string | dom.ElementHandle | types.SelectOption | string[] | dom.ElementHandle[] | types.SelectOption[] | null, options?: types.NavigatingActionWaitOptions): Promise<string[]> {
|
||||
return this._attributeToPage(() => this.mainFrame().selectOption(selector, values, options));
|
||||
}
|
||||
|
||||
async setInputFiles(selector: string, files: string | types.FilePayload | string[] | types.FilePayload[], options?: types.NavigatingActionWaitOptions): Promise<void> {
|
||||
return this._attributeToPage(() => this.mainFrame().setInputFiles(selector, files, options));
|
||||
}
|
||||
|
||||
async type(selector: string, text: string, options?: { delay?: number } & types.NavigatingActionWaitOptions) {
|
||||
return this._attributeToPage(() => this.mainFrame().type(selector, text, options));
|
||||
}
|
||||
|
||||
async press(selector: string, key: string, options?: { delay?: number } & types.NavigatingActionWaitOptions) {
|
||||
return this._attributeToPage(() => this.mainFrame().press(selector, key, options));
|
||||
}
|
||||
|
||||
async check(selector: string, options?: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions) {
|
||||
return this._attributeToPage(() => this.mainFrame().check(selector, options));
|
||||
}
|
||||
|
||||
async uncheck(selector: string, options?: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions) {
|
||||
return this._attributeToPage(() => this.mainFrame().uncheck(selector, options));
|
||||
}
|
||||
|
||||
async waitForTimeout(timeout: number) {
|
||||
await this.mainFrame().waitForTimeout(timeout);
|
||||
}
|
||||
|
||||
async waitForFunction<R, Arg>(pageFunction: js.Func1<Arg, R>, arg: Arg, options?: types.WaitForFunctionOptions): Promise<js.SmartHandle<R>>;
|
||||
async waitForFunction<R>(pageFunction: js.Func1<void, R>, arg?: any, options?: types.WaitForFunctionOptions): Promise<js.SmartHandle<R>>;
|
||||
async waitForFunction<R, Arg>(pageFunction: js.Func1<Arg, R>, arg: Arg, options?: types.WaitForFunctionOptions): Promise<js.SmartHandle<R>> {
|
||||
return this._attributeToPage(() => this.mainFrame().waitForFunction(pageFunction, arg, options));
|
||||
}
|
||||
|
||||
async _waitForFunctionExpression<R>(expression: string, isFunction: boolean, arg: any, options: types.WaitForFunctionOptions = {}): Promise<js.SmartHandle<R>> {
|
||||
return this._attributeToPage(() => this.mainFrame()._waitForFunctionExpression(expression, isFunction, arg, options));
|
||||
}
|
||||
|
||||
workers(): Worker[] {
|
||||
return [...this._workers.values()];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,16 +28,11 @@ export interface Progress {
|
|||
throwIfAborted(): void;
|
||||
}
|
||||
|
||||
export async function runAbortableTask<T>(task: (progress: Progress) => Promise<T>, logger: Logger, timeout: number, apiName: string): Promise<T> {
|
||||
const controller = new ProgressController(logger, timeout, apiName);
|
||||
export async function runAbortableTask<T>(task: (progress: Progress) => Promise<T>, logger: Logger, timeout: number): Promise<T> {
|
||||
const controller = new ProgressController(logger, timeout);
|
||||
return controller.run(task);
|
||||
}
|
||||
|
||||
let useApiName = true;
|
||||
export function setUseApiName(value: boolean) {
|
||||
useApiName = value;
|
||||
}
|
||||
|
||||
export class ProgressController {
|
||||
// Promise and callback that forcefully abort the progress.
|
||||
// This promise always rejects.
|
||||
|
|
@ -54,12 +49,10 @@ export class ProgressController {
|
|||
|
||||
private _logger: Logger;
|
||||
private _state: 'before' | 'running' | 'aborted' | 'finished' = 'before';
|
||||
private _apiName: string;
|
||||
private _deadline: number;
|
||||
private _timeout: number;
|
||||
|
||||
constructor(logger: Logger, timeout: number, apiName: string) {
|
||||
this._apiName = apiName;
|
||||
constructor(logger: Logger, timeout: number) {
|
||||
this._logger = logger;
|
||||
|
||||
this._timeout = timeout;
|
||||
|
|
@ -74,7 +67,7 @@ export class ProgressController {
|
|||
assert(this._state === 'before');
|
||||
this._state = 'running';
|
||||
|
||||
const loggerScope = this._logger.createScope(useApiName ? this._apiName : undefined, true);
|
||||
const loggerScope = this._logger.createScope(undefined, true);
|
||||
|
||||
const progress: Progress = {
|
||||
aborted: this._abortedPromise,
|
||||
|
|
@ -105,7 +98,6 @@ export class ProgressController {
|
|||
} catch (e) {
|
||||
this._aborted();
|
||||
rewriteErrorMessage(e,
|
||||
(useApiName ? `${this._apiName}: ` : '') +
|
||||
e.message +
|
||||
formatLogRecording(loggerScope.recording()) +
|
||||
kLoggingNote);
|
||||
|
|
|
|||
|
|
@ -18,14 +18,11 @@ import { DispatcherConnection } from './server/dispatcher';
|
|||
import type { Playwright as PlaywrightImpl } from '../server/playwright';
|
||||
import type { Playwright as PlaywrightAPI } from './client/playwright';
|
||||
import { PlaywrightDispatcher } from './server/playwrightDispatcher';
|
||||
import { setUseApiName } from '../progress';
|
||||
import { Connection } from './client/connection';
|
||||
import { isUnderTest } from '../helper';
|
||||
import { BrowserServerLauncherImpl } from './browserServerImpl';
|
||||
|
||||
export function setupInProcess(playwright: PlaywrightImpl): PlaywrightAPI {
|
||||
setUseApiName(false);
|
||||
|
||||
const clientConnection = new Connection();
|
||||
const dispatcherConnection = new DispatcherConnection();
|
||||
|
||||
|
|
|
|||
|
|
@ -19,11 +19,8 @@ import { DispatcherConnection } from './server/dispatcher';
|
|||
import { Playwright } from '../server/playwright';
|
||||
import { PlaywrightDispatcher } from './server/playwrightDispatcher';
|
||||
import { Electron } from '../server/electron';
|
||||
import { setUseApiName } from '../progress';
|
||||
import { gracefullyCloseAll } from '../server/processLauncher';
|
||||
|
||||
setUseApiName(false);
|
||||
|
||||
const dispatcherConnection = new DispatcherConnection();
|
||||
const transport = new Transport(process.stdout, process.stdin);
|
||||
transport.onclose = async () => {
|
||||
|
|
|
|||
|
|
@ -149,10 +149,6 @@ export class PageDispatcher extends Dispatcher<Page, PageInitializer> implements
|
|||
this._page.removeListener(Events.Page.FileChooser, this._onFileChooser);
|
||||
}
|
||||
|
||||
async title() {
|
||||
return await this._page.title();
|
||||
}
|
||||
|
||||
async keyboardDown(params: { key: string }): Promise<void> {
|
||||
await this._page.keyboard.down(params.key);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,8 +85,7 @@ export abstract class BrowserTypeBase implements BrowserType {
|
|||
assert(!(options as any).port, 'Cannot specify a port without launching as a server.');
|
||||
options = validateLaunchOptions(options);
|
||||
const loggers = new Loggers(options.logger);
|
||||
const label = 'browserType.launch';
|
||||
const browser = await runAbortableTask(progress => this._innerLaunch(progress, options, loggers, undefined), loggers.browser, TimeoutSettings.timeout(options), label).catch(e => { throw this._rewriteStartupError(e, label); });
|
||||
const browser = await runAbortableTask(progress => this._innerLaunch(progress, options, loggers, undefined), loggers.browser, TimeoutSettings.timeout(options)).catch(e => { throw this._rewriteStartupError(e); });
|
||||
return browser;
|
||||
}
|
||||
|
||||
|
|
@ -95,8 +94,7 @@ export abstract class BrowserTypeBase implements BrowserType {
|
|||
options = validateLaunchOptions(options);
|
||||
const persistent = validateBrowserContextOptions(options);
|
||||
const loggers = new Loggers(options.logger);
|
||||
const label = 'browserType.launchPersistentContext';
|
||||
const browser = await runAbortableTask(progress => this._innerLaunch(progress, options, loggers, persistent, userDataDir), loggers.browser, TimeoutSettings.timeout(options), label).catch(e => { throw this._rewriteStartupError(e, label); });
|
||||
const browser = await runAbortableTask(progress => this._innerLaunch(progress, options, loggers, persistent, userDataDir), loggers.browser, TimeoutSettings.timeout(options)).catch(e => { throw this._rewriteStartupError(e); });
|
||||
return browser._defaultContext!;
|
||||
}
|
||||
|
||||
|
|
@ -224,7 +222,7 @@ export abstract class BrowserTypeBase implements BrowserType {
|
|||
abstract _connectToTransport(transport: ConnectionTransport, options: BrowserOptions): Promise<BrowserBase>;
|
||||
abstract _amendEnvironment(env: Env, userDataDir: string, executable: string, browserArguments: string[]): Env;
|
||||
abstract _amendArguments(browserArguments: string[]): string[];
|
||||
abstract _rewriteStartupError(error: Error, prefix: string): Error;
|
||||
abstract _rewriteStartupError(error: Error): Error;
|
||||
abstract _attemptToGracefullyCloseBrowser(transport: ConnectionTransport): void;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,13 +61,13 @@ export class Chromium extends BrowserTypeBase {
|
|||
return CRBrowser.connect(transport, options, devtools);
|
||||
}
|
||||
|
||||
_rewriteStartupError(error: Error, prefix: string): Error {
|
||||
_rewriteStartupError(error: Error): Error {
|
||||
// These error messages are taken from Chromium source code as of July, 2020:
|
||||
// https://github.com/chromium/chromium/blob/70565f67e79f79e17663ad1337dc6e63ee207ce9/content/browser/zygote_host/zygote_host_impl_linux.cc
|
||||
if (!error.message.includes('crbug.com/357670') && !error.message.includes('No usable sandbox!') && !error.message.includes('crbug.com/638180'))
|
||||
return error;
|
||||
return rewriteErrorMessage(error, [
|
||||
`${prefix}: Chromium sandboxing failed!`,
|
||||
`Chromium sandboxing failed!`,
|
||||
`================================`,
|
||||
`To workaround sandboxing issues, do either of the following:`,
|
||||
` - (preferred): Configure environment to support sandboxing: https://github.com/microsoft/playwright/blob/master/docs/troubleshooting.md`,
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ export class ElectronApplication extends EventEmitter {
|
|||
this._windows.delete(page);
|
||||
});
|
||||
this._windows.add(page);
|
||||
await page.waitForLoadState('domcontentloaded').catch(e => {}); // can happen after detach
|
||||
await page.mainFrame().waitForLoadState('domcontentloaded').catch(e => {}); // can happen after detach
|
||||
this.emit(ElectronEvents.ElectronApplication.Window, page);
|
||||
}
|
||||
|
||||
|
|
@ -136,7 +136,7 @@ export class ElectronApplication extends EventEmitter {
|
|||
|
||||
async waitForEvent(event: string, optionsOrPredicate: types.WaitForEventOptions = {}): Promise<any> {
|
||||
const options = typeof optionsOrPredicate === 'function' ? { predicate: optionsOrPredicate } : optionsOrPredicate;
|
||||
const progressController = new ProgressController(this._apiLogger, this._timeoutSettings.timeout(options), 'electron.waitForEvent');
|
||||
const progressController = new ProgressController(this._apiLogger, this._timeoutSettings.timeout(options));
|
||||
if (event !== ElectronEvents.ElectronApplication.Close)
|
||||
this._browserContext._closePromise.then(error => progressController.abort(error));
|
||||
return progressController.run(progress => helper.waitForEvent(progress, this, event, options.predicate).promise);
|
||||
|
|
@ -212,6 +212,6 @@ export class Electron {
|
|||
app = new ElectronApplication(loggers, browser, nodeConnection);
|
||||
await app._init();
|
||||
return app;
|
||||
}, loggers.browser, TimeoutSettings.timeout(options), 'electron.launch');
|
||||
}, loggers.browser, TimeoutSettings.timeout(options));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ export class Firefox extends BrowserTypeBase {
|
|||
return FFBrowser.connect(transport, options);
|
||||
}
|
||||
|
||||
_rewriteStartupError(error: Error, prefix: string): Error {
|
||||
_rewriteStartupError(error: Error): Error {
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ export class WebKit extends BrowserTypeBase {
|
|||
return browserArguments;
|
||||
}
|
||||
|
||||
_rewriteStartupError(error: Error, prefix: string): Error {
|
||||
_rewriteStartupError(error: Error): Error {
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ const CRASH_FAIL = (FFOX && WIN) || WIRE;
|
|||
// Firefox Win: it just doesn't crash sometimes.
|
||||
function crash(pageImpl) {
|
||||
if (CHROMIUM)
|
||||
pageImpl.goto('chrome://crash').catch(e => {});
|
||||
pageImpl.mainFrame().goto('chrome://crash').catch(e => {});
|
||||
else if (WEBKIT)
|
||||
pageImpl._delegate._session.send('Page.crash', {}).catch(e => {});
|
||||
else if (FFOX)
|
||||
|
|
|
|||
Loading…
Reference in a new issue