summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/html/browsers/browsing-the-web
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/html/browsers/browsing-the-web')
-rw-r--r--testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/disable_bfcache.js15
-rw-r--r--testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor-pushstate.html1
-rw-r--r--testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor.html1
-rw-r--r--testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor.js17
-rw-r--r--testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js5
-rw-r--r--testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-cross-origin.sub.html65
-rw-r--r--testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-iframe.html45
-rw-r--r--testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-initial-navigation.html35
-rw-r--r--testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-from-click.html74
-rw-r--r--testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-navigation-hidden-document.html68
-rw-r--r--testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-navigation.html64
-rw-r--r--testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-with-cross-origin-redirect.sub.html69
-rw-r--r--testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-with-redirect.html64
-rw-r--r--testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-reload-navigation.html65
-rw-r--r--testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-replace-navigation.html64
-rw-r--r--testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-replace-with-cross-origin-redirect.sub.html69
-rw-r--r--testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-traverse-navigation-cross-origin-redirect-no-bfcache.https.sub.html77
-rw-r--r--testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-traverse-navigation-no-bfcache.https.html75
18 files changed, 854 insertions, 19 deletions
diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/disable_bfcache.js b/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/disable_bfcache.js
new file mode 100644
index 0000000000..dea70ef4bd
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/disable_bfcache.js
@@ -0,0 +1,15 @@
+// Try to disable BFCache by acquiring and never releasing a Web Lock.
+// This requires HTTPS.
+// Note: This is a workaround depending on non-specified WebLock+BFCache
+// behavior, and doesn't work on Safari. We might want to introduce a
+// test-only BFCache-disabling API instead in the future.
+// https://github.com/web-platform-tests/wpt/issues/16359#issuecomment-795004780
+// https://crbug.com/1298336
+window.disableBFCache = () => {
+ return new Promise(resolve => {
+ navigator.locks.request("disablebfcache", () => {
+ resolve();
+ return new Promise(() => {});
+ });
+ });
+};
diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor-pushstate.html b/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor-pushstate.html
index dcf4a798d0..3dd8f341f1 100644
--- a/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor-pushstate.html
+++ b/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor-pushstate.html
@@ -11,3 +11,4 @@
window.isLoadedFromPushState = true;
</script>
<script src="executor.js" type="module"></script>
+<script src="disable_bfcache.js" type="module"></script>
diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor.html b/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor.html
index 2d118bbe2b..c3af5f6ba8 100644
--- a/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor.html
+++ b/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor.html
@@ -3,3 +3,4 @@
<script src="event-recorder.js" type="module"></script>
<script src="worker-helper.js" type="module"></script>
<script src="executor.js" type="module"></script>
+<script src="disable_bfcache.js" type="module"></script>
diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor.js b/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor.js
index 67ce068130..5137616d85 100644
--- a/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor.js
+++ b/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor.js
@@ -45,20 +45,3 @@ window.prepareNavigation = function(callback) {
{once: true});
executor.suspend(callback);
}
-
-// Try to disable BFCache by acquiring and never releasing a Web Lock.
-// This requires HTTPS.
-// Note: This is a workaround depending on non-specified WebLock+BFCache
-// behavior, and doesn't work on Safari. We might want to introduce a
-// test-only BFCache-disabling API instead in the future.
-// https://github.com/web-platform-tests/wpt/issues/16359#issuecomment-795004780
-// https://crbug.com/1298336
-window.disableBFCache = () => {
- return new Promise(resolve => {
- // Use page's UUID as a unique lock name.
- navigator.locks.request(uuid, () => {
- resolve();
- return new Promise(() => {});
- });
- });
-};
diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js b/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js
index 80c164f560..ad2119b738 100644
--- a/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js
+++ b/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js
@@ -41,13 +41,14 @@ function sorted(s) {
return Array.from(s).sort();
}
-// Assert expected reasons and the reported reasons match.
+// Assert expected reasons are all present. Note that the extra reasons are allowed
+// as UAs might block bfcache for their specific reasons.
function matchReasons(expectedNotRestoredReasonsSet, notRestoredReasonsSet) {
const missing = setMinus(
expectedNotRestoredReasonsSet, notRestoredReasonsSet, 'Missing reasons');
const extra = setMinus(
notRestoredReasonsSet, expectedNotRestoredReasonsSet, 'Extra reasons');
- assert_true(missing.size + extra.size == 0, `Expected: ${sorted(expectedNotRestoredReasonsSet)}\n` +
+ assert_true(missing.size == 0, `Expected: ${sorted(expectedNotRestoredReasonsSet)}\n` +
`Got: ${sorted(notRestoredReasonsSet)}\n` +
`Missing: ${sorted(missing)}\n` +
`Extra: ${sorted(extra)}\n`);
diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-cross-origin.sub.html b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-cross-origin.sub.html
new file mode 100644
index 0000000000..4b68c32378
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-cross-origin.sub.html
@@ -0,0 +1,65 @@
+<!DOCTYPE HTML>
+<title>Tests pageswap for cross-origin navigations</title>
+<link rel="author" title="Khushal Sagar" href="mailto:khushalsagar@chromium.org">
+<link rel="help" href="https://html.spec.whatwg.org/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script>
+const expectedUrl = get_host_info().HTTPS_REMOTE_ORIGIN + "/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-cross-origin.sub.html?new";
+
+const params = new URLSearchParams(location.search);
+// The page the popup navigates to.
+const is_new_page = params.has('new');
+// The initial page in the popup.
+const is_popup_page = params.has('popup');
+// The test page itself.
+const is_test_page = !is_popup_page && !is_new_page;
+
+const channel = new BroadcastChannel("testchannel");
+
+if (is_test_page) {
+ const expectedUrl = location.href + "?new";
+ const expectedEvents = ["pageswap", "pagehide"];
+
+ promise_test(async t => {
+ let popup;
+ onload = () => {
+ window.events = [];
+ popup = window.open("?popup");
+ };
+
+ await new Promise(resolve => {
+ channel.addEventListener(
+ "message", t.step_func(async (e) => {
+ if (e.data === "nav") {
+ assert_array_equals(window.events, expectedEvents, 'incorrect event order');
+ popup.close();
+ resolve();
+ }
+ }));
+ });
+ }, `pageswap on navigation from script`);
+} else if (is_popup_page) {
+ onload = () => {
+ requestAnimationFrame(() => requestAnimationFrame(() => {
+ location.href = expectedUrl;
+ }));
+
+ onpageswap = (e) => {
+ window.opener.events.push("pageswap");
+ if (e.activation != null)
+ window.opener.events.push("activation");
+ if (e.viewTransition != null)
+ window.opener.events.push("transition");
+ };
+
+ onpagehide = () => {
+ window.opener.events.push("pagehide");
+ channel.postMessage("nav");
+ };
+ };
+}
+</script>
diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-iframe.html b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-iframe.html
new file mode 100644
index 0000000000..05ca1a9428
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-iframe.html
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML>
+<title>Tests pageswap dispatch on iframe Documents</title>
+<link rel="author" title="Khushal Sagar" href="mailto:khushalsagar@chromium.org">
+<link rel="help" href="https://html.spec.whatwg.org/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script>
+setup({explicit_done: true});
+
+function runTest(frame) {
+ let frameWindow = frame.contentWindow;
+
+ let pageswapfired = false;
+ let expectedUrl = frameWindow.location.href + '?new';
+ frameWindow.onpageswap = (e) => {
+ assert_equals(e.activation.entry.url, expectedUrl, 'activation url incorrect in pageswap');
+ assert_equals(e.activation.navigationType, "push", 'navigation type incorrect in pageswap');
+ assert_equals(e.activation.from, frameWindow.navigation.currentEntry, 'from entry incorrect in pageswap');
+ assert_false(e.activation.entry.sameDocument, 'new entry must be cross-document');
+ pageswapfired = true;
+ }
+
+ frameWindow.onpagehide = (e) => {
+ assert_true(pageswapfired, 'pageswap not fired');
+ done();
+ }
+
+ frame.src = expectedUrl;
+}
+
+promise_test(async t => {
+ onload = () => {
+ let frame = document.createElement('iframe');
+ frame.src = "/resources/blank.html";
+ frame.onload = () => {
+ frame.contentWindow.requestAnimationFrame(() => {
+ runTest(frame);
+ });
+ }
+ document.body.appendChild(frame);
+ };
+});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-initial-navigation.html b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-initial-navigation.html
new file mode 100644
index 0000000000..5483b9394d
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-initial-navigation.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<title>Tests pageswap dispatch on initial doc navigation</title>
+<link rel="author" title="Khushal Sagar" href="mailto:khushalsagar@chromium.org">
+<link rel="help" href="https://html.spec.whatwg.org/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script>
+setup({explicit_done: true});
+
+function runTest(frame) {
+ let frameWindow = frame.contentWindow;
+
+ let pageswapfired = false;
+ frameWindow.onpageswap = (e) => {
+ pageswapfired = true;
+ }
+
+ frameWindow.onpagehide = (e) => {
+ assert_true(pageswapfired, 'pageswap fired');
+ done();
+ }
+
+ frame.srcdoc = '<html></html>';
+}
+
+promise_test(async t => {
+ onload = () => {
+ let frame = document.createElement('iframe');
+ document.body.appendChild(frame);
+ runTest(frame);
+ };
+});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-from-click.html b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-from-click.html
new file mode 100644
index 0000000000..936158cd47
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-from-click.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<title>pageswap navigationactivation for push navigations from user click</title>
+<link rel="help" href="https://html.spec.whatwg.org/">
+<link rel="author" href="mailto:khushalsagar@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script>
+const expectedUrl = location.href + '?new';
+
+const params = new URLSearchParams(location.search);
+// The page the popup navigates to.
+const is_new_page = params.has('new');
+// The initial page in the popup.
+const is_popup_page = params.has('popup');
+// The test page itself.
+const is_test_page = !is_popup_page && !is_new_page;
+
+const channel = new BroadcastChannel("testchannel");
+
+if (is_test_page) {
+ const expectedUrl = location.href + "?new";
+ const expectedEvents = ["pageswap", expectedUrl, "push","from", "pagehide"];
+
+ promise_test(async t => {
+ let popup;
+ onload = () => {
+ document.getElementById('nav_link').remove();
+ window.events = [];
+ popup = window.open("?popup");
+
+ popup.addEventListener("load", () => {
+ popup.requestAnimationFrame(
+ () => popup.requestAnimationFrame(() => {
+ let nav_link = popup.document.getElementById('nav_link');
+ test_driver
+ .click(nav_link)
+ .catch(() => assert_unreached("click failed"));
+ }));
+ });
+ };
+
+ await new Promise(resolve => {
+ channel.addEventListener(
+ "message", t.step_func(async (e) => {
+ if (e.data === "nav") {
+ assert_array_equals(window.events, expectedEvents, 'incorrect event order');
+ popup.close();
+ resolve();
+ }
+ }));
+ });
+ }, `pageswap on navigation from user click`);
+} else if (is_popup_page) {
+ onpageswap = (e) => {
+ window.opener.events.push("pageswap");
+ if (e.viewTransition != null)
+ window.opener.events.push("transition");
+ window.opener.events.push(e.activation.entry.url);
+ window.opener.events.push(e.activation.navigationType);
+ if (e.activation.from == navigation.currentEntry)
+ window.opener.events.push("from");
+ };
+
+ onpagehide = () => {
+ window.opener.events.push("pagehide");
+ channel.postMessage("nav");
+ };
+}
+</script>
+<body>
+ <a id="nav_link" href='/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-from-click.html?new'>Click me</a>
+ </body>
diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-navigation-hidden-document.html b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-navigation-hidden-document.html
new file mode 100644
index 0000000000..0a699232f0
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-navigation-hidden-document.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<title>Tests pageswap dispatch on hidden Documents</title>
+<link rel="author" title="Khushal Sagar" href="mailto:khushalsagar@chromium.org">
+<link rel="author" href="mailto:khushalsagar@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script>
+const expectedUrl = location.href + '?new';
+
+const params = new URLSearchParams(location.search);
+// The page the popup navigates to.
+const is_new_page = params.has('new');
+// The initial page in the popup.
+const is_popup_page = params.has('popup');
+// The test page itself.
+const is_test_page = !is_popup_page && !is_new_page;
+
+const channel = new BroadcastChannel("testchannel");
+
+if (is_test_page) {
+ const expectedUrl = location.href + "?new";
+ const expectedEvents = ["pageswap", expectedUrl, "push","from", "pagehide"];
+
+ promise_test(async t => {
+ let popup;
+ onload = async () => {
+ window.events = [];
+ popup = window.open("?popup");
+ };
+
+ await new Promise(resolve => {
+ channel.addEventListener(
+ "message", t.step_func(async (e) => {
+ if (e.data === "nav") {
+ assert_array_equals(window.events, expectedEvents, 'incorrect event order');
+ popup.close();
+ resolve();
+ }
+ }));
+ });
+ }, `pageswap on navigation from script`);
+} else if (is_popup_page) {
+ onload = async () => {
+ await test_driver.minimize_window();
+ assert_equals(document.visibilityState, "hidden");
+ assert_equals(document.hidden, true);
+
+ location.href = location.href.split('?')[0] + '?new';
+ };
+
+ onpageswap = (e) => {
+ window.opener.events.push("pageswap");
+ if (e.viewTransition != null)
+ window.opener.events.push("transition");
+ window.opener.events.push(e.activation.entry.url);
+ window.opener.events.push(e.activation.navigationType);
+ if (e.activation.from == navigation.currentEntry)
+ window.opener.events.push("from");
+ };
+
+ onpagehide = () => {
+ window.opener.events.push("pagehide");
+ channel.postMessage("nav");
+ };
+ }
+</script>
diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-navigation.html b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-navigation.html
new file mode 100644
index 0000000000..4542d7cae2
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-navigation.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<title>pageswap navigationactivation for push navigations</title>
+<link rel="help" href="https://html.spec.whatwg.org/">
+<link rel="author" href="mailto:khushalsagar@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+const expectedUrl = location.href + '?new';
+
+const params = new URLSearchParams(location.search);
+// The page the popup navigates to.
+const is_new_page = params.has('new');
+// The initial page in the popup.
+const is_popup_page = params.has('popup');
+// The test page itself.
+const is_test_page = !is_popup_page && !is_new_page;
+
+const channel = new BroadcastChannel("testchannel");
+
+if (is_test_page) {
+ const expectedUrl = location.href + "?new";
+ const expectedEvents = ["pageswap", expectedUrl, "push","from", "pagehide"];
+
+ promise_test(async t => {
+ let popup;
+ onload = () => {
+ window.events = [];
+ popup = window.open("?popup");
+ };
+
+ await new Promise(resolve => {
+ channel.addEventListener(
+ "message", t.step_func(async (e) => {
+ if (e.data === "nav") {
+ assert_array_equals(window.events, expectedEvents, 'incorrect event order');
+ popup.close();
+ resolve();
+ }
+ }));
+ });
+ }, `pageswap on navigation from script`);
+} else if (is_popup_page) {
+ onload = () => {
+ requestAnimationFrame(() => requestAnimationFrame(() => {
+ location.href = location.href.split('?')[0] + '?new';
+ }));
+
+ onpageswap = (e) => {
+ window.opener.events.push("pageswap");
+ if (e.viewTransition != null)
+ window.opener.events.push("transition");
+ window.opener.events.push(e.activation.entry.url);
+ window.opener.events.push(e.activation.navigationType);
+ if (e.activation.from == navigation.currentEntry)
+ window.opener.events.push("from");
+ };
+
+ onpagehide = () => {
+ window.opener.events.push("pagehide");
+ channel.postMessage("nav");
+ };
+ };
+}
+</script>
diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-with-cross-origin-redirect.sub.html b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-with-cross-origin-redirect.sub.html
new file mode 100644
index 0000000000..8ecf920b51
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-with-cross-origin-redirect.sub.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<title>pageswap navigationactivation for push navigations with a same-origin final url with cross-origin redirects</title>
+<link rel="help" href="https://html.spec.whatwg.org/">
+<link rel="author" href="mailto:khushalsagar@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script>
+const params = new URLSearchParams(location.search);
+// The page the popup navigates to.
+const is_new_page = params.has('new');
+// The initial page in the popup.
+const is_popup_page = params.has('popup');
+// The test page itself.
+const is_test_page = !is_popup_page && !is_new_page;
+
+const channel = new BroadcastChannel("testchannel");
+
+if (is_test_page) {
+ const expectedUrl = location.href + "?new";
+ const expectedEvents = ["pageswap", "pagehide", "pagereveal", "activation"];
+
+ promise_test(async t => {
+ let popup;
+ onload = () => {
+ window.events = [];
+ popup = window.open("?popup");
+ };
+
+ await new Promise(resolve => {
+ channel.addEventListener(
+ "message", t.step_func(async (e) => {
+ if (e.data === "nav") {
+ assert_array_equals(window.events, expectedEvents, 'incorrect event order');
+ popup.close();
+ resolve();
+ }
+ }));
+ });
+ }, `pageswap on navigation with same-origin redirect`);
+} else if (is_popup_page) {
+ onload = () => {
+ requestAnimationFrame(() => requestAnimationFrame(() => {
+ let newUrl = get_host_info().HTTPS_REMOTE_ORIGIN + "/common/redirect.py?location=" + location.href.split('?')[0] + "?new";
+ location.href = newUrl
+ }));
+
+ onpageswap = (e) => {
+ window.opener.events.push("pageswap");
+ if (e.viewTransition != null)
+ window.opener.events.push("transition");
+ if (e.activation != null)
+ window.opener.events.push("activation");
+ };
+
+ onpagehide = () => {
+ window.opener.events.push("pagehide");
+ };
+ };
+} else {
+ assert_true(is_new_page);
+ onpageshow = () => {
+ window.opener.events.push("pagereveal");
+ if (navigation.activation.from != null)
+ window.opener.events.push("activation");
+ channel.postMessage("nav");
+ }
+}
+</script>
diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-with-redirect.html b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-with-redirect.html
new file mode 100644
index 0000000000..8252fff84d
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-with-redirect.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<title>pageswap navigationactivation for push navigations with a same-origin redirect</title>
+<link rel="help" href="https://html.spec.whatwg.org/">
+<link rel="author" href="mailto:khushalsagar@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+const expectedUrl = location.href + '?new';
+
+const params = new URLSearchParams(location.search);
+// The page the popup navigates to.
+const is_new_page = params.has('new');
+// The initial page in the popup.
+const is_popup_page = params.has('popup');
+// The test page itself.
+const is_test_page = !is_popup_page && !is_new_page;
+
+const channel = new BroadcastChannel("testchannel");
+
+if (is_test_page) {
+ const expectedUrl = location.href + "?new";
+ const expectedEvents = ["pageswap", expectedUrl, "push","from", "pagehide"];
+
+ promise_test(async t => {
+ let popup;
+ onload = () => {
+ window.events = [];
+ popup = window.open("?popup");
+ };
+
+ await new Promise(resolve => {
+ channel.addEventListener(
+ "message", t.step_func(async (e) => {
+ if (e.data === "nav") {
+ assert_array_equals(window.events, expectedEvents, 'incorrect event order');
+ popup.close();
+ resolve();
+ }
+ }));
+ });
+ }, `pageswap on navigation with same-origin redirect`);
+} else if (is_popup_page) {
+ onload = () => {
+ requestAnimationFrame(() => requestAnimationFrame(() => {
+ location.href = "/common/redirect.py?location=/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-with-redirect.html?new";
+ }));
+
+ onpageswap = (e) => {
+ window.opener.events.push("pageswap");
+ if (e.viewTransition != null)
+ window.opener.events.push("transition");
+ window.opener.events.push(e.activation.entry.url);
+ window.opener.events.push(e.activation.navigationType);
+ if (e.activation.from == navigation.currentEntry)
+ window.opener.events.push("from");
+ };
+
+ onpagehide = () => {
+ window.opener.events.push("pagehide");
+ channel.postMessage("nav");
+ };
+ };
+}
+</script>
diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-reload-navigation.html b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-reload-navigation.html
new file mode 100644
index 0000000000..f7539ebc47
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-reload-navigation.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<title>pageswap navigationactivation for replace navigations</title>
+<link rel="help" href="https://html.spec.whatwg.org/">
+<link rel="author" href="mailto:khushalsagar@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+const expectedUrl = location.href + '?new';
+
+const params = new URLSearchParams(location.search);
+// The initial page in the popup.
+const is_popup_page = params.has('popup') && !window.opener.didreload;
+// The test page itself.
+const is_test_page = !params.has('popup');
+
+const channel = new BroadcastChannel("testchannel");
+
+if (is_test_page) {
+ const expectedUrl = location.href.split('?')[0] + "?popup";
+ const expectedEvents = ["pageswap", "entry", "reload","from", "pagehide"];
+
+ promise_test(async t => {
+ let popup;
+ onload = () => {
+ window.events = [];
+ window.didreload = false;
+ popup = window.open("?popup");
+ };
+
+ await new Promise(resolve => {
+ channel.addEventListener(
+ "message", t.step_func(async (e) => {
+ if (e.data === "nav") {
+ assert_array_equals(window.events, expectedEvents, 'incorrect event order');
+ popup.close();
+ resolve();
+ }
+ }));
+ });
+ }, `pageswap on replace navigation from script`);
+} else if (is_popup_page) {
+ onload = () => {
+ requestAnimationFrame(() => requestAnimationFrame(() => {
+ window.opener.didreload = true;
+ location.reload();
+ }));
+
+ onpageswap = (e) => {
+ window.opener.events.push("pageswap");
+ if (e.viewTransition != null)
+ window.opener.events.push("transition");
+ if (e.activation.entry == navigation.currentEntry)
+ window.opener.events.push("entry");
+ window.opener.events.push(e.activation.navigationType);
+ if (e.activation.from == navigation.currentEntry)
+ window.opener.events.push("from");
+ };
+
+ onpagehide = () => {
+ window.opener.events.push("pagehide");
+ channel.postMessage("nav");
+ };
+ };
+}
+</script>
diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-replace-navigation.html b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-replace-navigation.html
new file mode 100644
index 0000000000..f6b3f7408c
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-replace-navigation.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<title>pageswap navigationactivation for replace navigations</title>
+<link rel="help" href="https://html.spec.whatwg.org/">
+<link rel="author" href="mailto:khushalsagar@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+const expectedUrl = location.href + '?new';
+
+const params = new URLSearchParams(location.search);
+// The page the popup navigates to.
+const is_new_page = params.has('new');
+// The initial page in the popup.
+const is_popup_page = params.has('popup');
+// The test page itself.
+const is_test_page = !is_popup_page && !is_new_page;
+
+const channel = new BroadcastChannel("testchannel");
+
+if (is_test_page) {
+ const expectedUrl = location.href.split('?')[0] + "?new";
+ const expectedEvents = ["pageswap", expectedUrl, "replace","from", "pagehide"];
+
+ promise_test(async t => {
+ let popup;
+ onload = () => {
+ window.events = [];
+ popup = window.open("?popup");
+ };
+
+ await new Promise(resolve => {
+ channel.addEventListener(
+ "message", t.step_func(async (e) => {
+ if (e.data === "nav") {
+ assert_array_equals(window.events, expectedEvents, 'incorrect event order');
+ popup.close();
+ resolve();
+ }
+ }));
+ });
+ }, `pageswap on replace navigation from script`);
+} else if (is_popup_page) {
+ onload = () => {
+ requestAnimationFrame(() => requestAnimationFrame(() => {
+ location.replace(location.href.split('?')[0] + '?new');
+ }));
+
+ onpageswap = (e) => {
+ window.opener.events.push("pageswap");
+ if (e.viewTransition != null)
+ window.opener.events.push("transition");
+ window.opener.events.push(e.activation.entry.url);
+ window.opener.events.push(e.activation.navigationType);
+ if (e.activation.from == navigation.currentEntry)
+ window.opener.events.push("from");
+ };
+
+ onpagehide = () => {
+ window.opener.events.push("pagehide");
+ channel.postMessage("nav");
+ };
+ };
+}
+</script>
diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-replace-with-cross-origin-redirect.sub.html b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-replace-with-cross-origin-redirect.sub.html
new file mode 100644
index 0000000000..c6ced62057
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-replace-with-cross-origin-redirect.sub.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<title>pageswap navigationactivation for replace navigations with a same-origin final url with cross-origin redirects</title>
+<link rel="help" href="https://html.spec.whatwg.org/">
+<link rel="author" href="mailto:khushalsagar@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script>
+const params = new URLSearchParams(location.search);
+// The page the popup navigates to.
+const is_new_page = params.has('new');
+// The initial page in the popup.
+const is_popup_page = params.has('popup');
+// The test page itself.
+const is_test_page = !is_popup_page && !is_new_page;
+
+const channel = new BroadcastChannel("testchannel");
+
+if (is_test_page) {
+ const expectedUrl = location.href + "?new";
+ const expectedEvents = ["pageswap", "pagehide", "pagereveal", "activation"];
+
+ promise_test(async t => {
+ let popup;
+ onload = () => {
+ window.events = [];
+ popup = window.open("?popup");
+ };
+
+ await new Promise(resolve => {
+ channel.addEventListener(
+ "message", t.step_func(async (e) => {
+ if (e.data === "nav") {
+ assert_array_equals(window.events, expectedEvents, 'incorrect event order');
+ popup.close();
+ resolve();
+ }
+ }));
+ });
+ }, `pageswap on navigation with same-origin redirect`);
+} else if (is_popup_page) {
+ onload = () => {
+ requestAnimationFrame(() => requestAnimationFrame(() => {
+ let newUrl = get_host_info().HTTPS_REMOTE_ORIGIN + "/common/redirect.py?location=" + location.href.split('?')[0] + "?new";
+ location.replace(newUrl);
+ }));
+
+ onpageswap = (e) => {
+ window.opener.events.push("pageswap");
+ if (e.viewTransition != null)
+ window.opener.events.push("transition");
+ if (e.activation != null)
+ window.opener.events.push("activation");
+ };
+
+ onpagehide = () => {
+ window.opener.events.push("pagehide");
+ };
+ };
+} else {
+ assert_true(is_new_page);
+ onpageshow = () => {
+ window.opener.events.push("pagereveal");
+ if (navigation.activation.from != null)
+ window.opener.events.push("activation");
+ channel.postMessage("nav");
+ }
+}
+</script>
diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-traverse-navigation-cross-origin-redirect-no-bfcache.https.sub.html b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-traverse-navigation-cross-origin-redirect-no-bfcache.https.sub.html
new file mode 100644
index 0000000000..5543830721
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-traverse-navigation-cross-origin-redirect-no-bfcache.https.sub.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<title>pageswap navigationactivation for traverse navigation when original navigation has cross-origin redirect</title>
+<link rel="help" href="https://html.spec.whatwg.org/">
+<link rel="author" href="mailto:khushalsagar@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/common.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="/html/browsers/browsing-the-web/back-forward-cache/resources/disable_bfcache.js"></script>
+<style></style>
+<script>
+const channel = new BroadcastChannel("testchannel");
+
+const params = new URLSearchParams(location.search);
+const is_initial_page_first_navigation = params.has('popup') && navigation.entries().length == 1;
+const is_new_page = params.has('new');
+const is_test_page = !params.has('popup') && !params.has('new');
+
+// The test page which opens a popup for the navigation sequence.
+if (is_test_page) {
+ const expectedUrl = location.href.split('?')[0] + "?popup";
+ const expectedEvents = ["pageswap", expectedUrl, "traverse","from", "pagehide"];
+
+ promise_test(async t => {
+ let popup;
+ onload = () => {
+ window.events = [];
+ popup = window.open("?popup");
+ };
+
+ await new Promise(resolve => {
+ channel.addEventListener(
+ "message", t.step_func(async (e) => {
+ if (e.data === "nav") {
+ assert_array_equals(window.events, expectedEvents, 'incorrect event order');
+ popup.close();
+ resolve();
+ }
+ }));
+ });
+ }, `pageswap on traverse navigation from script`);
+} else if (is_initial_page_first_navigation) {
+ // The popup page which the user navigates back to.
+ onload = async () => {
+ await disableBFCache();
+ requestAnimationFrame(() => requestAnimationFrame(() => {
+ let newUrl = get_host_info().HTTPS_REMOTE_ORIGIN + "/common/redirect.py?location=" + location.href.split('?')[0] + "?new";
+ location.href = newUrl
+ }));
+ };
+
+ onpageshow = (e) => {
+ assert_false(e.persisted, 'the test should run without BFCache');
+ }
+} else if (is_new_page) {
+ onload = () => {
+ requestAnimationFrame(() => requestAnimationFrame(() => {
+ navigation.back();
+ }));
+ };
+
+ onpageswap = (e) => {
+ window.opener.events.push("pageswap");
+ if (e.viewTransition != null)
+ window.opener.events.push("transition");
+ window.opener.events.push(e.activation.entry.url);
+ window.opener.events.push(e.activation.navigationType);
+ if (e.activation.from == navigation.currentEntry)
+ window.opener.events.push("from");
+ };
+
+ onpagehide = () => {
+ window.opener.events.push("pagehide");
+ channel.postMessage("nav");
+ };
+}
+</script>
diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-traverse-navigation-no-bfcache.https.html b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-traverse-navigation-no-bfcache.https.html
new file mode 100644
index 0000000000..9e8c0e100e
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-traverse-navigation-no-bfcache.https.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<title>pageswap navigationactivation for traverse navigations</title>
+<link rel="help" href="https://html.spec.whatwg.org/">
+<link rel="author" href="mailto:khushalsagar@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/common.js"></script>
+<script src="/html/browsers/browsing-the-web/back-forward-cache/resources/disable_bfcache.js"></script>
+<style></style>
+<script>
+const channel = new BroadcastChannel("testchannel");
+
+const params = new URLSearchParams(location.search);
+const is_initial_page_first_navigation = params.has('popup') && navigation.entries().length == 1;
+const is_new_page = params.has('new');
+const is_test_page = !params.has('popup') && !params.has('new');
+
+// The test page which opens a popup for the navigation sequence.
+if (is_test_page) {
+ const expectedUrl = location.href.split('?')[0] + "?popup";
+ const expectedEvents = ["pageswap", expectedUrl, "traverse","from", "pagehide"];
+
+ promise_test(async t => {
+ let popup;
+ onload = () => {
+ window.events = [];
+ popup = window.open("?popup");
+ };
+
+ await new Promise(resolve => {
+ channel.addEventListener(
+ "message", t.step_func(async (e) => {
+ if (e.data === "nav") {
+ assert_array_equals(window.events, expectedEvents, 'incorrect event order');
+ popup.close();
+ resolve();
+ }
+ }));
+ });
+ }, `pageswap on traverse navigation from script`);
+} else if (is_initial_page_first_navigation) {
+ // The popup page which the user navigates back to.
+ onload = async () => {
+ await disableBFCache();
+ requestAnimationFrame(() => requestAnimationFrame(() => {
+ location.href = location.href.split('?')[0] + '?new';
+ }));
+ };
+
+ onpageshow = (e) => {
+ assert_false(e.persisted, 'the test should run without BFCache');
+ }
+} else if (is_new_page) {
+ onload = () => {
+ requestAnimationFrame(() => requestAnimationFrame(() => {
+ navigation.back();
+ }));
+ };
+
+ onpageswap = (e) => {
+ window.opener.events.push("pageswap");
+ if (e.viewTransition != null)
+ window.opener.events.push("transition");
+ window.opener.events.push(e.activation.entry.url);
+ window.opener.events.push(e.activation.navigationType);
+ if (e.activation.from == navigation.currentEntry)
+ window.opener.events.push("from");
+ };
+
+ onpagehide = () => {
+ window.opener.events.push("pagehide");
+ channel.postMessage("nav");
+ };
+}
+</script>