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 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: 1328939, 1107415, whatwg/storage#119
Change-Id: I53c92b2d5f8f4791a43c2c702a441029fdbc7101
  • Loading branch information
hiroshige-g authored and chromium-wpt-export-bot committed May 24, 2022
1 parent 4bee022 commit a07f7d2
Showing 1 changed file with 98 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<!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',
'storage2',
],
'pageA should not receive storage events for updates while in BFCache');

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

0 comments on commit a07f7d2

Please sign in to comment.