summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/navigation-api/per-entry-events
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /testing/web-platform/tests/navigation-api/per-entry-events
parentInitial commit. (diff)
downloadfirefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz
firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/navigation-api/per-entry-events')
-rw-r--r--testing/web-platform/tests/navigation-api/per-entry-events/dispose-after-bfcache.html32
-rw-r--r--testing/web-platform/tests/navigation-api/per-entry-events/dispose-cross-document.html37
-rw-r--r--testing/web-platform/tests/navigation-api/per-entry-events/dispose-for-full-session-history.tentative.html20
-rw-r--r--testing/web-platform/tests/navigation-api/per-entry-events/dispose-for-navigation-in-child.html41
-rw-r--r--testing/web-platform/tests/navigation-api/per-entry-events/dispose-same-document-intercept.html71
-rw-r--r--testing/web-platform/tests/navigation-api/per-entry-events/dispose-same-document-navigate-during.html50
-rw-r--r--testing/web-platform/tests/navigation-api/per-entry-events/dispose-same-document-reload-with-intercept.html17
-rw-r--r--testing/web-platform/tests/navigation-api/per-entry-events/dispose-same-document-replace-with-intercept.html36
-rw-r--r--testing/web-platform/tests/navigation-api/per-entry-events/dispose-same-document-replaceState.html28
-rw-r--r--testing/web-platform/tests/navigation-api/per-entry-events/dispose-same-document.html65
-rw-r--r--testing/web-platform/tests/navigation-api/per-entry-events/dispose-skip-current-on-truncate.html40
11 files changed, 437 insertions, 0 deletions
diff --git a/testing/web-platform/tests/navigation-api/per-entry-events/dispose-after-bfcache.html b/testing/web-platform/tests/navigation-api/per-entry-events/dispose-after-bfcache.html
new file mode 100644
index 0000000000..7d3ef4f81e
--- /dev/null
+++ b/testing/web-platform/tests/navigation-api/per-entry-events/dispose-after-bfcache.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/browsers/browsing-the-web/back-forward-cache/resources/helper.sub.js"></script>
+<script src="resources/is_uuid.js"></script>
+
+<script>
+// This test:
+// * Does a fragment navigation, then goes back (same-document).
+// * Navigates away, then back via bfcache.
+// When navigating away, navigation.entries()[1] will be overwritten.
+// When returning after bfcache restore, navigation.entries()[1] should represent
+// pageB, and the original navigation.entries()[1] should have been disposed.
+runBfcacheTest({
+ targetOrigin: originSameOrigin,
+ funcBeforeNavigation: async () => {
+ window.events = [];
+ await navigation.navigate("#1");
+ await navigation.back();
+ window.originalEntry1 = navigation.entries()[1];
+ window.originalEntry1.ondispose = () => events.push("dispose");
+ window.onpageshow = () => events.push("pageshow");
+ },
+ async funcAfterAssertion(pageA, pageB) {
+ assert_equals(await pageA.execute_script(() => navigation.entries().length), 2);
+ assert_false(await pageA.execute_script(() => window.originalEntry1 === navigation.entries[1]));
+ assert_array_equals(await pageA.execute_script(() => window.events), ["pageshow", "dispose"]);
+ }
+}, "entries() must contain the forward-history page after navigating back to a bfcached page");
+</script>
diff --git a/testing/web-platform/tests/navigation-api/per-entry-events/dispose-cross-document.html b/testing/web-platform/tests/navigation-api/per-entry-events/dispose-cross-document.html
new file mode 100644
index 0000000000..67f54da48d
--- /dev/null
+++ b/testing/web-platform/tests/navigation-api/per-entry-events/dispose-cross-document.html
@@ -0,0 +1,37 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<iframe id="iframe" src="/common/blank.html"></iframe>
+<script>
+promise_test(async (t) => {
+ // Wait for after the load event so that the navigation doesn't get converted
+ // into a replace navigation.
+ await new Promise(r => window.onload = () => t.step_timeout(r, 0));
+
+ iframe.contentWindow.location.search = "?1";
+ await new Promise(r => iframe.onload = () => t.step_timeout(r, 0));
+
+ const keyFor1 = iframe.contentWindow.navigation.currentEntry.key;
+
+ iframe.contentWindow.location.search = "?2";
+ await new Promise(r => iframe.onload = () => t.step_timeout(r, 0));
+ iframe.contentWindow.location.search = "?3";
+ await new Promise(r => iframe.onload = () => t.step_timeout(r, 0));
+
+ iframe.contentWindow.navigation.traverseTo(keyFor1);
+ await new Promise(r => iframe.onload = () => t.step_timeout(r, 0));
+
+ assert_equals((new URL(iframe.contentWindow.location.href)).search, "?1");
+
+ assert_equals(iframe.contentWindow.navigation.entries().length, 4);
+ const [, entry2, entry3] = iframe.contentWindow.navigation.entries();
+
+ entry2.ondispose = t.unreached_func("entry2 dispose must not fire");
+ entry2.addEventListener("dispose", t.unreached_func("entry3 dispose must not fire"));
+
+ iframe.contentWindow.navigation.navigate("/common/blank.html?fork");
+ await new Promise(r => iframe.onload = r);
+
+ // Test passes if we reached this point with no dispose events firing.
+}, "No dispose events are fired due to cross-document forward pruning");
+</script>
diff --git a/testing/web-platform/tests/navigation-api/per-entry-events/dispose-for-full-session-history.tentative.html b/testing/web-platform/tests/navigation-api/per-entry-events/dispose-for-full-session-history.tentative.html
new file mode 100644
index 0000000000..9bed225cf3
--- /dev/null
+++ b/testing/web-platform/tests/navigation-api/per-entry-events/dispose-for-full-session-history.tentative.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+promise_test(async (t) => {
+ // Wait for after the load event so that the navigation doesn't get converted
+ // into a replace navigation.
+ await new Promise(r => window.onload = () => t.step_timeout(r, 0));
+ assert_equals(navigation.entries().length, 1);
+
+ let dispose_promise = new Promise(r => navigation.entries()[0].ondispose = r);
+
+ // There is no spec for the maximum number of joint session history entries
+ // (hence this is a .tentative.html test). However, all(?) browsers have a
+ // settled on a maximum of 50.
+ for (let i = 0; i < 50; i++)
+ await navigation.navigate("#" + i).finished;
+ await dispose_promise;
+}, "Dispose should fire when an entry is removed from session history due to too many entries");
+</script>
diff --git a/testing/web-platform/tests/navigation-api/per-entry-events/dispose-for-navigation-in-child.html b/testing/web-platform/tests/navigation-api/per-entry-events/dispose-for-navigation-in-child.html
new file mode 100644
index 0000000000..2482877085
--- /dev/null
+++ b/testing/web-platform/tests/navigation-api/per-entry-events/dispose-for-navigation-in-child.html
@@ -0,0 +1,41 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<iframe id="iframe" src="/common/blank.html"></iframe>
+<script>
+promise_test(async (t) => {
+ // Wait for after the load event so that the navigation doesn't get converted
+ // into a replace navigation.
+ await new Promise(r => window.onload = () => t.step_timeout(r, 0));
+
+ await iframe.contentWindow.navigation.navigate("#a");
+ await navigation.navigate("#1").finished;
+ await navigation.navigate("#2").finished;
+ await navigation.navigate("#3").finished;
+ await iframe.contentWindow.navigation.back().finished;
+ assert_equals(navigation.entries().length, 4);
+ assert_equals(iframe.contentWindow.navigation.entries().length, 2);
+ assert_equals(navigation.currentEntry.index, 0);
+ assert_equals(iframe.contentWindow.navigation.currentEntry.index, 0);
+
+ let top_entry_0_before = navigation.entries()[0];
+ let dispose_promises = [];
+ for (let i = 1; i < navigation.entries().length; i++) {
+ dispose_promises.push(new Promise(r => navigation.entries()[i].ondispose = r))
+ }
+
+ // This push navigation should truncate in the top window.
+ await iframe.contentWindow.navigation.navigate("#b").finished;
+
+ // entries() should be updated in both frames, and all forward entries in the
+ // top window should have dispose events, even though that wasn't the window
+ // that navigated.
+ await Promise.all(dispose_promises);
+ assert_equals(navigation.entries().length, 1);
+ assert_equals(iframe.contentWindow.navigation.entries().length, 2);
+ assert_equals(navigation.currentEntry.index, 0);
+ assert_equals(iframe.contentWindow.navigation.currentEntry.index, 1);
+ assert_equals(navigation.entries()[0], top_entry_0_before);
+
+}, "Dispose events should fire when entries are removed by a navigation in a different frame");
+</script>
diff --git a/testing/web-platform/tests/navigation-api/per-entry-events/dispose-same-document-intercept.html b/testing/web-platform/tests/navigation-api/per-entry-events/dispose-same-document-intercept.html
new file mode 100644
index 0000000000..44aa096aaf
--- /dev/null
+++ b/testing/web-platform/tests/navigation-api/per-entry-events/dispose-same-document-intercept.html
@@ -0,0 +1,71 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+promise_test(async (t) => {
+ // Wait for after the load event so that the navigation doesn't get converted
+ // into a replace navigation.
+ await new Promise(r => window.onload = () => t.step_timeout(r, 0));
+
+ location.hash = "#1";
+ location.hash = "#2";
+ location.hash = "#3";
+
+ assert_equals(navigation.entries().length, 4);
+ const [entry0, entry1, entry2, entry3] = navigation.entries();
+ assert_equals((new URL(entry2.url)).hash, "#2");
+ assert_equals((new URL(entry3.url)).hash, "#3");
+
+ let dispose2Called = false;
+ entry2.ondispose = t.step_func(e => {
+ dispose2Called = true;
+
+ assert_equals(e.constructor, Event);
+ assert_equals(e.bubbles, false);
+ assert_equals(e.cancelable, false);
+ assert_equals(e.composed, false);
+
+ assert_array_equals(
+ navigation.entries(),
+ [entry0, entry1, navigation.currentEntry],
+ "entries() is updated during dispose for entry 2");
+ assert_not_equals(navigation.currentEntry, entry1, "current entry must be updated during dispose for entry 3");
+ assert_true(navigation.canGoBack, "canGoBack is still true during dispose for entry 2");
+ assert_false(navigation.canGoForward, "canGoForward is still false during beforedispose for entry 2");
+ assert_equals(navigation.transition.navigationType, "push", "transition navigationType during dispose for entry 2");
+ assert_equals(navigation.transition.from, entry1, "transition from during dispose for entry 2");
+ assert_equals(location.hash, "#fork", "location.hash is updated during dispose for entry 2");
+ });
+
+ entry3.addEventListener("dispose", t.step_func_done(e => {
+ assert_true(dispose2Called, "dispose for entry 2 must have happened before entry 3");
+
+ assert_array_equals(
+ navigation.entries(),
+ [entry0, entry1, navigation.currentEntry],
+ "entries() is updated during dispose for entry 3");
+ assert_not_equals(navigation.currentEntry, entry1, "current entry must be updated during dispose for entry 3");
+ assert_true(navigation.canGoBack, "canGoBack is still true during dispose for entry 3");
+ assert_false(navigation.canGoForward, "canGoForward is still false during beforedispose for entry 3");
+ assert_equals(navigation.transition.navigationType, "push", "transition navigationType during dispose for entry 3");
+ assert_equals(navigation.transition.from, entry1, "transition from during dispose for entry 3");
+ assert_equals(location.hash, "#fork", "location.hash is updated during dispose for entry 3");
+ }));
+
+ await navigation.traverseTo(entry1.key).committed;
+
+ navigation.addEventListener("navigate", e => {
+ e.intercept();
+ });
+
+ navigation.navigate("#fork");
+
+ assert_equals(navigation.entries().length, 3);
+ const [finalEntry0, finalEntry1, finalEntry2] = navigation.entries();
+ assert_equals(finalEntry0, entry0);
+ assert_equals(finalEntry1, entry1);
+ assert_not_equals(finalEntry2, entry2);
+ assert_equals(navigation.currentEntry, finalEntry2);
+ assert_equals((new URL(finalEntry2.url)).hash, "#fork");
+}, "dispose events when forward-pruning same-document entries");
+</script>
diff --git a/testing/web-platform/tests/navigation-api/per-entry-events/dispose-same-document-navigate-during.html b/testing/web-platform/tests/navigation-api/per-entry-events/dispose-same-document-navigate-during.html
new file mode 100644
index 0000000000..59d9b3cce3
--- /dev/null
+++ b/testing/web-platform/tests/navigation-api/per-entry-events/dispose-same-document-navigate-during.html
@@ -0,0 +1,50 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+promise_test(async (t) => {
+ // Wait for after the load event so that the navigation doesn't get converted
+ // into a replace navigation.
+ await new Promise(r => window.onload = () => t.step_timeout(r, 0));
+
+ location.hash = "#1";
+ location.hash = "#2";
+ location.hash = "#3";
+
+ assert_equals(navigation.entries().length, 4);
+ const [entry0, entry1, entry2, entry3] = navigation.entries();
+ assert_equals((new URL(entry2.url)).hash, "#2");
+ assert_equals((new URL(entry3.url)).hash, "#3");
+
+ let dispose3Called = 0;
+ let spoonPromise;
+ entry3.addEventListener("dispose", t.step_func(e => {
+ ++dispose3Called;
+
+ spoonPromise = navigation.navigate("#spoon").committed;
+ }));
+
+ await navigation.traverseTo(entry1.key).committed;
+
+ const forkPromise = navigation.navigate("#fork").committed;
+ assert_equals(dispose3Called, 1, "dispose for entry 3 must happen exactly once (first check)")
+
+ // The navigation to #fork will *not* be finished by the time the navigation
+ // to #spoon kicks off, so the finished promise will reject. But, the
+ // committed promise should still fulfill, since as we see below, #fork ends
+ // up in the history list.
+ await Promise.all([forkPromise, spoonPromise]);
+
+ assert_equals(dispose3Called, 1, "dispose for entry 3 must happen exactly once (final check)");
+
+ assert_equals(navigation.entries().length, 4);
+ const [finalEntry0, finalEntry1, finalEntry2, finalEntry3] = navigation.entries();
+ assert_equals(finalEntry0, entry0);
+ assert_equals(finalEntry1, entry1);
+ assert_not_equals(finalEntry2, entry2);
+ assert_not_equals(finalEntry3, entry3);
+ assert_equals(navigation.currentEntry, finalEntry3);
+ assert_equals((new URL(finalEntry2.url)).hash, "#fork");
+ assert_equals((new URL(finalEntry3.url)).hash, "#spoon");
+}, "navigate() during a same-document-navigation-initiated dispose works (since it's after the previous navigation)");
+</script>
diff --git a/testing/web-platform/tests/navigation-api/per-entry-events/dispose-same-document-reload-with-intercept.html b/testing/web-platform/tests/navigation-api/per-entry-events/dispose-same-document-reload-with-intercept.html
new file mode 100644
index 0000000000..1e083714f6
--- /dev/null
+++ b/testing/web-platform/tests/navigation-api/per-entry-events/dispose-same-document-reload-with-intercept.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<script>
+promise_test(async (t) => {
+ // Wait for after the load event so that the navigation doesn't get converted
+ // into a replace navigation.
+ await new Promise(r => window.onload = () => t.step_timeout(r, 0));
+
+ navigation.currentEntry.ondispose = t.unreached_func("dispose must not happen for reloads");
+
+ navigation.addEventListener("navigate", e => e.intercept());
+
+ await navigation.reload().finished;
+}, "dispose events are not fired when doing a same-document reload using navigation.reload() and intercept()");
+</script>
diff --git a/testing/web-platform/tests/navigation-api/per-entry-events/dispose-same-document-replace-with-intercept.html b/testing/web-platform/tests/navigation-api/per-entry-events/dispose-same-document-replace-with-intercept.html
new file mode 100644
index 0000000000..4e492e30ae
--- /dev/null
+++ b/testing/web-platform/tests/navigation-api/per-entry-events/dispose-same-document-replace-with-intercept.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+promise_test(async (t) => {
+ // Wait for after the load event so that we're definitely testing intentional,
+ // navigate()-caused replacement and not the replacement that happens
+ // automatically before the load event completes.
+ await new Promise(r => window.onload = () => t.step_timeout(r, 0));
+
+ const entriesBefore = navigation.entries();
+ const currentBefore = navigation.currentEntry;
+
+ let disposeCalled = false;
+ navigation.currentEntry.ondispose = t.step_func(e => {
+ disposeCalled = true;
+
+ assert_equals(e.constructor, Event);
+ assert_equals(e.bubbles, false);
+ assert_equals(e.cancelable, false);
+ assert_equals(e.composed, false);
+
+ assert_not_equals(navigation.currentEntry, currentBefore);
+ assert_array_equals(navigation.entries(), [navigation.currentEntry]);
+ assert_equals((new URL(navigation.currentEntry.url)).search, "?replacement");
+ assert_equals(navigation.transition.navigationType, "replace");
+ assert_equals(navigation.transition.from, entriesBefore[0]);
+ assert_equals(location.search, "?replacement");
+ });
+
+ navigation.addEventListener("navigate", e => e.intercept());
+
+ navigation.navigate("?replacement", { history: "replace" });
+ assert_true(disposeCalled);
+}, "dispose events when doing a same-document replace using navigation.navigate() and intercept()");
+</script>
diff --git a/testing/web-platform/tests/navigation-api/per-entry-events/dispose-same-document-replaceState.html b/testing/web-platform/tests/navigation-api/per-entry-events/dispose-same-document-replaceState.html
new file mode 100644
index 0000000000..a6197260a2
--- /dev/null
+++ b/testing/web-platform/tests/navigation-api/per-entry-events/dispose-same-document-replaceState.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(t => {
+ const entriesBefore = navigation.entries();
+ const currentBefore = navigation.currentEntry;
+
+ let disposeCalled = false;
+ navigation.currentEntry.ondispose = t.step_func(e => {
+ disposeCalled = true;
+
+ assert_equals(e.constructor, Event);
+ assert_equals(e.bubbles, false);
+ assert_equals(e.cancelable, false);
+ assert_equals(e.composed, false);
+
+ assert_not_equals(navigation.currentEntry, currentBefore);
+ assert_array_equals(navigation.entries(), [navigation.currentEntry]);
+ assert_equals((new URL(navigation.currentEntry.url)).search, "?replacement");
+ assert_equals(navigation.transition, null);
+ assert_equals(location.search, "?replacement");
+ });
+
+ history.replaceState(null, "", "?replacement");
+ assert_true(disposeCalled);
+}, "dispose events when doing a same-document replace using history.replaceState()");
+</script>
diff --git a/testing/web-platform/tests/navigation-api/per-entry-events/dispose-same-document.html b/testing/web-platform/tests/navigation-api/per-entry-events/dispose-same-document.html
new file mode 100644
index 0000000000..27806ce3c8
--- /dev/null
+++ b/testing/web-platform/tests/navigation-api/per-entry-events/dispose-same-document.html
@@ -0,0 +1,65 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+promise_test(async (t) => {
+ // Wait for after the load event so that the navigation doesn't get converted
+ // into a replace navigation.
+ await new Promise(r => window.onload = () => t.step_timeout(r, 0));
+
+ location.hash = "#1";
+ location.hash = "#2";
+ location.hash = "#3";
+
+ assert_equals(navigation.entries().length, 4);
+ const [entry0, entry1, entry2, entry3] = navigation.entries();
+ assert_equals((new URL(entry2.url)).hash, "#2");
+ assert_equals((new URL(entry3.url)).hash, "#3");
+
+ let dispose2Called = false;
+ entry2.ondispose = t.step_func(e => {
+ dispose2Called = true;
+
+ assert_equals(e.constructor, Event);
+ assert_equals(e.bubbles, false);
+ assert_equals(e.cancelable, false);
+ assert_equals(e.composed, false);
+
+ assert_array_equals(
+ navigation.entries(),
+ [entry0, entry1, navigation.currentEntry],
+ "entries() is updated during dispose for entry 2");
+ assert_not_equals(navigation.currentEntry, entry1, "current entry must be updated during dispose for entry 3");
+ assert_true(navigation.canGoBack, "canGoBack is still true during dispose for entry 2");
+ assert_false(navigation.canGoForward, "canGoForward is still false during beforedispose for entry 2");
+ assert_equals(navigation.transition, null, "transition during dispose for entry 2");
+ assert_equals(location.hash, "#fork", "location.hash is updated during dispose for entry 2");
+ });
+
+ entry3.addEventListener("dispose", t.step_func_done(e => {
+ assert_true(dispose2Called, "dispose for entry 2 must have happened before entry 3");
+
+ assert_array_equals(
+ navigation.entries(),
+ [entry0, entry1, navigation.currentEntry],
+ "entries() is updated during dispose for entry 3");
+ assert_not_equals(navigation.currentEntry, entry1, "current entry must be updated during dispose for entry 3");
+ assert_true(navigation.canGoBack, "canGoBack is still true during dispose for entry 3");
+ assert_false(navigation.canGoForward, "canGoForward is still false during beforedispose for entry 3");
+ assert_equals(navigation.transition, null, "transition during dispose for entry 2");
+ assert_equals(location.hash, "#fork", "location.hash is updated during dispose for entry 3");
+ }));
+
+ await navigation.traverseTo(entry1.key).committed;
+
+ navigation.navigate("#fork");
+
+ assert_equals(navigation.entries().length, 3);
+ const [finalEntry0, finalEntry1, finalEntry2] = navigation.entries();
+ assert_equals(finalEntry0, entry0);
+ assert_equals(finalEntry1, entry1);
+ assert_not_equals(finalEntry2, entry2);
+ assert_equals(navigation.currentEntry, finalEntry2);
+ assert_equals((new URL(finalEntry2.url)).hash, "#fork");
+}, "dispose events when forward-pruning same-document entries");
+</script>
diff --git a/testing/web-platform/tests/navigation-api/per-entry-events/dispose-skip-current-on-truncate.html b/testing/web-platform/tests/navigation-api/per-entry-events/dispose-skip-current-on-truncate.html
new file mode 100644
index 0000000000..56ec4d301f
--- /dev/null
+++ b/testing/web-platform/tests/navigation-api/per-entry-events/dispose-skip-current-on-truncate.html
@@ -0,0 +1,40 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+promise_test(async (t) => {
+ // Wait for after the load event so that the navigation doesn't get converted
+ // into a replace navigation.
+ await new Promise(r => window.onload = () => t.step_timeout(r, 0));
+ await navigation.navigate("#1").finished;
+ assert_equals(navigation.entries().length, 2);
+
+ let iframe = document.createElement("iframe");
+ iframe.src = "/common/blank.html";
+ document.body.appendChild(iframe);
+ await new Promise(r => iframe.onload = () => t.step_timeout(r, 0));
+ assert_equals(iframe.contentWindow.navigation.entries().length, 1);
+
+ // Go back to before the iframe was added. The iframe will still be in the
+ // document, but we will be at a joint session history entry that was created
+ // before the iframe was added to the document.
+ await navigation.back().finished;
+ assert_equals(navigation.entries().length, 2);
+ assert_equals(iframe.contentWindow.navigation.entries().length, 1);
+ assert_equals(navigation.currentEntry.index, 0);
+ assert_equals(iframe.contentWindow.navigation.currentEntry.index, 0);
+
+ // A push navigation in the top window will truncate-then-push the joint
+ // session history. This should dispose the forward entry in the top window,
+ // but should not interfere with the currentEntry in the iframe.
+ let dispose_promise = new Promise(r => navigation.entries()[1].ondispose = r);
+ iframe.contentWindow.navigation.currentEntry.ondispose = t.unreached_func("iframe entry must not be disposed");
+ await navigation.navigate("#b").finished;
+
+ await dispose_promise;
+ assert_equals(navigation.entries().length, 2);
+ assert_equals(iframe.contentWindow.navigation.entries().length, 1);
+ assert_equals(navigation.currentEntry.index, 1);
+ assert_equals(iframe.contentWindow.navigation.currentEntry.index, 0);
+}, "Removing a currentEntry from the joint session history shouldn't dispose it");
+</script>