Bug 1584305 [wpt PR 19333] - Portals: Add WPTs for navigations in portals, a=testonly

Automatic update from web-platform-tests
Portals: Add WPTs for navigations in portals

We test that methods for history manipulation work inside a portal
context and that their behaviour is the same as in a non-portal context.
We also test the new behaviour introduced with portals where a portal
and its host do not form a joint session history. So unlike iframes,
any session history change within a portal is done independently of its
host.

Bug: 914108
Change-Id: Ib1cdbe3e8d1c0e009eea1f05af28ef2971e8b353
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1807773
Reviewed-by: Jeremy Roman <jbroman@chromium.org>
Commit-Queue: Kevin McNee <mcnee@chromium.org>
Cr-Commit-Position: refs/heads/master@{#706587}

--

wpt-commits: f71a17b10a9d4c59e28a7095d59fdc4ef3428719
wpt-pr: 19333
This commit is contained in:
Kevin McNee 2019-10-22 10:58:18 +00:00 коммит произвёл James Graham
Родитель 8a480e5897
Коммит 05192f1eb9
8 изменённых файлов: 305 добавлений и 0 удалений

Просмотреть файл

@ -313,6 +313,7 @@ SET TIMEOUT: html/cross-origin-embedder-policy/resources/navigate-none.sub.html
SET TIMEOUT: html/cross-origin-embedder-policy/resources/navigate-require-corp.sub.html
SET TIMEOUT: html/dom/documents/dom-tree-accessors/Document.currentScript.html
SET TIMEOUT: html/webappapis/timers/*
SET TIMEOUT: portals/history/resources/portal-harness.js
SET TIMEOUT: resources/chromium/*
SET TIMEOUT: resources/test/tests/functional/add_cleanup.html
SET TIMEOUT: resources/test/tests/functional/add_cleanup_async.html

Просмотреть файл

@ -0,0 +1,42 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/run-test-in-portal.js"></script>
<body>
<script>
var portalSrc =
'resources/portal-manipulate-history-with-subframes.sub.html';
// Runs before and after the history manipulation in the portal to confirm
// that the session history of the portal host is not affected by any history
// changes in the portal.
function assertInitialHistoryState() {
assert_equals(history.length, 1);
assert_false(!!history.state);
}
promise_test(async () => {
assertInitialHistoryState();
await runTestInPortal(portalSrc, 'testIFrameSrcInPortal');
assertInitialHistoryState();
}, 'Setting iframe src navigates independently in a portal');
promise_test(async () => {
assertInitialHistoryState();
await runTestInPortal(portalSrc, 'testCrossSiteIFrameSrcInPortal');
assertInitialHistoryState();
}, 'Setting cross site iframe src navigates independently in a portal');
promise_test(async () => {
assertInitialHistoryState();
await runTestInPortal(portalSrc, 'testIFrameNavInPortal');
assertInitialHistoryState();
}, 'iframe navigates itself independently in a portal');
promise_test(async () => {
assertInitialHistoryState();
await runTestInPortal(portalSrc, 'testCrossSiteIFrameNavInPortal');
assertInitialHistoryState();
}, 'Cross site iframe navigates itself independently in a portal');
</script>
</body>

Просмотреть файл

@ -0,0 +1,54 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/run-test-in-portal.js"></script>
<body>
<script>
var portalSrc =
'resources/portal-manipulate-history.html';
// Runs before and after the history manipulation in the portal to confirm
// that the session history of the portal host is not affected by any history
// changes in the portal.
function assertInitialHistoryState() {
assert_equals(history.length, 1);
assert_false(!!history.state);
}
promise_test(async () => {
assertInitialHistoryState();
await runTestInPortal(portalSrc, 'testHistoryPushStateInPortal');
assertInitialHistoryState();
}, 'history.pushState navigates independently in a portal');
promise_test(async () => {
assertInitialHistoryState();
await runTestInPortal(portalSrc, 'testHistoryReplaceStateInPortal');
assertInitialHistoryState();
}, 'history.replaceState navigates independently in a portal');
promise_test(async () => {
assertInitialHistoryState();
await runTestInPortal(portalSrc, 'testLocationAssignInPortal');
assertInitialHistoryState();
}, 'location.assign navigates independently in a portal');
promise_test(async () => {
assertInitialHistoryState();
await runTestInPortal(portalSrc, 'testLocationReplaceInPortal');
assertInitialHistoryState();
}, 'location.replace navigates independently in a portal');
promise_test(async () => {
assertInitialHistoryState();
await runTestInPortal(portalSrc, 'testSetLocationHrefInPortal');
assertInitialHistoryState();
}, 'Setting location.href navigates independently in a portal');
promise_test(async () => {
assertInitialHistoryState();
await runTestInPortal(portalSrc, 'testSyntheticAnchorClickInPortal');
assertInitialHistoryState();
}, 'Synthetic anchor click navigates independently in a portal');
</script>
</body>

Просмотреть файл

@ -0,0 +1,13 @@
<!DOCTYPE html>
<body>
<script>
window.onmessage = (e) => {
if (e.data == 'reportHistoryLength') {
e.source.postMessage(history.length, '*');
} else if (e.data == 'navigate') {
location.href = '#test';
e.source.postMessage('Done', '*');
}
};
</script>
</body>

Просмотреть файл

@ -0,0 +1,30 @@
// We don't have the test harness in this context, so we roll our own
// which communicates with our host which is actually running the tests.
window.onload = async () => {
let urlParams = new URLSearchParams(window.location.search);
let testName = urlParams.get('testName');
let testFn = window[testName];
if (!testFn) {
window.portalHost.postMessage('Missing test: ' + testName, '*');
return;
}
// The document load event is not finished at this point, so navigations
// would be done with replacement. This interferes with our tests. We wait
// for the next task before navigating to avoid this.
await new Promise((resolve) => { window.setTimeout(resolve); });
try {
await testFn();
window.portalHost.postMessage('Passed', '*');
} catch (e) {
window.portalHost.postMessage(
'Failed: ' + e.name + ': ' + e.message, '*');
}
};
function assert(condition, message) {
if (!condition)
throw new Error('Assertion failed: ' + message);
}

Просмотреть файл

@ -0,0 +1,83 @@
<!DOCTYPE html>
<script src="portal-harness.js"></script>
<body>
<script>
function messageFrameAndAwaitResponse(frame, message) {
return new Promise((resolve) => {
window.onmessage = (e) => {
resolve(e.data);
};
frame.contentWindow.postMessage(message, '*');
});
}
function innerFrameUrl(crossSite) {
return (crossSite ?
'https://{{hosts[alt][www]}}:{{ports[https][0]}}' : '') +
'/portals/history/resources/inner-iframe.html'
}
async function runTestIFrameSrcInPortal(crossSite) {
assert(history.length == 1, 'Initial history length');
let iframe = document.createElement('iframe');
iframe.src = innerFrameUrl(crossSite);
await new Promise((resolve) => {
iframe.onload = resolve;
document.body.appendChild(iframe);
});
let frameHistoryLength =
await messageFrameAndAwaitResponse(iframe, 'reportHistoryLength');
assert(history.length == 1, 'History length unchanged when iframe added');
assert(frameHistoryLength == 1, 'History length in iframe when added');
iframe.src = iframe.src + '#test';
frameHistoryLength =
await messageFrameAndAwaitResponse(iframe, 'reportHistoryLength');
assert(
history.length == 2, 'History length changed when iframe src set');
assert(
frameHistoryLength == 2,
'History length in iframe changed when iframe src set');
}
function testIFrameSrcInPortal() {
return runTestIFrameSrcInPortal(false);
}
function testCrossSiteIFrameSrcInPortal() {
return runTestIFrameSrcInPortal(true);
}
async function runTestIFrameNavInPortal(crossSite) {
assert(history.length == 1, 'Initial history length');
let iframe = document.createElement('iframe');
iframe.src = innerFrameUrl(crossSite);
await new Promise((resolve) => {
iframe.onload = resolve;
document.body.appendChild(iframe);
});
await messageFrameAndAwaitResponse(iframe, 'navigate');
let frameHistoryLength =
await messageFrameAndAwaitResponse(iframe, 'reportHistoryLength');
assert(
history.length == 2, 'History length changed when iframe navigates');
assert(
frameHistoryLength == 2,
'History length in iframe changed when iframe navigates');
}
function testIFrameNavInPortal() {
return runTestIFrameNavInPortal(false);
}
function testCrossSiteIFrameNavInPortal() {
return runTestIFrameNavInPortal(true);
}
</script>
</body>

Просмотреть файл

@ -0,0 +1,66 @@
<!DOCTYPE html>
<script src="portal-harness.js"></script>
<body>
<script>
function testHistoryPushStateInPortal() {
assert(history.length == 1, 'Initial history length');
assert(!history.state, 'Initial history state');
history.pushState('teststate', null, null);
assert(history.length == 2, 'History length changed');
assert(history.state == 'teststate', 'Update state');
}
function testHistoryReplaceStateInPortal() {
assert(history.length == 1, 'Initial history length');
assert(!history.state, 'Initial history state');
history.replaceState('teststate', null, null);
assert(history.length == 1, 'History length unchanged');
assert(history.state == 'teststate', 'Update state');
}
function testLocationAssignInPortal() {
assert(history.length == 1, 'Initial history length');
let initialLocation = location.href;
location.assign('#test');
assert(history.length == 2, 'History length changed');
assert(location.href != initialLocation, 'Update location');
}
function testLocationReplaceInPortal() {
assert(history.length == 1, 'Initial history length');
let initialLocation = location.href;
location.replace('#test');
assert(history.length == 1, 'History length unchanged');
assert(location.href != initialLocation, 'Update location');
}
function testSetLocationHrefInPortal() {
assert(history.length == 1, 'Initial history length');
let initialLocation = location.href;
location.href = '#test';
assert(history.length == 2, 'History length changed');
assert(location.href != initialLocation, 'Update location');
}
function testSyntheticAnchorClickInPortal() {
assert(history.length == 1, 'Initial history length');
let initialLocation = location.href;
var anchor = document.createElement('a');
anchor.href = '#test';
document.body.appendChild(anchor);
anchor.click();
assert(history.length == 2, 'History length changed');
assert(location.href != initialLocation, 'Update location');
}
</script>
</body>

Просмотреть файл

@ -0,0 +1,16 @@
// This is called from the portal host which is running with the test harness.
// This creates a portal and communicates with our ad hoc test harness in the
// portal context which performs the history manipulation in the portal. We
// confirm that the history manipulation works as expected in the portal.
async function runTestInPortal(portalSrc, testName) {
let portal = document.createElement('portal');
portal.src = portalSrc + '?testName=' + testName;
let result = await new Promise((resolve) => {
portal.onmessage = (e) => {
resolve(e.data);
};
document.body.appendChild(portal);
});
assert_equals(result, 'Passed');
}