summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/portals/history
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /testing/web-platform/tests/portals/history
parentInitial commit. (diff)
downloadthunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz
thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/portals/history')
-rw-r--r--testing/web-platform/tests/portals/history/history-manipulation-inside-portal-with-subframes.html42
-rw-r--r--testing/web-platform/tests/portals/history/history-manipulation-inside-portal.html60
-rw-r--r--testing/web-platform/tests/portals/history/resources/inner-iframe.html13
-rw-r--r--testing/web-platform/tests/portals/history/resources/portal-harness.js30
-rw-r--r--testing/web-platform/tests/portals/history/resources/portal-manipulate-history-with-subframes.sub.html83
-rw-r--r--testing/web-platform/tests/portals/history/resources/portal-manipulate-history.html66
-rw-r--r--testing/web-platform/tests/portals/history/resources/run-test-in-portal.js16
7 files changed, 310 insertions, 0 deletions
diff --git a/testing/web-platform/tests/portals/history/history-manipulation-inside-portal-with-subframes.html b/testing/web-platform/tests/portals/history/history-manipulation-inside-portal-with-subframes.html
new file mode 100644
index 0000000000..cb4c8d0f91
--- /dev/null
+++ b/testing/web-platform/tests/portals/history/history-manipulation-inside-portal-with-subframes.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 with replacement in a portal');
+
+ promise_test(async () => {
+ assertInitialHistoryState();
+ await runTestInPortal(portalSrc, 'testCrossSiteIFrameSrcInPortal');
+ assertInitialHistoryState();
+ }, 'Setting cross site iframe src navigates independently with replacement in a portal');
+
+ promise_test(async () => {
+ assertInitialHistoryState();
+ await runTestInPortal(portalSrc, 'testIFrameNavInPortal');
+ assertInitialHistoryState();
+ }, 'iframe navigates itself independently with replacement in a portal');
+
+ promise_test(async () => {
+ assertInitialHistoryState();
+ await runTestInPortal(portalSrc, 'testCrossSiteIFrameNavInPortal');
+ assertInitialHistoryState();
+ }, 'Cross site iframe navigates itself independently with replacement in a portal');
+</script>
+</body>
diff --git a/testing/web-platform/tests/portals/history/history-manipulation-inside-portal.html b/testing/web-platform/tests/portals/history/history-manipulation-inside-portal.html
new file mode 100644
index 0000000000..d4b0cf4db9
--- /dev/null
+++ b/testing/web-platform/tests/portals/history/history-manipulation-inside-portal.html
@@ -0,0 +1,60 @@
+<!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 () => {
+ assert_implements("HTMLPortalElement" in self);
+ assertInitialHistoryState();
+ await runTestInPortal(portalSrc, 'testHistoryPushStateInPortal');
+ assertInitialHistoryState();
+ }, 'history.pushState navigates independently with replacement in a portal');
+
+ promise_test(async () => {
+ assert_implements("HTMLPortalElement" in self);
+ assertInitialHistoryState();
+ await runTestInPortal(portalSrc, 'testHistoryReplaceStateInPortal');
+ assertInitialHistoryState();
+ }, 'history.replaceState navigates independently in a portal');
+
+ promise_test(async () => {
+ assert_implements("HTMLPortalElement" in self);
+ assertInitialHistoryState();
+ await runTestInPortal(portalSrc, 'testLocationAssignInPortal');
+ assertInitialHistoryState();
+ }, 'location.assign navigates independently with replacement in a portal');
+
+ promise_test(async () => {
+ assert_implements("HTMLPortalElement" in self);
+ assertInitialHistoryState();
+ await runTestInPortal(portalSrc, 'testLocationReplaceInPortal');
+ assertInitialHistoryState();
+ }, 'location.replace navigates independently in a portal');
+
+ promise_test(async () => {
+ assert_implements("HTMLPortalElement" in self);
+ assertInitialHistoryState();
+ await runTestInPortal(portalSrc, 'testSetLocationHrefInPortal');
+ assertInitialHistoryState();
+ }, 'Setting location.href navigates independently with replacement in a portal');
+
+ promise_test(async () => {
+ assert_implements("HTMLPortalElement" in self);
+ assertInitialHistoryState();
+ await runTestInPortal(portalSrc, 'testSyntheticAnchorClickInPortal');
+ assertInitialHistoryState();
+ }, 'Synthetic anchor click navigates independently with replacement in a portal');
+</script>
+</body>
diff --git a/testing/web-platform/tests/portals/history/resources/inner-iframe.html b/testing/web-platform/tests/portals/history/resources/inner-iframe.html
new file mode 100644
index 0000000000..5c6daa22a5
--- /dev/null
+++ b/testing/web-platform/tests/portals/history/resources/inner-iframe.html
@@ -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>
diff --git a/testing/web-platform/tests/portals/history/resources/portal-harness.js b/testing/web-platform/tests/portals/history/resources/portal-harness.js
new file mode 100644
index 0000000000..fa8c761afb
--- /dev/null
+++ b/testing/web-platform/tests/portals/history/resources/portal-harness.js
@@ -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);
+}
diff --git a/testing/web-platform/tests/portals/history/resources/portal-manipulate-history-with-subframes.sub.html b/testing/web-platform/tests/portals/history/resources/portal-manipulate-history-with-subframes.sub.html
new file mode 100644
index 0000000000..bab83b444f
--- /dev/null
+++ b/testing/web-platform/tests/portals/history/resources/portal-manipulate-history-with-subframes.sub.html
@@ -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 == 1, 'History length unchanged when iframe src set');
+ assert(
+ frameHistoryLength == 1,
+ 'History length in iframe unchanged 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 == 1, 'History length unchanged when iframe navigates');
+ assert(
+ frameHistoryLength == 1,
+ 'History length in iframe unchanged when iframe navigates');
+ }
+
+ function testIFrameNavInPortal() {
+ return runTestIFrameNavInPortal(false);
+ }
+
+ function testCrossSiteIFrameNavInPortal() {
+ return runTestIFrameNavInPortal(true);
+ }
+</script>
+</body>
diff --git a/testing/web-platform/tests/portals/history/resources/portal-manipulate-history.html b/testing/web-platform/tests/portals/history/resources/portal-manipulate-history.html
new file mode 100644
index 0000000000..3e25f0e6f2
--- /dev/null
+++ b/testing/web-platform/tests/portals/history/resources/portal-manipulate-history.html
@@ -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 == 1, 'History length unchanged');
+ 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 == 1, 'History length unchanged');
+ 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 == 1, 'History length unchanged');
+ 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 == 1, 'History length unchanged');
+ assert(location.href != initialLocation, 'Update location');
+ }
+</script>
+</body>
diff --git a/testing/web-platform/tests/portals/history/resources/run-test-in-portal.js b/testing/web-platform/tests/portals/history/resources/run-test-in-portal.js
new file mode 100644
index 0000000000..c982a1fac8
--- /dev/null
+++ b/testing/web-platform/tests/portals/history/resources/run-test-in-portal.js
@@ -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');
+}