From f7c302fd331d6cc1e85b8e8c8bb1af74662800b4 Mon Sep 17 00:00:00 2001 From: "trop[bot]" <37223003+trop[bot]@users.noreply.github.com> Date: Mon, 28 Aug 2023 16:38:00 +0000 Subject: [PATCH] fix: promise resolved to early when browser initiated in-page navigation v2 Co-authored-by: Tomasz Malinowski --- lib/browser/api/web-contents.ts | 11 +++++++++-- spec/api-web-contents-spec.ts | 10 ++++++++++ .../fixtures/pages/navigate_in_page_and_wait.html | 15 +++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 spec/fixtures/pages/navigate_in_page_and_wait.html diff --git a/lib/browser/api/web-contents.ts b/lib/browser/api/web-contents.ts index 8f0f53aa2ba74..0c1cb11d9e5fe 100644 --- a/lib/browser/api/web-contents.ts +++ b/lib/browser/api/web-contents.ts @@ -446,6 +446,7 @@ WebContents.prototype.loadURL = function (url, options) { }; let navigationStarted = false; + let browserInitiatedInPageNavigation = false; const navigationListener = (event: Electron.Event, url: string, isSameDocument: boolean, isMainFrame: boolean) => { if (isMainFrame) { if (navigationStarted && !isSameDocument) { @@ -460,6 +461,7 @@ WebContents.prototype.loadURL = function (url, options) { // as the routing does not leave the document return rejectAndCleanup(-3, 'ERR_ABORTED', url); } + browserInitiatedInPageNavigation = navigationStarted && isSameDocument; navigationStarted = true; } }; @@ -474,17 +476,22 @@ WebContents.prototype.loadURL = function (url, options) { // would be more appropriate. rejectAndCleanup(-2, 'ERR_FAILED', url); }; + const finishListenerWhenUserInitiatedNavigation = () => { + if (!browserInitiatedInPageNavigation) { + finishListener(); + } + }; const removeListeners = () => { this.removeListener('did-finish-load', finishListener); this.removeListener('did-fail-load', failListener); - this.removeListener('did-navigate-in-page', finishListener); + this.removeListener('did-navigate-in-page', finishListenerWhenUserInitiatedNavigation); this.removeListener('did-start-navigation', navigationListener); this.removeListener('did-stop-loading', stopLoadingListener); this.removeListener('destroyed', stopLoadingListener); }; this.on('did-finish-load', finishListener); this.on('did-fail-load', failListener); - this.on('did-navigate-in-page', finishListener); + this.on('did-navigate-in-page', finishListenerWhenUserInitiatedNavigation); this.on('did-start-navigation', navigationListener); this.on('did-stop-loading', stopLoadingListener); this.on('destroyed', stopLoadingListener); diff --git a/spec/api-web-contents-spec.ts b/spec/api-web-contents-spec.ts index c53115c636cbe..b16fbd6434419 100644 --- a/spec/api-web-contents-spec.ts +++ b/spec/api-web-contents-spec.ts @@ -375,6 +375,16 @@ describe('webContents module', () => { await expect(w.loadURL(w.getURL() + '#foo')).to.eventually.be.fulfilled(); }); + it('resolves after browser initiated navigation', async () => { + let finishedLoading = false; + w.webContents.on('did-finish-load', function () { + finishedLoading = true; + }); + + await w.loadFile(path.join(fixturesPath, 'pages', 'navigate_in_page_and_wait.html')); + expect(finishedLoading).to.be.true(); + }); + it('rejects when failing to load a file URL', async () => { await expect(w.loadURL('file:non-existent')).to.eventually.be.rejected() .and.have.property('code', 'ERR_FILE_NOT_FOUND'); diff --git a/spec/fixtures/pages/navigate_in_page_and_wait.html b/spec/fixtures/pages/navigate_in_page_and_wait.html new file mode 100644 index 0000000000000..f582af55a5835 --- /dev/null +++ b/spec/fixtures/pages/navigate_in_page_and_wait.html @@ -0,0 +1,15 @@ + +
+ +
+ + +