diff options
Diffstat (limited to 'dom/presentation/tests/mochitest/test_presentation_terminate.js')
-rw-r--r-- | dom/presentation/tests/mochitest/test_presentation_terminate.js | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/dom/presentation/tests/mochitest/test_presentation_terminate.js b/dom/presentation/tests/mochitest/test_presentation_terminate.js new file mode 100644 index 000000000..8ebfd9d64 --- /dev/null +++ b/dom/presentation/tests/mochitest/test_presentation_terminate.js @@ -0,0 +1,243 @@ +'use strict'; + +SimpleTest.waitForExplicitFinish(); +SimpleTest.requestFlakyTimeout('Test for guarantee not firing async event'); + +function debug(str) { + // info(str); +} + +var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('PresentationSessionChromeScript1UA.js')); +var receiverUrl = SimpleTest.getTestFileURL('file_presentation_terminate.html'); +var request; +var connection; +var receiverIframe; + +function setup() { + gScript.addMessageListener('device-prompt', function devicePromptHandler() { + debug('Got message: device-prompt'); + gScript.removeMessageListener('device-prompt', devicePromptHandler); + gScript.sendAsyncMessage('trigger-device-prompt-select'); + }); + + gScript.addMessageListener('control-channel-established', function controlChannelEstablishedHandler() { + gScript.removeMessageListener('control-channel-established', + controlChannelEstablishedHandler); + gScript.sendAsyncMessage('trigger-control-channel-open'); + }); + + gScript.addMessageListener('sender-launch', function senderLaunchHandler(url) { + debug('Got message: sender-launch'); + gScript.removeMessageListener('sender-launch', senderLaunchHandler); + is(url, receiverUrl, 'Receiver: should receive the same url'); + receiverIframe = document.createElement('iframe'); + receiverIframe.setAttribute('mozbrowser', 'true'); + receiverIframe.setAttribute('mozpresentation', receiverUrl); + var oop = location.pathname.indexOf('_inproc') == -1; + receiverIframe.setAttribute('remote', oop); + + receiverIframe.setAttribute('src', receiverUrl); + receiverIframe.addEventListener('mozbrowserloadend', function mozbrowserloadendHander() { + receiverIframe.removeEventListener('mozbrowserloadend', mozbrowserloadendHander); + info('Receiver loaded.'); + }); + + // This event is triggered when the iframe calls 'alert'. + receiverIframe.addEventListener('mozbrowsershowmodalprompt', function receiverListener(evt) { + var message = evt.detail.message; + if (/^OK /.exec(message)) { + ok(true, message.replace(/^OK /, '')); + } else if (/^KO /.exec(message)) { + ok(false, message.replace(/^KO /, '')); + } else if (/^INFO /.exec(message)) { + info(message.replace(/^INFO /, '')); + } else if (/^COMMAND /.exec(message)) { + var command = JSON.parse(message.replace(/^COMMAND /, '')); + gScript.sendAsyncMessage(command.name, command.data); + } else if (/^DONE$/.exec(message)) { + ok(true, 'Messaging from iframe complete.'); + receiverIframe.removeEventListener('mozbrowsershowmodalprompt', + receiverListener); + } + }, false); + + var promise = new Promise(function(aResolve, aReject) { + document.body.appendChild(receiverIframe); + aResolve(receiverIframe); + }); + + var obs = SpecialPowers.Cc['@mozilla.org/observer-service;1'] + .getService(SpecialPowers.Ci.nsIObserverService); + obs.notifyObservers(promise, 'setup-request-promise', null); + }); + + gScript.addMessageListener('promise-setup-ready', function promiseSetupReadyHandler() { + debug('Got message: promise-setup-ready'); + gScript.removeMessageListener('promise-setup-ready', + promiseSetupReadyHandler); + gScript.sendAsyncMessage('trigger-on-session-request', receiverUrl); + }); + + return Promise.resolve(); +} + +function testCreateRequest() { + return new Promise(function(aResolve, aReject) { + info('Sender: --- testCreateRequest ---'); + request = new PresentationRequest(receiverUrl); + request.getAvailability().then((aAvailability) => { + is(aAvailability.value, false, "Sender: should have no available device after setup"); + aAvailability.onchange = function() { + aAvailability.onchange = null; + ok(aAvailability.value, 'Sender: Device should be available.'); + aResolve(); + } + + gScript.sendAsyncMessage('trigger-device-add'); + }).catch((aError) => { + ok(false, 'Sender: Error occurred when getting availability: ' + aError); + teardown(); + aReject(); + }); + }); +} + +function testStartConnection() { + return new Promise(function(aResolve, aReject) { + request.start().then((aConnection) => { + connection = aConnection; + ok(connection, 'Sender: Connection should be available.'); + ok(connection.id, 'Sender: Connection ID should be set.'); + is(connection.state, 'connecting', 'Sender: The initial state should be connecting.'); + connection.onconnect = function() { + connection.onconnect = null; + is(connection.state, 'connected', 'Connection should be connected.'); + aResolve(); + }; + + info('Sender: test terminate at connecting state'); + connection.onterminate = function() { + connection.onterminate = null; + ok(false, 'Should not be able to terminate at connecting state'); + aReject(); + } + connection.terminate(); + }).catch((aError) => { + ok(false, 'Sender: Error occurred when establishing a connection: ' + aError); + teardown(); + aReject(); + }); + }); +} + +function testConnectionTerminate() { + return new Promise(function(aResolve, aReject) { + info('Sender: --- testConnectionTerminate---'); + connection.onterminate = function() { + connection.onterminate = null; + is(connection.state, 'terminated', 'Sender: Connection should be terminated.'); + }; + gScript.addMessageListener('control-channel-established', function controlChannelEstablishedHandler() { + gScript.removeMessageListener('control-channel-established', + controlChannelEstablishedHandler); + gScript.sendAsyncMessage('trigger-control-channel-open'); + }); + gScript.addMessageListener('sender-terminate', function senderTerminateHandler() { + gScript.removeMessageListener('sender-terminate', + senderTerminateHandler); + + Promise.all([ + new Promise((resolve) => { + gScript.addMessageListener('device-disconnected', function deviceDisconnectedHandler() { + gScript.removeMessageListener('device-disconnected', deviceDisconnectedHandler); + ok(true, 'observe device disconnect'); + resolve(); + }); + }), + new Promise((resolve) => { + receiverIframe.addEventListener('mozbrowserclose', function() { + ok(true, 'observe receiver page closing'); + resolve(); + }); + }), + ]).then(aResolve); + + gScript.sendAsyncMessage('trigger-on-terminate-request'); + }); + gScript.addMessageListener('ready-to-terminate', function onReadyToTerminate() { + gScript.removeMessageListener('ready-to-terminate', onReadyToTerminate); + connection.terminate(); + + // test unexpected close right after terminate + connection.onclose = function() { + ok(false, 'close after terminate should do nothing'); + }; + connection.close(); + }); + }); +} + +function testSendAfterTerminate() { + return new Promise(function(aResolve, aReject) { + try { + connection.send('something'); + ok(false, 'PresentationConnection.send should be failed'); + } catch (e) { + is(e.name, 'InvalidStateError', 'Must throw InvalidStateError'); + } + aResolve(); + }); +} + +function testCloseAfterTerminate() { + return Promise.race([ + new Promise(function(aResolve, aReject) { + connection.onclose = function() { + connection.onclose = null; + ok(false, 'close at terminated state should do nothing'); + aResolve(); + }; + connection.close(); + }), + new Promise(function(aResolve, aReject) { + setTimeout(function() { + is(connection.state, 'terminated', 'Sender: Connection should be terminated.'); + aResolve(); + }, 3000); + }), + ]); +} + +function teardown() { + gScript.addMessageListener('teardown-complete', function teardownCompleteHandler() { + debug('Got message: teardown-complete'); + gScript.removeMessageListener('teardown-complete', teardownCompleteHandler); + gScript.destroy(); + SimpleTest.finish(); + }); + gScript.sendAsyncMessage('teardown'); +} + +function runTests() { + setup().then(testCreateRequest) + .then(testStartConnection) + .then(testConnectionTerminate) + .then(testSendAfterTerminate) + .then(testCloseAfterTerminate) + .then(teardown); +} + +SpecialPowers.pushPermissions([ + {type: 'presentation-device-manage', allow: false, context: document}, + {type: 'browser', allow: true, context: document}, +], () => { + SpecialPowers.pushPrefEnv({ 'set': [['dom.presentation.enabled', true], + ["dom.presentation.controller.enabled", true], + ["dom.presentation.receiver.enabled", true], + ['dom.presentation.test.enabled', true], + ['dom.mozBrowserFramesEnabled', true], + ["network.disable.ipc.security", true], + ['dom.ipc.tabs.disabled', false], + ['dom.presentation.test.stage', 0]]}, + runTests); +}); |