diff --git a/html/browsers/browsing-the-web/remote-context-helper-tests/resources/test-helper.js b/html/browsers/browsing-the-web/remote-context-helper-tests/resources/test-helper.js index 95d516e2752803..5f8e07711cbcaa 100644 --- a/html/browsers/browsing-the-web/remote-context-helper-tests/resources/test-helper.js +++ b/html/browsers/browsing-the-web/remote-context-helper-tests/resources/test-helper.js @@ -46,3 +46,40 @@ async function assertHeaderIsAsExpected( 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'}); + await rc1.executeScript(() => { + window.bc = new BroadcastChannel('foo'); + }); + const rc1_url = await rc1.executeScript(() => { + return location.href; + }); + + // Navigate away. + const rc2 = await rc1.navigateToNew(); + + // Navigate back. + await rc2.historyBack(); + // Check the reported reasons. + await assertNotRestoredReasonsEquals( + rc1, + /*blocked=*/true, + /*url=*/rc1_url, + /*src=*/ "", + /*id=*/"", + /*name=*/"", + /*reasons=*/["BroadcastChannel"], + /*children=*/[]); + + 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. + await assertNotRestoredReasonsEquals( + rc1, + /*blocked=*/true, + /*url=*/rc1_url, + /*src=*/ "", + /*id=*/"", + /*name=*/"", + /*reasons=*/["BroadcastChannel"], + /*children=*/[]); + }); diff --git a/performance-timeline/performance-navigation-timing-bfcache.window.js b/performance-timeline/performance-navigation-timing-bfcache.window.js new file mode 100644 index 00000000000000..549e72b30dd639 --- /dev/null +++ b/performance-timeline/performance-navigation-timing-bfcache.window.js @@ -0,0 +1,31 @@ +// META: title=RemoteContextHelper navigation using BFCache +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/get-host-info.sub.js +// META: script=/common/utils.js +// META: script=/resources/testharness.js +// META: script=/resources/testharnessreport.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'; + +// Ensure that notRestoredReasons is empty for successful BFCache restore. +promise_test(async t => { + const rcHelper = new RemoteContextHelper(); + + // Open a window with noopener so that BFCache will work. + const rc1 = await rcHelper.addWindow( + /*config=*/ null, /*options=*/ {features: 'noopener'}); + + // Navigate away. + const rc2 = await rc1.navigateToNew(); + + // Navigate back. + await rc2.historyBack(); + + // Verify that no reasons are recorded for successful restore. + assert_true(await rc1.executeScript(() => { + let reasons = performance.getEntriesByType('navigation')[0].notRestoredReasons; + return reasons == null; + })); +}); \ No newline at end of file diff --git a/performance-timeline/performance-navigation-timing-cross-origin-bfcache.window.js b/performance-timeline/performance-navigation-timing-cross-origin-bfcache.window.js new file mode 100644 index 00000000000000..457d4a1451f1f0 --- /dev/null +++ b/performance-timeline/performance-navigation-timing-cross-origin-bfcache.window.js @@ -0,0 +1,66 @@ +// META: title=RemoteContextHelper navigation using BFCache +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/get-host-info.sub.js +// META: script=/common/utils.js +// META: script=/resources/testharness.js +// META: script=/resources/testharnessreport.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'; + +// 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. + const rc1 = await rcHelper.addWindow( + /*config=*/ null, /*options=*/ {features: 'noopener'}); + const rc1_url = await rc1.executeScript(() => { + return location.href; + }); + // 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'}, + ); + await rc1_child.executeScript(() => { + window.bc = new BroadcastChannel('foo'); + }); + const rc1_child_url = await rc1_child.executeScript(() => { + return location.href; + }); + // Add a child to the iframe. + const rc1_grand_child = await rc1_child.addIframe(); + const rc1_grand_child_url = await rc1_grand_child.executeScript(() => { + return location.href; + }); + + // Navigate away. + const rc2 = await rc1.navigateToNew(); + + // Navigate back. + await rc2.historyBack(); + + // 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": [] + }]); +}); \ No newline at end of file diff --git a/performance-timeline/performance-navigation-timing-not-bfcached.window.js b/performance-timeline/performance-navigation-timing-not-bfcached.window.js new file mode 100644 index 00000000000000..7c4ed9531f4d31 --- /dev/null +++ b/performance-timeline/performance-navigation-timing-not-bfcached.window.js @@ -0,0 +1,41 @@ +// META: title=RemoteContextHelper navigation using BFCache +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/get-host-info.sub.js +// META: script=/common/utils.js +// META: script=/resources/testharness.js +// META: script=/resources/testharnessreport.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'; + +// Ensure that notRestoredReasons is populated when not restored. +promise_test(async t => { + const rcHelper = new RemoteContextHelper(); + // Open a window with noopener so that BFCache will work. + const rc1 = await rcHelper.addWindow( + /*config=*/ null, /*options=*/ {features: 'noopener'}); + await rc1.executeScript(() => { + window.bc = new BroadcastChannel('foo'); + }); + + const rc1_url = await rc1.executeScript(() => { + return location.href; + }); + + // Navigate away. + const rc2 = await rc1.navigateToNew(); + + // Navigate back. + await rc2.historyBack(); + // Check the reported reasons. + await assertNotRestoredReasonsEquals( + rc1, + /*blocked=*/true, + /*url=*/rc1_url, + /*src=*/ "", + /*id=*/"", + /*name=*/"", + /*reasons=*/["BroadcastChannel"], + /*children=*/[]); +}); \ No newline at end of file diff --git a/performance-timeline/performance-navigation-timing-same-origin-bfcache.window.js b/performance-timeline/performance-navigation-timing-same-origin-bfcache.window.js new file mode 100644 index 00000000000000..f1662786c2c294 --- /dev/null +++ b/performance-timeline/performance-navigation-timing-same-origin-bfcache.window.js @@ -0,0 +1,69 @@ +// META: title=RemoteContextHelper navigation using BFCache +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/get-host-info.sub.js +// META: script=/common/utils.js +// META: script=/resources/testharness.js +// META: script=/resources/testharnessreport.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'; + +// Ensure that same-origin subtree's reasons are exposed to notRestoredReasons. +promise_test(async t => { + const rcHelper = new RemoteContextHelper(); + // Open a window with noopener so that BFCache will work. + const rc1 = await rcHelper.addWindow( + /*config=*/ null, /*options=*/ {features: 'noopener'}); + const rc1_url = await rc1.executeScript(() => { + return location.href; + }); + // Add a same-origin iframe and use BroadcastChannel. + const rc1_child = await rc1.addIframe(/*extra_config=*/{}, /*attributes=*/ {id: 'test-id'}); + await rc1_child.executeScript(() => { + window.bc = new BroadcastChannel('foo'); + }); + const rc1_child_url = await rc1_child.executeScript(() => { + return location.href; + }); + // Add a child to the iframe. + const rc1_grand_child = await rc1_child.addIframe(); + const rc1_grand_child_url = await rc1_grand_child.executeScript(() => { + return location.href; + }); + + // Navigate away. + const rc2 = await rc1.navigateToNew(); + + // Navigate back. + await rc2.historyBack(); + + // 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": ["BroadcastChannel"], + "children": [ + { + "blocked": false, + "url": rc1_grand_child_url, + "src": rc1_grand_child_url, + "id": "", + "name": "", + "reasons": [], + "children": [] + } + ] + }]); +}); \ No newline at end of file