summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/html/browsers/history
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /testing/web-platform/tests/html/browsers/history
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'testing/web-platform/tests/html/browsers/history')
-rw-r--r--testing/web-platform/tests/html/browsers/history/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/browsers/history/history-notes/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/browsers/history/joint-session-history/joint-session-history-child1.html18
-rw-r--r--testing/web-platform/tests/html/browsers/history/joint-session-history/joint-session-history-child2.html5
-rw-r--r--testing/web-platform/tests/html/browsers/history/joint-session-history/joint-session-history-grandchild1.html8
-rw-r--r--testing/web-platform/tests/html/browsers/history/joint-session-history/joint-session-history-grandchild2.html5
-rw-r--r--testing/web-platform/tests/html/browsers/history/joint-session-history/joint-session-history-only-fully-active.html30
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/001.html333
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/002.html308
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/004.html62
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/005.html47
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/006.html53
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/007.html56
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/008.html40
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/008.js11
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/009-1.html20
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/009-3.html28
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/009-5.html23
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/009.html22
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/010-1.html16
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/010-3.html24
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/010-5.html23
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/010.html22
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/011.html32
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/012.html32
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/blank.html8
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/blank2.html13
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/blank3.html11
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/combination_history_001.html20
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/combination_history_002.html22
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/combination_history_003.html26
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/combination_history_004.html29
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/combination_history_005.html34
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/combination_history_006.html30
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/combination_history_007.html32
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/history.js35
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/history_back-1.html17
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/history_back.html27
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/history_back_1.html28
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/history_entry.html12
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/history_forward-1.html15
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/history_forward-2.html17
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/history_forward.html32
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/history_forward_1.html28
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_minus.html27
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_no_argument-1.html18
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_no_argument.html29
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_plus.html33
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_undefined-1.html15
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_undefined.html28
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_zero-1.html18
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_zero.html29
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/history_pushstate.html19
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/history_pushstate_err.html18
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/history_pushstate_nooptionalparam.html20
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/history_replacestate.html20
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/history_replacestate_err.html18
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/history_replacestate_nooptionalparam.html20
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/history_state.html24
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/joint_session_history/001-1.html72
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/joint_session_history/001.html18
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/joint_session_history/002-1.html35
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/joint_session_history/002.html18
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/joint_session_history/filler.html5
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/history.js35
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/history_entry.html12
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/traverse_the_history_unload_prompt_1-1.html18
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/traverse_the_history_unload_prompt_1-manual.html31
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/traverse_the_history_unload_prompt_2-1.html18
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/traverse_the_history_unload_prompt_2-manual.html31
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/traverse_the_session_history_unload_prompt_1-1.html17
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/traverse_the_session_history_unload_prompt_1-manual.html30
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_1-1.html18
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_1.html28
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_2-1.html17
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_2.html28
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_3-1.html17
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_3.html28
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_4-1.html17
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_4.html28
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_5-1.html17
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_5.html28
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_unload_1-1.html17
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_unload_1.html30
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_after_load_1-1.html15
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_after_load_1.html30
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_after_load_2-1.html12
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_after_load_2.html28
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_onload_1-1.html12
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_onload_1.html29
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_onload_2-1.html12
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_onload_2.html29
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/allow_prototype_cycle_through_location.sub.html197
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/assign_after_load-1.html9
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/assign_after_load-2.html7
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/assign_after_load.html23
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/assign_before_load-1.html7
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/assign_before_load-2.html7
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/assign_before_load.html23
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/contains.json6
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/cross_origin_joined_frame.sub.html15
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/document_location.html17
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/location-prototype-setting.html18
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/location-stringifier.html11
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/location_assign.html26
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/location_assign_about_blank-1.html2
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/location_assign_about_blank.html24
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/location_hash.html33
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/location_host.html28
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/location_hostname.html33
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/location_href.html19
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/location_origin.html14
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/location_pathname.html22
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/location_port.html31
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/location_protocol.html25
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/location_reload-iframe.html4
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/location_reload.html41
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/location_replace.html20
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/location_search.html20
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_click_assign_during_load-1.html7
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_click_assign_during_load-2.html7
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_click_assign_during_load-manual.html17
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_click_location_replace_during_load-1.html10
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_click_location_replace_during_load-2.html7
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_click_location_replace_during_load-manual.html17
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_click_replace_during_load-manual.html17
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_form_submit_assign_during_load-1.html9
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_form_submit_assign_during_load-2.html7
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_form_submit_assign_during_load-manual.html17
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/reload_in_resize-1.html15
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/reload_in_resize-manual.html26
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/reload_document_open_write-1.html14
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/reload_document_open_write.html26
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/reload_document_write-1.html4
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/reload_document_write.html21
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/reload_document_write_onload-1.html9
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/reload_document_write_onload.html26
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/reload_post_1-1.html10
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/reload_post_1.html27
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/same_origin_frame.html12
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_click_assign_during_load-1.html10
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_click_assign_during_load-2.html7
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_click_assign_during_load.html17
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_click_location_assign_during_load-1.html13
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_click_location_assign_during_load-2.html7
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_click_location_assign_during_load.html16
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_form_submit_assign_during_load-1.html12
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_form_submit_assign_during_load-2.html7
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_form_submit_assign_during_load.html17
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-location-interface/security_location_0.sub.htm27
-rw-r--r--testing/web-platform/tests/html/browsers/history/the-session-history-of-browsing-contexts/.gitkeep0
153 files changed, 3890 insertions, 0 deletions
diff --git a/testing/web-platform/tests/html/browsers/history/.gitkeep b/testing/web-platform/tests/html/browsers/history/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/.gitkeep
diff --git a/testing/web-platform/tests/html/browsers/history/history-notes/.gitkeep b/testing/web-platform/tests/html/browsers/history/history-notes/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/history-notes/.gitkeep
diff --git a/testing/web-platform/tests/html/browsers/history/joint-session-history/joint-session-history-child1.html b/testing/web-platform/tests/html/browsers/history/joint-session-history/joint-session-history-child1.html
new file mode 100644
index 000000000..22bb0b298
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/joint-session-history/joint-session-history-child1.html
@@ -0,0 +1,18 @@
+<body>
+ <a id="link" href="joint-session-history-child2.html">Child1</a>.
+ <iframe id="grandchild"></iframe>
+</body>
+<script>
+ window.onload = function() {
+ var link = document.getElementById("link");
+ var grandchild = document.getElementById("grandchild");
+ var timer = window.setInterval(poll, 100);
+ function poll() {
+ if (grandchild.getAttribute("data-grandchild-loaded")) {
+ window.clearInterval(timer);
+ link.click();
+ }
+ }
+ grandchild.src="joint-session-history-grandchild1.html";
+ };
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/joint-session-history/joint-session-history-child2.html b/testing/web-platform/tests/html/browsers/history/joint-session-history/joint-session-history-child2.html
new file mode 100644
index 000000000..24b469516
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/joint-session-history/joint-session-history-child2.html
@@ -0,0 +1,5 @@
+<body>Child 2.</body>
+<script>
+ // Servo doesn't support postMessage yet, so we poll on attributes.
+ window.frameElement.setAttribute("data-child-loaded", true);
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/joint-session-history/joint-session-history-grandchild1.html b/testing/web-platform/tests/html/browsers/history/joint-session-history/joint-session-history-grandchild1.html
new file mode 100644
index 000000000..d05e15242
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/joint-session-history/joint-session-history-grandchild1.html
@@ -0,0 +1,8 @@
+<body>
+ <a id="link" href="joint-session-history-grandchild2.html">Grandchild1</a>.
+</body>
+<script>
+ window.onload = function() {
+ document.getElementById("link").click();
+ }
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/joint-session-history/joint-session-history-grandchild2.html b/testing/web-platform/tests/html/browsers/history/joint-session-history/joint-session-history-grandchild2.html
new file mode 100644
index 000000000..b5c81e1fc
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/joint-session-history/joint-session-history-grandchild2.html
@@ -0,0 +1,5 @@
+<body>Grandchild2.</body>
+<script>
+ // Servo doesn't support postMessage yet, so we poll on attributes.
+ window.frameElement.setAttribute("data-grandchild-loaded", true);
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/joint-session-history/joint-session-history-only-fully-active.html b/testing/web-platform/tests/html/browsers/history/joint-session-history/joint-session-history-only-fully-active.html
new file mode 100644
index 000000000..c42d160a2
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/joint-session-history/joint-session-history-only-fully-active.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Do only fully active documents count for session history?</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+ <iframe id="child"></iframe>
+</body>
+<script>
+ async_test(function(t) {
+ var old_history_len = window.history.length;
+ var child = document.getElementById("child");
+ var timer = window.setInterval(t.step_func(poll), 100);
+ function poll() {
+ if (child.getAttribute("data-child-loaded")) {
+ // Check to see how many entries have been added to the session history.
+ // The spec https://html.spec.whatwg.org/multipage/#joint-session-history
+ // says that only fully active documents are included in the joint session history.
+ // If only fully active documents count, then the only fully active document
+ // is the child, with session length 1, so the joint session length change will be 1.
+ // If all documents count, then the grandchild is reachable via the session history,
+ // and it has session length 1, so the joint session length change will be 2.
+ assert_equals(2, window.history.length - old_history_len);
+ window.clearInterval(timer);
+ t.done();
+ }
+ }
+ child.src = "joint-session-history-child1.html";
+ });
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/.gitkeep b/testing/web-platform/tests/html/browsers/history/the-history-interface/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/.gitkeep
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/001.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/001.html
new file mode 100644
index 000000000..0e5632bbc
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/001.html
@@ -0,0 +1,333 @@
+<!doctype html>
+<html>
+ <head>
+ <title>history.pushState tests</title>
+ <script type="text/javascript" src="/resources/testharness.js"></script>
+ <script type="text/javascript" src="/resources/testharnessreport.js"></script>
+ <script type="text/javascript">
+//does not test for firing of popstate onload, because this was dropped from the specification on 25 March 2011
+//covers history.state after load, in accordance with the specification draft from 25 March 2011
+//history.state before load is tested in 006 and 007
+//does not test for structured cloning of FileList, File or Blob interfaces, as these require manual file selection
+
+//**This test assumes that assignments to location.hash will be synchronous - this is how all browsers implement it.
+//The spec (as of 25 March 2011) disagrees.**//
+
+var histlength, atstep = 0, lasttimer;
+setup({explicit_done:true}); //tests should take under 6 seconds + execution time
+
+window.onload = function () {
+ if( location.protocol == 'file:' ) {
+ document.getElementsByTagName('p')[0].innerHTML = 'ERROR: This test cannot be run from file: (URL resolving will not work). It must be loaded over HTTP.';
+ return;
+ } else if( location.protocol == 'https:' ) {
+ document.getElementsByTagName('p')[0].innerHTML += '<br>WARNING: Browsers may intentionally fail to update history.length when pages are loaded over HTTPS, as a privacy restriction. If possible, load this page over HTTP.';
+ }
+ //use a timeout, because some browsers intentionally do not add history entries for URL changes in the onload thread
+ setTimeout(testinit,100);
+};
+function testinit() {
+ atstep = 1;
+ histlength = history.length;
+ iframe = document.getElementsByTagName('iframe')[0].src = 'blank2.html';
+ //reportload will now be called by the onload handler for the iframe
+}
+function reportload() {
+ var iframe = document.getElementsByTagName('iframe')[0], hashchng = false;
+ var canvassup = false, cloneobj;
+
+ function tests1() {
+ //Firefox may fail when reloading, because it recovers iframe state, and therefore does not see the need to alter history length
+ test(function () { assert_equals( history.length, histlength + 1, 'make sure that you loaded the test in a new tab/window' ); }, 'history.length should update when loading pages in an iframe');
+ histlength = history.length;
+ iframe.contentWindow.location.hash = 'test'; //should be synchronous **SEE COMMENT AT TOP OF FILE
+ test(function () {
+ assert_equals( history.length, histlength + 1, 'make sure that you loaded the test in a new tab/window' );
+ }, 'history.length should update when setting location.hash');
+ test(function () { assert_true( !!history.pushState, 'critical test; ignore any failures after this' ); }, 'history.pushState must exist'); //assert_exists does not allow prototype inheritance
+ test(function () { assert_true( !!iframe.contentWindow.history.pushState, 'critical test; ignore any failures after this' ); }, 'history.pushState must exist within iframes');
+ test(function () {
+ assert_equals( iframe.contentWindow.history.state, null );
+ }, 'initial history.state should be null');
+ test(function () {
+ histlength = history.length;
+ iframe.contentWindow.history.pushState('','');
+ assert_equals( history.length, histlength + 1 );
+ }, 'history.length should update when pushing a state');
+ test(function () {
+ assert_equals( iframe.contentWindow.history.state, '' );
+ }, 'history.state should update after a state is pushed');
+ histlength = history.length;
+ history.back();
+ setTimeout(tests2,50); //.back is queued to end of thread
+ }
+ function tests2() {
+ test(function () {
+ assert_equals( history.length, histlength );
+ }, 'history.length should not decrease after going back');
+ test(function () {
+ assert_equals( iframe.contentWindow.location.hash.replace(/^#/,''), 'test' );
+ }, 'traversing history must traverse pushed states');
+ history.go(-1);
+ setTimeout(tests3,50); //.go is queued to end of thread
+ }
+ function tests3() {
+ test(function () {
+ assert_equals( iframe.contentWindow.location.hash.replace(/^#/,''), '', '(this could cause other failures later on)' );
+ }, 'traversing history must also traverse hash changes');
+ //Safari 5.0.3 fails here - it navigates *this* document to the *iframe's* location, instead of just navigating the iframe
+ history.go(2);
+ setTimeout(tests4,50); //.go is queued to end of thread
+ }
+ function tests4() {
+ test(function () {
+ //Firefox 4 beta 11 has a messed up error object, which does not have the right error type or .SECURITY_ERR property
+ assert_throws('SECURITY_ERR',function () { history.pushState('','','//exa mple'); });
+ }, 'pushState must not be allowed to create invalid URLs');
+ test(function () {
+ assert_throws('SECURITY_ERR',function () { history.pushState('','','http://www.example.com/'); });
+ }, 'pushState must not be allowed to create cross-origin URLs');
+ test(function () {
+ assert_throws('SECURITY_ERR',function () { history.pushState('','','about:blank'); });
+ }, 'pushState must not be allowed to create cross-origin URLs (about:blank)');
+ test(function () {
+ assert_throws('SECURITY_ERR',function () { history.pushState('','','data:text/html,'); });
+ }, 'pushState must not be allowed to create cross-origin URLs (data:URI)');
+ test(function () {
+ assert_throws('SECURITY_ERR',function () { iframe.contentWindow.history.pushState('','','http://www.example.com/'); },iframe.contentWindow);
+ }, 'security errors are expected to be thrown in the context of the document that owns the history object');
+ test(function () {
+ iframe.contentWindow.location.hash = 'test2';
+ assert_equals( iframe.contentWindow.location.hash.replace(/^#/,''), 'test2', 'location.hash did not change when told to' );
+ }, 'location.hash must be allowed to change (part 1)');
+ history.go(-1);
+ setTimeout(tests5,50); //.go is queued to end of thread
+ }
+ function tests5() {
+ test(function () {
+ assert_equals( iframe.contentWindow.location.hash.replace(/^#/,''), 'test', 'location.hash did not change when going back' );
+ }, 'location.hash must be allowed to change (part 2)');
+ test(function () {
+ iframe.contentWindow.history.pushState('','');
+ assert_equals( iframe.contentWindow.location.hash.replace(/^#/,''), 'test', 'location.hash changed when an unrelated state was pushed' );
+ }, 'pushState must not alter location.hash when no URL is provided');
+ history.go(1); //should do nothing, since the pushState should have removed the forward history
+ setTimeout(tests6,50); //.go is queued to end of thread
+ }
+ function tests6() {
+ test(function () {
+ assert_equals( iframe.contentWindow.location.hash.replace(/^#/,''), 'test' );
+ }, 'pushState must remove all history after the current state');
+ test(function () {
+ iframe.contentWindow.history.pushState('','','#test3');
+ assert_equals( iframe.contentWindow.location.hash.replace(/^#/,''), 'test3' );
+ }, 'pushState must be able to set location.hash');
+ //begin setup for "remove any tasks queued by the history traversal task source"
+ iframe.contentWindow.location.hash = '#test4';
+ iframe.contentWindow.history.go(-1); //must be queued
+ try {
+ //must remove the queued navigation in the same browsing context
+ iframe.contentWindow.history.pushState('','');
+ } catch(unsuperr) {}
+ //allow the browser to mistakenly run the .go if it is going to
+ //do not put two .go commands in the same thread, in case the browser mistakenly calculates the history position when
+ //calling .go instead of when executing the traversal task - that could give a false PASS in the next test otherwise
+ setTimeout(tests7,50);
+ }
+ function tests7() {
+ iframe.contentWindow.history.go(-1); //must be queued, but should not be removed this time
+ setTimeout(tests8,50); //.go is queued to end of thread
+ }
+ function tests8() {
+ test(function () {
+ assert_equals( iframe.contentWindow.location.hash.replace(/^#/,''), 'test4' );
+ }, 'pushState must remove any tasks queued by the history traversal task source');
+ //end "remove any tasks queued by the history traversal task source"
+ window.addEventListener('hashchange',function () { hashchng = true; },false);
+ try {
+ //push a state that changes the hash
+ iframe.contentWindow.history.pushState('','',iframe.contentWindow.location.pathname+'#test5');
+ } catch(unsuperr) {}
+ setTimeout(tests9,50); //allow the hashchange event to process, if the browser has mistakenly fired it
+ }
+ function tests9() {
+ test(function () {
+ assert_false( hashchng );
+ }, 'pushState must not fire hashchange events');
+ test(function () {
+ iframe.contentWindow.history.pushState('','','/testing_ignore_me_404');
+ assert_equals( iframe.contentWindow.location.pathname, '/testing_ignore_me_404' );
+ }, 'pushState must be able to set location.pathname');
+ test(function () {
+ var newURL = location.href.replace(/\/[^\/]*$/)+'/testing_ignore_me_404/';
+ iframe.contentWindow.history.pushState('','',newURL);
+ assert_equals( iframe.contentWindow.location.href, newURL );
+ }, 'pushState must be able to set absolute URLs to the same host');
+ test(function () {
+ assert_throws( 'DATA_CLONE_ERR', function () {
+ history.pushState({dummy:function () {}},'');
+ } );
+ }, 'pushState must not be able to use a function as data');
+ test(function () {
+ assert_throws( 'DATA_CLONE_ERR', function () {
+ history.pushState({dummy:window},'');
+ } );
+ }, 'pushState must not be able to use a DOM node as data');
+ test(function () {
+ try { a.b = c; } catch(errdata) {
+ assert_throws( 'DATA_CLONE_ERR', function () {
+ history.pushState({dummy:errdata},'');
+ } );
+ }
+ }, 'pushState must not be able to use an error object as data');
+ test(function () {
+ assert_throws( 'DATA_CLONE_ERR', function () {
+ iframe.contentWindow.history.pushState(document,'');
+ }, iframe.contentWindow );
+ }, 'security errors are expected to be thrown in the context of the document that owns the history object (2)');
+ cloneobj = {
+ nulldata: null,
+ udefdata: window.undefined,
+ booldata: true,
+ numdata: 1,
+ strdata: 'string data',
+ boolobj: new Boolean(true),
+ numobj: new Number(1),
+ strobj: new String('string data'),
+ datedata: new Date(),
+ regdata: /a/g,
+ arrdata: [1]
+ };
+ cloneobj.regdata.lastIndex = 1;
+ cloneobj.looped = cloneobj;
+ //test the ImageData type, if the browser supports it
+ var canvas = document.createElement('canvas');
+ if( canvas.getContext && ( canvas = canvas.getContext('2d') ) && canvas.createImageData ) {
+ canvassup = true;
+ cloneobj.imgdata = canvas.createImageData(1,1);
+ }
+ test(function () {
+ try {
+ iframe.contentWindow.history.pushState(cloneobj,'new title');
+ } catch(e) {
+ cloneobj.looped = null;
+ //try again because this object is needed for future tests
+ iframe.contentWindow.history.pushState(cloneobj,'new title');
+ //rethrow so the browser gets a FAIL for not coping with the circular reference; "internal structured cloning algorithm" step 1
+ throw(e);
+ }
+ }, 'pushState must be able to make structured clones of complex objects');
+ test(function () {
+ assert_equals( iframe.contentWindow.history.state && iframe.contentWindow.history.state.strdata, 'string data' );
+ }, 'history.state should also reference a clone of the original object');
+ test(function () {
+ assert_false( cloneobj === iframe.contentWindow.history.state );
+ }, 'history.state should be a clone of the original object, not a reference to it');
+ /*
+ behaviour is not defined per spec, and no known implementations do this
+ test(function () {
+ assert_equals( iframe.contentDocument.title, 'new title', 'not required for specification conformance' );
+ }, 'pushState MIGHT set the document title');
+ */
+ history.go(-1);
+ setTimeout(tests10,50); //.go is queued to end of thread
+ }
+ function tests10() {
+ var eventtime = setTimeout(function () { tests11(false); },500); //should be cleared by the event handler long before it has a chance to fire
+ iframe.contentWindow.addEventListener('popstate',function (e) { clearTimeout(eventtime); tests11(true,e); },false);
+ history.forward();
+ }
+ function tests11(hasFired,ev) {
+ test(function () {
+ assert_true( hasFired );
+ }, 'popstate event should fire when navigation occurs');
+ test(function () {
+ assert_true( !!ev && typeof(ev.state) != 'undefined', 'state information was not passed' );
+ assert_true( !!ev.state, 'state information does not contain the expected value - browser is probably stuck in the wrong history position' );
+ assert_equals( ev.state.nulldata, null, 'state null data was not correct' );
+ assert_equals( ev.state.udefdata, window.undefined, 'state undefined data was not correct' );
+ assert_true( ev.state.booldata, 'state boolean data was not correct' );
+ assert_equals( ev.state.numdata, 1, 'state numeric data was not correct' );
+ assert_equals( ev.state.strdata, 'string data', 'state string data was not correct' );
+ assert_true( !!ev.state.datedata.getTime, 'state date data was not correct' );
+ assert_exists( ev.state, 'regdata', 'state regex data was not correct' );
+ assert_equals( ev.state.regdata.source, 'a', 'state regex pattern data was not correct' );
+ assert_true( ev.state.regdata.global, 'state regex flag data was not correct' );
+ assert_equals( ev.state.regdata.lastIndex, 0, 'state regex lastIndex data was not correct' );
+ assert_equals( ev.state.arrdata.length, 1, 'state array data was not correct' );
+ assert_true( ev.state.boolobj.valueOf(), 'state boolean data was not correct' );
+ assert_equals( ev.state.numobj.valueOf(), 1, 'state numeric data was not correct' );
+ assert_equals( ev.state.strobj.valueOf(), 'string data', 'state string data was not correct' );
+ if( canvassup ) {
+ assert_equals( ev.state.imgdata.width, 1, 'state ImageData was not correct' );
+ }
+ }, 'popstate event should pass the state data');
+ test(function () {
+ assert_equals( ev.state.looped, ev.state );
+ }, 'state data should cope with circular object references');
+ test(function () {
+ assert_false( cloneobj === ev.state );
+ }, 'state data should be a clone of the original object, not a reference to it');
+ test(function () {
+ assert_equals( iframe.contentWindow.history.state && iframe.contentWindow.history.state.strdata, 'string data' );
+ }, 'history.state should also reference a clone of the original object (2)');
+ test(function () {
+ assert_false( cloneobj === iframe.contentWindow.history.state );
+ }, 'history.state should be a clone of the original object, not a reference to it (2)');
+ test(function () {
+ assert_false( iframe.contentWindow.history.state === ev.state );
+ }, 'history.state should be a separate clone of the object, not a reference to the object passed to the event handler');
+ try {
+ iframe.contentWindow.persistval = true;
+ iframe.contentWindow.history.pushState('','', location.href.replace(/\/[^\/]*$/,'/blank3.html') );
+ } catch(unsuperr) {}
+ //it's already cached, so this should be very fast if the browser mistakenly loads it
+ //it should not need to load at all, since it's just a pushed state
+ setTimeout(tests12,1000);
+ }
+ function tests12() {
+ test(function () {
+ assert_true( iframe.contentWindow.persistval && !iframe.contentWindow.forreal );
+ }, 'pushState should not actually load the new URL');
+ atstep = 3;
+ iframe.contentWindow.location.reload(); //load the real URL
+ lasttimer = setTimeout(function () { tests13(false); },3000); //should be cleared by the onload handler long before it has a chance to fire
+ }
+ function tests13(passed) {
+ test(function () {
+ assert_true( passed, 'expected a load event to fire when reloading the URL from cache, gave up waiting after 3 seconds' );
+ }, 'reloading a pushed state should actually load the new URL');
+ //try to make browsers behave when reloading so that the correct URL is recovered - does not always work
+ iframe.contentWindow.location.href = location.href.replace(/\/[^\/]*$/,'/blank.html');
+ done();
+ }
+
+ if( atstep == 1 ) {
+ //blank2 has loaded
+ atstep = 2;
+ //use a timeout, because some browsers intentionally do not add history entries for URL changes in an onload thread
+ setTimeout(tests1,100);
+ } else if( atstep == 3 ) {
+ //blank3 should now have loaded after the .reload() command
+ atstep = 4;
+ clearTimeout(lasttimer);
+ tests13(true);
+ }
+}
+
+
+
+ </script>
+ </head>
+ <body>
+
+ <noscript><p>Enable JavaScript and reload</p></noscript>
+ <p>WARNING: This test should always be loaded in a new tab/window, to avoid browsers attempting to recover the state of frames, and history length. Do not reload the test.</p>
+ <div id="log">Running test...</div>
+ <p><iframe onload="reportload();" src="blank.html"></iframe></p>
+ <p><iframe src="blank.html"></iframe></p>
+ <p><iframe src="blank2.html"></iframe></p>
+ <p><iframe src="blank3.html"></iframe></p>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/002.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/002.html
new file mode 100644
index 000000000..eb0c15aab
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/002.html
@@ -0,0 +1,308 @@
+<!doctype html>
+<html>
+ <head>
+ <title>history.replaceState tests</title>
+ <script type="text/javascript" src="/resources/testharness.js"></script>
+ <script type="text/javascript" src="/resources/testharnessreport.js"></script>
+ <script type="text/javascript">
+//does not test for firing of popstate onload, because this was dropped from the specification on 25 March 2011
+//covers history.state after load, in accordance with the specification draft from 25 March 2011
+//history.state before load is tested in 006 and 007
+//does not test for structured cloning of FileList, File or Blob interfaces, as these require manual file selection
+
+//**This test assumes that assignments to location.hash will be synchronous - this is how all browsers implement it.
+//The spec (as of 25 March 2011) disagrees.
+
+var histlength, atstep = 0, lasttimer;
+setup({explicit_done:true}); //tests should take under 6 seconds + execution time
+
+window.onload = function () {
+ if( location.protocol == 'file:' ) {
+ document.getElementsByTagName('p')[0].innerHTML = 'ERROR: This test cannot be run from file: (URL resolving will not work). It must be loaded over HTTP.';
+ return;
+ } else if( location.protocol == 'https:' ) {
+ document.getElementsByTagName('p')[0].innerHTML += '<br>WARNING: Browsers may intentionally fail to update history.length when pages are loaded over HTTPS, as a privacy restriction. If possible, load this page over HTTP.';
+ }
+ //use a timeout, because some browsers intentionally do not add history entries for URL changes in the onload thread
+ setTimeout(testinit,100);
+};
+function testinit() {
+ atstep = 1;
+ histlength = history.length;
+ iframe = document.getElementsByTagName('iframe')[0].src = 'blank2.html';
+ //reportload will now be called by the onload handler for the iframe
+}
+function reportload() {
+ var iframe = document.getElementsByTagName('iframe')[0], hashchng = false;
+ var canvassup = false, cloneobj;
+
+ function tests1() {
+ test(function () { assert_equals( history.length, histlength + 1, 'make sure that you loaded the test in a new tab/window' ); }, 'history.length should update when loading pages in an iframe');
+ histlength = history.length;
+ iframe.contentWindow.location.hash = 'test'; //should be synchronous **SEE COMMENT AT TOP OF FILE
+ test(function () {
+ assert_equals( history.length, histlength + 1, 'make sure that you loaded the test in a new tab/window' );
+ }, 'history.length should update when setting location.hash');
+ test(function () { assert_true( !!history.replaceState, 'critical test; ignore any failures after this' ); }, 'history.replaceState must exist'); //assert_exists does not allow prototype inheritance
+ test(function () { assert_true( !!iframe.contentWindow.history.replaceState, 'critical test; ignore any failures after this' ); }, 'history.replaceState must exist within iframes');
+ test(function () {
+ assert_equals( iframe.contentWindow.history.state, null );
+ }, 'initial history.state should be null');
+ iframe.contentWindow.location.hash = 'test2';
+ history.back();
+ setTimeout(tests2,50); //.go is queued to end of thread
+ }
+ function tests2() {
+ test(function () {
+ histlength = history.length;
+ iframe.contentWindow.history.replaceState('','');
+ assert_equals( history.length, histlength );
+ }, 'history.length should not update when replacing a state with no URL');
+ test(function () {
+ assert_equals( iframe.contentWindow.history.state, '' );
+ }, 'history.state should update after a state is pushed');
+ test(function () {
+ assert_equals( iframe.contentWindow.location.hash.replace(/^#/,''), 'test' );
+ }, 'hash should not change when replaceState is called without a URL');
+ test(function () {
+ histlength = history.length;
+ iframe.contentWindow.history.replaceState('','','#test3');
+ assert_equals( history.length, histlength );
+ }, 'history.length should not update when replacing a state with a URL');
+ test(function () {
+ assert_equals( iframe.contentWindow.location.hash.replace(/^#/,''), 'test3' );
+ }, 'hash should change when replaceState is called with a URL');
+ history.go(-1);
+ setTimeout(tests3,50); //.go is queued to end of thread
+ }
+ function tests3() {
+ test(function () {
+ assert_equals( iframe.contentWindow.location.hash.replace(/^#/,''), '' );
+ }, 'replaceState must replace the existing state and not add an extra one');
+ history.go(2);
+ setTimeout(tests4,50); //.go is queued to end of thread
+ }
+ function tests4() {
+ test(function () {
+ assert_equals( iframe.contentWindow.location.hash.replace(/^#/,''), 'test2' );
+ }, 'replaceState must replace the existing state without altering the forward history');
+ test(function () {
+ assert_throws('SECURITY_ERR',function () { history.replaceState('','','//exa mple'); });
+ }, 'replaceState must not be allowed to create invalid URLs');
+ test(function () {
+ assert_throws('SECURITY_ERR',function () { history.replaceState('','','http://www.example.com/'); });
+ }, 'replaceState must not be allowed to create cross-origin URLs');
+ test(function () {
+ assert_throws('SECURITY_ERR',function () { history.replaceState('','','about:blank'); });
+ }, 'replaceState must not be allowed to create cross-origin URLs (about:blank)');
+ test(function () {
+ assert_throws('SECURITY_ERR',function () { history.replaceState('','','data:text/html,'); });
+ }, 'replaceState must not be allowed to create cross-origin URLs (data:URI)');
+ test(function () {
+ assert_throws('SECURITY_ERR',function () { iframe.contentWindow.history.replaceState('','','http://www.example.com/'); },iframe.contentWindow);
+ }, 'security errors are expected to be thrown in the context of the document that owns the history object');
+ test(function () {
+ //avoids browsers running .go synchronously when only a hash change is involved
+ iframe.contentWindow.history.replaceState('','','/testing_ignore_me_404#test4');
+ assert_equals( iframe.contentWindow.location.pathname, '/testing_ignore_me_404' );
+ }, 'replaceState must be able to set location.pathname');
+ test(function () {
+ var newURL = location.href.replace(/\/[^\/]*$/)+'/testing_ignore_me_404/';
+ iframe.contentWindow.history.replaceState('','',newURL);
+ assert_equals( iframe.contentWindow.location.href, newURL );
+ }, 'replaceState must be able to set absolute URLs to the same host');
+ //begin setup for "[must not] remove any tasks queued by the history traversal task source"
+ iframe.contentWindow.history.go(-1); //must be queued so the next command takes place *beforehand*
+ try {
+ //must not remove the queued navigation in the same browsing context
+ iframe.contentWindow.history.replaceState('','',iframe.contentWindow.location.pathname+'#test5');
+ } catch(unsuperr2) {}
+ //allow the browser to run the .go
+ setTimeout(tests5,50);
+ }
+ function tests5() {
+ test(function () {
+ assert_equals( iframe.contentWindow.location.hash.replace(/^#/,''), 'test3' );
+ }, 'replaceState must not remove any tasks queued by the history traversal task source');
+ //Safari 5.0.3 fails here - it navigates *this* document to the *iframe's* location, instead of just navigating the iframe
+ history.go(1);
+ setTimeout(tests6,50); //.go is queued to end of thread
+ }
+ function tests6() {
+ test(function () {
+ assert_equals( iframe.contentWindow.location.hash.replace(/^#/,''), 'test5' );
+ }, '.go must queue a task with the history traversal task source (run asynchronously)');
+ //end "[must not] remove any tasks queued by the history traversal task source"
+ window.addEventListener('hashchange',function () { hashchng = true; },false);
+ try {
+ //push a state that changes the hash
+ iframe.contentWindow.history.replaceState('','',iframe.contentWindow.location.pathname+'#test6');
+ } catch(unsuperr) {}
+ setTimeout(tests7,50); //allow the hashchange event to process, if the browser has mistakenly fired it
+ }
+ function tests7() {
+ test(function () {
+ assert_false( hashchng );
+ }, 'replaceState must not fire hashchange events');
+ test(function () {
+ assert_throws( 'DATA_CLONE_ERR', function () {
+ history.replaceState({dummy:function () {}},'');
+ } );
+ }, 'replaceState must not be able to use a function as data');
+ test(function () {
+ assert_throws( 'DATA_CLONE_ERR', function () {
+ history.replaceState({dummy:window},'');
+ } );
+ }, 'replaceState must not be able to use a DOM node as data');
+ test(function () {
+ try { a.b = c; } catch(errdata) {
+ assert_throws( 'DATA_CLONE_ERR', function () {
+ history.replaceState({dummy:errdata},'');
+ } );
+ }
+ }, 'replaceState must not be able to use an error object as data');
+ test(function () {
+ assert_throws( 'DATA_CLONE_ERR', function () {
+ iframe.contentWindow.history.replaceState(document,'');
+ }, iframe.contentWindow );
+ }, 'security errors are expected to be thrown in the context of the document that owns the history object (2)');
+ cloneobj = {
+ nulldata: null,
+ udefdata: window.undefined,
+ booldata: true,
+ numdata: 1,
+ strdata: 'string data',
+ boolobj: new Boolean(true),
+ numobj: new Number(1),
+ strobj: new String('string data'),
+ datedata: new Date(),
+ regdata: /a/g,
+ arrdata: [1]
+ };
+ cloneobj.regdata.lastIndex = 1;
+ cloneobj.looped = cloneobj;
+ //test the ImageData type, if the browser supports it
+ var canvas = document.createElement('canvas');
+ if( canvas.getContext && ( canvas = canvas.getContext('2d') ) && canvas.createImageData ) {
+ canvassup = true;
+ cloneobj.imgdata = canvas.createImageData(1,1);
+ }
+ test(function () {
+ try {
+ iframe.contentWindow.history.replaceState(cloneobj,'new title');
+ } catch(e) {
+ cloneobj.looped = null;
+ //try again because this object is needed for future tests
+ iframe.contentWindow.history.replaceState(cloneobj,'new title');
+ //rethrow so the browser gets a FAIL for not coping with the circular reference; "internal structured cloning algorithm" step 1
+ throw(e);
+ }
+ }, 'replaceState must be able to make structured clones of complex objects');
+ test(function () {
+ assert_equals( iframe.contentWindow.history.state && iframe.contentWindow.history.state.strdata, 'string data' );
+ }, 'history.state should also reference a clone of the original object');
+ test(function () {
+ assert_false( cloneobj === iframe.contentWindow.history.state );
+ }, 'history.state should be a clone of the original object, not a reference to it');
+ history.go(-1);
+ setTimeout(tests8,50); //.go is queued to end of thread
+ }
+ function tests8() {
+ var eventtime = setTimeout(function () { tests9(false); },500); //should be cleared by the event handler long before it has a chance to fire
+ iframe.contentWindow.addEventListener('popstate',function (e) { clearTimeout(eventtime); tests9(true,e); },false);
+ history.forward();
+ }
+ function tests9(hasFired,ev) {
+ test(function () {
+ assert_true( hasFired );
+ }, 'popstate event should fire when navigation occurs');
+ test(function () {
+ assert_true( !!ev && typeof(ev.state) != 'undefined', 'state information was not passed' );
+ assert_true( !!ev.state, 'state information does not contain the expected value - browser is probably stuck in the wrong history position' );
+ assert_equals( ev.state.nulldata, null, 'state null data was not correct' );
+ assert_equals( ev.state.udefdata, window.undefined, 'state undefined data was not correct' );
+ assert_true( ev.state.booldata, 'state boolean data was not correct' );
+ assert_equals( ev.state.numdata, 1, 'state numeric data was not correct' );
+ assert_equals( ev.state.strdata, 'string data', 'state string data was not correct' );
+ assert_true( !!ev.state.datedata.getTime, 'state date data was not correct' );
+ assert_exists( ev.state, 'regdata', 'state regex data was not correct' );
+ assert_equals( ev.state.regdata.source, 'a', 'state regex pattern data was not correct' );
+ assert_true( ev.state.regdata.global, 'state regex flag data was not correct' );
+ assert_equals( ev.state.regdata.lastIndex, 0, 'state regex lastIndex data was not correct' );
+ assert_equals( ev.state.arrdata.length, 1, 'state array data was not correct' );
+ assert_true( ev.state.boolobj.valueOf(), 'state boolean data was not correct' );
+ assert_equals( ev.state.numobj.valueOf(), 1, 'state numeric data was not correct' );
+ assert_equals( ev.state.strobj.valueOf(), 'string data', 'state string data was not correct' );
+ if( canvassup ) {
+ assert_equals( ev.state.imgdata.width, 1, 'state ImageData was not correct' );
+ }
+ }, 'popstate event should pass the state data');
+ test(function () {
+ assert_equals( ev.state.looped, ev.state );
+ }, 'state data should cope with circular object references');
+ test(function () {
+ assert_false( cloneobj === ev.state );
+ }, 'state data should be a clone of the original object, not a reference to it');
+ test(function () {
+ assert_equals( iframe.contentWindow.history.state && iframe.contentWindow.history.state.strdata, 'string data' );
+ }, 'history.state should also reference a clone of the original object (2)');
+ test(function () {
+ assert_false( cloneobj === iframe.contentWindow.history.state );
+ }, 'history.state should be a clone of the original object, not a reference to it (2)');
+ test(function () {
+ assert_false( iframe.contentWindow.history.state === ev.state );
+ }, 'history.state should be a separate clone of the object, not a reference to the object passed to the event handler');
+ try {
+ iframe.contentWindow.persistval = true;
+ iframe.contentWindow.history.replaceState('','', location.href.replace(/\/[^\/]*$/,'/blank3.html') );
+ } catch(unsuperr) {}
+ //it's already cached, so this should be very fast if the browser mistakenly loads it
+ //it should not need to load at all, since it's just a pushed state
+ setTimeout(tests10,1000);
+ }
+ function tests10() {
+ test(function () {
+ assert_true( iframe.contentWindow.persistval && !iframe.contentWindow.forreal );
+ }, 'replaceState should not actually load the new URL');
+ atstep = 3;
+ iframe.contentWindow.location.reload(); //load the real URL
+ lasttimer = setTimeout(function () { tests11(false); },3000); //should be cleared by the onload handler long before it has a chance to fire
+ }
+ function tests11(passed) {
+ test(function () {
+ assert_true( passed, 'expected a load event to fire when reloading the URL from cache, gave up waiting after 3 seconds' );
+ }, 'reloading a replaced state should actually load the new URL');
+ //try to make browsers behave when reloading so that the correct URL is recovered - does not always work
+ iframe.contentWindow.location.href = location.href.replace(/\/[^\/]*$/,'/blank.html');
+ done();
+ }
+
+ if( atstep == 1 ) {
+ //blank2 has loaded
+ atstep = 2;
+ //use a timeout, because some browsers intentionally do not add history entries for URL changes in an onload thread
+ setTimeout(tests1,100);
+ } else if( atstep == 3 ) {
+ //blank3 should now have loaded after the .reload() command
+ atstep = 4;
+ clearTimeout(lasttimer);
+ tests11(true);
+ }
+}
+
+
+
+ </script>
+ </head>
+ <body>
+
+ <noscript><p>Enable JavaScript and reload</p></noscript>
+ <p>WARNING: This test should always be loaded in a new tab/window, to avoid browsers attempting to recover the state of frames, and history length. Do not reload the test.</p>
+ <div id="log">Running test...</div>
+ <p><iframe onload="reportload();" src="blank.html"></iframe></p>
+ <p><iframe src="blank.html"></iframe></p>
+ <p><iframe src="blank2.html"></iframe></p>
+ <p><iframe src="blank3.html"></iframe></p>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/004.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/004.html
new file mode 100644
index 000000000..e69889724
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/004.html
@@ -0,0 +1,62 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Final history position for history.go should be calculated when executing the task</title>
+ <script type="text/javascript" src="/resources/testharness.js"></script>
+ <script type="text/javascript" src="/resources/testharnessreport.js"></script>
+ <script type="text/javascript">
+setup({explicit_done:true});
+window.onload = function () {
+ var hashcount = 0;
+ if( location.hash && location.hash != '#' ) {
+ location.href = location.href.replace(/#.*$/,'');
+ return;
+ }
+ setTimeout(add1,100);
+ function add1() {
+ location.hash = '#foo';
+ setTimeout(add2,100);
+ }
+ function add2() {
+ location.hash = '#bar';
+ setTimeout(add3,100);
+ }
+ function add3() {
+ location.hash = '#baz';
+ setTimeout(dojumps,100);
+ }
+ function dojumps() {
+ window.onhashchange = function () {
+ hashcount++;
+ };
+ history.go(-2);
+ test(function () {
+ //many browsers special-case jumps that only imply hash changes and will do them synchronously - the spec does allow this
+ assert_equals( hashcount, 0, 'hashchange fired even though the location should not have changed' );
+ assert_equals( location.hash.replace(/^#/,''), 'baz', 'the browser navigated synchronously' );
+ }, '.go commands should be queued until the thread has ended');
+ history.go(-1);
+ setTimeout(checkjumps,100);
+ }
+ function checkjumps() {
+ test(function () {
+ assert_true( !!hashcount, 'this testcase requires haschange support; the test cannot be used in this browser' );
+ }, 'browser needs to support hashchange events for this testcase');
+ test(function () {
+ assert_equals( hashcount, 2, 'the wrong number of queued commands were executed' );
+ }, 'queued .go commands should all be executed when the queue is processed');
+ test(function () {
+ assert_equals( location.hash.replace(/^#/,''), '' );
+ }, 'history position should be calculated when executing, not when calling the .go command');
+ done();
+ }
+};
+ </script>
+ </head>
+ <body>
+
+ <noscript><p>Enable JavaScript and reload</p></noscript>
+ <div id="log"></div>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/005.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/005.html
new file mode 100644
index 000000000..2152e85a3
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/005.html
@@ -0,0 +1,47 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Popstate event listener registration</title>
+ <script type="text/javascript" src="/resources/testharness.js"></script>
+ <script type="text/javascript" src="/resources/testharnessreport.js"></script>
+ <script type="text/javascript">
+
+//this test checks that onpopstate works on the body element
+
+var readyForPop = false, bodypop = false, inlinepop = false;
+setup({explicit_done:true});
+
+//use a timeout to avoid "popstate fires onload" from setting the variables too early
+setTimeout(step1,1000);
+function step1() {
+ readyForPop = true;
+ test(function () {
+ history.pushState('','');
+ history.pushState('','');
+ }, 'history.pushState support is needed for this testcase');
+ history.go(-1);
+ setTimeout(step2,50); //.go is queued to end of thread
+}
+function step2() {
+ test(function () {
+ assert_true( bodypop );
+ }, '<body onpopstate="..."> should register a listener for the popstate event');
+ window.onpopstate = function () { inlinepop = true; };
+ history.go(-1);
+ setTimeout(step3,50); //.go is queued to end of thread
+}
+function step3() {
+ test(function () {
+ assert_true( inlinepop );
+ }, 'window.onpopstate should register a listener for the popstate event');
+ done();
+}
+ </script>
+ </head>
+ <body onpopstate="if( readyForPop ) { bodypop = true; }">
+
+ <noscript><p>Enable JavaScript and reload</p></noscript>
+ <div id="log"></div>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/006.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/006.html
new file mode 100644
index 000000000..442b6f8f1
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/006.html
@@ -0,0 +1,53 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Firing popstate after onload, even if there is no pushed/replaced state</title>
+ <script type="text/javascript" src="/resources/testharness.js"></script>
+ <script type="text/javascript" src="/resources/testharnessreport.js"></script>
+ <script type="text/javascript">
+
+//spec (25 March 2011 draft) states that popstate must not fire after onload unless there is a pushed/replaced state that is navigated
+var popfired = false;
+setup({explicit_done:true});
+window.addEventListener('popstate',function (e) { popfired = true; },false);
+test(function () {
+ assert_equals( history.state, null );
+}, 'history.state should initially be null');
+window.onload = function () {
+ test(function () {
+ assert_false( popfired );
+ }, 'popstate event should not fire before onload fires');
+ test(function () {
+ assert_equals( history.state, null );
+ }, 'history.state should still be null onload');
+ popfired = false;
+ setTimeout(function () {
+ test(function () {
+ assert_false( popfired );
+ }, 'popstate event should not fire after onload fires');
+ test(function () {
+ assert_equals( history.state, null );
+ }, 'history.state should still be null after onload');
+ test(function () {
+ var failed = false, realstate = history.state;
+ try {
+ history.state = '';
+ } catch(e) {
+ failed = e;
+ }
+ assert_equals(history.state,realstate,'property was read/write');
+ assert_false(failed);
+ }, 'writing to history.state should be silently ignored and not throw an error');
+ done();
+ },100);
+};
+
+ </script>
+ </head>
+ <body>
+
+ <noscript><p>Enable JavaScript and reload</p></noscript>
+ <div id="log"></div>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/007.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/007.html
new file mode 100644
index 000000000..29ed8bf0e
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/007.html
@@ -0,0 +1,56 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Firing popstate after onload with pushed state</title>
+ <meta name=timeout content=long>
+ <script type="text/javascript" src="/resources/testharness.js"></script>
+ <script type="text/javascript" src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+
+ <noscript><p>Enable JavaScript and reload</p></noscript>
+ <div id="log">It looks like the browser stopped loading the page when encountering a .go(-1) command pointing to a pushed state. This will break the tests.</div>
+ <script type="text/javascript">
+
+//spec (25 March 2011 draft) states that popstate must fire before onload if there is a pushed/replaced state that is navigated
+var popfired = false;
+setup({explicit_done:true});
+test(function () {
+ assert_equals( history.state, null );
+}, 'history.state should initially be null');
+window.addEventListener('popstate',function (e) { popfired = e.state; },false);
+test(function () {
+ history.pushState('state1','');
+ history.pushState('state2','');
+}, 'history.pushState support is needed for this testcase');
+test(function () {
+ assert_equals( history.state, 'state2' );
+}, 'history.state should reflect pushed state');
+if( history.pushState ) { history.go(-1); }
+window.onload = function () {
+ test(function () {
+ assert_true( !!popfired );
+ }, 'popstate event should fire before onload fires');
+ test(function () {
+ assert_equals( popfired, 'state1' );
+ }, 'the correct state should be restored when navigating during initial load');
+ test(function () {
+ assert_equals( history.state, 'state1' );
+ }, 'history.state should reflect the navigated state onload');
+ popfired = false;
+ setTimeout(function () {
+ test(function () {
+ assert_false( !!popfired );
+ }, 'popstate event should not fire after onload fires');
+ test(function () {
+ assert_equals( history.state, 'state1' );
+ }, 'history.state should reflect the navigated state after onload');
+ done();
+ if( history.pushState ) { history.go(-1); } //go back to the start to avoid state recovery when reloading
+ },100);
+};
+
+ </script>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/008.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/008.html
new file mode 100644
index 000000000..c8071e315
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/008.html
@@ -0,0 +1,40 @@
+<!doctype html>
+<html>
+
+<!-- configure this test below to point to the script -->
+
+ <head>
+ <title>history.pushState/replaceState resolving</title>
+ <script type="text/javascript" src="/resources/testharness.js"></script>
+ <script type="text/javascript" src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+
+ <p></p>
+ <noscript><p>Enable JavaScript and reload</p></noscript>
+ <div id="log"></div>
+ <script type="text/javascript">
+
+/*
+Location of the script (which must be hosted on a separate domain from this test) containing the test code:
+var beforehref = location.href;
+test(function () {
+ history.pushState('','','/testing_ignore_me_404');
+ assert_equals(location.href,beforehref.replace(/^(\w*:\/\/[^\/]*\/)[\w\W]*$/,'$1testing_ignore_me_404'));
+}, 'history.pushState URL resolving should be done relative to the document, not the script');
+test(function () {
+ history.replaceState('','','/testing_ignore_me_404_2');
+ assert_equals(location.href,beforehref.replace(/^(\w*:\/\/[^\/]*\/)[\w\W]*$/,'$1testing_ignore_me_404_2'));
+}, 'history.replaceState URL resolving should be done relative to the document, not the script');
+*/
+var scriptlocation = 'http://www.' + location.host + location.pathname.split("/").slice(0,-1).join("/") + "/008.js";
+
+if( location.protocol == 'file:' ) {
+ document.getElementsByTagName('p')[0].innerHTML = 'ERROR: This test cannot be run from file: (URL resolving will not work). It must be loaded over HTTP.';
+} else {
+ document.write('<script type="text\/javascript" src="'+scriptlocation+'"><\/script>');
+}
+ </script>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/008.js b/testing/web-platform/tests/html/browsers/history/the-history-interface/008.js
new file mode 100644
index 000000000..96a1fe5d4
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/008.js
@@ -0,0 +1,11 @@
+var beforehref = location.href;
+
+test(function () {
+ history.pushState('','','/testing_ignore_me_404');
+ assert_equals(location.href,beforehref.replace(/^(\w*:\/\/[^\/]*\/)[\w\W]*$/,'$1testing_ignore_me_404'));
+}, 'history.pushState URL resolving should be done relative to the document, not the script');
+
+test(function () {
+ history.replaceState('','','/testing_ignore_me_404_2');
+ assert_equals(location.href,beforehref.replace(/^(\w*:\/\/[^\/]*\/)[\w\W]*$/,'$1testing_ignore_me_404_2'));
+}, 'history.replaceState URL resolving should be done relative to the document, not the script');
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/009-1.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/009-1.html
new file mode 100644
index 000000000..00b72e8ec
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/009-1.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<html>
+ <head>
+ <title>history.pushState/replaceState and referer headers</title>
+ </head>
+ <body>
+
+ <noscript><p>Enable JavaScript and reload</p></noscript>
+ <div id="log"></div>
+ <script type="text/javascript">
+window.onload = function () {
+ setTimeout(function () {
+ try { history.pushState('','','009-2.html?1234'); } catch(e) {}
+ location.href = '009-3.html?pipe=sub';
+ },10);
+};
+ </script>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/009-3.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/009-3.html
new file mode 100644
index 000000000..e58b8fa5e
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/009-3.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<html>
+ <head>
+ <title>history.pushState/replaceState and referer headers</title>
+ </head>
+ <body>
+
+ <noscript><p>Enable JavaScript and reload</p></noscript>
+ <div id="log"></div>
+ <script type="text/javascript">
+var httpReferer = "{{headers[referer]}}";
+var lastUrl = location.href.replace(/\/[^\/]*$/,'\/009-2.html?1234');
+parent.test(function () {
+ parent.assert_equals( httpReferer, lastUrl );
+}, 'HTTP Referer should use the pushed state');
+parent.test(function () {
+ parent.assert_equals( document.referrer, lastUrl );
+}, 'document.referrer should use the pushed state');
+window.onload = function () {
+ setTimeout(function () {
+ try { history.pushState('','','009-4.html?2345'); } catch(e) {}
+ location.href = '009-5.html?pipe=sub';
+ },10);
+};
+ </script>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/009-5.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/009-5.html
new file mode 100644
index 000000000..068a089af
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/009-5.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<html>
+ <head>
+ <title>history.pushState/replaceState and referer headers</title>
+ </head>
+ <body>
+
+ <noscript><p>Enable JavaScript and reload</p></noscript>
+ <div id="log"></div>
+ <script type="text/javascript">
+var httpReferer = unescape("{{headers[referer]}}");
+var lastUrl = location.href.replace(/\/[^\/]*$/,'\/009-4.html?2345');
+parent.test(function () {
+ parent.assert_equals( httpReferer, lastUrl );
+}, 'HTTP Referer should use the replaced state');
+parent.test(function () {
+ parent.assert_equals( document.referrer, lastUrl );
+}, 'document.referrer should use the replaced state');
+parent.done();
+ </script>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/009.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/009.html
new file mode 100644
index 000000000..c1ae0bbe0
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/009.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<html>
+ <head>
+ <title>history.pushState/replaceState and referer headers</title>
+ <script type="text/javascript" src="/resources/testharness.js"></script>
+ <script type="text/javascript" src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+
+ <noscript><p>Enable JavaScript and reload</p></noscript>
+ <div id="log"></div>
+ <script type="text/javascript">
+setup({explicit_done:true});
+var iframe = document.createElement('iframe');
+window.onload = function () {
+ iframe.setAttribute('src','009-1.html');
+ document.body.appendChild(iframe)
+};
+ </script>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/010-1.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/010-1.html
new file mode 100644
index 000000000..683397745
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/010-1.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<html>
+ <head>
+ <title>history.pushState/replaceState and referer headers (before onload)</title>
+ </head>
+ <body>
+
+ <noscript><p>Enable JavaScript and reload</p></noscript>
+ <div id="log"></div>
+ <script type="text/javascript">
+try { history.pushState('','','010-2.html?1234'); } catch(e) {}
+location.href = '010-3.html?pipe=sub';
+ </script>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/010-3.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/010-3.html
new file mode 100644
index 000000000..b80f56c3d
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/010-3.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<html>
+ <head>
+ <title>history.pushState/replaceState and referer headers (before onload)</title>
+ </head>
+ <body>
+
+ <noscript><p>Enable JavaScript and reload</p></noscript>
+ <div id="log"></div>
+ <script type="text/javascript">
+ var httpReferer = "{{headers[referer]}}";
+var lastUrl = location.href.replace(/\/[^\/]*$/,'\/010-2.html?1234');
+parent.test(function () {
+ parent.assert_equals( httpReferer, lastUrl );
+}, 'HTTP Referer should use the pushed state (before onload)');
+parent.test(function () {
+ parent.assert_equals( document.referrer, lastUrl );
+}, 'document.referrer should use the pushed state (before onload)');
+try { history.pushState('','','010-4.html?2345'); } catch(e) {}
+location.href = '010-5.html?pipe=sub';
+ </script>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/010-5.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/010-5.html
new file mode 100644
index 000000000..d150449eb
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/010-5.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<html>
+ <head>
+ <title>history.pushState/replaceState and referer headers (before onload)</title>
+ </head>
+ <body>
+
+ <noscript><p>Enable JavaScript and reload</p></noscript>
+ <div id="log"></div>
+ <script type="text/javascript">
+var httpReferer = "{{headers[referer]}}";
+var lastUrl = location.href.replace(/\/[^\/]*$/,'\/010-4.html?2345');
+parent.test(function () {
+ parent.assert_equals( httpReferer, lastUrl );
+}, 'HTTP Referer should use the replaced state (before onload)');
+parent.test(function () {
+ parent.assert_equals( document.referrer, lastUrl );
+}, 'document.referrer should use the replaced state (before onload)');
+parent.done();
+ </script>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/010.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/010.html
new file mode 100644
index 000000000..ca109a744
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/010.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<html>
+ <head>
+ <title>history.pushState/replaceState and referer headers (before onload)</title>
+ <script type="text/javascript" src="/resources/testharness.js"></script>
+ <script type="text/javascript" src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+
+ <noscript><p>Enable JavaScript and reload</p></noscript>
+ <div id="log"></div>
+ <script type="text/javascript">
+setup({explicit_done:true});
+var iframe = document.createElement('iframe');
+window.onload = function () {
+ iframe.setAttribute('src','010-1.html');
+ document.body.appendChild(iframe)
+};
+ </script>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/011.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/011.html
new file mode 100644
index 000000000..4043aff7f
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/011.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<html>
+ <head>
+ <title>history.pushState before onload</title>
+ <script type="text/javascript" src="/resources/testharness.js"></script>
+ <script type="text/javascript" src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+
+ <noscript><p>Enable JavaScript and reload</p></noscript>
+ <div id="log"></div>
+ <script type="text/javascript">
+var newUrl = location.href.replace(/\/[^\/]*$/,'\/011-1.html');
+setup({explicit_done:true});
+test(function () {
+ history.pushState('','','011-1.html');
+}, 'pushState should be able to set the location state');
+test(function () {
+ assert_equals( location.href, newUrl );
+}, 'pushed location should be reflected immediately');
+window.onload = function () {
+ setTimeout(function () {
+ test(function () {
+ assert_equals( location.href, newUrl );
+ }, 'pushed location should be retained after the page has loaded');
+ done();
+ },10);
+};
+ </script>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/012.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/012.html
new file mode 100644
index 000000000..f5e625167
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/012.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<html>
+ <head>
+ <title>history.replaceState before onload</title>
+ <script type="text/javascript" src="/resources/testharness.js"></script>
+ <script type="text/javascript" src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+
+ <noscript><p>Enable JavaScript and reload</p></noscript>
+ <div id="log"></div>
+ <script type="text/javascript">
+var newUrl = location.href.replace(/\/[^\/]*$/,'\/011-1.html');
+setup({explicit_done:true});
+test(function () {
+ history.replaceState('','','011-1.html');
+}, 'replaceState should be able to set the location state');
+test(function () {
+ assert_equals( location.href, newUrl );
+}, 'replaced location should be reflected immediately');
+window.onload = function () {
+ setTimeout(function () {
+ test(function () {
+ assert_equals( location.href, newUrl );
+ }, 'replaced location should be retained after the page has loaded');
+ done();
+ },10);
+};
+ </script>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/blank.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/blank.html
new file mode 100644
index 000000000..89c8724c0
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/blank.html
@@ -0,0 +1,8 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Dummy page 1</title>
+ </head>
+ <body>
+ </body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/blank2.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/blank2.html
new file mode 100644
index 000000000..f79982e32
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/blank2.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Dummy page 2</title>
+ </head>
+ <body>
+ <script type="text/javascript">
+if( self == top || !parent.reportload ) {
+ document.write("<p>FAIL. Browser got confused when navigating forwards, and navigated the whole window to the iframe's location, instead of just navigating the iframe. It is not possible to run the testsuite.<\/p>");
+}
+ </script>
+ </body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/blank3.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/blank3.html
new file mode 100644
index 000000000..2a8989f27
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/blank3.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Dummy page 3</title>
+ <script type="text/javascript">
+var forreal = true;
+ </script>
+ </head>
+ <body>
+ </body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/combination_history_001.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/combination_history_001.html
new file mode 100644
index 000000000..21ba22f6f
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/combination_history_001.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>combination_history_001(Combine pushState and replaceSate methods.)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function () {
+ window.history.pushState(1, document.title, '?x=1');
+ assert_equals(history.state, 1, "first");
+
+ window.history.replaceState(2, document.title, '?x=1');
+ assert_equals(history.state, 2, "second")
+ }, "Combine pushState and replaceSate methods");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/combination_history_002.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/combination_history_002.html
new file mode 100644
index 000000000..29e82f51b
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/combination_history_002.html
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>combination_history_002(After calling of pushState method, check length.)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function () {
+ var first;
+ var second;
+ first = window.history.length;
+ window.history.pushState(1, document.title, '?x=1');
+ second = window.history.length;
+
+ assert_equals(second - first, 1, "second - first");
+ }, "After calling of pushState method, check length");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/combination_history_003.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/combination_history_003.html
new file mode 100644
index 000000000..7467d9b29
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/combination_history_003.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>combination_history_003(After calling of pushState and replaceState methods, check length.)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function () {
+ var first;
+ var second;
+ var third;
+ first = window.history.length;
+ window.history.pushState(1, document.title, '?x=1');
+ second = window.history.length;
+ window.history.replaceState(2, document.title, '?x=2');
+ third = window.history.length;
+
+ assert_equals(second - first, 1, "second - first");
+ assert_equals(third, second, "third");
+ }, "After calling of pushState and replaceState methods, check length");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/combination_history_004.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/combination_history_004.html
new file mode 100644
index 000000000..4e38b5620
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/combination_history_004.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>combination_history_004(After calling of back method, check length.)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var t = async_test("After calling of back method, check length");
+
+ var last;
+ t.step(function () {
+ window.history.pushState(1, document.title, '?x=1');
+ window.history.pushState(2, document.title, '?x=2');
+ last = window.history.length;
+
+ window.history.back();
+ });
+
+ window.addEventListener('popstate', t.step_func(function(e) {
+ assert_equals(e.state, 1, "state");
+ assert_equals(window.history.length, last, "last");
+ t.done();
+ }), false);
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/combination_history_005.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/combination_history_005.html
new file mode 100644
index 000000000..448767801
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/combination_history_005.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>combination_history_005(After calling of forward method, check length.)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var t = async_test("After calling of forward method, check length");
+
+ var last;
+ var fired = false;
+ t.step(function () {
+ window.history.pushState(1, document.title, '?x=1');
+ window.history.pushState(2, document.title, '?x=2');
+ last = window.history.length;
+
+ window.history.back();
+ });
+
+ window.addEventListener('popstate', t.step_func(function(e) {
+ if(fired) {
+ assert_equals(e.state, 2, "state");
+ assert_equals(window.history.length, last, "last");
+ t.done();
+ }
+ fired = true;
+ window.history.forward();
+ }), false);
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/combination_history_006.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/combination_history_006.html
new file mode 100644
index 000000000..305f593c0
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/combination_history_006.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>combination_history_006(After calling of go method, check length.)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var t = async_test("After calling of go method, check length");
+
+ var last;
+ t.step(function () {
+ window.history.pushState(1, document.title, '?x=1');
+ window.history.pushState(2, document.title, '?x=2');
+
+ last = window.history.length;
+
+ window.history.go(-1);
+ });
+
+ window.addEventListener('popstate', t.step_func(function(e) {
+ assert_equals(e.state, 1, "state");
+ assert_equals(window.history.length, last, "last");
+ t.done();
+ }), false);
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/combination_history_007.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/combination_history_007.html
new file mode 100644
index 000000000..cec9ea098
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/combination_history_007.html
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>combination_history_007(After calling of back and pushState method, check length.)</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var t = async_test("After calling of back and pushState method, check length");
+
+ var last;
+ t.step(function () {
+ window.history.pushState(1, document.title, '?x=1');
+ window.history.pushState(2, document.title, '?x=2');
+
+ last = window.history.length;
+
+ window.history.back();
+ });
+
+ window.addEventListener('popstate', t.step_func(function(e) {
+ assert_equals(e.state, 1, "state");
+ assert_equals(window.history.length, last, "last");
+ window.history.pushState(3, document.title, '?x=3');
+ assert_equals(window.history.length, last, "last");
+ t.done();
+ }), false);
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/history.js b/testing/web-platform/tests/html/browsers/history/the-history-interface/history.js
new file mode 100644
index 000000000..bb5ee6dde
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/history.js
@@ -0,0 +1,35 @@
+function parse_query() {
+ var query = location.search.slice(1);
+ var vars = query.split("&");
+ var fields = {};
+ vars.forEach(
+ function (x) {
+ var split = x.split("=");
+ return fields[split[0]] = split.slice(1).join("=");
+ });
+ return fields;
+}
+
+var query_parts = parse_query();
+var id = "id" in query_parts ? parseInt(query_parts.id) : 1;
+var urls_to_load = query_parts.urls.split(",");
+
+document.write(id);
+
+onunload = function() {};
+
+function queue_next() {
+ t = opener.t;
+ setTimeout(t.step_func(
+ function() {
+// opener.assert_equals(history.length, id);
+ if (urls_to_load[0]) {
+ var next_page = urls_to_load[0];
+ (next_page.indexOf("?") > -1) ? (next_page += "&") : (next_page += "?");
+ next_page += "urls=" + urls_to_load.slice(1).join(",");
+ next_page += "&id=" + ++id;
+ location = next_page;
+ }
+ }
+ ), 100);
+}
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/history_back-1.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_back-1.html
new file mode 100644
index 000000000..78547019f
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_back-1.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<script src="history.js"></script>
+<script>
+ onunload = function() {}
+
+ opener.pages.push(id);
+ if (!opener.started) {
+ onload = function() {
+ setTimeout(function() {
+ opener.started = true;
+ history.back();
+ }, 100);
+ }
+ } else {
+ opener.start_test_wait();
+ }
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/history_back.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_back.html
new file mode 100644
index 000000000..042da4e61
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_back.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>history_back</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var t = async_test("history back");
+
+ t.step(function () {
+ window.history.pushState(1, document.title, '?x=1');
+ window.history.pushState(2, document.title, '?x=2');
+
+ window.history.back();
+ });
+
+ window.addEventListener('popstate', t.step_func(function(e) {
+ assert_equals(e.state, 1, "history state");
+
+ t.done();
+ }), false);
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/history_back_1.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_back_1.html
new file mode 100644
index 000000000..cc37ddd35
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_back_1.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<title>history.back() with session history</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+ var t = async_test(undefined, {timeout:5000});
+ started = false;
+ pages = []
+ timer = null;
+ start_test_wait = t.step_func(
+ function() {
+ clearTimeout(timer);
+ timer = setTimeout(t.step_func(
+ function() {
+ try {
+ assert_array_equals(pages, [2, 1], "Pages opened during history navigation");
+ t.done();
+ } finally {
+ win.close();
+ }
+ }
+ ), 500);
+ }
+ );
+ t.step(function() {win = window.open("history_entry.html?urls=history_back-1.html");
+});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/history_entry.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_entry.html
new file mode 100644
index 000000000..e5929ddbe
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_entry.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<script src="history.js"></script>
+<script>
+ onload = function() {
+ if (!opener.started) {
+ queue_next();
+ } else {
+ opener.pages.push(id);
+ opener.start_test_wait();
+ }
+};
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/history_forward-1.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_forward-1.html
new file mode 100644
index 000000000..5880eacf0
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_forward-1.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<script src="history.js"></script>
+<script>
+ onunload = function() {}
+
+ onload = function() {
+ if (!opener.started) {
+ queue_next();
+ } else {
+ opener.pages.push(id);
+ opener.start_test_wait();
+ history.forward();
+ }
+ };
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/history_forward-2.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_forward-2.html
new file mode 100644
index 000000000..c7a9a1068
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_forward-2.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<script src="history.js"></script>
+<script>
+ onunload = function() {}
+
+ opener.pages.push(id);
+ if (!opener.started) {
+ onload = function() {
+ setTimeout(function() {
+ opener.started = true;
+ history.go(-1);
+ }, 100);
+ }
+ } else {
+ opener.start_test_wait();
+ }
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/history_forward.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_forward.html
new file mode 100644
index 000000000..6c37f2521
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_forward.html
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>history_forward</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var t = async_test("history forward");
+
+ var fired = false;
+ t.step(function () {
+ window.history.pushState(1, document.title, '?x=1');
+ window.history.pushState(2, document.title, '?x=2');
+
+ window.history.back();
+ });
+
+ window.addEventListener('popstate', t.step_func(function(e) {
+ if(fired) {
+ assert_equals(e.state, 2, "history state");
+
+ t.done();
+ }
+ fired = true;
+ window.history.forward();
+ }), false);
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/history_forward_1.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_forward_1.html
new file mode 100644
index 000000000..3d119482c
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_forward_1.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<title>history.forward() with session history</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+ var t = async_test(undefined, {timeout:5000});
+ started = false;
+ pages = []
+ timer = null;
+ start_test_wait = t.step_func(
+ function() {
+ clearTimeout(timer);
+ timer = setTimeout(t.step_func(
+ function() {
+ try {
+ assert_array_equals(pages, [3, 2, 3], "Pages opened during history navigation");
+ t.done();
+ } finally {
+ win.close();
+ }
+ }
+ ), 500);
+ }
+ );
+ t.step(function() {win = window.open("history_entry.html?urls=history_forward-1.html,history_forward-2.html");
+});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_minus.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_minus.html
new file mode 100644
index 000000000..b8fe75573
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_minus.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>history_go_minus</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var t = async_test("history go minus");
+
+ t.step(function () {
+ window.history.pushState(1, document.title, '?x=1');
+ window.history.pushState(2, document.title, '?x=2');
+
+ window.history.go(-1);
+ });
+
+ window.addEventListener('popstate', t.step_func(function(e) {
+ assert_equals(e.state, 1, "history state");
+
+ t.done();
+ }), false);
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_no_argument-1.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_no_argument-1.html
new file mode 100644
index 000000000..acd9bda31
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_no_argument-1.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<script src="history.js"></script>
+<script>
+ onunload = function() {}
+
+ onload = function() {
+ if (!opener.started) {
+ queue_next();
+ } else {
+ opener.pages.push(id);
+ opener.start_test_wait();
+ if (!opener.gone) {
+ history.go();
+ opener.gone = true;
+ }
+ }
+ };
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_no_argument.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_no_argument.html
new file mode 100644
index 000000000..278cf86c2
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_no_argument.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<title>history.go()</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+ var t = async_test(undefined, {timeout:5000});
+ started = false;
+ gone = false;
+ pages = []
+ timer = null;
+ start_test_wait = t.step_func(
+ function() {
+ clearTimeout(timer);
+ timer = setTimeout(t.step_func(
+ function() {
+ try {
+ assert_array_equals(pages, [3, 2, 2], "Pages opened during history navigation");
+ t.done();
+ } finally {
+ win.close();
+ }
+ }
+ ), 500);
+ }
+ );
+ t.step(function() {win = window.open("history_entry.html?urls=history_go_no_argument-1.html,history_forward-2.html");
+});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_plus.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_plus.html
new file mode 100644
index 000000000..74d4c588c
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_plus.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>history_go_plus</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ var t = async_test("history go plus");
+
+ var fired = false;
+ t.step(function () {
+ window.history.pushState(1, document.title, '?x=1');
+ window.history.pushState(2, document.title, '?x=2');
+
+ window.history.back();
+ });
+
+ window.addEventListener('popstate', t.step_func(function(e) {
+ if(fired) {
+ assert_equals(e.state, 2, "history state");
+
+ t.done();
+ }
+ fired = true;
+ window.history.go(1);
+
+ }), false);
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_undefined-1.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_undefined-1.html
new file mode 100644
index 000000000..5880eacf0
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_undefined-1.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<script src="history.js"></script>
+<script>
+ onunload = function() {}
+
+ onload = function() {
+ if (!opener.started) {
+ queue_next();
+ } else {
+ opener.pages.push(id);
+ opener.start_test_wait();
+ history.forward();
+ }
+ };
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_undefined.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_undefined.html
new file mode 100644
index 000000000..e2a40275e
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_undefined.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<title>history.forward() with session history</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+ var t = async_test(undefined, {timeout:5000});
+ started = false;
+ pages = []
+ timer = null;
+ start_test_wait = t.step_func(
+ function() {
+ clearTimeout(timer);
+ timer = setTimeout(t.step_func(
+ function() {
+ try {
+ assert_array_equals(pages, [3, 2, 2], "Pages opened during history navigation");
+ t.done();
+ } finally {
+ win.close();
+ }
+ }
+ ), 500);
+ }
+ );
+ t.step(function() {win = window.open("history_entry.html?urls=history_go_undefined-1.html,history_forward-2.html");
+});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_zero-1.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_zero-1.html
new file mode 100644
index 000000000..d9d4f330b
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_zero-1.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<script src="history.js"></script>
+<script>
+ onunload = function() {}
+
+ onload = function() {
+ if (!opener.started) {
+ queue_next();
+ } else {
+ opener.pages.push(id);
+ opener.start_test_wait();
+ if (!opener.gone) {
+ history.go(0);
+ opener.gone = true;
+ }
+ }
+ };
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_zero.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_zero.html
new file mode 100644
index 000000000..685878383
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_go_zero.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<title>history.go(0)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+ var t = async_test(undefined, {timeout:5000});
+ started = false;
+ gone = false;
+ pages = []
+ timer = null;
+ start_test_wait = t.step_func(
+ function() {
+ clearTimeout(timer);
+ timer = setTimeout(t.step_func(
+ function() {
+ try {
+ assert_array_equals(pages, [3, 2, 2], "Pages opened during history navigation");
+ t.done();
+ } finally {
+ win.close();
+ }
+ }
+ ), 500);
+ }
+ );
+ t.step(function() {win = window.open("history_entry.html?urls=history_go_zero-1.html,history_forward-2.html");
+});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/history_pushstate.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_pushstate.html
new file mode 100644
index 000000000..5180a3f6e
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_pushstate.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>history_pushState</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function () {
+ window.history.pushState(1, document.title, '?x=1');
+ var state;
+ state = window.history.state;
+ assert_equals(state, 1, "history state");
+ }, "history pushState");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/history_pushstate_err.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_pushstate_err.html
new file mode 100644
index 000000000..82afc04f2
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_pushstate_err.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>history_pushState SECURITY_ERR</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function () {
+ assert_throws("SecurityError", function () {
+ window.history.pushState(1, document.title, 'http://www.microsoft.com/test.html');
+ });
+ }, "history pushState SECURITY_ERR");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/history_pushstate_nooptionalparam.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_pushstate_nooptionalparam.html
new file mode 100644
index 000000000..8e4b049a1
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_pushstate_nooptionalparam.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>history_pushState_NoOptionalParam</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function () {
+ window.history.pushState(1, document.title);
+
+ var state;
+ state = window.history.state;
+ assert_equals(state, 1, "history state");
+ }, "history pushState NoOptionalParam");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/history_replacestate.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_replacestate.html
new file mode 100644
index 000000000..794c2f371
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_replacestate.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>history_replaceState</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function () {
+ window.history.replaceState(1, document.title, '?x=1');
+
+ var second;
+ second = window.history.state;
+ assert_equals(second, 1, "history state");
+ }, "history replaceState");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/history_replacestate_err.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_replacestate_err.html
new file mode 100644
index 000000000..3060cf1f1
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_replacestate_err.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>history_replaceState SECURITY_ERR</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function () {
+ assert_throws("SecurityError", function () {
+ window.history.replaceState(1, document.title, 'http://www.microsoft.com/test.html');
+ });
+ }, "history replaceState SECURITY_ERR");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/history_replacestate_nooptionalparam.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_replacestate_nooptionalparam.html
new file mode 100644
index 000000000..838467d78
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_replacestate_nooptionalparam.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>history_replaceStateNoOptionalParam</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function () {
+ window.history.replaceState(1, document.title);
+
+ var second;
+ second = window.history.state;
+ assert_equals(second, 1, "history state");
+ }, "history replaceStateNoOptionalParam");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/history_state.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_state.html
new file mode 100644
index 000000000..2ee2356b1
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_state.html
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>history_state</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function () {
+ var first;
+ var second;
+
+ first = window.history.state;
+ window.history.pushState(1, document.title, '?x=1');
+
+ second = window.history.state;
+ assert_equals(first, null, "first");
+ assert_equals(second, 1, "second");
+ }, "history state");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/joint_session_history/001-1.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/joint_session_history/001-1.html
new file mode 100644
index 000000000..9aa5d30d1
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/joint_session_history/001-1.html
@@ -0,0 +1,72 @@
+<!doctype html>
+<script>
+var o = opener;
+
+var frameloaded = null;
+
+o.t.step(function() {o.assert_equals(history.length, 1)});
+
+onload = function () {
+ o.t.step(function() {
+ o.assert_equals(history.length, 1);
+ o.t.done();
+ });
+
+ o.t1.step(function() {
+ var iframe = document.createElement("iframe");
+ iframe.src = "filler.html?id=2";
+ document.body.appendChild(iframe);
+ frameloaded = o.t1.step_func(function () {
+ o.assert_equals(history.length, 1);
+ setTimeout(o.t1.step_func(function () {
+ o.assert_equals(history.length, 1);
+ iframe.src = "filler.html?id=3";
+ frameloaded = o.t2.step_func(function() {
+ o.assert_equals(history.length, 2);
+ history.go(-1);
+ frameloaded = o.t3.step_func(function() {
+ o.assert_equals(history.length, 2);
+ var parts = iframe.contentWindow.location.href.split("/")
+ o.assert_equals(parts[parts.length - 1], "filler.html?id=2");
+ o.t3.done();
+ o.t4.step(function() {
+ var iframe0 = document.getElementsByTagName("iframe")[0];
+ iframe0.src = "filler.html?id=4"
+ frameloaded = o.t4.step_func(function() {
+ o.assert_equals(history.length, 2);
+ var parts = iframe0.contentWindow.location.href.split("/")
+ o.assert_equals(parts[parts.length - 1], "filler.html?id=4");
+ //This is the point at which gecko and webkit stop running tests
+ history.go(-1);
+ frameloaded = o.t5.step_func(function() {
+ o.assert_equals(history.length, 2);
+ var parts = iframe0.contentWindow.location.href.split("/")
+ o.assert_equals(parts[parts.length - 1], "filler.html?id=1");
+ var parts = iframe.contentWindow.location.href.split("/")
+ o.assert_equals(parts[parts.length - 1], "filler.html?id=2");
+ history.go(1);
+ frameloaded = o.t6.step_func(function() {
+ o.assert_equals(history.length, 2);
+ var parts = iframe0.contentWindow.location.href.split("/")
+ o.assert_equals(parts[parts.length - 1], "filler.html?id=4");
+ var parts = iframe.contentWindow.location.href.split("/")
+ o.assert_equals(parts[parts.length - 1], "filler.html?id=2");
+ o.t6.done();
+ });
+ o.t5.done();
+ });
+ o.t4.done();
+ });
+ });
+ });
+ o.t2.done();
+ });
+ o.t1.done();
+ }, 500))
+ });
+ });
+
+}
+</script>
+
+<iframe src="filler.html?id=1"></iframe>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/joint_session_history/001.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/joint_session_history/001.html
new file mode 100644
index 000000000..c9d1c6416
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/joint_session_history/001.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<title>Joint session history with single iframe</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+setup({timeout:10000});
+var t = async_test("Session history length on initial load");
+var t1 = async_test("Session history length on adding new iframe");
+var t2 = async_test("Navigating second iframe");
+var t3 = async_test("Traversing history back (1)");
+var t4 = async_test("Navigating first iframe");
+var t5 = async_test("Traversing history back (2)");
+var t6 = async_test("Traversing history forward");
+var w = window.open("001-1.html");
+//add_completion_callback(function() {w.close()});
+</script>
+
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/joint_session_history/002-1.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/joint_session_history/002-1.html
new file mode 100644
index 000000000..ed69d679d
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/joint_session_history/002-1.html
@@ -0,0 +1,35 @@
+<!doctype html>
+<script>
+var o = opener;
+
+var frameloaded = null;
+
+o.t.step(function() {o.assert_equals(history.length, 1)});
+
+onload = function () {
+ o.t.step(function() {
+ o.assert_equals(history.length, 1);
+ o.t.done();
+ });
+
+ o.t1.step(function() {
+ var iframe = document.createElement("iframe");
+ iframe.src = "filler.html?id=2";
+ document.body.appendChild(iframe);
+ o.assert_equals(history.length, 1);
+ frameloaded = o.t2.step_func(function() {
+ iframe.contentDocument.open();
+ iframe.contentDocument.write("3<script>onpageshow = function() {alert('pageshow'); parent.frameloaded()}<\/script>");
+ iframe.contentDocument.close();
+ frameloaded = o.t2.step_func(function () {
+ o.assert_equals(history.length, 2);
+ o.t2.done();
+ });
+ });
+ o.t1.done();
+ });
+
+}
+</script>
+
+<iframe src="filler.html?id=1"></iframe>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/joint_session_history/002.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/joint_session_history/002.html
new file mode 100644
index 000000000..b08c19e52
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/joint_session_history/002.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<title>Joint session history with single iframe</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+setup({timeout:10000});
+var t = async_test("Session history length on initial load");
+var t1 = async_test("Session history length on adding new iframe");
+var t2 = async_test("Navigating second iframe");
+<!-- var t3 = async_test("Traversing history back (1)"); -->
+<!-- var t4 = async_test("Navigating first iframe"); -->
+<!-- var t5 = async_test("Traversing history back (2)"); -->
+<!-- var t6 = async_test("Traversing history forward"); -->
+var w = window.open("002-1.html");
+//add_completion_callback(function() {w.close()});
+</script>
+
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/joint_session_history/filler.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/joint_session_history/filler.html
new file mode 100644
index 000000000..93e3c7ccf
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/joint_session_history/filler.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<script>
+document.write(location.search)
+onpageshow = function() {if (parent.frameloaded) {parent.frameloaded()}}
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/history.js b/testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/history.js
new file mode 100644
index 000000000..bb5ee6dde
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/history.js
@@ -0,0 +1,35 @@
+function parse_query() {
+ var query = location.search.slice(1);
+ var vars = query.split("&");
+ var fields = {};
+ vars.forEach(
+ function (x) {
+ var split = x.split("=");
+ return fields[split[0]] = split.slice(1).join("=");
+ });
+ return fields;
+}
+
+var query_parts = parse_query();
+var id = "id" in query_parts ? parseInt(query_parts.id) : 1;
+var urls_to_load = query_parts.urls.split(",");
+
+document.write(id);
+
+onunload = function() {};
+
+function queue_next() {
+ t = opener.t;
+ setTimeout(t.step_func(
+ function() {
+// opener.assert_equals(history.length, id);
+ if (urls_to_load[0]) {
+ var next_page = urls_to_load[0];
+ (next_page.indexOf("?") > -1) ? (next_page += "&") : (next_page += "?");
+ next_page += "urls=" + urls_to_load.slice(1).join(",");
+ next_page += "&id=" + ++id;
+ location = next_page;
+ }
+ }
+ ), 100);
+}
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/history_entry.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/history_entry.html
new file mode 100644
index 000000000..e5929ddbe
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/history_entry.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<script src="history.js"></script>
+<script>
+ onload = function() {
+ if (!opener.started) {
+ queue_next();
+ } else {
+ opener.pages.push(id);
+ opener.start_test_wait();
+ }
+};
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/traverse_the_history_unload_prompt_1-1.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/traverse_the_history_unload_prompt_1-1.html
new file mode 100644
index 000000000..8c4401836
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/traverse_the_history_unload_prompt_1-1.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<script src="history.js"></script>
+<script>
+ onbeforeunload = function() {opener.beforeunload_ran = true; return "Opt to stay on the page"};
+
+ opener.pages.push(id);
+ if (!opener.started) {
+ onload = function() {
+ setTimeout(function() {
+ opener.started = true;
+ history.back();
+ }, 100);
+ }
+ }
+</script>
+<p>You should see/have seen a prompt asking if you want to leave the page.</p>
+<p>Opt to stay on the page</p>
+<button onclick="onbeforeunload = null; opener.start_test_wait(); document.getElementsByTagName('button')[0].disabled = true;">Click here</button>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/traverse_the_history_unload_prompt_1-manual.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/traverse_the_history_unload_prompt_1-manual.html
new file mode 100644
index 000000000..b1d0aed52
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/traverse_the_history_unload_prompt_1-manual.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<title>Traversing the history, prompt in before unload, navigation denied</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+ setup({timeout:3600000});
+ var t = async_test(undefined, {timeout:3600000});
+ started = false;
+ pages = []
+ timer = null;
+ beforeunload_ran = false;
+ start_test_wait = t.step_func(
+ function() {
+ clearTimeout(timer);
+ timer = setTimeout(t.step_func(
+ function() {
+ try {
+ assert_true(beforeunload_ran, "beforeunload event handler ran");
+ assert_array_equals(pages, [2], "Pages opened during history navigation");
+ t.done();
+ } finally {
+ win.close();
+ }
+ }
+ ), 500);
+ }
+ );
+ t.step(function() {win = window.open("history_entry.html?urls=traverse_the_history_unload_prompt_1-1.html");
+});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/traverse_the_history_unload_prompt_2-1.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/traverse_the_history_unload_prompt_2-1.html
new file mode 100644
index 000000000..608a579e6
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/traverse_the_history_unload_prompt_2-1.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<script src="history.js"></script>
+<script>
+ onbeforeunload = function() {opener.beforeunload_ran = true; return "Opt to leave the page"};
+
+ opener.pages.push(id);
+ if (!opener.started) {
+ onload = function() {
+ setTimeout(function() {
+ opener.started = true;
+ history.back();
+ }, 100);
+ }
+ }
+</script>
+<p>You should see/have seen a prompt asking if you want to leave the page.</p>
+<p>Opt to leave the page</p>
+<p>If you weren't navigated away after opting to leave the page, that's a FAIL</p>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/traverse_the_history_unload_prompt_2-manual.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/traverse_the_history_unload_prompt_2-manual.html
new file mode 100644
index 000000000..d45a2afb1
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/traverse_the_history_unload_prompt_2-manual.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<title>Traversing the history, prompt in before unload, navigation allowed</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+ setup({timeout:3600000});
+ var t = async_test(undefined, {timeout:3600000});
+ started = false;
+ pages = []
+ timer = null;
+ beforeunload_ran = false;
+ start_test_wait = t.step_func(
+ function() {
+ clearTimeout(timer);
+ timer = setTimeout(t.step_func(
+ function() {
+ try {
+ assert_true(beforeunload_ran, "beforeunload event handler ran");
+ assert_array_equals(pages, [2,1], "Pages opened during history navigation");
+ t.done();
+ } finally {
+ win.close();
+ }
+ }
+ ), 500);
+ }
+ );
+ t.step(function() {win = window.open("history_entry.html?urls=traverse_the_history_unload_prompt_2-1.html");
+});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/traverse_the_session_history_unload_prompt_1-1.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/traverse_the_session_history_unload_prompt_1-1.html
new file mode 100644
index 000000000..c0079b6be
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/traverse_the_session_history_unload_prompt_1-1.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<script src="history.js"></script>
+<script>
+ onunload = function(e) {opener.unload_ran = true; return "Now refuse to leave the current page"}
+
+ opener.pages.push(id);
+ if (!opener.started) {
+ onload = function() {
+ setTimeout(function() {
+ opener.started = true;
+ history.back();
+ }, 100);
+ }
+ } else {
+ opener.start_test_wait();
+ }
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/traverse_the_session_history_unload_prompt_1-manual.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/traverse_the_session_history_unload_prompt_1-manual.html
new file mode 100644
index 000000000..8154e8e47
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/non-automated/traverse_the_session_history_unload_prompt_1-manual.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<title>Traversing the history, unload event is fired on doucment</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+ var t = async_test(undefined, {timeout:5000});
+ started = false;
+ pages = []
+ timer = null;
+ unload_ran = false;
+ start_test_wait = t.step_func(
+ function() {
+ clearTimeout(timer);
+ timer = setTimeout(t.step_func(
+ function() {
+ try {
+ assert_array_equals(pages, [2], "Pages opened during history navigation");
+ assert_true(unload_ran, "Unload event handler ran");
+ t.done();
+ } finally {
+ // win.close();
+ }
+ }
+ ), 500);
+ }
+ );
+ t.step(function() {win = window.open("history_entry.html?urls=traverse_the_history_unload_prompt_1-1.html");
+});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_1-1.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_1-1.html
new file mode 100644
index 000000000..a11fcf2d2
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_1-1.html
@@ -0,0 +1,18 @@
+<!doctype html>
+4
+<script>
+ onunload = function() {}
+
+ opener.pages.push(4);
+ if (!opener.started) {
+ onload = function() {
+ setTimeout(function() {
+ opener.started = true;
+ history.go(-2);
+ history.go(-1);
+ }, 100);
+ }
+ } else {
+ opener.start_test_wait();
+ }
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_1.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_1.html
new file mode 100644
index 000000000..11715583d
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_1.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<title>Multiple history traversals from the same task</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+ var t = async_test();
+ started = false;
+ pages = []
+ timer = null;
+ start_test_wait = t.step_func(
+ function() {
+ clearTimeout(timer);
+ timer = setTimeout(t.step_func(
+ function() {
+ try {
+ assert_array_equals(pages, [4, 2], "Pages opened during history navigation");
+ t.done();
+ } finally {
+ // win.close();
+ }
+ }
+ ), 500);
+ }
+ );
+ t.step(function() {win = window.open("history_entry.html&urls=history_entry.html,history_entry.html,traverse_the_history_1-1.html");
+});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_2-1.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_2-1.html
new file mode 100644
index 000000000..64920b4f4
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_2-1.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<script src="history.js"></script>
+<script>
+ opener.pages.push(id);
+ if (!opener.started) {
+ onload = function() {
+ setTimeout(function() {
+ opener.started = true;
+ history.go(-3);
+ history.go(-2);
+ history.go(1);
+ }, 100);
+ }
+ } else {
+ opener.start_test_wait();
+ }
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_2.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_2.html
new file mode 100644
index 000000000..1d1003380
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_2.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<title>Multiple history traversals, last would be aborted</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+ var t = async_test();
+ started = false;
+ pages = []
+ timer = null;
+ start_test_wait = t.step_func(
+ function() {
+ clearTimeout(timer);
+ timer = setTimeout(t.step_func(
+ function() {
+ try {
+ assert_array_equals(pages, [6, 3], "Pages opened during history navigation");
+ t.done();
+ } finally {
+ // win.close();
+ }
+ }
+ ), 500);
+ }
+ );
+ t.step(function() {win = window.open("history_entry.html?urls=history_entry.html,history_entry.html,history_entry.html,history_entry.html,traverse_the_history_2-1.html");
+});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_3-1.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_3-1.html
new file mode 100644
index 000000000..c49bfd384
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_3-1.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<script src="history.js"></script>
+<script>
+ opener.pages.push(id);
+ if (!opener.started) {
+ onload = function() {
+ setTimeout(function() {
+ opener.started = true;
+ history.go(-2);
+ history.go(-1);
+ history.go(3);
+ }, 100);
+ }
+ } else {
+ opener.start_test_wait();
+ }
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_3.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_3.html
new file mode 100644
index 000000000..51ed4eb39
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_3.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<title>Multiple history traversals, last would be aborted</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+ var t = async_test(undefined, {timeout:5000});
+ started = false;
+ pages = []
+ timer = null;
+ start_test_wait = t.step_func(
+ function() {
+ clearTimeout(timer);
+ timer = setTimeout(t.step_func(
+ function() {
+ try {
+ assert_array_equals(pages, [6, 3], "Pages opened during history navigation");
+ t.done();
+ } finally {
+ // win.close();
+ }
+ }
+ ), 500);
+ }
+ );
+ t.step(function() {win = window.open("history_entry.html?urls=history_entry.html,history_entry.html,history_entry.html,history_entry.html,traverse_the_history_2-1.html");
+});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_4-1.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_4-1.html
new file mode 100644
index 000000000..cf7f72379
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_4-1.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<script src="history.js"></script>
+<script>
+ opener.pages.push(id);
+ if (!opener.started) {
+ onload = function() {
+ setTimeout(function() {
+ opener.started = true;
+ history.go(-10); //Outside the range
+ history.go(-1);
+ history.go(-2);
+ }, 100);
+ }
+ } else {
+ opener.start_test_wait();
+ }
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_4.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_4.html
new file mode 100644
index 000000000..651693011
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_4.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<title>Multiple history traversals, last would be aborted</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+ var t = async_test(undefined, {timeout:5000});
+ started = false;
+ pages = []
+ timer = null;
+ start_test_wait = t.step_func(
+ function() {
+ clearTimeout(timer);
+ timer = setTimeout(t.step_func(
+ function() {
+ try {
+ assert_array_equals(pages, [6, 5], "Pages opened during history navigation");
+ t.done();
+ } finally {
+ // win.close();
+ }
+ }
+ ), 500);
+ }
+ );
+ t.step(function() {win = window.open("history_entry.html?urls=history_entry.html,history_entry.html,history_entry.html,history_entry.html,traverse_the_history_4-1.html");
+});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_5-1.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_5-1.html
new file mode 100644
index 000000000..a3f2553fa
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_5-1.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<script src="history.js"></script>
+<script>
+ opener.pages.push(id);
+ if (!opener.started) {
+ onload = function() {
+ setTimeout(function() {
+ opener.started = true;
+ history.go(10); //Outside the range
+ history.go(-1);
+ history.go(-2);
+ }, 100);
+ }
+ } else {
+ opener.start_test_wait();
+ }
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_5.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_5.html
new file mode 100644
index 000000000..837f265b5
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_5.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<title>Multiple history traversals, last would be aborted</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+ var t = async_test(undefined, {timeout:5000});
+ started = false;
+ pages = []
+ timer = null;
+ start_test_wait = t.step_func(
+ function() {
+ clearTimeout(timer);
+ timer = setTimeout(t.step_func(
+ function() {
+ try {
+ assert_array_equals(pages, [6, 5], "Pages opened during history navigation");
+ t.done();
+ } finally {
+ // win.close();
+ }
+ }
+ ), 500);
+ }
+ );
+ t.step(function() {win = window.open("history_entry.html?urls=history_entry.html,history_entry.html,history_entry.html,history_entry.html,traverse_the_history_5-1.html");
+});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_unload_1-1.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_unload_1-1.html
new file mode 100644
index 000000000..d3f3f6d5d
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_unload_1-1.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<script src="history.js"></script>
+<script>
+ onunload = function() {opener.unload_ran = true;}
+
+ opener.pages.push(id);
+ if (!opener.started) {
+ onload = function() {
+ setTimeout(function() {
+ opener.started = true;
+ history.back();
+ }, 100);
+ }
+ } else {
+ opener.start_test_wait();
+ }
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_unload_1.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_unload_1.html
new file mode 100644
index 000000000..5a72dd635
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_unload_1.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<title>Traversing the history, unload event is fired on doucment</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+ var t = async_test(undefined, {timeout:5000});
+ started = false;
+ pages = []
+ timer = null;
+ unload_ran = false;
+ start_test_wait = t.step_func(
+ function() {
+ clearTimeout(timer);
+ timer = setTimeout(t.step_func(
+ function() {
+ try {
+ assert_array_equals(pages, [2, 1], "Pages opened during history navigation");
+ assert_true(unload_ran, "Unload event handler ran");
+ t.done();
+ } finally {
+ // win.close();
+ }
+ }
+ ), 500);
+ }
+ );
+ t.step(function() {win = window.open("history_entry.html?urls=traverse_the_history_unload_1-1.html");
+});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_after_load_1-1.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_after_load_1-1.html
new file mode 100644
index 000000000..af0118a01
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_after_load_1-1.html
@@ -0,0 +1,15 @@
+<!doctype html>
+2
+<script>
+ onunload = function() {}
+ opener.pages.push(2);
+ onload = function() {
+ setTimeout(function() {
+ document.write("<!doctype html>3<script>opener.pages.push(3); if(!opener.started) {opener.started = true; history.go(-1);} opener.start_test_wait();<\/script>");
+ document.close();
+ if (opener.started) {
+ opener.start_test_wait();
+ }
+ }, 100);
+ }
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_after_load_1.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_after_load_1.html
new file mode 100644
index 000000000..c2c31e76f
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_after_load_1.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<title>Traverse the history after document.write after the load event</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+ var t = async_test();
+ started = false;
+ pages = []
+ start_test_wait = t.step_func(
+ function() {
+ check_result = t.step_func(
+ function() {
+ if (pages.length < 4) {
+ setTimeout(check_result, 500);
+ return
+ }
+ //The pass condition here is based on the idea that the spec is wrong and browsers are right
+ assert_array_equals(pages, [2, 3, 2, 3], "Pages opened during history navigation");
+ t.done();
+ }
+ )
+ setTimeout(check_result, 500);
+ }
+ );
+ t.step(function() {
+ win = window.open("history_entry.html?urls=traverse_the_history_write_after_load_1-1.html");
+ t.add_cleanup(function() {win.close()});
+});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_after_load_2-1.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_after_load_2-1.html
new file mode 100644
index 000000000..0e58cf573
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_after_load_2-1.html
@@ -0,0 +1,12 @@
+<!doctype html>
+3
+<script>
+ onunload = function() {}
+ opener.pages.push(3);
+ onload = function() {
+ document.write("<!doctype html>4<script>opener.pages.push(4); if(!opener.started) {opener.started = true; history.go(-2);} opener.start_test_wait();<\/script>");
+ if (opener.started) {
+ opener.start_test_wait();
+ }
+ }
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_after_load_2.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_after_load_2.html
new file mode 100644
index 000000000..28e363f91
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_after_load_2.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<title>Traverse the history back and forward when a history entry is written after the load event</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+ var t = async_test();
+ started = false;
+ pages = []
+ start_test_wait = t.step_func(
+ function() {
+ var check_result = t.step_func(function() {
+ if (pages.length < 5) {
+ setTimeout(check_result, 500);
+ return
+ }
+ //The pass condition here is based on the idea that the spec is wrong and browsers are right
+ assert_array_equals(pages, [3, 4, 2, 3, 4], "Pages opened during history navigation");
+ t.done();
+ });
+ setTimeout(check_result, 500);
+ }
+ );
+ t.step(function() {
+ win = window.open("history_entry.html?urls=history_forward-1.html,traverse_the_history_write_onload_2-1.html");
+ t.add_cleanup(function() {win.close()});
+ });
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_onload_1-1.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_onload_1-1.html
new file mode 100644
index 000000000..261955533
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_onload_1-1.html
@@ -0,0 +1,12 @@
+<!doctype html>
+2
+<script>
+ onunload = function() {}
+ opener.pages.push(2);
+ onload = function() {
+ document.write("<!doctype html>3<script>opener.pages.push(3); if(!opener.started) {opener.started = true; history.go(-1);} opener.start_test_wait();<\/script>");
+ if (opener.started) {
+ opener.start_test_wait();
+ }
+ }
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_onload_1.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_onload_1.html
new file mode 100644
index 000000000..ff2729c3c
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_onload_1.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<title>Traverse the history when a history entry is written in the load event</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+ var t = async_test();
+ started = false;
+ pages = []
+ timer = null;
+ start_test_wait = t.step_func(
+ function() {
+ clearTimeout(timer);
+ timer = setTimeout(t.step_func(
+ function() {
+ try {
+ //The pass condition here is based on the idea that the spec is wrong and browsers are right
+ assert_array_equals(pages, [2, 3, 1], "Pages opened durning history navigation");
+ t.done();
+ } finally {
+ // win.close();
+ }
+ }
+ ), 500);
+ }
+ );
+ t.step(function() {win = window.open("history_entry.html?urls=traverse_the_history_write_onload_1-1.html");
+});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_onload_2-1.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_onload_2-1.html
new file mode 100644
index 000000000..f32bee5e1
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_onload_2-1.html
@@ -0,0 +1,12 @@
+<!doctype html>
+3
+<script>
+ onunload = function() {}
+ opener.pages.push(3);
+ onload = function() {
+ document.write("<!doctype html>4<script>opener.pages.push(4); if(!opener.started) {opener.started = true; history.go(-1);} opener.start_test_wait();<\/script>");
+ if (opener.started) {
+ opener.start_test_wait();
+ }
+ }
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_onload_2.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_onload_2.html
new file mode 100644
index 000000000..bc29174b0
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/traverse_the_history_write_onload_2.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<title>Traverse the history back and forward when a history entry is written in the load event</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+ var t = async_test();
+ started = false;
+ pages = []
+ timer = null;
+ start_test_wait = t.step_func(
+ function() {
+ clearTimeout(timer);
+ timer = setTimeout(t.step_func(
+ function() {
+ try {
+ //The pass condition here is based on the idea that the spec is wrong and browsers are right
+ assert_array_equals(pages, [3, 4, 2, 3, 4], "Pages opened durning history navigation");
+ t.done();
+ } finally {
+ win.close();
+ }
+ }
+ ), 500);
+ }
+ );
+ t.step(function() {win = window.open("history_entry.html?urls=history_forward-1.html,traverse_the_history_write_onload_2-1.html");
+});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/.gitkeep b/testing/web-platform/tests/html/browsers/history/the-location-interface/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/.gitkeep
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/allow_prototype_cycle_through_location.sub.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/allow_prototype_cycle_through_location.sub.html
new file mode 100644
index 000000000..f72ed1eaf
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/allow_prototype_cycle_through_location.sub.html
@@ -0,0 +1,197 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="UTF-8">
+
+ <title>Location objects' custom [[GetPrototypeOf]] trap permit [[Prototype]] chain cycles to be created through them</title>
+
+ <link rel="author" title="Jeff Walden" href="http://whereswalden.com/" />
+ <link rel="help" href="https://tc39.github.io/ecma262/#sec-ordinarysetprototypeof" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/browsers.html#location-getprototypeof" />
+
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<div id="log"></div>
+
+<hr />
+
+<iframe id="same-origin-different-window"></iframe>
+<iframe id="cross-origin-joined-via-document-domain"></iframe>
+
+<script>
+"use strict";
+
+// Handle same-origin, same-window testing first, before any async-requiring
+// testing.
+test(function() {
+ var LocationPrototype = Location.prototype;
+ var ObjectPrototype = Object.prototype;
+
+ var loc = window.location;
+
+ var locProto = Object.getPrototypeOf(loc);
+ assert_equals(locProto, LocationPrototype,
+ "loc's initial [[Prototype]]");
+
+ var originalLocProtoProto = Object.getPrototypeOf(locProto);
+ assert_equals(originalLocProtoProto, ObjectPrototype,
+ "Location.prototype's initial [[Prototype]]");
+
+ Object.setPrototypeOf(locProto, loc);
+
+ assert_equals(Object.getPrototypeOf(locProto), loc,
+ "LocationPrototype's new [[Prototype]]");
+ assert_equals(Object.getPrototypeOf(loc), locProto,
+ "loc's new [[Prototype]]");
+
+ // Reset so as not to muck with testharness.js expectations.
+ Object.setPrototypeOf(locProto, originalLocProtoProto);
+}, "same-origin, same-window location cycle");
+
+var pathdir =
+ location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1);
+
+var triggerCrossOriginTest = (function() {
+ var crossOrigin =
+ document.getElementById("cross-origin-joined-via-document-domain");
+
+ var t = async_test("cross-origin location has null prototype");
+
+ return new Promise(function(resolve, reject) {
+ crossOrigin.onload = t.step_func_done(function(e) {
+ try {
+ var win = crossOrigin.contentWindow;
+
+ var loc = win.location;
+
+ // Between un-opted-in windows, location objects appear to have null
+ // [[Prototype]].
+ assert_equals(Object.getPrototypeOf(loc), null,
+ "cross-origin unjoined location's [[Prototype]");
+
+ resolve();
+ } catch (e) {
+ reject(e);
+ throw e;
+ }
+ });
+
+ crossOrigin.src =
+ "//{{domains[www]}}:" + location.port + pathdir + "cross_origin_joined_frame.sub.html";
+ })
+ .catch(t.unreached_func("crossOrigin onload/src setting"));
+})();
+
+var triggerSameOriginTest = (function() {
+ var sameOriginDifferentWindow =
+ document.getElementById("same-origin-different-window");
+
+ var t = async_test("same-origin, different-window location cycle");
+
+ return new Promise(function(resolve, reject) {
+ sameOriginDifferentWindow.onload = t.step_func_done(function() {
+ try {
+ var win = sameOriginDifferentWindow.contentWindow;
+
+ var loc = win.location;
+ var LocationPrototype = win.Location.prototype;
+ var ObjectPrototype = win.Object.prototype;
+
+ var locProto = Object.getPrototypeOf(loc);
+ assert_equals(locProto, LocationPrototype,
+ "loc's initial [[Prototype]]");
+
+ var originalLocProtoProto = Object.getPrototypeOf(locProto);
+ assert_equals(originalLocProtoProto, ObjectPrototype,
+ "Location.prototype's initial [[Prototype]]");
+
+ Object.setPrototypeOf(locProto, loc);
+
+ assert_equals(Object.getPrototypeOf(locProto), loc,
+ "LocationPrototype's new [[Prototype]]");
+ assert_equals(Object.getPrototypeOf(loc), locProto,
+ "loc's new [[Prototype]]");
+
+ // Reset so as not to muck with testharness.js expectations.
+ Object.setPrototypeOf(locProto, originalLocProtoProto);
+
+ resolve();
+ } catch (e) {
+ reject(e);
+ throw e;
+ }
+ });
+
+ sameOriginDifferentWindow.src = "same_origin_frame.html";
+ })
+ .catch(t.unreached_func("sameOriginDifferentWindow onload/src setting"));
+})();
+
+function crossOriginJoinTest() {
+ var win =
+ document.getElementById("cross-origin-joined-via-document-domain")
+ .contentWindow;
+
+ assert_equals(document.domain, "{{host}}");
+
+ var loc = win.location;
+
+ var threw = false;
+ try {
+ // Still cross-origin until the document.domain set below.
+ win.Location;
+ } catch (e) {
+ threw = true;
+ }
+
+ assert_equals(threw, true,
+ "accessing win.Location before joining win's origin");
+
+ // Join with other frames that have set |document.domain| to this same
+ // value -- namely, this cross-origin frame. Now access between the two
+ // windows should be permitted.
+ assert_equals(document.domain, "{{host}}",
+ "initial document.domain sanity check");
+ document.domain = "{{host}}";
+
+ var LocationPrototype = win.Location.prototype;
+ var ObjectPrototype = win.Object.prototype;
+
+ var locProto = Object.getPrototypeOf(loc);
+ assert_equals(locProto, LocationPrototype,
+ "loc's initial [[Prototype]]");
+
+ var originalLocProtoProto = Object.getPrototypeOf(locProto);
+ assert_equals(originalLocProtoProto, ObjectPrototype,
+ "Location.prototype's initial [[Prototype]]");
+
+ Object.setPrototypeOf(locProto, loc);
+
+ assert_equals(Object.getPrototypeOf(locProto), loc,
+ "LocationPrototype's new [[Prototype]]");
+ assert_equals(Object.getPrototypeOf(loc), locProto,
+ "loc's new [[Prototype]]");
+
+ // Reset so as not to muck with testharness.js expectations.
+ Object.setPrototypeOf(locProto, originalLocProtoProto);
+}
+
+function run() {
+ var t =
+ async_test("cross-origin, but joined via document.domain, location cycle");
+
+ // The cross-origin/joined case must be tested after both unjoined same-origin
+ // and unjoined cross-origin tests: by mucking with document.domain, the
+ // cross-origin/joined case makes it impossible to perform those tests.
+ t.step(function() {
+ Promise.all([triggerCrossOriginTest, triggerSameOriginTest])
+ .then(t.step_func_done(crossOriginJoinTest),
+ t.unreached_func("cross-origin joined error case"));
+ });
+}
+run();
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/assign_after_load-1.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/assign_after_load-1.html
new file mode 100644
index 000000000..3d2b89722
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/assign_after_load-1.html
@@ -0,0 +1,9 @@
+<!doctype html>
+1
+<script>
+onload = parent.t.step_func(function() {
+ setTimeout(function() {
+ location = location.toString().replace("assign_after_load-1.html", "assign_after_load-2.html");
+ }, 100);
+});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/assign_after_load-2.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/assign_after_load-2.html
new file mode 100644
index 000000000..94679571b
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/assign_after_load-2.html
@@ -0,0 +1,7 @@
+<!doctype html>
+2
+<script>
+onload = parent.t.step_func(function() {
+ setTimeout(function() {parent.do_test()}, 100);
+});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/assign_after_load.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/assign_after_load.html
new file mode 100644
index 000000000..00dc931d4
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/assign_after_load.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<title>Assignment to location after document is completely loaded</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<iframe></iframe>
+<script>
+var t = async_test();
+var history_length;
+
+onload = t.step_func(function() {
+ setTimeout(function() {
+ history_length = history.length;
+ document.getElementsByTagName("iframe")[0].src = "assign_after_load-1.html";
+ }, 100);
+});
+
+do_test = t.step_func(function() {
+ assert_equals(history.length, history_length + 2);
+ t.done();
+});
+
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/assign_before_load-1.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/assign_before_load-1.html
new file mode 100644
index 000000000..2549867c8
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/assign_before_load-1.html
@@ -0,0 +1,7 @@
+<!doctype html>
+1
+<script>
+onload = parent.t.step_func(function() {
+ location = location.toString().replace("assign_before_load-1.html", "assign_before_load-2.html");
+});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/assign_before_load-2.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/assign_before_load-2.html
new file mode 100644
index 000000000..94679571b
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/assign_before_load-2.html
@@ -0,0 +1,7 @@
+<!doctype html>
+2
+<script>
+onload = parent.t.step_func(function() {
+ setTimeout(function() {parent.do_test()}, 100);
+});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/assign_before_load.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/assign_before_load.html
new file mode 100644
index 000000000..62a2aa7c6
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/assign_before_load.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<title>Assignment to location before document is completely loaded</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<iframe></iframe>
+<script>
+var t = async_test();
+var history_length;
+
+onload = t.step_func(function() {
+ setTimeout(function() {
+ history_length = history.length;
+ document.getElementsByTagName("iframe")[0].src = "assign_before_load-1.html";
+ }, 100);
+});
+
+do_test = t.step_func(function() {
+ assert_equals(history.length, history_length + 1);
+ t.done();
+});
+
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/contains.json b/testing/web-platform/tests/html/browsers/history/the-location-interface/contains.json
new file mode 100644
index 000000000..d311dbb31
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/contains.json
@@ -0,0 +1,6 @@
+[
+ {
+ "id": "security-location",
+ "original_id": "security-location"
+ }
+] \ No newline at end of file
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/cross_origin_joined_frame.sub.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/cross_origin_joined_frame.sub.html
new file mode 100644
index 000000000..a3ffdd005
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/cross_origin_joined_frame.sub.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="UTF-8">
+ <title>Cross-origin subframe for Location cyclic [[Prototype]] test</title>
+ <link rel="author" title="Jeff Walden" href="http://whereswalden.com/" />
+</head>
+<body>
+<script>
+document.domain = "{{host}}";
+</script>
+<!-- this should be accessible to the parent once it sets document.domain -->
+<p>Cross-origin iframe with joined <code>document.domain</code></p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/document_location.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/document_location.html
new file mode 100644
index 000000000..5ccc9c76b
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/document_location.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<title>document.location</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+test(function() {
+ var doc = document.implementation.createHTMLDocument("");
+ assert_equals(doc.location, null);
+}, "document not in a browsing context");
+
+test(function() {
+ assert_equals(document.location, location);
+}, "document.location equals window.location");
+
+</script>
+
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/location-prototype-setting.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/location-prototype-setting.html
new file mode 100644
index 000000000..726aaea23
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/location-prototype-setting.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>[[SetPrototypeOf]] on a location object should return false</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+ test(function() {
+ var origProto = Object.getPrototypeOf(location);
+ assert_throws(new TypeError, function() {
+ Object.setPrototypeOf(location, {});
+ });
+ assert_throws(new TypeError, function() {
+ location.__proto__ = {};
+ });
+ assert_false(Reflect.setPrototypeOf(location, {}));
+ assert_equals(Object.getPrototypeOf(location), origProto);
+ });
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/location-stringifier.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/location-stringifier.html
new file mode 100644
index 000000000..d23323b37
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/location-stringifier.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<title>Location stringifier</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://heycam.github.io/webidl/#es-stringifier">
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/common/stringifiers.js></script>
+<div id=log></div>
+<script>
+test_stringifier_attribute(location, "href", true);
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/location_assign.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_assign.html
new file mode 100644
index 000000000..7e18804c2
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_assign.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>location_assign</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function () {
+ var href = location.href;
+ location.assign('#x');
+
+ assert_equals((href + "#x"), location.href, "location href");
+
+ }, "location assign");
+
+ test(function () {
+ var href = location.href;
+ assert_throws('SYNTAX_ERR', function() { location.assign("http://:"); });
+ assert_equals(location.href, href);
+ }, "URL that fails to parse");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/location_assign_about_blank-1.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_assign_about_blank-1.html
new file mode 100644
index 000000000..b43598f2c
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_assign_about_blank-1.html
@@ -0,0 +1,2 @@
+<!doctype html>
+Filler text
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/location_assign_about_blank.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_assign_about_blank.html
new file mode 100644
index 000000000..f3f7cf26b
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_assign_about_blank.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<title>location.assign with initial about:blank browsing context</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<iframe></iframe>
+<script>
+var t = async_test();
+var history_length;
+onload = t.step_func(function() {
+ setTimeout(t.step_func(function() {
+ var iframe = document.getElementsByTagName("iframe")[0];
+ iframe.onload = t.step_func(function() {
+ setTimeout(t.step_func(function() {
+ assert_equals(history.length, history_length);
+ t.done();
+ }), 100);
+ });
+ history_length = history.length;
+ iframe.src = "location_assign_about_blank-1.html"
+ }), 100);
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/location_hash.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_hash.html
new file mode 100644
index 000000000..74d2d0154
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_hash.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>location_hash</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <iframe id="srcdoc-iframe"
+ srcdoc="<div style='height: 200vh'></div><div id='test'></div>"></iframe>
+ <script>
+ test(function () {
+ window.history.pushState(1, document.title, '#x=1');
+ var hash = location.hash;
+
+ assert_equals(hash, "#x=1", "hash");
+
+ }, "location hash");
+
+ var t = async_test("Setting location.hash on srcdoc iframe");
+ addEventListener("load", t.step_func_done(function() {
+ var frameWin = document.getElementById("srcdoc-iframe").contentWindow;
+ assert_equals(frameWin.location.href, "about:srcdoc");
+ assert_equals(frameWin.scrollY, 0, "Should not have scrolled yet");
+ frameWin.location.hash = "test";
+ assert_equals(frameWin.location.href, "about:srcdoc#test");
+ assert_true(frameWin.scrollY > frameWin.innerHeight,
+ "Should have scrolled by more than one viewport height");
+ }));
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/location_host.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_host.html
new file mode 100644
index 000000000..d93bf47e5
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_host.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>location_host</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function () {
+ var host = location.host;
+ var url = location.href;
+
+ var pos = url.indexOf("//");
+ if (pos != -1) {
+ url = url.substr(pos+2, url.length-pos-2);
+ pos = url.indexOf("/");
+ if (pos != -1)
+ url = url.substr(0, pos);
+ }
+
+ assert_equals(host, url, "host");
+
+ }, "location host");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/location_hostname.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_hostname.html
new file mode 100644
index 000000000..2ffa0e5fc
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_hostname.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>location_hostname</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function () {
+ var hostname = location.hostname;
+ var url = location.href;
+
+ var pos = url.indexOf("//");
+ if (pos != -1) {
+ url = url.substr(pos+2, url.length-pos-2);
+ pos = url.indexOf(":");
+ if (pos != -1) {
+ url = url.substr(0, pos);
+ } else {
+ pos = url.indexOf("/");
+ if (pos != -1)
+ url = url.substr(0, pos);
+ }
+ }
+
+ assert_equals(hostname, url, "hostname");
+
+ }, "location hostname");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/location_href.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_href.html
new file mode 100644
index 000000000..1aa85dcdc
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_href.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>location_href</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function () {
+ var href = location.href;
+
+ assert_equals(href, document.URL, "href");
+
+ }, "location href");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/location_origin.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_origin.html
new file mode 100644
index 000000000..2325f4018
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_origin.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<meta charset="utf-8">
+<title></title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ test(function () {
+ assert_equals(
+ location.origin,
+ location.protocol + '//' + location.host,
+ "origin"
+ );
+ }, "location origin");
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/location_pathname.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_pathname.html
new file mode 100644
index 000000000..dea05d2f3
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_pathname.html
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>location_pathname</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function () {
+ var pathname = location.pathname;
+ var url = location.href
+
+ url = url.replace(location.protocol + "//" + location.host, "");
+
+ assert_equals(pathname, url, "pathname");
+
+ }, "location pathname");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/location_port.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_port.html
new file mode 100644
index 000000000..fa1308ca5
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_port.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>location_port</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function () {
+ var port = location.port;
+ var url = location.href;
+
+ var pos = url.indexOf("//");
+ if (pos != -1) {
+ url = url.substr(pos+2, url.length-pos-2);
+ pos = url.indexOf("/");
+ if (pos != -1)
+ url = url.substr(0, pos);
+ pos = url.indexOf(":");
+ if (pos != -1)
+ url = url.substr(pos+1, url.length-pos-1);
+ }
+
+ assert_equals(port, url, "port");
+
+ }, "location port");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/location_protocol.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_protocol.html
new file mode 100644
index 000000000..d28bd5639
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_protocol.html
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>location_protocol</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function () {
+ var protocol = location.protocol;
+ var url = location.href;
+
+ var pos = url.indexOf("//");
+ if (pos != -1) {
+ url = url.substr(0, pos);
+ }
+
+ assert_equals(protocol, url, "protocol");
+
+ }, "location protocol");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/location_reload-iframe.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_reload-iframe.html
new file mode 100644
index 000000000..95b63d9f5
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_reload-iframe.html
@@ -0,0 +1,4 @@
+<script>
+ parent._ping(window.location.href)
+ location.reload();
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/location_reload.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_reload.html
new file mode 100644
index 000000000..78b3cc35e
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_reload.html
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>location_reload</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+
+ <iframe></iframe>
+
+ <script>
+ var history_length;
+ async_test(function(t) {
+
+ var url = new URL("./location_reload-iframe.html", window.location).href;
+ var pingCount = 0;
+
+ window._ping = t.step_func(function(innerURL) {
+ // Some browsers keep 'about:blank' in the session history
+ if (pingCount == 0) {
+ history_length = history.length;
+ }
+ assert_equals(url, innerURL, "iframe url (" + pingCount + ")");
+ assert_equals(history_length, history.length, "history length (" + pingCount + ")");
+ pingCount++;
+ if (pingCount == 5) {
+ iframe.src = 'about:blank';
+ t.done();
+ }
+ });
+
+ var iframe = document.querySelector("iframe");
+ iframe.src = url;
+ history_length = history.length;
+ });
+ </script>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/location_replace.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_replace.html
new file mode 100644
index 000000000..2f2d57308
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_replace.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>location_replace</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function () {
+ var href = location.href;
+ location.replace('#x');
+
+ assert_equals((href + "#x"), location.href, "location href");
+
+ }, "location replace");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/location_search.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_search.html
new file mode 100644
index 000000000..f9db75784
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/location_search.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>location_search</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+ test(function () {
+ window.history.pushState(1, document.title, '?x=1');
+ var search = location.search;
+
+ assert_equals(search, "?x=1", "search");
+
+ }, "location search");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_click_assign_during_load-1.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_click_assign_during_load-1.html
new file mode 100644
index 000000000..c762ece3b
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_click_assign_during_load-1.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<script>
+opener.history_length = history.length;
+</script>
+<a onclick="location = 'manual_click_assign_during_load-2.html'; return false;" href>Click Here</a>
+<p>Filler image to keep the page loading:</p>
+<img src="/images/smiley.png?pipe=trickle(20:d1:r2)">
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_click_assign_during_load-2.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_click_assign_during_load-2.html
new file mode 100644
index 000000000..1bf7f41e0
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_click_assign_during_load-2.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<p>This window should close itself and the test result appear in the original window
+<script>
+onload = function() {
+ setTimeout(function() {opener.do_test(history.length); window.close();}, 100);
+}
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_click_assign_during_load-manual.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_click_assign_during_load-manual.html
new file mode 100644
index 000000000..4f2555c5e
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_click_assign_during_load-manual.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<title>Assignment to location with click during load</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<p>The popup blocker must be disabled for this test</p>
+<div id="log"></div>
+<script>
+setup({timeout:3600000});
+var t = async_test(undefined, {timeout:3600000});
+var win = window.open("manual_click_assign_during_load-1.html");
+
+var history_length;
+do_test = t.step_func(function(new_length) {
+ assert_equals(new_length, history_length + 1);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_click_location_replace_during_load-1.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_click_location_replace_during_load-1.html
new file mode 100644
index 000000000..e9d03e936
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_click_location_replace_during_load-1.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<script>
+opener.history_length = history.length;
+</script>
+<a onclick="location.replace('manual_click_location_replace_during_load-2.html'); return false;" href>Click Here</a>
+<p>Filler image to keep the page loading:</p>
+<img>
+<script>
+document.images[0].src = "/images/smiley.png?pipe=trickle(20:d1:r2)&random=" + Math.random();
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_click_location_replace_during_load-2.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_click_location_replace_during_load-2.html
new file mode 100644
index 000000000..1bf7f41e0
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_click_location_replace_during_load-2.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<p>This window should close itself and the test result appear in the original window
+<script>
+onload = function() {
+ setTimeout(function() {opener.do_test(history.length); window.close();}, 100);
+}
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_click_location_replace_during_load-manual.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_click_location_replace_during_load-manual.html
new file mode 100644
index 000000000..43af1b1d3
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_click_location_replace_during_load-manual.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<title>location.replace with click during load</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<p>The popup blocker must be disabled for this test</p>
+<div id="log"></div>
+<script>
+setup({timeout:3600000});
+var t = async_test(undefined, {timeout:3600000});
+var win = window.open("manual_click_location_replace_during_load-1.html");
+
+var history_length;
+do_test = t.step_func(function(new_length) {
+ assert_equals(new_length, history_length);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_click_replace_during_load-manual.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_click_replace_during_load-manual.html
new file mode 100644
index 000000000..3507222ca
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_click_replace_during_load-manual.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<title>Assignment to location with click during load</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<p>The popup blocker must be disabled for this test</p>
+<div id="log"></div>
+<script>
+setup({timeout:3600000});
+var t = async_test(undefined, {timeout:3600000});
+var win = window.open("manual_click_replace_during_load-1.html");
+
+var history_length;
+do_test = t.step_func(function(new_length) {
+ assert_equals(new_length, history_length);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_form_submit_assign_during_load-1.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_form_submit_assign_during_load-1.html
new file mode 100644
index 000000000..08f7e2dd6
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_form_submit_assign_during_load-1.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<script>
+opener.history_length = history.length;
+</script>
+<form onsubmit="location = 'manual_form_submit_assign_during_load-2.html'; return false;">
+<input type=submit value="Click Me">
+</form>
+<p>Filler image to keep the page loading:</p>
+<img src="/images/smiley.png?pipe=trickle(20:d1:r2)">
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_form_submit_assign_during_load-2.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_form_submit_assign_during_load-2.html
new file mode 100644
index 000000000..1bf7f41e0
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_form_submit_assign_during_load-2.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<p>This window should close itself and the test result appear in the original window
+<script>
+onload = function() {
+ setTimeout(function() {opener.do_test(history.length); window.close();}, 100);
+}
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_form_submit_assign_during_load-manual.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_form_submit_assign_during_load-manual.html
new file mode 100644
index 000000000..df6487407
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/manual_form_submit_assign_during_load-manual.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<title>Assignment to location with form submit during load</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<p>The popup blocker must be disabled for this test</p>
+<div id="log"></div>
+<script>
+setup({timeout:3600000});
+var t = async_test(undefined, {timeout:3600000});
+var win = window.open("manual_form_submit_assign_during_load-1.html");
+
+var history_length;
+do_test = t.step_func(function(new_length) {
+ assert_equals(new_length, history_length + 1);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/reload_in_resize-1.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/reload_in_resize-1.html
new file mode 100644
index 000000000..05b44f4c4
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/reload_in_resize-1.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<p>Resize this window. FAIL if the window doesn't close shortly afterwards.</p>
+<script>
+onload = opener.t.step_func(function() {
+ opener.load_count++;
+ if (opener.load_count > 1) {
+ opener.do_test();
+ }
+})
+
+onresize = opener.t.step_func(function() {
+ opener.flag_resized();
+ location.reload();
+});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/reload_in_resize-manual.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/reload_in_resize-manual.html
new file mode 100644
index 000000000..1991cee8a
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/non-automated/reload_in_resize-manual.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<title>Reload called from resize event</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<p>Resize the popup window. That window should then close and the result be presented here. If that window doesn't close after resize that's a FAIL.</p>
+<div id="log"></div>
+<script>
+setup({timeout:3600000})
+var t = async_test(undefined, {timeout:3600000});
+var load_count = 0;
+var resized = false;
+var win = window.open("reload_in_resize-1.html")
+
+flag_resized = t.step_func(function() {
+ resized = true;
+ setTimeout(do_test, 1000);
+});
+
+do_test = t.step_func(function() {
+ win.close();
+ assert_true(resized, "Resize event happened");
+ assert_equals(load_count, 1, "Number of load events");
+ t.done();
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/reload_document_open_write-1.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/reload_document_open_write-1.html
new file mode 100644
index 000000000..1c5a1db8f
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/reload_document_open_write-1.html
@@ -0,0 +1,14 @@
+<!doctype html>
+1
+<script>
+function f() {
+ opener.postMessage("original", "*");
+ setTimeout(function () {
+ document.open();
+ document.write("<!doctype html>2<script>opener.postMessage('written', '*');<\/script>");
+ document.close();
+ }), 100;
+}
+
+window.onload = f
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/reload_document_open_write.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/reload_document_open_write.html
new file mode 100644
index 000000000..0fc2a2c3d
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/reload_document_open_write.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<title>Reload document with document.open and document.written content</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+var win = window.open("reload_document_open_write-1.html");
+var t = async_test();
+
+var data = [];
+
+window.onmessage = t.step_func(function(e) {
+ data.push(e.data);
+ if (data.length < 3) {
+ win.location.reload();
+ } else {
+ setTimeout(t.step_func(function() {
+ assert_array_equals(data, ["original", "written", "written"]);
+ t.done();
+ }), 500);
+ }
+});
+
+add_completion_callback(function() {win.close()});
+</script>
+
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/reload_document_write-1.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/reload_document_write-1.html
new file mode 100644
index 000000000..9a0843392
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/reload_document_write-1.html
@@ -0,0 +1,4 @@
+<script>
+document.write(Math.random());
+opener.postMessage(document.body.innerHTML, "*");
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/reload_document_write.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/reload_document_write.html
new file mode 100644
index 000000000..dfbd436a4
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/reload_document_write.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<title>Reload document with document.written content</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+var win = window.open("reload_document_write-1.html");
+var t = async_test();
+
+window.onmessage = t.step_func(function(e) {
+ var initial_value = e.data;
+ win.location.reload();
+ window.onmessage = t.step_func(function(e) {
+ assert_true(e.data !== initial_value);
+ t.done();
+ });
+});
+
+add_completion_callback(function() {win.close()});
+</script>
+
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/reload_document_write_onload-1.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/reload_document_write_onload-1.html
new file mode 100644
index 000000000..36445af3c
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/reload_document_write_onload-1.html
@@ -0,0 +1,9 @@
+<script>
+function f() {
+ opener.postMessage("original", "*");
+ document.write("<!doctype html>2<script>opener.postMessage('written', '*');<\/script>");
+ document.close();
+}
+
+window.onload = f
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/reload_document_write_onload.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/reload_document_write_onload.html
new file mode 100644
index 000000000..b2cf31147
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/reload_document_write_onload.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<title>Reload document with document.written content written in load event</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+var win = window.open("reload_document_write_onload-1.html");
+var t = async_test();
+
+var data = [];
+
+window.onmessage = t.step_func(function(e) {
+ data.push(e.data);
+ if (data.length < 3) {
+ win.location.reload();
+ } else {
+ setTimeout(t.step_func(function() {
+ assert_array_equals(data, ["original", "written", "written"]);
+ t.done();
+ }), 500);
+ }
+});
+
+add_completion_callback(function() {win.close()});
+</script>
+
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/reload_post_1-1.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/reload_post_1-1.html
new file mode 100644
index 000000000..69e48f77c
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/reload_post_1-1.html
@@ -0,0 +1,10 @@
+<script>
+onload = function() {opener.next()}
+document.write(Math.random());
+</script>
+
+<form method="POST" action="">
+<input type=hidden name=test value=test>
+<input type=submit>
+</form>
+<button onclick="location.reload()">Reload</button>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/reload_post_1.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/reload_post_1.html
new file mode 100644
index 000000000..080545e23
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/reload_post_1.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<title>Reload document with POST</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+var win = window.open("reload_post_1-1.html");
+var t = async_test();
+var posted = false;
+var reloaded = false;
+
+next = t.step_func(function() {
+
+if (posted && !reloaded) {
+ reloaded = true;
+ win.location.reload();
+} else if (posted && reloaded) {
+ t.done();
+} else {
+ posted = true;
+ win.document.forms[0].submit();
+}
+
+});
+
+add_completion_callback(function() {win.close()});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/same_origin_frame.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/same_origin_frame.html
new file mode 100644
index 000000000..953e696b2
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/same_origin_frame.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="UTF-8">
+ <title>Same-origin subframe for Location cyclic [[Prototype]] test</title>
+ <link rel="author" title="Jeff Walden" href="http://whereswalden.com/" />
+</head>
+<body>
+<!-- nothing to do, this window should be accessible to the parent frame -->
+<p>Same-origin iframe</p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_click_assign_during_load-1.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_click_assign_during_load-1.html
new file mode 100644
index 000000000..9561cabdd
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_click_assign_during_load-1.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<script>
+opener.history_length = history.length;
+</script>
+<a onclick="location = 'scripted_click_assign_during_load-2.html'; return false;" href>Click Here</a>
+<script>
+document.links[0].click()
+</script>
+<p>Filler image to keep the page loading:</p>
+<img src="/images/smiley.png?pipe=trickle(20:d1:r2)">
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_click_assign_during_load-2.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_click_assign_during_load-2.html
new file mode 100644
index 000000000..1bf7f41e0
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_click_assign_during_load-2.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<p>This window should close itself and the test result appear in the original window
+<script>
+onload = function() {
+ setTimeout(function() {opener.do_test(history.length); window.close();}, 100);
+}
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_click_assign_during_load.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_click_assign_during_load.html
new file mode 100644
index 000000000..4d7352f4c
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_click_assign_during_load.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<title>Assignment to location with click during load</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<p>The popup blocker must be disabled for this test</p>
+<div id="log"></div>
+<script>
+setup({timeout:3600000});
+var t = async_test(undefined, {timeout:3600000});
+var win = window.open("scripted_click_assign_during_load-1.html");
+
+var history_length;
+do_test = t.step_func(function(new_length) {
+ assert_equals(new_length, history_length);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_click_location_assign_during_load-1.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_click_location_assign_during_load-1.html
new file mode 100644
index 000000000..05bb42f96
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_click_location_assign_during_load-1.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<script>
+opener.history_length = history.length;
+</script>
+<a onclick="location.assign('scripted_click_location_assign_during_load-2.html'); return false;" href>Click Here</a>
+<script>
+document.links[0].click()
+</script>
+<p>Filler image to keep the page loading:</p>
+<img>
+<script>
+document.images[0].src = "/images/smiley.png?pipe=trickle(20:d1:r2)&random=" + Math.random()
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_click_location_assign_during_load-2.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_click_location_assign_during_load-2.html
new file mode 100644
index 000000000..1bf7f41e0
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_click_location_assign_during_load-2.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<p>This window should close itself and the test result appear in the original window
+<script>
+onload = function() {
+ setTimeout(function() {opener.do_test(history.length); window.close();}, 100);
+}
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_click_location_assign_during_load.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_click_location_assign_during_load.html
new file mode 100644
index 000000000..64f3ff942
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_click_location_assign_during_load.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<title>location.assign with click during load</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<p>The popup blocker must be disabled for this test</p>
+<div id="log"></div>
+<script>
+var t = async_test();
+var win = window.open("scripted_click_location_assign_during_load-1.html");
+
+var history_length;
+do_test = t.step_func(function(new_length) {
+ assert_equals(new_length, history_length + 1);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_form_submit_assign_during_load-1.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_form_submit_assign_during_load-1.html
new file mode 100644
index 000000000..ae07ac5cf
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_form_submit_assign_during_load-1.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<script>
+opener.history_length = history.length;
+</script>
+<form onsubmit="location = 'scripted_form_submit_assign_during_load-2.html'; return false;">
+<input type=submit value="Click Me">
+</form>
+<script>
+document.forms[0].elements[0].click()
+</script>
+<p>Filler image to keep the page loading:</p>
+<img src="/images/smiley.png?pipe=trickle(20:d1:r2)">
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_form_submit_assign_during_load-2.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_form_submit_assign_during_load-2.html
new file mode 100644
index 000000000..1bf7f41e0
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_form_submit_assign_during_load-2.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<p>This window should close itself and the test result appear in the original window
+<script>
+onload = function() {
+ setTimeout(function() {opener.do_test(history.length); window.close();}, 100);
+}
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_form_submit_assign_during_load.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_form_submit_assign_during_load.html
new file mode 100644
index 000000000..981b9c9a3
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/scripted_form_submit_assign_during_load.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<title>Assignment to location with form submit during load</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<p>The popup blocker must be disabled for this test</p>
+<div id="log"></div>
+<script>
+setup({timeout:3600000});
+var t = async_test(undefined, {timeout:3600000});
+var win = window.open("scripted_form_submit_assign_during_load-1.html");
+
+var history_length;
+do_test = t.step_func(function(new_length) {
+ assert_equals(new_length, history_length);
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/security_location_0.sub.htm b/testing/web-platform/tests/html/browsers/history/the-location-interface/security_location_0.sub.htm
new file mode 100644
index 000000000..f509c23b1
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/security_location_0.sub.htm
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Location interface Security</title>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#security-location" />
+ <meta name="assert" content="access location object from different origins doesn't raise SECURITY_ERR exception" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <p>Access location object from different origins doesn't raise SECURITY_ERR exception</p>
+ <div id=log></div>
+ <script src="/common/get-host-info.sub.js"></script>
+ <script>
+ var runTest = async_test("Accessing location object from different origins doesn't raise SECURITY_ERR exception").step_func_done(function() {
+ var frame = document.getElementById('testframe');
+ frame.setAttribute('onload', '');
+ frame.contentWindow.location = get_host_info().HTTP_REMOTE_ORIGIN + "/";
+ });
+ </script>
+ <iframe id='testframe' onload="runTest()">Test Frame</iframe>
+ <script>
+ document.getElementById('testframe').setAttribute('src', get_host_info().HTTP_REMOTE_ORIGIN + '/');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/browsers/history/the-session-history-of-browsing-contexts/.gitkeep b/testing/web-platform/tests/html/browsers/history/the-session-history-of-browsing-contexts/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-session-history-of-browsing-contexts/.gitkeep