From 916158656ca58c098f2ee1f6d8abac846d97c124 Mon Sep 17 00:00:00 2001 From: Dmitry Gozman Date: Tue, 17 Dec 2019 11:28:09 -0800 Subject: [PATCH] chore: unify reload/goBack/goForward across browsers (#273) --- src/chromium/FrameManager.ts | 27 ++++++++++--------------- src/firefox/FrameManager.ts | 38 ++++++++---------------------------- src/frames.ts | 2 +- src/page.ts | 26 ++++++++++++++++++------ src/webkit/FrameManager.ts | 34 ++++++++++++-------------------- 5 files changed, 52 insertions(+), 75 deletions(-) diff --git a/src/chromium/FrameManager.ts b/src/chromium/FrameManager.ts index 0eb69b212c..dfdd536bc1 100644 --- a/src/chromium/FrameManager.ts +++ b/src/chromium/FrameManager.ts @@ -315,32 +315,25 @@ export class FrameManager implements PageDelegate { return this._networkManager.setCacheEnabled(enabled); } - async reload(options?: frames.NavigateOptions): Promise { - const [response] = await Promise.all([ - this._page.waitForNavigation(options), - this._client.send('Page.reload') - ]); - return response; + async reload(): Promise { + await this._client.send('Page.reload'); } - private async _go(delta: number, options?: frames.NavigateOptions): Promise { + private async _go(delta: number): Promise { const history = await this._client.send('Page.getNavigationHistory'); const entry = history.entries[history.currentIndex + delta]; if (!entry) - return null; - const [response] = await Promise.all([ - this._page.waitForNavigation(options), - this._client.send('Page.navigateToHistoryEntry', {entryId: entry.id}), - ]); - return response; + return false; + await this._client.send('Page.navigateToHistoryEntry', { entryId: entry.id }); + return true; } - goBack(options?: frames.NavigateOptions): Promise { - return this._go(-1, options); + goBack(): Promise { + return this._go(-1); } - goForward(options?: frames.NavigateOptions): Promise { - return this._go(+1, options); + goForward(): Promise { + return this._go(+1); } async evaluateOnNewDocument(source: string): Promise { diff --git a/src/firefox/FrameManager.ts b/src/firefox/FrameManager.ts index cb96f7dfe6..79940a3552 100644 --- a/src/firefox/FrameManager.ts +++ b/src/firefox/FrameManager.ts @@ -223,40 +223,18 @@ export class FrameManager implements PageDelegate { await this._session.send('Page.setCacheDisabled', {cacheDisabled: !enabled}); } - private async _go(action: () => Promise<{ navigationId: string | null, navigationURL: string | null }>, options: frames.NavigateOptions = {}): Promise { - const { - timeout = this._page._timeoutSettings.navigationTimeout(), - waitUntil = (['load'] as frames.LifecycleEvent[]), - } = options; - const frame = this._page.mainFrame(); - const watcher = new frames.LifecycleWatcher(frame, waitUntil, timeout); - const { navigationId } = await action(); - if (navigationId === null) { - // Cannot go back/forward. - watcher.dispose(); - return null; - } - const error = await Promise.race([ - watcher.timeoutOrTerminationPromise, - watcher.newDocumentNavigationPromise, - watcher.sameDocumentNavigationPromise, - ]); - watcher.dispose(); - if (error) - throw error; - return watcher.navigationResponse(); + async reload(): Promise { + await this._session.send('Page.reload', { frameId: this._page.mainFrame()._id }); } - reload(options?: frames.NavigateOptions): Promise { - return this._go(() => this._session.send('Page.reload', { frameId: this._page.mainFrame()._id }), options); + async goBack(): Promise { + const { navigationId } = await this._session.send('Page.goBack', { frameId: this._page.mainFrame()._id }); + return navigationId !== null; } - goBack(options?: frames.NavigateOptions): Promise { - return this._go(() => this._session.send('Page.goBack', { frameId: this._page.mainFrame()._id }), options); - } - - goForward(options?: frames.NavigateOptions): Promise { - return this._go(() => this._session.send('Page.goForward', { frameId: this._page.mainFrame()._id }), options); + async goForward(): Promise { + const { navigationId } = await this._session.send('Page.goForward', { frameId: this._page.mainFrame()._id }); + return navigationId !== null; } async evaluateOnNewDocument(source: string): Promise { diff --git a/src/frames.ts b/src/frames.ts index 9789f2697b..dab49ccd68 100644 --- a/src/frames.ts +++ b/src/frames.ts @@ -836,7 +836,7 @@ class RerunnableTask { } } -export class LifecycleWatcher { +class LifecycleWatcher { readonly sameDocumentNavigationPromise: Promise; readonly lifecyclePromise: Promise; readonly newDocumentNavigationPromise: Promise; diff --git a/src/page.ts b/src/page.ts index 638e798b18..a84951baa0 100644 --- a/src/page.ts +++ b/src/page.ts @@ -34,9 +34,9 @@ export interface PageDelegate { readonly rawMouse: input.RawMouse; readonly rawKeyboard: input.RawKeyboard; - reload(options?: frames.NavigateOptions): Promise; - goBack(options?: frames.NavigateOptions): Promise; - goForward(options?: frames.NavigateOptions): Promise; + reload(): Promise; + goBack(): Promise; + goForward(): Promise; exposeBinding(name: string, bindingFunction: string): Promise; evaluateOnNewDocument(source: string): Promise; closePage(runBeforeUnload: boolean): Promise; @@ -319,7 +319,9 @@ export class Page extends EventEmitter { } async reload(options?: frames.NavigateOptions): Promise { - return this._delegate.reload(options); + const waitPromise = this.waitForNavigation(options); + await this._delegate.reload(); + return waitPromise; } waitForNavigation(options?: frames.NavigateOptions): Promise { @@ -353,11 +355,23 @@ export class Page extends EventEmitter { } async goBack(options?: frames.NavigateOptions): Promise { - return this._delegate.goBack(options); + const waitPromise = this.waitForNavigation(options); + const result = await this._delegate.goBack(); + if (!result) { + waitPromise.catch(() => {}); + return null; + } + return waitPromise; } async goForward(options?: frames.NavigateOptions): Promise { - return this._delegate.goForward(options); + const waitPromise = this.waitForNavigation(options); + const result = await this._delegate.goForward(); + if (!result) { + waitPromise.catch(() => {}); + return null; + } + return waitPromise; } async emulate(options: { viewport: types.Viewport; userAgent: string; }) { diff --git a/src/webkit/FrameManager.ts b/src/webkit/FrameManager.ts index 74d5d661c8..30fae8dba8 100644 --- a/src/webkit/FrameManager.ts +++ b/src/webkit/FrameManager.ts @@ -282,7 +282,7 @@ export class FrameManager implements PageDelegate { async setUserAgent(userAgent: string): Promise { await this._setUserAgent(this._session, userAgent); - await this.reload(); + await this._page.reload(); } async setJavaScriptEnabled(enabled: boolean): Promise { @@ -309,32 +309,24 @@ export class FrameManager implements PageDelegate { return this._networkManager.setCacheEnabled(enabled); } - async reload(options?: frames.NavigateOptions): Promise { - const [response] = await Promise.all([ - this._page.waitForNavigation(options), - this._session.send('Page.reload') - ]); - return response; + async reload(): Promise { + await this._session.send('Page.reload'); } - async _go(command: T, options?: frames.NavigateOptions): Promise { - const [response] = await Promise.all([ - this._page.waitForNavigation(options), - this._session.send(command).then(() => null), - ]).catch(error => { - if (error instanceof Error && error.message.includes(`Protocol error (${command}): Failed to go`)) - return [null]; + goBack(): Promise { + return this._session.send('Page.goBack').then(() => true).catch(error => { + if (error instanceof Error && error.message.includes(`Protocol error (Page.goBack): Failed to go`)) + return false; throw error; }); - return response; } - goBack(options?: frames.NavigateOptions): Promise { - return this._go('Page.goBack', options); - } - - goForward(options?: frames.NavigateOptions): Promise { - return this._go('Page.goForward', options); + goForward(): Promise { + return this._session.send('Page.goForward').then(() => true).catch(error => { + if (error instanceof Error && error.message.includes(`Protocol error (Page.goForward): Failed to go`)) + return false; + throw error; + }); } async exposeBinding(name: string, bindingFunction: string): Promise {