| <!doctype html> |
| <meta name="timeout" content="long"> |
| <title>AudioContext.suspend() with navigation</title> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="/common/utils.js"></script> |
| <script src="/common/dispatcher/dispatcher.js"></script> |
| <script src="/html/browsers/browsing-the-web/back-forward-cache/resources/helper.sub.js"></script> |
| <script> |
| 'use strict'; |
| runBfcacheTest({ |
| funcBeforeNavigation: async () => { |
| window.promise_event = (target, name) => { |
| return new Promise(resolve => target[`on${name}`] = resolve); |
| }; |
| window.promise_source_ended = (audioCtx) => { |
| const source = new ConstantSourceNode(audioCtx); |
| source.start(0); |
| source.stop(audioCtx.currentTime + 1/audioCtx.sampleRate); |
| return promise_event(source, "ended"); |
| }; |
| |
| window.suspended_ctx = new AudioContext(); |
| // Perform the equivalent of test_driver.bless() to request a user gesture |
| // for when the test is run from a browser. test_driver would need to be |
| // able to postMessage() to the test context, which is not available due |
| // to window.open() being called with noopener (for back/forward cache). |
| // Audio autoplay is expected to be allowed when run through webdriver |
| // from `wpt run`. |
| let button = document.createElement('button'); |
| button.innerHTML = 'This test requires user interaction.<br />' + |
| 'Please click here to allow AudioContext.'; |
| document.body.appendChild(button); |
| button.addEventListener('click', () => { |
| document.body.removeChild(button); |
| suspended_ctx.resume(); |
| }, {once: true}); |
| // Wait for user gesture, if required. |
| await suspended_ctx.resume(); |
| await suspended_ctx.suspend(); |
| window.ended_promise = promise_source_ended(suspended_ctx); |
| }, |
| funcAfterAssertion: async (pageA) => { |
| const state = await pageA.execute_script(() => suspended_ctx.state); |
| assert_equals(state, 'suspended', 'state after back()'); |
| const first_ended = await pageA.execute_script(async () => { |
| // Wait for an ended event from a running AudioContext to provide enough |
| // time to check that the ended event has not yet been dispatched from |
| // the suspended ctx. |
| const running_ctx = new AudioContext(); |
| await running_ctx.resume(); |
| return Promise.race([ |
| ended_promise.then(() => 'suspended_ctx'), |
| promise_source_ended(running_ctx).then(() => 'running_ctx'), |
| ]); |
| }); |
| assert_equals(first_ended, 'running_ctx', |
| 'AudioContext of first ended event'); |
| await pageA.execute_script(() => { |
| window.suspended_ctx.resume(); |
| return ended_promise; |
| }); |
| }, |
| }, 'suspend() with navigation'); |
| </script> |