| <!DOCTYPE html> |
| |
| <meta charset="utf-8"> |
| <title>Terminating a presentation in a controlling browsing context</title> |
| <link rel="author" title="Intel" href="http://www.intel.com"> |
| <link rel="author" title="Chunyan Wang" href="mailto:chunyanx.wang@intel.com"> |
| <link rel="author" title="Tomoyuki Shimizu" href="https://github.com/tomoyukilabs/"> |
| <link rel="help" href="https://w3c.github.io/presentation-api/#terminating-a-presentation-in-a-controlling-browsing-context"> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="common.js"></script> |
| <style>iframe { display: none; }</style> |
| <p> |
| Click the button below and select the available presentation display, to start the manual test. The test passes if a "PASS" result appears.<br> |
| This test asks you to click the button twice, unless the test fails.<br> |
| </p> |
| <button id="presentBtn">Start Presentation Test</button> |
| <iframe id="childFrame" src="support/iframe.html"></iframe> |
| |
| <script> |
| setup({explicit_timeout: true}); |
| const presentBtn = document.getElementById('presentBtn'); |
| const childFrame = document.getElementById('childFrame'); |
| |
| promise_test(t => { |
| const clickWatcher = new EventWatcher(t, presentBtn, 'click'); |
| const messageWatcher = new EventWatcher(t, window, 'message'); |
| const request = new PresentationRequest(presentationUrls); |
| let connection, eventWatcher, timeout; |
| |
| t.add_cleanup(() => { |
| if (connection) { |
| connection.onconnect = () => { connection.terminate(); }; |
| if (connection.state === 'closed') |
| request.reconnect(connection.id); |
| else |
| connection.terminate(); |
| } |
| }); |
| |
| const startTimeout = () => { |
| timeout = t.step_timeout(() => { |
| t.force_timeout(); |
| t.done(); |
| }, 10000); |
| }; |
| |
| const checkTerminateEvent = evt => { |
| assert_true(evt.isTrusted && !evt.bubbles && !evt.cancelable && evt instanceof Event, 'A simple event is fired.'); |
| assert_equals(evt.type, 'terminate', 'The event name is "terminate".'); |
| assert_equals(evt.target, connection, 'event.target is the presentation connection.'); |
| assert_equals(connection.state, 'terminated', 'State of the presentation connection is "terminated".'); |
| }; |
| |
| const watchEvent = (obj, watcher, type) => { |
| const watchHandler = new Promise(resolve => { |
| obj['on' + type] = evt => { resolve(evt); }; |
| }); |
| return Promise.all([ watchHandler, watcher.wait_for(type) ]).then(results => { |
| assert_equals(results[0], results[1], 'Both on' + type + ' and addEventListener pass the same event object.'); |
| return results[0]; |
| }); |
| }; |
| |
| const waitForEvent = (obj, watcher, type) => { |
| const watchHandler = new Promise(resolve => { |
| obj['on' + type] = evt => { resolve(evt); }; |
| }); |
| return Promise.race([ watchHandler, watcher.wait_for(type) ]); |
| }; |
| |
| return Promise.all([ |
| clickWatcher.wait_for('click'), |
| messageWatcher.wait_for('message') |
| ]).then(() => { |
| presentBtn.disabled = true; |
| |
| return request.start(); |
| }).then(c => { |
| startTimeout(); |
| |
| connection = c; |
| eventWatcher = new EventWatcher(t, connection, 'terminate'); |
| |
| // Step 1: terminate the presentation when the presentation connection is in "connecting" state |
| connection.terminate(); |
| return Promise.race([ |
| new Promise((_, reject) => { |
| t.step_timeout(() => { reject('The presentation is not terminated successfully when the presentation connection in "connecting" state.'); }, 3000); |
| }), |
| watchEvent(connection, eventWatcher, 'terminate') |
| ]); |
| }).then(evt => { |
| checkTerminateEvent(evt); |
| |
| // Step 2: terminate the presentation when the presentation connection is in "closed" state (nothing should happen) |
| presentBtn.textContent = 'Continue Presentation Test'; |
| presentBtn.disabled = false; |
| clearTimeout(timeout); |
| return clickWatcher.wait_for('click'); |
| }).then(() => { |
| return request.start(); |
| }).then(c => { |
| startTimeout(); |
| connection = c; |
| eventWatcher = new EventWatcher(t, connection, ['connect', 'close', 'terminate']); |
| return eventWatcher.wait_for('connect'); |
| }).then(() => { |
| connection.close(); |
| return eventWatcher.wait_for('close'); |
| }).then(() => { |
| const terminateWatcher = new EventWatcher(t, connection, 'terminate'); |
| connection.terminate(); |
| return Promise.race([ |
| new Promise(resolve => { t.step_timeout(resolve, 1000); }), |
| waitForEvent(connection, terminateWatcher, 'terminate').then(() => { |
| assert_unreached('Invoking PresentationConnection.terminate() in the "closed" state causes nothing.'); }) |
| ]); |
| }).then(() => { |
| // Step 3: terminate the presentation when the presentation connection is in "connected" state; |
| // this step also checks an event fired at another presentation connection in a nested browsing context |
| return request.reconnect(connection.id); |
| }).then(() => { |
| return eventWatcher.wait_for('connect'); |
| }).then(() => { |
| childFrame.contentWindow.postMessage('terminate?id=' + connection.id, '*'); |
| return messageWatcher.wait_for('message') |
| }).then(() => { |
| connection.terminate(); |
| return Promise.race([ |
| new Promise((_, reject) => { |
| t.step_timeout(() => { reject('The presentation is not terminated successfully when the presentation connection in "connected" state.'); }, 3000); |
| }), |
| Promise.all([ |
| watchEvent(connection, eventWatcher, 'terminate'), |
| messageWatcher.wait_for('message') |
| ]) |
| ]); |
| }).then(results => { |
| checkTerminateEvent(results[0]); |
| const evt = results[1].data; |
| assert_true(evt.isSimpleEvent, 'A simple event is fired in a nested browsing context.'); |
| assert_equals(evt.type, 'terminate', 'The event name is "terminate".'); |
| assert_true(evt.checkConnection, 'event.target is the presentation connection.'); |
| assert_equals(evt.state, 'terminated', 'State of the presentation connection is "terminated".'); |
| |
| // Step 4: terminate the presentation when the presentation connection is in "terminated" state (nothing should happen) |
| const terminateWatcher = new EventWatcher(t, connection, 'terminate'); |
| connection.terminate(); |
| return Promise.race([ |
| new Promise(resolve => { t.step_timeout(resolve, 1000); }), |
| waitForEvent(connection, terminateWatcher, 'terminate').then(() => { |
| assert_unreached('Invoking PresentationConnection.terminate() in the "terminated" state causes nothing.'); }) |
| ]); |
| }); |
| }); |
| </script> |