| <!doctype html> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <iframe id="i" 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(resolve => window.onload = () => t.step_timeout(resolve, 0)); |
| // Step 1 |
| assert_equals(navigation.entries().length, 1, "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(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(i.contentWindow.navigation.entries().length, 2, "step 3 iframe entries() length"); |
| assert_equals(navigation.currentEntry.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. |
| |
| // Going back in the iframe should go 3->2 (navigating iframe only) |
| await Promise.all([ |
| 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(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(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(i.contentWindow.navigation.currentEntry.index, 0, "after outer back() iframe index"); |
| |
| // Next two should not navigate the iframe |
| i.contentWindow.onpopstate = t.unreached_func("popstate must not be called"); |
| |
| // 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(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(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(i.contentWindow.navigation.currentEntry.index, 1, "after iframe second forward() iframe index"); |
| }, "navigation.back() and navigation.forward() can navigate multiple frames"); |
| </script> |