<!DOCTYPE HTML> <html> <!-- Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ --> <head> <meta charset="utf-8"> <title>Test for B2G Presentation API at sender side</title> <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> </head> <body> <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1069230">Test for B2G Presentation API at sender side</a> <script type="application/javascript;version=1.8"> 'use strict'; var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('PresentationSessionChromeScript.js')); var request; var connection; function testSetup() { return new Promise(function(aResolve, aReject) { request = new PresentationRequest("https://example.com"); request.getAvailability().then( function(aAvailability) { is(aAvailability.value, false, "Sender: should have no available device after setup"); aAvailability.onchange = function() { aAvailability.onchange = null; ok(aAvailability.value, "Device should be available."); aResolve(); } gScript.sendAsyncMessage('trigger-device-add'); }, function(aError) { ok(false, "Error occurred when getting availability: " + aError); teardown(); aReject(); } ); }); } function testStartConnection() { return new Promise(function(aResolve, aReject) { gScript.addMessageListener('device-prompt', function devicePromptHandler() { gScript.removeMessageListener('device-prompt', devicePromptHandler); info("Device prompt is triggered."); gScript.sendAsyncMessage('trigger-device-prompt-select'); }); gScript.addMessageListener('control-channel-established', function controlChannelEstablishedHandler() { gScript.removeMessageListener('control-channel-established', controlChannelEstablishedHandler); info("A control channel is established."); gScript.sendAsyncMessage('trigger-control-channel-open'); }); gScript.addMessageListener('control-channel-opened', function controlChannelOpenedHandler(aReason) { gScript.removeMessageListener('control-channel-opened', controlChannelOpenedHandler); info("The control channel is opened."); }); gScript.addMessageListener('control-channel-closed', function controlChannelClosedHandler(aReason) { gScript.removeMessageListener('control-channel-closed', controlChannelClosedHandler); info("The control channel is closed. " + aReason); }); gScript.addMessageListener('offer-sent', function offerSentHandler(aIsValid) { gScript.removeMessageListener('offer-sent', offerSentHandler); ok(aIsValid, "A valid offer is sent out."); gScript.sendAsyncMessage('trigger-incoming-transport'); }); gScript.addMessageListener('answer-received', function answerReceivedHandler() { gScript.removeMessageListener('answer-received', answerReceivedHandler); info("An answer is received."); }); gScript.addMessageListener('data-transport-initialized', function dataTransportInitializedHandler() { gScript.removeMessageListener('data-transport-initialized', dataTransportInitializedHandler); info("Data transport channel is initialized."); gScript.sendAsyncMessage('trigger-incoming-answer'); }); gScript.addMessageListener('data-transport-notification-enabled', function dataTransportNotificationEnabledHandler() { gScript.removeMessageListener('data-transport-notification-enabled', dataTransportNotificationEnabledHandler); info("Data notification is enabled for data transport channel."); }); var connectionFromEvent; request.onconnectionavailable = function(aEvent) { request.onconnectionavailable = null; connectionFromEvent = aEvent.connection; ok(connectionFromEvent, "|connectionavailable| event is fired with a connection."); if (connection) { is(connection, connectionFromEvent, "The connection from promise and the one from |connectionavailable| event should be the same."); } }; request.start().then( function(aConnection) { connection = aConnection; ok(connection, "Connection should be available."); ok(connection.id, "Connection ID should be set."); is(connection.state, "connecting", "The initial state should be connecting."); if (connectionFromEvent) { is(connection, connectionFromEvent, "The connection from promise and the one from |connectionavailable| event should be the same."); } connection.onconnect = function() { connection.onconnect = null; is(connection.state, "connected", "Connection should be connected."); aResolve(); }; }, function(aError) { ok(false, "Error occurred when establishing a connection: " + aError); teardown(); aReject(); } ); }); } function testSend() { return new Promise(function(aResolve, aReject) { const outgoingMessage = "test outgoing message"; gScript.addMessageListener('message-sent', function messageSentHandler(aMessage) { gScript.removeMessageListener('message-sent', messageSentHandler); is(aMessage, outgoingMessage, "The message is sent out."); aResolve(); }); connection.send(outgoingMessage); }); } function testIncomingMessage() { return new Promise(function(aResolve, aReject) { const incomingMessage = "test incoming message"; connection.addEventListener('message', function messageHandler(aEvent) { connection.removeEventListener('message', messageHandler); is(aEvent.data, incomingMessage, "An incoming message should be received."); aResolve(); }); gScript.sendAsyncMessage('trigger-incoming-message', incomingMessage); }); } function testCloseConnection() { return new Promise(function(aResolve, aReject) { gScript.addMessageListener('data-transport-closed', function dataTransportClosedHandler(aReason) { gScript.removeMessageListener('data-transport-closed', dataTransportClosedHandler); info("The data transport is closed. " + aReason); }); connection.onclose = function() { connection.onclose = null; is(connection.state, "closed", "Connection should be closed."); aResolve(); }; connection.close(); }); } function testReconnect() { return new Promise(function(aResolve, aReject) { info('--- testReconnect ---'); gScript.addMessageListener('control-channel-established', function controlChannelEstablished() { gScript.removeMessageListener('control-channel-established', controlChannelEstablished); gScript.sendAsyncMessage("trigger-control-channel-open"); }); gScript.addMessageListener('start-reconnect', function startReconnectHandler(url) { gScript.removeMessageListener('start-reconnect', startReconnectHandler); is(url, "https://example.com/", "URLs should be the same.") gScript.sendAsyncMessage('trigger-reconnected-acked', url); }); gScript.addMessageListener('offer-sent', function offerSentHandler() { gScript.removeMessageListener('offer-sent', offerSentHandler); gScript.sendAsyncMessage('trigger-incoming-transport'); }); gScript.addMessageListener('answer-received', function answerReceivedHandler() { gScript.removeMessageListener('answer-received', answerReceivedHandler); info("An answer is received."); }); gScript.addMessageListener('data-transport-initialized', function dataTransportInitializedHandler() { gScript.removeMessageListener('data-transport-initialized', dataTransportInitializedHandler); info("Data transport channel is initialized."); gScript.sendAsyncMessage('trigger-incoming-answer'); }); gScript.addMessageListener('data-transport-notification-enabled', function dataTransportNotificationEnabledHandler() { gScript.removeMessageListener('data-transport-notification-enabled', dataTransportNotificationEnabledHandler); info("Data notification is enabled for data transport channel."); }); request.reconnect(connection.id).then( function(aConnection) { ok(aConnection, "Connection should be available."); ok(aConnection.id, "Connection ID should be set."); is(aConnection.state, "connecting", "The initial state should be connecting."); is(aConnection, connection, "The reconnected connection should be the same."); aConnection.onconnect = function() { aConnection.onconnect = null; is(aConnection.state, "connected", "Connection should be connected."); aResolve(); }; }, function(aError) { ok(false, "Error occurred when establishing a connection: " + aError); teardown(); aReject(); } ); }); } function teardown() { gScript.addMessageListener('teardown-complete', function teardownCompleteHandler() { gScript.removeMessageListener('teardown-complete', teardownCompleteHandler); gScript.destroy(); SimpleTest.finish(); }); gScript.sendAsyncMessage('teardown'); } function runTests() { ok(window.PresentationRequest, "PresentationRequest should be available."); testSetup(). then(testStartConnection). then(testSend). then(testIncomingMessage). then(testCloseConnection). then(testReconnect). then(testCloseConnection). then(teardown); } SimpleTest.waitForExplicitFinish(); SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true], ["dom.presentation.controller.enabled", true], ["dom.presentation.session_transport.data_channel.enable", false]]}, runTests); </script> </body> </html>