| 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>
 | 
| 
 |