From 7e8c773010e6f4afe75161b561037695d7c93320 Mon Sep 17 00:00:00 2001 From: Blink WPT Bot Date: Thu, 13 Oct 2022 16:11:39 +0000 Subject: [PATCH] Bug 1793735 [wpt PR 36280] - [bfcache] Do not reset notRestoredReasons upon successful bfcache navigation, a=testonly Automatic update from web-platform-tests [bfcache] Do not reset notRestoredReasons upon successful bfcache navigation (#36280) This CL makes PerformanceNavigationEntry.notRestoredReasons not reset after successful bfcache navigation. After this CL, when the page is successfully restored from bfcache, the reasons from the previous navigation stay. Now, the only time we reset the reasons is when we get a new set of reasons. This was discussed on the email thread here: https://groups.google.com/a/chromium.org/g/bfcache-dev/c/fGPWPVTbyJA Bug:1363438 Change-Id: I5214f56e8424356cad8190c2a0144e4d1c017746 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3906513 Reviewed-by: Kentaro Hara Reviewed-by: Fergal Daly Commit-Queue: Yuzu Saijo Cr-Commit-Position: refs/heads/main@{#1056205} Co-authored-by: Yuzu Saijo -- wpt-commits: 04ee132a7c7cf5f6c59b1a5819facef62f54a371 wpt-pr: 36280 --- .../resources/test-helper.js | 37 ----------- ...avigation-timing-bfcache-reasons-stay.window.js | 56 ++++++++++++++++ ...performance-navigation-timing-bfcache.window.js | 7 +- ...avigation-timing-cross-origin-bfcache.window.js | 60 +++++++++-------- ...rmance-navigation-timing-not-bfcached.window.js | 27 ++++---- ...navigation-timing-same-origin-bfcache.window.js | 64 +++++++++--------- .../not-restored-reasons/test-helper.js | 75 ++++++++++++++++++++++ 7 files changed, 208 insertions(+), 118 deletions(-) create mode 100644 testing/web-platform/tests/performance-timeline/not-restored-reasons/performance-navigation-timing-bfcache-reasons-stay.window.js create mode 100644 testing/web-platform/tests/performance-timeline/not-restored-reasons/test-helper.js diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/remote-context-helper-tests/resources/test-helper.js b/testing/web-platform/tests/html/browsers/browsing-the-web/remote-context-helper-tests/resources/test-helper.js index 5f8e07711cbc..71cd87e55391 100644 --- a/testing/web-platform/tests/html/browsers/browsing-the-web/remote-context-helper-tests/resources/test-helper.js +++ b/testing/web-platform/tests/html/browsers/browsing-the-web/remote-context-helper-tests/resources/test-helper.js @@ -45,41 +45,4 @@ async function assertHeaderIsAsExpected( const res = await fetch(location); return res.headers.get(headerName); }, [headerName]), 'header is set'); -} - -async function assertNotRestoredReasonsEquals( - remoteContextHelper, blocked, url, src, id, name, reasons, children) { - let result = await remoteContextHelper.executeScript(() => { - return performance.getEntriesByType('navigation')[0].notRestoredReasons; - }); - assertReasonsStructEquals(result, blocked, url, src, id, name, reasons, children); -} - -function assertReasonsStructEquals(result, blocked, url, src, id, name, reasons, children) { - assert_equals(result.blocked, blocked); - assert_equals(result.url, url); - assert_equals(result.src, src); - assert_equals(result.id, id); - assert_equals(result.name, name); - // Reasons should match. - assert_equals(result.reasons.length, reasons.length); - reasons.sort(); - result.reasons.sort(); - for (let i=0; i { + const rcHelper = new RemoteContextHelper(); + // Open a window with noopener so that BFCache will work. + const rc1 = await rcHelper.addWindow( + /*config=*/ null, /*options=*/ {features: 'noopener'}); + // Use WebSocket to block BFCache. + await useWebSocket(rc1); + const rc1_url = await rc1.executeScript(() => { + return location.href; + }); + prepareForBFCache(rc1); + + // Navigate away. + const rc2 = await rc1.navigateToNew(); + // Navigate back. + await rc2.historyBack(); + assert_not_bfcached(rc1); + + // Check the reported reasons. + await assertNotRestoredReasonsEquals( + rc1, + /*blocked=*/ true, + /*url=*/ rc1_url, + /*src=*/ '', + /*id=*/ '', + /*name=*/ '', + /*reasons=*/['WebSocket'], + /*children=*/[]); + prepareForBFCache(rc1); + + await rc1.historyForward(); + await rc2.historyBack(); + // This time no blocking feature is used, so the page is restored + // from BFCache. Ensure that the previous reasons stay there. + assert_implements_bfcache(rc1); + await assertNotRestoredReasonsEquals( + rc1, + /*blocked=*/ true, + /*url=*/ rc1_url, + /*src=*/ '', + /*id=*/ '', + /*name=*/ '', + /*reasons=*/['WebSocket'], + /*children=*/[]); +}); diff --git a/testing/web-platform/tests/performance-timeline/not-restored-reasons/performance-navigation-timing-bfcache.window.js b/testing/web-platform/tests/performance-timeline/not-restored-reasons/performance-navigation-timing-bfcache.window.js index a5646f492c73..1e7f6d882a59 100644 --- a/testing/web-platform/tests/performance-timeline/not-restored-reasons/performance-navigation-timing-bfcache.window.js +++ b/testing/web-platform/tests/performance-timeline/not-restored-reasons/performance-navigation-timing-bfcache.window.js @@ -1,9 +1,9 @@ // META: title=RemoteContextHelper navigation using BFCache +// META: script=./test-helper.js // META: script=/common/dispatcher/dispatcher.js // META: script=/common/get-host-info.sub.js // META: script=/common/utils.js // META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js -// META: script=/html/browsers/browsing-the-web/remote-context-helper-tests/resources/test-helper.js 'use strict'; @@ -14,16 +14,19 @@ promise_test(async t => { // Open a window with noopener so that BFCache will work. const rc1 = await rcHelper.addWindow( /*config=*/ null, /*options=*/ {features: 'noopener'}); + prepareForBFCache(rc1); // Navigate away. const rc2 = await rc1.navigateToNew(); // Navigate back. await rc2.historyBack(); + assert_implements_bfcache(rc1); // Verify that no reasons are recorded for successful restore. assert_true(await rc1.executeScript(() => { - let reasons = performance.getEntriesByType('navigation')[0].notRestoredReasons; + let reasons = + performance.getEntriesByType('navigation')[0].notRestoredReasons; return reasons == null; })); }); \ No newline at end of file diff --git a/testing/web-platform/tests/performance-timeline/not-restored-reasons/performance-navigation-timing-cross-origin-bfcache.window.js b/testing/web-platform/tests/performance-timeline/not-restored-reasons/performance-navigation-timing-cross-origin-bfcache.window.js index d49e13741ef4..c3ad64949295 100644 --- a/testing/web-platform/tests/performance-timeline/not-restored-reasons/performance-navigation-timing-cross-origin-bfcache.window.js +++ b/testing/web-platform/tests/performance-timeline/not-restored-reasons/performance-navigation-timing-cross-origin-bfcache.window.js @@ -1,14 +1,15 @@ // META: title=RemoteContextHelper navigation using BFCache +// META: script=./test-helper.js // META: script=/common/dispatcher/dispatcher.js // META: script=/common/get-host-info.sub.js // META: script=/common/utils.js // META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js -// META: script=/html/browsers/browsing-the-web/remote-context-helper-tests/resources/test-helper.js // META: script=/websockets/constants.sub.js 'use strict'; -// Ensure that cross-origin subtree's reasons are not exposed to notRestoredReasons. +// Ensure that cross-origin subtree's reasons are not exposed to +// notRestoredReasons. promise_test(async t => { const rcHelper = new RemoteContextHelper(); // Open a window with noopener so that BFCache will work. @@ -19,18 +20,15 @@ promise_test(async t => { }); // Add a cross-origin iframe and use BroadcastChannel. const rc1_child = await rc1.addIframe( - /*extraConfig=*/ { - origin: 'HTTP_REMOTE_ORIGIN', - scripts: [], - headers: [], - }, - /*attributes=*/ {id: 'test-id'}, + /*extraConfig=*/ { + origin: 'HTTP_REMOTE_ORIGIN', + scripts: [], + headers: [], + }, + /*attributes=*/ {id: 'test-id'}, ); - - const domainPort = SCHEME_DOMAIN_PORT; - await rc1_child.executeScript((domain) => { - var ws = new WebSocket(domain + '/echo'); - }, [domainPort]); + // Use WebSocket to block BFCache. + await useWebSocket(rc1_child); const rc1_child_url = await rc1_child.executeScript(() => { return location.href; @@ -40,29 +38,29 @@ promise_test(async t => { const rc1_grand_child_url = await rc1_grand_child.executeScript(() => { return location.href; }); - + prepareForBFCache(rc1); // Navigate away. const rc2 = await rc1.navigateToNew(); // Navigate back. await rc2.historyBack(); - + assert_not_bfcached(rc1); // Check the reported reasons. await assertNotRestoredReasonsEquals( - rc1, - /*blocked=*/false, - /*url=*/rc1_url, - /*src=*/ "", - /*id=*/"", - /*name=*/"", - /*reasons=*/[], - /*children=*/[{ - "blocked": true, - "url": "", - "src": "", - "id": "", - "name": "", - "reasons": [], - "children": [] - }]); + rc1, + /*blocked=*/ false, + /*url=*/ rc1_url, + /*src=*/ '', + /*id=*/ '', + /*name=*/ '', + /*reasons=*/[], + /*children=*/[{ + 'blocked': true, + 'url': '', + 'src': '', + 'id': '', + 'name': '', + 'reasons': [], + 'children': [] + }]); }); \ No newline at end of file diff --git a/testing/web-platform/tests/performance-timeline/not-restored-reasons/performance-navigation-timing-not-bfcached.window.js b/testing/web-platform/tests/performance-timeline/not-restored-reasons/performance-navigation-timing-not-bfcached.window.js index 12e02f2c5b5f..325425912cce 100644 --- a/testing/web-platform/tests/performance-timeline/not-restored-reasons/performance-navigation-timing-not-bfcached.window.js +++ b/testing/web-platform/tests/performance-timeline/not-restored-reasons/performance-navigation-timing-not-bfcached.window.js @@ -1,9 +1,9 @@ // META: title=RemoteContextHelper navigation using BFCache +// META: script=./test-helper.js // META: script=/common/dispatcher/dispatcher.js // META: script=/common/get-host-info.sub.js // META: script=/common/utils.js // META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js -// META: script=/html/browsers/browsing-the-web/remote-context-helper-tests/resources/test-helper.js // META: script=/websockets/constants.sub.js 'use strict'; @@ -14,29 +14,28 @@ promise_test(async t => { // Open a window with noopener so that BFCache will work. const rc1 = await rcHelper.addWindow( /*config=*/ null, /*options=*/ {features: 'noopener'}); - - const domainPort = SCHEME_DOMAIN_PORT; - await rc1.executeScript((domain) => { - var ws = new WebSocket(domain + '/echo'); - }, [domainPort]); + // Use WebSocket to block BFCache. + await useWebSocket(rc1); const rc1_url = await rc1.executeScript(() => { return location.href; }); + prepareForBFCache(rc1); // Navigate away. const rc2 = await rc1.navigateToNew(); // Navigate back. await rc2.historyBack(); + assert_not_bfcached(rc1); // Check the reported reasons. await assertNotRestoredReasonsEquals( - rc1, - /*blocked=*/true, - /*url=*/rc1_url, - /*src=*/ "", - /*id=*/"", - /*name=*/"", - /*reasons=*/["WebSocket"], - /*children=*/[]); + rc1, + /*blocked=*/ true, + /*url=*/ rc1_url, + /*src=*/ '', + /*id=*/ '', + /*name=*/ '', + /*reasons=*/['WebSocket'], + /*children=*/[]); }); \ No newline at end of file diff --git a/testing/web-platform/tests/performance-timeline/not-restored-reasons/performance-navigation-timing-same-origin-bfcache.window.js b/testing/web-platform/tests/performance-timeline/not-restored-reasons/performance-navigation-timing-same-origin-bfcache.window.js index 6d1413ff58d1..108fc9d2ea38 100644 --- a/testing/web-platform/tests/performance-timeline/not-restored-reasons/performance-navigation-timing-same-origin-bfcache.window.js +++ b/testing/web-platform/tests/performance-timeline/not-restored-reasons/performance-navigation-timing-same-origin-bfcache.window.js @@ -1,9 +1,9 @@ // META: title=RemoteContextHelper navigation using BFCache +// META: script=./test-helper.js // META: script=/common/dispatcher/dispatcher.js // META: script=/common/get-host-info.sub.js // META: script=/common/utils.js // META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js -// META: script=/html/browsers/browsing-the-web/remote-context-helper-tests/resources/test-helper.js // META: script=/websockets/constants.sub.js 'use strict'; @@ -18,12 +18,9 @@ promise_test(async t => { return location.href; }); // Add a same-origin iframe and use WebSocket. - const rc1_child = await rc1.addIframe(/*extra_config=*/{}, /*attributes=*/ {id: 'test-id'}); - - const domainPort = SCHEME_DOMAIN_PORT; - await rc1_child.executeScript((domain) => { - var ws = new WebSocket(domain + '/echo'); - }, [domainPort]); + const rc1_child = await rc1.addIframe( + /*extra_config=*/ {}, /*attributes=*/ {id: 'test-id'}); + await useWebSocket(rc1_child); const rc1_child_url = await rc1_child.executeScript(() => { return location.href; @@ -33,39 +30,38 @@ promise_test(async t => { const rc1_grand_child_url = await rc1_grand_child.executeScript(() => { return location.href; }); + prepareForBFCache(rc1); // Navigate away. const rc2 = await rc1.navigateToNew(); // Navigate back. await rc2.historyBack(); - + assert_not_bfcached(rc1); // Check the reported reasons. await assertNotRestoredReasonsEquals( - rc1, - /*blocked=*/false, - /*url=*/rc1_url, - /*src=*/ "", - /*id=*/"", - /*name=*/"", - /*reasons=*/[], - /*children=*/[{ - "blocked": true, - "url": rc1_child_url, - "src": rc1_child_url, - "id": "test-id", - "name": "", - "reasons": ["WebSocket"], - "children": [ - { - "blocked": false, - "url": rc1_grand_child_url, - "src": rc1_grand_child_url, - "id": "", - "name": "", - "reasons": [], - "children": [] - } - ] - }]); + rc1, + /*blocked=*/ false, + /*url=*/ rc1_url, + /*src=*/ '', + /*id=*/ '', + /*name=*/ '', + /*reasons=*/[], + /*children=*/[{ + 'blocked': true, + 'url': rc1_child_url, + 'src': rc1_child_url, + 'id': 'test-id', + 'name': '', + 'reasons': ['WebSocket'], + 'children': [{ + 'blocked': false, + 'url': rc1_grand_child_url, + 'src': rc1_grand_child_url, + 'id': '', + 'name': '', + 'reasons': [], + 'children': [] + }] + }]); }); \ No newline at end of file diff --git a/testing/web-platform/tests/performance-timeline/not-restored-reasons/test-helper.js b/testing/web-platform/tests/performance-timeline/not-restored-reasons/test-helper.js new file mode 100644 index 000000000000..26d2a3cd65b9 --- /dev/null +++ b/testing/web-platform/tests/performance-timeline/not-restored-reasons/test-helper.js @@ -0,0 +1,75 @@ +async function assertNotRestoredReasonsEquals( + remoteContextHelper, blocked, url, src, id, name, reasons, children) { + let result = await remoteContextHelper.executeScript(() => { + return performance.getEntriesByType('navigation')[0].notRestoredReasons; + }); + assertReasonsStructEquals( + result, blocked, url, src, id, name, reasons, children); +} + +function assertReasonsStructEquals( + result, blocked, url, src, id, name, reasons, children) { + assert_equals(result.blocked, blocked); + assert_equals(result.url, url); + assert_equals(result.src, src); + assert_equals(result.id, id); + assert_equals(result.name, name); + // Reasons should match. + assert_equals(result.reasons.length, reasons.length); + reasons.sort(); + result.reasons.sort(); + for (let i = 0; i < reasons.length; i++) { + assert_equals(result.reasons[i], reasons[i]); + } + // Children should match. + assert_equals(result.children.length, children.length); + children.sort(); + result.children.sort(); + for (let j = 0; j < children.length; j++) { + assertReasonsStructEquals( + result.children[0], children[0].blocked, children[0].url, + children[0].src, children[0].id, children[0].name, children[0].reasons, + children[0].children); + } +} + +// Requires: +// - /websockets/constants.sub.js in the test file and pass the domainPort +// constant here. +async function useWebSocket(remoteContextHelper) { + await remoteContextHelper.executeScript((domain) => { + var webSocketInNotRestoredReasonsTests = new WebSocket(domain + '/echo'); + }, [SCHEME_DOMAIN_PORT]); +} + +// Call |prepareForBFCache()| before navigating away from the page. This simply +// sets a variable in window. +async function prepareForBFCache(remoteContextHelper) { + await remoteContextHelper.executeScript(() => { + window.beforeBFCache = true; + }); +} + +// Call |getBeforeCache| after navigating back to the page. This returns the +// value in window. +async function getBeforeBFCache(remoteContextHelper) { + return await remoteContextHelper.executeScript(() => { + return window.beforeBFCache; + }); +} + +// If the value in window is set to true, this means that the page was reloaded, +// i.e., the page was restored from BFCache. +// Call |prepareForBFCache()| before navigating away to call this function. +async function assert_implements_bfcache(remoteContextHelper) { + var beforeBFCache = await getBeforeBFCache(remoteContextHelper); + assert_implements_optional(beforeBFCache == true, 'BFCache not supported.'); +} + +// If the value in window is undefined, this means that the page was reloaded, +// i.e., the page was not restored from BFCache. +// Call |prepareForBFCache()| before navigating away to call this function. +async function assert_not_bfcached(remoteContextHelper) { + var beforeBFCache = await getBeforeBFCache(remoteContextHelper); + assert_equals(beforeBFCache, undefined); +} -- 2.11.4.GIT