Index: third_party/WebKit/LayoutTests/imported/wpt/html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/resume-timer-on-history-back.html |
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/resume-timer-on-history-back.html b/third_party/WebKit/LayoutTests/imported/wpt/html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/resume-timer-on-history-back.html |
new file mode 100644 |
index 0000000000000000000000000000000000000000..fb7365bd31893fd20f4af35f033d468543ce7f0f |
--- /dev/null |
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/resume-timer-on-history-back.html |
@@ -0,0 +1,145 @@ |
+<!doctype html> |
+<title>Verify history.back() on a persisted page resumes timers</title> |
+<script src="/resources/testharness.js"></script> |
+<script src="/resources/testharnessreport.js"></script> |
+<script type="text/javascript"> |
+ |
+function make_post_back_url(name) { |
+ return new URL('resources/post_name_on_load.html?name=' + name, |
+ window.location).href; |
+} |
+ |
+function wait_for_message(name) { |
+ return new Promise(resolve => { |
+ addEventListener('message', function onMsg(evt) { |
+ if (evt.data !== name) { |
+ return; |
+ } |
+ removeEventListener('message', onMsg); |
+ resolve(); |
+ }); |
+ }); |
+} |
+ |
+function with_window_by_name(name) { |
+ let win = window.open(make_post_back_url(name)); |
+ return wait_for_message(name).then(_ => { |
+ return win; |
+ }); |
+} |
+ |
+function with_nested_frame(win, url) { |
+ return new Promise(resolve => { |
+ let frame = win.document.createElement('iframe'); |
+ frame.addEventListener('load', function onLoad(evt) { |
+ removeEventListener('load', onLoad); |
+ resolve(frame); |
+ }); |
+ frame.src = url; |
+ win.document.body.appendChild(frame); |
+ }); |
+} |
+ |
+function delay(win, delay) { |
+ return new Promise(resolve => { |
+ win.setTimeout(_ => { |
+ resolve(win); |
+ }, delay); |
+ }); |
+} |
+ |
+function navigate_by_name(win, name) { |
+ win.location = make_post_back_url(name); |
+ return wait_for_message(name).then(_ => { |
+ return win; |
+ }); |
+} |
+ |
+function go_back(win) { |
+ return new Promise(resolve => { |
+ win.onpagehide = e => resolve(win); |
+ win.history.back(); |
+ }); |
+} |
+ |
+let DELAY = 500; |
+ |
+promise_test(t => { |
+ // Create a new window so we can navigate it later. |
+ return with_window_by_name('foo').then(win => { |
+ // Schedule a timer within the new window. Our intent is |
+ // to navigate the window before the timer fires. |
+ let delayFired = false; |
+ let innerDelay = delay(win, DELAY); |
+ innerDelay.then(_ => { |
+ delayFired = true; |
+ }); |
+ |
+ return navigate_by_name(win, 'bar').then(_ => { |
+ // Since the window has navigated the timer should not |
+ // fire. We set a timer on our current test window |
+ // to verify the other timer is not received. |
+ assert_false(delayFired); |
+ return delay(window, DELAY * 2); |
+ }).then(_ => { |
+ // The navigated window's timer should not have fired. |
+ assert_false(delayFired); |
+ // Now go back to the document that set the timer. |
+ return go_back(win); |
+ }).then(_ => { |
+ // We wait for one of two conditions here. For browsers |
+ // with a bfcache the original suspended timer will fire. |
+ // Alternatively, if the browser reloads the page the original |
+ // message will be sent again. Wait for either of these |
+ // two events. |
+ return Promise.race([wait_for_message('foo'), innerDelay]); |
+ }).then(_ => { |
+ win.close(); |
+ }); |
+ }); |
+}, 'history.back() handles top level page timer correctly'); |
+ |
+promise_test(t => { |
+ let win; |
+ // Create a new window so we can navigate it later. |
+ return with_window_by_name('foo').then(w => { |
+ win = w; |
+ |
+ // Create a nested frame so we check if navigation and history.back() |
+ // properly handle child window state. |
+ return with_nested_frame(win, 'about:blank'); |
+ |
+ }).then(frame => { |
+ // Schedule a timer within the nested frame contained by the new window. |
+ // Our intent is to navigate the window before the timer fires. |
+ let delayFired = false; |
+ let innerDelay = delay(frame.contentWindow, DELAY); |
+ innerDelay.then(_ => { |
+ delayFired = true; |
+ }); |
+ |
+ return navigate_by_name(win, 'bar').then(_ => { |
+ // Since the window has navigated the timer should not |
+ // fire. We set a timer on our current test window |
+ // to verify the other timer is not received. |
+ assert_false(delayFired); |
+ return delay(window, DELAY * 2); |
+ }).then(_ => { |
+ // The navigated window's timer should not have fired. |
+ assert_false(delayFired); |
+ // Now go back to the document containing the frame that set the timer. |
+ return go_back(win); |
+ }).then(_ => { |
+ // We wait for one of two conditions here. For browsers |
+ // with a bfcache the original suspended timer will fire. |
+ // Alternatively, if the browser reloads the page the original |
+ // message will be sent again. Wait for either of these |
+ // two events. |
+ return Promise.race([wait_for_message('foo'), innerDelay]); |
+ }).then(_ => { |
+ win.close(); |
+ }); |
+ }); |
+}, 'history.back() handles nested iframe timer correctly'); |
+ |
+</script> |