-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[WPT] BFCache: pushState() in BFCache/non-BFCache cases
Bug: 1107415, whatwg/html#6207 Change-Id: I609276fe865fa92409fd7a547777dba222bac36c
- Loading branch information
1 parent
e65aefe
commit 902f30b
Showing
4 changed files
with
126 additions
and
49 deletions.
There are no files selected for viewing
50 changes: 50 additions & 0 deletions
50
html/browsers/browsing-the-web/back-forward-cache/pushstate.https.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
<!DOCTYPE HTML> | ||
<meta name="timeout" content="long"> | ||
<script src="/resources/testharness.js"></script> | ||
<script src="/resources/testharnessreport.js"></script> | ||
<script src="/common/utils.js"></script> | ||
<script src="/common/dispatcher/dispatcher.js"></script> | ||
<script src="resources/helper.sub.js"></script> | ||
<script> | ||
// See https://github.com/whatwg/html/issues/6207 for discussion on the | ||
// specified, implemented and desired behaviors. | ||
for (const bfcacheDisabled of [false, true]) { | ||
const pushStateExecutorPath = | ||
'/html/browsers/browsing-the-web/back-forward-cache/resources/executor-pushstate.html'; | ||
|
||
runBfcacheTest({ | ||
funcBeforeNavigation: async (bfcacheDisabled, pushStateExecutorPath) => { | ||
const urlPushState = new URL(location.href); | ||
urlPushState.pathname = pushStateExecutorPath; | ||
if (bfcacheDisabled) { | ||
await disableBFCache(); | ||
} | ||
|
||
// `pushState(..., urlPushState)` on `urlA`, | ||
history.pushState('blue', '', urlPushState.href); | ||
}, | ||
argsBeforeNavigation: [bfcacheDisabled, pushStateExecutorPath], | ||
shouldBeCached: !bfcacheDisabled, | ||
funcAfterAssertion: async (pageA) => { | ||
// We've navigatated to `urlB` and back again | ||
// (already done within `runBfcacheTest()`). | ||
// After the back navigation, `location` etc. should point to | ||
// `urlPushState` and the state that's pushed. | ||
const urlPushState = location.origin + pushStateExecutorPath + | ||
'?uuid=' + pageA.context_id; | ||
assert_equals(await pageA.execute_script(() => location.href), | ||
urlPushState, 'url'); | ||
assert_equals(await pageA.execute_script(() => history.state), | ||
'blue', 'history.state'); | ||
|
||
if (bfcacheDisabled) { | ||
// When the page is not restored from BFCache, the HTML page is loaded | ||
// from `urlPushState` (not from `urlA`). | ||
assert_true(await pageA.execute_script(() => isLoadedFromPushState), | ||
'document should be loaded from urlPushState'); | ||
} | ||
} | ||
}, 'back navigation to pushState()d page (' + | ||
(bfcacheDisabled ? 'not ' : '') + 'in BFCache)'); | ||
} | ||
</script> |
13 changes: 13 additions & 0 deletions
13
html/browsers/browsing-the-web/back-forward-cache/resources/executor-pushstate.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<!DOCTYPE HTML> | ||
<script src="/common/dispatcher/dispatcher.js"></script> | ||
<script src="event-recorder.js" type="module"></script> | ||
<script src="worker-helper.js" type="module"></script> | ||
<script type="module"> | ||
// This is mostly the same as `executor.html`, except for | ||
// `isLoadedFromPushState` is set here, in order to detect whether the page | ||
// was loaded from `executor.html` or `executor-pushstate.html`. | ||
// Full executor functionality is still needed to handle remote script | ||
// execution requests etc. | ||
window.isLoadedFromPushState = true; | ||
</script> | ||
<script src="executor.js" type="module"></script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
62 changes: 62 additions & 0 deletions
62
html/browsers/browsing-the-web/back-forward-cache/resources/executor.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
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. We might want to introduce a test-only BFCache-disabling API | ||
// instead in the future. | ||
window.disableBFCache = () => { | ||
return new Promise(resolve => { | ||
// Use page's UUID as a unique lock name. | ||
navigator.locks.request(uuid, () => { | ||
resolve(); | ||
return new Promise(() => {}); | ||
}); | ||
}); | ||
}; |