From 0bd009148d915825cdc9f9af487afb883106bb8e Mon Sep 17 00:00:00 2001 From: Hiroshige Hayashizaki Date: Fri, 18 Mar 2022 10:26:03 +0000 Subject: [PATCH] Bug 1733861 [wpt PR 31083] - [WPT] BFCache: pushState() in BFCache/non-BFCache cases, a=testonly Automatic update from web-platform-tests [WPT] BFCache: pushState() in BFCache/non-BFCache cases When doing history navigation to an entry that's created via pushState, the page should be: - With BFCache: Restored from BFCache. - Without BFCache: Loaded from the URL set by `pushState()`. While this test contradicts the current spec but matches the desired behavior, and the spec will be fixed as part of https://github.com/whatwg/html/pull/6315. Tests pass on Firefox/Safari/Chrome, except for Safari on non-BFCache case (just because WebLock doesn't disable BFCache). Bug: 1107415, 1298336, https://github.com/whatwg/html/issues/6207 Change-Id: I609276fe865fa92409fd7a547777dba222bac36c Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3199857 Reviewed-by: Kouhei Ueno Reviewed-by: Domenic Denicola Reviewed-by: Rakina Zata Amni Commit-Queue: Hiroshige Hayashizaki Cr-Commit-Position: refs/heads/main@{#972799} -- wpt-commits: a400637a6ee3b7b6f315be2a17a7b28257663b4b wpt-pr: 31083 --- .../back-forward-cache/pushstate.https.html | 63 ++++++++++++++++++ .../resources/executor-pushstate.html | 13 ++++ .../resources/executor.html | 50 +-------------- .../back-forward-cache/resources/executor.js | 64 +++++++++++++++++++ 4 files changed, 141 insertions(+), 49 deletions(-) create mode 100644 testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/pushstate.https.html create mode 100644 testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor-pushstate.html create mode 100644 testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor.js diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/pushstate.https.html b/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/pushstate.https.html new file mode 100644 index 0000000000000..218562254a6f6 --- /dev/null +++ b/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/pushstate.https.html @@ -0,0 +1,63 @@ + + + + + + + + diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor-pushstate.html b/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor-pushstate.html new file mode 100644 index 0000000000000..dcf4a798d00de --- /dev/null +++ b/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor-pushstate.html @@ -0,0 +1,13 @@ + + + + + + diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor.html b/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor.html index a93f68cce72e3..2d118bbe2b2b8 100644 --- a/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor.html +++ b/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor.html @@ -2,52 +2,4 @@ - + diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor.js b/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor.js new file mode 100644 index 0000000000000..67ce0681303da --- /dev/null +++ b/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor.js @@ -0,0 +1,64 @@ +const params = new URLSearchParams(window.location.search); +const uuid = params.get('uuid'); + +// Executor and BFCache detection + +// When navigating out from this page, always call +// `prepareNavigation(callback)` synchronously from the script injected by +// `RemoteContext.execute_script()`, and trigger navigation on or after the +// callback is called. +// prepareNavigation() suspends task polling and avoid in-flight fetch +// requests during navigation that might evict the page from BFCache. +// +// When we navigate to the page again, task polling is resumed, either +// - (BFCache cases) when the pageshow event listener added by +// prepareNavigation() is executed, or +// - (Non-BFCache cases) when `Executor.execute()` is called again during +// non-BFCache page loading. +// +// In such scenarios, `assert_bfcached()` etc. in `helper.sub.js` can determine +// whether the page is restored from BFCache or not, by observing +// - `isPageshowFired`: whether the pageshow event listener added by the +// prepareNavigation() before navigating out, and +// - `loadCount`: whether this inline script is evaluated again. +// - `isPageshowPersisted` is used to assert that `event.persisted` is true +// when restored from BFCache. + +window.isPageshowFired = false; +window.isPageshowPersisted = null; +window.loadCount = parseInt(localStorage.getItem(uuid + '.loadCount') || '0') + 1; +localStorage.setItem(uuid + '.loadCount', loadCount); + +window.pageShowPromise = new Promise(resolve => + window.addEventListener('pageshow', resolve, {once: true})); + +const executor = new Executor(uuid); + +window.prepareNavigation = function(callback) { + window.addEventListener( + 'pageshow', + (event) => { + window.isPageshowFired = true; + window.isPageshowPersisted = event.persisted; + executor.resume(); + }, + {once: true}); + executor.suspend(callback); +} + +// Try to disable BFCache by acquiring and never releasing a Web Lock. +// This requires HTTPS. +// Note: This is a workaround depending on non-specified WebLock+BFCache +// behavior, and doesn't work on Safari. We might want to introduce a +// test-only BFCache-disabling API instead in the future. +// https://github.com/web-platform-tests/wpt/issues/16359#issuecomment-795004780 +// https://crbug.com/1298336 +window.disableBFCache = () => { + return new Promise(resolve => { + // Use page's UUID as a unique lock name. + navigator.locks.request(uuid, () => { + resolve(); + return new Promise(() => {}); + }); + }); +};