Skip to content

Commit

Permalink
[WPT] BFCache: storage events
Browse files Browse the repository at this point in the history
Expectation:
When localStorage is modified when a page is in BFCache,
storage events should NOT be fired for the page
even after the page becomes active.

Results:
Firefox/Safari: Pass.
Chromium: Fail (events are fired, https://crbug.com/1328939).

Bug: 1328939, 1107415, whatwg/storage#119
Change-Id: I53c92b2d5f8f4791a43c2c702a441029fdbc7101
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3198458
Reviewed-by: Marijn Kruisselbrink <[email protected]>
Reviewed-by: Rakina Zata Amni <[email protected]>
Commit-Queue: Hiroshige Hayashizaki <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1009350}
  • Loading branch information
hiroshige-g authored and chromium-wpt-export-bot committed Jun 1, 2022
1 parent 9a7bbe4 commit 337a7a2
Showing 1 changed file with 101 additions and 0 deletions.
101 changes: 101 additions & 0 deletions html/browsers/browsing-the-web/back-forward-cache/storage-events.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<!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 not be fired for the page after becoming active.
// https://github.com/whatwg/storage/issues/119#issuecomment-1115844532
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 key to set while pageA is in BFCache.
const key1 = token();
// localStorage key to set after pageA is restored from BFCache.
const key2 = token();

const startRecordingStorageEvent = (key1, key2) => {
window.key1EventFired = new Promise(resolve => {
window.addEventListener('storage', e => {
if (e.key === key1) {
recordEvent('storage1');
resolve();
}
});
});
window.key2EventFired = new Promise(resolve => {
window.addEventListener('storage', e => {
if (e.key === key2) {
recordEvent('storage2');
resolve();
}
});
});
};

window.open(urlA, '_blank', 'noopener');
await pageA.execute_script(waitForPageShow);
await pageA.execute_script(startRecordingStorageEvent, [key1, key2]);

// Window C is an unrelated window 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 storage event is fired on PageC and a while,
// to prevent race conditions between event processing
// triggered by `setItem()` and the following operations.
await pageC.execute_script(() => window.key1EventFired);
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 storage event for `key2` is fired on PageA.
await pageA.execute_script(() => window.key2EventFired);

// Confirm that a storage event for `key1` is not fired on PageA.
assert_array_equals(
await pageA.execute_script(() => getRecordedEvents()),
[
'window.load',
'window.pageshow',
'window.pagehide.persisted',
'window.pageshow.persisted',
'storage2',
],
'pageA should not receive storage events for updates while in BFCache');

}, 'Storage events should not be fired for BFCached pages after becoming active');
</script>

0 comments on commit 337a7a2

Please sign in to comment.