<!doctype html> <meta charset=utf-8> <title>Dispatching idle callbacks should be able to be suspended and then resumed</title> <meta name="timeout" content="long"> <script src=/resources/testharness.js></script> <script src=/resources/testharnessreport.js></script> <div id="log"></div> <script> function withEventListener(target, event, handler) { handler = handler || (e => e); return new Promise(resolve => { let wrapper = function(e) { let result = handler(e); if (!result) { return; } resolve(result); } target.addEventListener(event, wrapper, { once: true }); }); } function makePostBackUrl(name) { return new URL('resources/post_name_on_load.html?name=' + name, window.location).href; } function waitForMessage(message, handler) { return withEventListener(window, 'message', e => (e.data === message) && handler(e));; } function withWindow(name) { let win = window.open(makePostBackUrl(name)) return waitForMessage(name, _ => win); } function navigateWindow(win, name) { win.location = makePostBackUrl(name); return waitForMessage(name, _ => win); } function waitDuration(delay) { return new Promise(resolve => { step_timeout(resolve, delay); }) } function goBack(win) { var p = withEventListener(win, 'pagehide'); win.history.back(); return p; } promise_test(t => { let idleCalled = false; let running = true; return withWindow('foo') .then(win => { let callback = function(d) { idleCalled = true; if (running) { win.requestIdleCallback(callback); } }; win.requestIdleCallback(callback); return navigateWindow(win, 'bar') .then(_ => idleCalled = false) .then(_ => waitDuration(2000)) .then(_ => { assert_false(idleCalled, "idle callback shouldn't have been called yet"); return goBack(win); }) .then(_ => Promise.race([ // At this point it's a matter of having bfcache ... waitDuration(2000) .then(_ => { assert_true(idleCalled, "idle callback should've been called by now"); running = false; }), // ... or not. If not, we expect a load event. waitForMessage("foo", _ => win) ])) .then(_ => win.close()) .catch(e => { win.close(); throw e; }) }); }); </script>