зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
8a480e5897
Коммит
05192f1eb9
|
@ -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');
|
||||
}
|
Загрузка…
Ссылка в новой задаче