Skip to content

Commit

Permalink
Make navigation-api/navigation-methods/ resilient to starting with ex…
Browse files Browse the repository at this point in the history
…tra NavigationHistoryEntries

When WPT are run in-browser or via wptrunner, there may be additional
session history entries when the test starts, so the tests shouldn't
assume that they start with navigation.entries().length == 1 or
navigation.currentEntry.index == 0.

This is a workaround for #33590.

Change-Id: I406474b33d9c17b682d5d54fc88f5c677bc3d3ea
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4904062
Reviewed-by: Domenic Denicola <domenic@chromium.org>
Commit-Queue: Nate Chapin <japhet@chromium.org>
Auto-Submit: Nate Chapin <japhet@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1204876}
  • Loading branch information
natechapin authored and chromium-wpt-export-bot committed Oct 3, 2023
1 parent 8d1695f commit e1f2e7c
Show file tree
Hide file tree
Showing 28 changed files with 147 additions and 100 deletions.
22 changes: 12 additions & 10 deletions navigation-api/navigation-methods/back-forward-multiple-frames.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,22 @@
promise_test(async t => {
// Wait for after the load event so that the navigation doesn't get converted
// into a replace navigation.
let start_length = navigation.entries().length;
let start_index = navigation.currentEntry.index;
await new Promise(resolve => window.onload = () => t.step_timeout(resolve, 0));
// Step 1
assert_equals(navigation.entries().length, 1, "step 1 outer entries() length");
assert_equals(navigation.entries().length, start_length, "step 1 outer entries() length");
assert_equals(i.contentWindow.navigation.entries().length, 1, "step 1 iframe entries() length");
await navigation.navigate("#top").committed;
// Step 2: iframe at initial entry, top on second entry
assert_equals(navigation.entries().length, 2, "step 2 outer entries() length");
assert_equals(navigation.entries().length, start_length+1, "step 2 outer entries() length");
assert_equals(i.contentWindow.navigation.entries().length, 1, "step 2 iframe entries() length");
await i.contentWindow.navigation.navigate("#iframe").committed;

// Step 3: Both windows on second entry.
assert_equals(navigation.entries().length, 2, "step 3 outer entries() length");
assert_equals(navigation.entries().length, start_length+1, "step 3 outer entries() length");
assert_equals(i.contentWindow.navigation.entries().length, 2, "step 3 iframe entries() length");
assert_equals(navigation.currentEntry.index, 1, "step 3 outer index");
assert_equals(navigation.currentEntry.index, start_index+1, "step 3 outer index");
assert_equals(i.contentWindow.navigation.currentEntry.index, 1, "step 1 iframe index");

// NOTE: the order of navigation in the two windows is not guaranteed; we need to wait for both.
Expand All @@ -29,23 +31,23 @@
i.contentWindow.navigation.back().committed,
new Promise(resolve => i.contentWindow.onpopstate = resolve)
]);
assert_equals(navigation.currentEntry.index, 1, "after iframe back() outer index");
assert_equals(navigation.currentEntry.index, start_index+1, "after iframe back() outer index");
assert_equals(i.contentWindow.navigation.currentEntry.index, 0, "after iframe back() iframe index");

// Going forward in iframe should go 2->3
await Promise.all([
i.contentWindow.navigation.forward().commited,
new Promise(resolve => i.contentWindow.onpopstate = resolve)
]);
assert_equals(navigation.currentEntry.index, 1, "after iframe forward() outer index");
assert_equals(navigation.currentEntry.index, start_index+1, "after iframe forward() outer index");
assert_equals(i.contentWindow.navigation.currentEntry.index, 1, "after iframe forward() iframe index");

// Going back in top should go 3->1 (navigating both windows).
await Promise.all([
navigation.back().commited,
new Promise(resolve => i.contentWindow.onpopstate = resolve)
]);
assert_equals(navigation.currentEntry.index, 0, "after outer back() outer index");
assert_equals(navigation.currentEntry.index, start_index, "after outer back() outer index");
assert_equals(i.contentWindow.navigation.currentEntry.index, 0, "after outer back() iframe index");

// Next two should not navigate the iframe
Expand All @@ -54,21 +56,21 @@
// Going forward in top should go 1->2 (navigating top only)
await navigation.forward().committed;
await new Promise(resolve => t.step_timeout(resolve, 0));
assert_equals(navigation.currentEntry.index, 1, "after outer forward() outer index");
assert_equals(navigation.currentEntry.index, start_index+1, "after outer forward() outer index");
assert_equals(i.contentWindow.navigation.currentEntry.index, 0, "after outer forward() iframe index");

// Going back in top should go 2->1
await navigation.back().committed;
await new Promise(resolve => t.step_timeout(resolve, 0));
assert_equals(navigation.currentEntry.index, 0, "after outer second back() outer index");
assert_equals(navigation.currentEntry.index, start_index, "after outer second back() outer index");
assert_equals(i.contentWindow.navigation.currentEntry.index, 0, "after outer second back() iframe index");

// Going forward in iframe should go 1->3 (navigating both windows)
await Promise.all([
i.contentWindow.navigation.forward().commited,
new Promise(resolve => i.contentWindow.onpopstate = resolve)
]);
assert_equals(navigation.currentEntry.index, 1, "after iframe second forward() outer index");
assert_equals(navigation.currentEntry.index, start_index+1, "after iframe second forward() outer index");
assert_equals(i.contentWindow.navigation.currentEntry.index, 1, "after iframe second forward() iframe index");
}, "navigation.back() and navigation.forward() can navigate multiple frames");
</script>
12 changes: 7 additions & 5 deletions navigation-api/navigation-methods/disambigaute-back.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,20 @@
<iframe id="i" src="/common/blank.html"></iframe>
<script>
async_test(t => {
let start_length = navigation.entries().length;
let start_index = navigation.currentEntry.index;
// Wait for after the load event so that the navigation doesn't get converted
// into a replace navigation.
window.onload = () => t.step_timeout(() => {
assert_equals(navigation.entries().length, 1);
assert_equals(navigation.entries().length, start_length);
assert_equals(i.contentWindow.navigation.entries().length, 1);
navigation.navigate("#top");
assert_equals(navigation.entries().length, 2);
assert_equals(navigation.entries().length, start_length+1);
assert_equals(i.contentWindow.navigation.entries().length, 1);
i.contentWindow.navigation.navigate("#1");
assert_equals(navigation.entries().length, 2);
assert_equals(navigation.entries().length, start_length+1);
assert_equals(i.contentWindow.navigation.entries().length, 2);
assert_equals(navigation.currentEntry.index, 1);
assert_equals(navigation.currentEntry.index, start_index+1);
assert_equals(i.contentWindow.navigation.currentEntry.index, 1);
assert_true(navigation.canGoBack);
assert_true(i.contentWindow.navigation.canGoBack);
Expand All @@ -24,7 +26,7 @@
// previous key. Navigate to the nearest one (which navigates the iframe
// but not the top window).
i.contentWindow.navigation.back().committed.then(t.step_func_done(() => {
assert_equals(navigation.currentEntry.index, 1);
assert_equals(navigation.currentEntry.index, start_index+1);
assert_equals(i.contentWindow.navigation.currentEntry.index, 0);
}));
}, 0);
Expand Down
16 changes: 9 additions & 7 deletions navigation-api/navigation-methods/disambigaute-forward.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,35 @@
<iframe id="i" src="/common/blank.html"></iframe>
<script>
async_test(t => {
let start_length = navigation.entries().length;
let start_index = navigation.currentEntry.index;
// Wait for after the load event so that the navigation doesn't get converted
// into a replace navigation.
window.onload = () => t.step_timeout(() => {
assert_equals(navigation.entries().length, 1);
assert_equals(navigation.entries().length, start_length);
assert_equals(i.contentWindow.navigation.entries().length, 1);
navigation.navigate("#top");
assert_equals(navigation.entries().length, 2);
assert_equals(navigation.entries().length, start_length+1);
assert_equals(i.contentWindow.navigation.entries().length, 1);
i.contentWindow.navigation.navigate("#1");
assert_equals(navigation.entries().length, 2);
assert_equals(navigation.entries().length, start_length+1);
assert_equals(i.contentWindow.navigation.entries().length, 2);
assert_equals(navigation.currentEntry.index, 1);
assert_equals(navigation.currentEntry.index, start_index+1);
assert_equals(i.contentWindow.navigation.currentEntry.index, 1);
assert_true(navigation.canGoBack);
assert_true(i.contentWindow.navigation.canGoBack);

i.contentWindow.navigation.back().committed.then(t.step_func(() => {
assert_equals(navigation.currentEntry.index, 1);
assert_equals(navigation.currentEntry.index, start_index+1);
assert_equals(i.contentWindow.navigation.currentEntry.index, 0);
navigation.back().committed.then(t.step_func(() => {
assert_equals(navigation.currentEntry.index, 0);
assert_equals(navigation.currentEntry.index, start_index);
assert_equals(i.contentWindow.navigation.currentEntry.index, 0);
// There are 2 joint session history entries containing the top window's
// final key. Navigate to the nearest one (which navigates only the
// top window).
navigation.forward().committed.then(t.step_func_done(() => {
assert_equals(navigation.currentEntry.index, 1);
assert_equals(navigation.currentEntry.index, start_index+1);
assert_equals(i.contentWindow.navigation.currentEntry.index, 0);
}));
}));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,23 @@
<iframe id="i" src="/common/blank.html"></iframe>
<script>
async_test(t => {
let start_length = navigation.entries().length;
let start_index = navigation.currentEntry.index;
// Wait for after the load event so that the navigation doesn't get converted
// into a replace navigation.
window.onload = () => t.step_timeout(() => {
assert_equals(navigation.entries().length, 1);
assert_equals(navigation.entries().length, start_length);
assert_equals(i.contentWindow.navigation.entries().length, 1);
navigation.navigate("#top");
assert_equals(navigation.entries().length, 2);
assert_equals(navigation.entries().length, start_length+1);
assert_equals(i.contentWindow.navigation.entries().length, 1);

let iframe_initial_key = i.contentWindow.navigation.currentEntry.key;
i.contentWindow.navigation.navigate("#1");
i.contentWindow.navigation.navigate("#2");
assert_equals(navigation.entries().length, 2);
assert_equals(navigation.entries().length, start_length+1);
assert_equals(i.contentWindow.navigation.entries().length, 3);
assert_equals(navigation.currentEntry.index, 1);
assert_equals(navigation.currentEntry.index, start_index+1);
assert_equals(i.contentWindow.navigation.currentEntry.index, 2);
assert_true(navigation.canGoBack);
assert_true(i.contentWindow.navigation.canGoBack);
Expand All @@ -27,7 +29,7 @@
// initial key. Navigate to the nearest one (which navigates the iframe
// but not the top window).
i.contentWindow.navigation.traverseTo(iframe_initial_key).committed.then(t.step_func_done(() => {
assert_equals(navigation.currentEntry.index, 1);
assert_equals(navigation.currentEntry.index, start_index+1);
assert_equals(i.contentWindow.navigation.currentEntry.index, 0);
}));
}, 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,38 @@
<iframe id="i" src="/common/blank.html"></iframe>
<script>
promise_test(async t => {
let start_length = navigation.entries().length;
let start_index = navigation.currentEntry.index;
// Wait for after the load event so that the navigation doesn't get converted
// into a replace navigation.
await new Promise(resolve => window.onload = () => t.step_timeout(resolve, 0));
assert_equals(navigation.entries().length, 1);
assert_equals(navigation.entries().length, start_length);
assert_equals(i.contentWindow.navigation.entries().length, 1);
let initial_key = navigation.currentEntry.key;
await navigation.navigate("#top1").committed;
await navigation.navigate("#top2").committed;
assert_equals(navigation.entries().length, 3);
assert_equals(navigation.entries().length, start_length+2);
assert_equals(i.contentWindow.navigation.entries().length, 1);
await i.contentWindow.navigation.navigate("#1").committed;
assert_equals(navigation.entries().length, 3);
assert_equals(navigation.entries().length, start_length+2);
assert_equals(i.contentWindow.navigation.entries().length, 2);
assert_equals(navigation.currentEntry.index, 2);
assert_equals(navigation.currentEntry.index, start_index+2);
assert_equals(i.contentWindow.navigation.currentEntry.index, 1);
assert_true(navigation.canGoBack);
assert_true(i.contentWindow.navigation.canGoBack);
let final_key = navigation.currentEntry.key;

await i.contentWindow.navigation.back().committed;
assert_equals(navigation.currentEntry.index, 2);
assert_equals(navigation.currentEntry.index, start_index+2);
assert_equals(i.contentWindow.navigation.currentEntry.index, 0);
await navigation.traverseTo(initial_key).committed;
assert_equals(navigation.currentEntry.index, 0);
assert_equals(navigation.currentEntry.index, start_index);
assert_equals(i.contentWindow.navigation.currentEntry.index, 0);
// There are 2 joint session history entries containing the top window's
// final key. Navigate to the nearest one (which navigates only the
// top window).
await navigation.traverseTo(final_key).committed;
assert_equals(navigation.currentEntry.index, 2);
assert_equals(navigation.currentEntry.index, start_index+2);
assert_equals(i.contentWindow.navigation.currentEntry.index, 0);
}, "navigation.traverseTo() goes to the nearest entry when going forward");
</script>
12 changes: 7 additions & 5 deletions navigation-api/navigation-methods/forward-to-pruned-entry.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
<script src="/resources/testharnessreport.js"></script>
<script>
promise_test(async t => {
let start_length = navigation.entries().length;
let start_index = navigation.currentEntry.index;
// Wait for after the load event so that the navigation doesn't get converted
// into a replace navigation.
await new Promise(resolve => window.onload = () => t.step_timeout(resolve, 0));
await navigation.navigate("#foo").finished;
assert_equals(navigation.entries().length, 2);
assert_equals(navigation.entries().length, start_length+1);
await navigation.back().finished;
assert_equals(navigation.currentEntry.index, 0);
assert_equals(navigation.currentEntry.index, start_index);

// Traverse forward then immediately do a same-document push. This will
// truncate the back forward list, and by the time the traverse commits, the
Expand All @@ -19,15 +21,15 @@
navigation.onnavigateerror = t.unreached_func("navigateerror should not fire");
let forward_value = navigation.forward();
await navigation.navigate("#clobber").finished;
assert_equals(navigation.currentEntry.index, 1);
assert_equals(navigation.currentEntry.index, start_index+1);
await promise_rejects_dom(t, "AbortError", forward_value.committed);
await promise_rejects_dom(t, "AbortError", forward_value.finished);

// This leaves navigation.entries() in a consistent state where traversing
// back and forward still works.
await navigation.back().finished;
assert_equals(navigation.currentEntry.index, 0);
assert_equals(navigation.currentEntry.index, start_index);
await navigation.forward().finished;
assert_equals(navigation.currentEntry.index, 1);
assert_equals(navigation.currentEntry.index, start_index+1);
}, "If forward pruning clobbers the target of a traverse, abort");
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@

<script>
promise_test(async t => {
let start_length = navigation.entries().length;
let start_index = navigation.currentEntry.index;
// Purposefully do not wait until after the load event (unlike some sibling tests).
assert_equals(navigation.entries().length, 1);
assert_equals(document.readyState, "loading", "Document must not have loaded yet");

let navigateEventType;
navigation.onnavigate = e => navigateEventType = e.navigationType;

await navigation.navigate("#1", { history: "push" }).finished;
assert_equals(navigateEventType, "push");
assert_equals(navigation.entries().length, 2);
assert_equals(navigation.currentEntry.index, 1);
assert_equals(navigation.entries().length, start_length+1);
assert_equals(navigation.currentEntry.index, start_index+1);
}, "navigate() with history: 'push' in a document that has not yet had its load event");
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@

<script>
promise_test(async t => {
let start_length = navigation.entries().length;
let start_index = navigation.currentEntry.index;
// Wait for after the load event so that the navigation doesn't get converted
// into a replace navigation due to onload not having completed.
await new Promise(resolve => window.onload = () => t.step_timeout(resolve, 0));
assert_equals(navigation.entries().length, 1);
assert_equals(navigation.entries().length, start_length);


let navigateEventType;
Expand All @@ -20,7 +22,7 @@

await navigation.navigate(location.href, { history: "push" }).finished;
assert_equals(navigateEventType, "push");
assert_equals(navigation.entries().length, 2);
assert_equals(navigation.currentEntry.index, 1);
assert_equals(navigation.entries().length, start_length+1);
assert_equals(navigation.currentEntry.index, start_index+1);
}, "navigate() to the current URL with history: 'push' and intercept so it remains same-document");
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
// Wait for after the load event so that the navigation doesn't get converted
// into a replace navigation (which would defeat the point of the test).
window.onload = () => t.step_timeout(() => {
let start_length = navigation.entries().length;
let start_history_length = history.length;
let start_entry_top = navigation.currentEntry;
let start_entry_iframe_id = i.contentWindow.navigation.currentEntry.id;
Expand All @@ -16,7 +17,7 @@
i.onload = t.step_func_done(() => {
assert_equals(history.length, start_history_length);

assert_equals(navigation.entries().length, 1);
assert_equals(navigation.entries().length, start_length);
assert_equals(navigation.currentEntry, start_entry_top);

assert_equals(i.contentWindow.navigation.entries().length, 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
// Wait for after the load event so that the navigation doesn't get converted
// into a replace navigation.
window.onload = () => t.step_timeout(t.step_func_done(async () => {
let start_length = navigation.entries().length;
let start_history_length = history.length;
let key1 = navigation.currentEntry.key;
await navigation.navigate("#1").committed;
Expand All @@ -14,7 +15,7 @@
await navigation.navigate("#2", { history: "replace" }).committed;
let key3 = navigation.currentEntry.key;
assert_equals(key2, key3);
assert_equals(navigation.entries().length, 2);
assert_equals(navigation.entries().length, start_length + 1);
assert_equals(history.length, start_history_length + 1);
}), 0);
}, "navigate() with history: 'replace' option");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/helpers.js"></script>

<iframe id="i" src="/common/blank.html"></iframe>
<script>
promise_test(async t => {
assert_equals(navigation.entries().length, 1);
assert_equals(navigation.entries()[0], navigation.currentEntry);
assert_false(navigation.canGoBack);
assert_false(navigation.canGoForward);
await new Promise(resolve => window.onload = resolve);
assert_equals(i.contentWindow.navigation.entries().length, 1);
assert_equals(i.contentWindow.navigation.entries()[0], i.contentWindow.navigation.currentEntry);
assert_false(i.contentWindow.navigation.canGoBack);
assert_false(i.contentWindow.navigation.canGoForward);

await assertBothRejectDOM(t, navigation.back(), "InvalidStateError");
await assertBothRejectDOM(t, navigation.forward(), "InvalidStateError");
await assertBothRejectDOM(t, i.contentWindow.navigation.back(), "InvalidStateError", i.contentWindow);
await assertBothRejectDOM(t, i.contentWindow.navigation.forward(), "InvalidStateError", i.contentWindow);
}, "back() and forward() out of bounds");
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@

<script>
promise_test(async t => {
let start_length = navigation.entries().length;
let start_index = navigation.currentEntry.index;
// Wait for after the load event so that the navigation doesn't get converted
// into a replace navigation.
await new Promise(resolve => window.onload = () => t.step_timeout(resolve, 0));

location.href = "#1";

assert_equals(navigation.entries().length, 2);
const [entry0, entry1] = navigation.entries();
assert_equals(navigation.entries().length, start_length + 1);
const [entry0, entry1] = navigation.entries().slice(start_index);
assert_equals((new URL(entry0.url)).hash, "");
assert_equals((new URL(entry1.url)).hash, "#1");

Expand Down
Loading

0 comments on commit e1f2e7c

Please sign in to comment.