Skip to content

Commit

Permalink
Reland "[bfcache] Add notRestoredReasons field in PerformanceNavigati…
Browse files Browse the repository at this point in the history
…onTiming"

This is a reland of commit e1af9facf232a11871b0c668b90ec17c5a5d5e16

To address the test failure, in this reland I added IsOutermostMainFrame() condition in web_view_impl.cc.

Original change's description:
> [bfcache] Add notRestoredReasons field in PerformanceNavigationTiming
>
> This CL adds back/forward cache not restored reasons in Performance
> NavigationTiming API.
> It's proposed here:
> w3c/navigation-timing#171
> Explainer: https://github.com/rubberyuzu/bfcache-not-retored-reason/blob/main/NotRestoredReason.md
>
> This CL does two things:
> - exposes not restored reasons to PerformanceNavigationTiming API
> - adds WPT
>
> The WPT have to run on all platforms because this API is intended to
> collect bfcache metrics from the wild, regardless of the platforms.
>
> LOW_COVERAGE_REASON=Adding coverage for new field. Just missing the tests for the existing fields
>
> Bug: 1349228
> Change-Id: I8dd96a60188bdff94a21c4e4e34cacf181a823db
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3835534
> Reviewed-by: Daniel Cheng <dcheng@chromium.org>
> Reviewed-by: Kentaro Hara <haraken@chromium.org>
> Reviewed-by: Weizhong Xia <weizhong@google.com>
> Commit-Queue: Yuzu Saijo <yuzus@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#1054800}

Bug: 1349228
Change-Id: I010009593e15dcb9da20cc9ee4982294e935f57a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3934434
Reviewed-by: Kentaro Hara <haraken@chromium.org>
Reviewed-by: Kent Tamura <tkent@chromium.org>
Commit-Queue: Yuzu Saijo <yuzus@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1055140}
  • Loading branch information
Yuzu Saijo authored and chromium-wpt-export-bot committed Oct 5, 2022
1 parent 98d2718 commit 25a2d19
Show file tree
Hide file tree
Showing 5 changed files with 255 additions and 0 deletions.
Expand Up @@ -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<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);
}
}
@@ -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;
}));
});
@@ -0,0 +1,70 @@
// 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
// META: script=/websockets/constants.sub.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'},
);

const domainPort = SCHEME_DOMAIN_PORT;
await rc1_child.executeScript((domain) => {
var ws = new WebSocket(domain + '/echo');
}, [domainPort]);

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": []
}]);
});
@@ -0,0 +1,44 @@
// 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
// META: script=/websockets/constants.sub.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'});

const domainPort = SCHEME_DOMAIN_PORT;
await rc1.executeScript((domain) => {
var ws = new WebSocket(domain + '/echo');
}, [domainPort]);

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=*/["WebSocket"],
/*children=*/[]);
});
@@ -0,0 +1,73 @@
// 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
// META: script=/websockets/constants.sub.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 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_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": ["WebSocket"],
"children": [
{
"blocked": false,
"url": rc1_grand_child_url,
"src": rc1_grand_child_url,
"id": "",
"name": "",
"reasons": [],
"children": []
}
]
}]);
});

0 comments on commit 25a2d19

Please sign in to comment.