-
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.
Expectation: When localStorage is modified when a page is in BFCache, storage events should be fired for the page after becoming active. Results: Chromium: Pass. Firefox/Safari: Fail (storage events are not fired when localStorage is modified when a page is in BFCache) Bug: 1107415, whatwg/storage#119 Change-Id: I53c92b2d5f8f4791a43c2c702a441029fdbc7101
- Loading branch information
1 parent
a286838
commit 26ecff4
Showing
1 changed file
with
99 additions
and
0 deletions.
There are no files selected for viewing
99 changes: 99 additions & 0 deletions
99
html/browsers/browsing-the-web/back-forward-cache/storage-events.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,99 @@ | ||
<!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> | ||
// When localStorage (`key1`) is modified when a page (`pageA`) is in BFCache, | ||
// storage events should be fired for the page after becoming active. | ||
// https://github.com/whatwg/storage/issues/119#issuecomment-785771108 | ||
promise_test(async t => { | ||
const pageA = new RemoteContext(token()); | ||
const pageB = new RemoteContext(token()); | ||
const pageC = new RemoteContext(token()); | ||
|
||
const urlA = executorPath + pageA.context_id + '&events=pagehide,pageshow,load'; | ||
const urlB = originCrossSite + executorPath + pageB.context_id; | ||
const urlC = executorPath + pageC.context_id + '&events=pagehide,pageshow,load'; | ||
|
||
// localStorage keys set while pageA is active/inactive. | ||
const key1 = token(); | ||
const key2 = token(); | ||
|
||
const startRecordingStorageEvent = (key1, key2) => { | ||
window.addEventListener('storage', e => { | ||
if (e.key === key1) { | ||
recordEvent('storage1'); | ||
} | ||
if (e.key === key2) { | ||
recordEvent('storage2'); | ||
} | ||
}); | ||
}; | ||
|
||
window.open(urlA, '_blank', 'noopener'); | ||
await pageA.execute_script(waitForPageShow); | ||
await pageA.execute_script(startRecordingStorageEvent, [key1, key2]); | ||
|
||
// Window C is kept open without navigation, to confirm that storage events are | ||
// fired as expected in non-BFCache-related scenario and not blocked due to | ||
// non-BFCache-related reasons. | ||
window.open(urlC, '_blank'); | ||
await pageC.execute_script(waitForPageShow); | ||
await pageC.execute_script(startRecordingStorageEvent, [key1, key2]); | ||
|
||
// Navigate A to B. | ||
await pageA.execute_script((url) => { | ||
prepareNavigation(() => { | ||
location.href = url; | ||
}); | ||
}, [urlB]); | ||
await pageB.execute_script(waitForPageShow); | ||
|
||
// Update `key1` while pageA is in BFCache. | ||
localStorage.setItem(key1, 'value'); | ||
// Wait for a while to prevent race conditions between event processing | ||
// triggered by `setItem()` and the following operations. | ||
await new Promise(resolve => t.step_timeout(resolve, 1000)); | ||
|
||
// Back navigate to pageA, to be restored from BFCache. | ||
await pageB.execute_script( | ||
() => { | ||
prepareNavigation(() => { history.back(); }); | ||
} | ||
); | ||
await pageA.execute_script(waitForPageShow); | ||
await assert_bfcached(pageA); | ||
|
||
// Update `key2` after pageA is restored from BFCache. | ||
localStorage.setItem(key2, 'value'); | ||
// Wait for a while to prevent race conditions between event processing | ||
// triggered by `setItem()` and the following operations. | ||
await new Promise(resolve => t.step_timeout(resolve, 1000)); | ||
|
||
assert_array_equals( | ||
await pageC.execute_script(() => getRecordedEvents()), | ||
[ | ||
'window.load', | ||
'window.pageshow', | ||
'storage1', | ||
'storage2', | ||
], | ||
'pageC should receive storage events'); | ||
|
||
assert_array_equals( | ||
await pageA.execute_script(() => getRecordedEvents()), | ||
[ | ||
'window.load', | ||
'window.pageshow', | ||
'window.pagehide.persisted', | ||
'window.pageshow.persisted', | ||
'storage1', | ||
'storage2', | ||
], | ||
'pageA should receive storage events after it becomes active'); | ||
|
||
}, 'Storage events should be fired for BFCached pages after becoming active'); | ||
</script> |