зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1069230 - Presentation API implementation. Part 9 - Tests. r=kikuo
This commit is contained in:
Родитель
1efa4382a3
Коммит
5eda6c5cc4
|
@ -518,6 +518,10 @@ PresentationRequesterInfo::OnStopListening(nsIServerSocket* aServerSocket,
|
|||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (aStatus == NS_BINDING_ABORTED) { // The server socket was manually closed.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
Shutdown(aStatus);
|
||||
|
||||
if (!IsSessionReady()) {
|
||||
|
@ -795,7 +799,7 @@ PresentationResponderInfo::RejectedCallback(JSContext* aCx,
|
|||
JS::Handle<JS::Value> aValue)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
NS_WARNING("The receiver page fails to become ready before timeout.");
|
||||
NS_WARNING("Launching the receiver page has been rejected.");
|
||||
|
||||
if (mTimer) {
|
||||
mTimer->Cancel();
|
||||
|
|
|
@ -0,0 +1,359 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
'use strict';
|
||||
|
||||
const { classes: Cc, interfaces: Ci, manager: Cm, utils: Cu, results: Cr } = Components;
|
||||
|
||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
|
||||
function registerMockedFactory(contractId, mockedClassId, mockedFactory) {
|
||||
var originalClassId, originalFactory;
|
||||
|
||||
var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
if (!registrar.isCIDRegistered(mockedClassId)) {
|
||||
try {
|
||||
originalClassId = registrar.contractIDToCID(contractId);
|
||||
originalFactory = Cm.getClassObject(Cc[contractId], Ci.nsIFactory);
|
||||
} catch (ex) {
|
||||
originalClassId = "";
|
||||
originalFactory = null;
|
||||
}
|
||||
if (originalFactory) {
|
||||
registrar.unregisterFactory(originalClassId, originalFactory);
|
||||
}
|
||||
registrar.registerFactory(mockedClassId, "", contractId, mockedFactory);
|
||||
}
|
||||
|
||||
return { contractId: contractId,
|
||||
mockedClassId: mockedClassId,
|
||||
mockedFactory: mockedFactory,
|
||||
originalClassId: originalClassId,
|
||||
originalFactory: originalFactory };
|
||||
}
|
||||
|
||||
function registerOriginalFactory(contractId, mockedClassId, mockedFactory, originalClassId, originalFactory) {
|
||||
if (originalFactory) {
|
||||
registrar.unregisterFactory(mockedClassId, mockedFactory);
|
||||
registrar.registerFactory(originalClassId, "", contractId, originalFactory);
|
||||
}
|
||||
}
|
||||
|
||||
const sessionId = 'test-session-id';
|
||||
|
||||
const address = Cc["@mozilla.org/supports-cstring;1"]
|
||||
.createInstance(Ci.nsISupportsCString);
|
||||
address.data = "127.0.0.1";
|
||||
const addresses = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
|
||||
addresses.appendElement(address, false);
|
||||
|
||||
const mockedChannelDescription = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationChannelDescription]),
|
||||
type: 1,
|
||||
tcpAddress: addresses,
|
||||
tcpPort: 1234,
|
||||
};
|
||||
|
||||
const mockedServerSocket = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIServerSocket,
|
||||
Ci.nsIFactory]),
|
||||
createInstance: function(aOuter, aIID) {
|
||||
if (aOuter) {
|
||||
throw Components.results.NS_ERROR_NO_AGGREGATION;
|
||||
}
|
||||
return this.QueryInterface(aIID);
|
||||
},
|
||||
get port() {
|
||||
return this._port;
|
||||
},
|
||||
set listener(listener) {
|
||||
this._listener = listener;
|
||||
},
|
||||
init: function(port, loopbackOnly, backLog) {
|
||||
if (port != -1) {
|
||||
this._port = port;
|
||||
} else {
|
||||
this._port = 5678;
|
||||
}
|
||||
},
|
||||
asyncListen: function(listener) {
|
||||
this._listener = listener;
|
||||
},
|
||||
close: function() {
|
||||
this._listener.onStopListening(this, Cr.NS_BINDING_ABORTED);
|
||||
},
|
||||
simulateOnSocketAccepted: function(serverSocket, socketTransport) {
|
||||
this._listener.onSocketAccepted(serverSocket, socketTransport);
|
||||
}
|
||||
};
|
||||
|
||||
const mockedSocketTransport = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISocketTransport]),
|
||||
};
|
||||
|
||||
const mockedControlChannel = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlChannel]),
|
||||
set listener(listener) {
|
||||
this._listener = listener;
|
||||
},
|
||||
get listener() {
|
||||
return this._listener;
|
||||
},
|
||||
sendOffer: function(offer) {
|
||||
sendAsyncMessage('offer-sent');
|
||||
},
|
||||
sendAnswer: function(answer) {
|
||||
this._listener.QueryInterface(Ci.nsIPresentationSessionTransportCallback).notifyTransportReady();
|
||||
},
|
||||
close: function(reason) {
|
||||
sendAsyncMessage('control-channel-closed', reason);
|
||||
this._listener.QueryInterface(Ci.nsIPresentationControlChannelListener).notifyClosed(reason);
|
||||
},
|
||||
simulateReceiverReady: function() {
|
||||
this._listener.QueryInterface(Ci.nsIPresentationControlChannelListener).notifyReceiverReady();
|
||||
},
|
||||
simulateOnOffer: function() {
|
||||
sendAsyncMessage('offer-received');
|
||||
this._listener.QueryInterface(Ci.nsIPresentationControlChannelListener).onOffer(mockedChannelDescription);
|
||||
},
|
||||
simulateOnAnswer: function() {
|
||||
sendAsyncMessage('answer-received');
|
||||
this._listener.QueryInterface(Ci.nsIPresentationControlChannelListener).onAnswer(mockedChannelDescription);
|
||||
},
|
||||
};
|
||||
|
||||
const mockedDevice = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDevice]),
|
||||
id: 'id',
|
||||
name: 'name',
|
||||
type: 'type',
|
||||
establishControlChannel: function(url, presentationId) {
|
||||
sendAsyncMessage('control-channel-established');
|
||||
return mockedControlChannel;
|
||||
},
|
||||
set listener(listener) {
|
||||
this._listener = listener;
|
||||
},
|
||||
get listener() {
|
||||
return this._listener;
|
||||
},
|
||||
simulateSessionRequest: function(url, presentationId, controlChannel) {
|
||||
this._listener.onSessionRequest(this, url, presentationId, controlChannel);
|
||||
},
|
||||
};
|
||||
|
||||
const mockedDevicePrompt = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDevicePrompt,
|
||||
Ci.nsIFactory]),
|
||||
createInstance: function(aOuter, aIID) {
|
||||
if (aOuter) {
|
||||
throw Components.results.NS_ERROR_NO_AGGREGATION;
|
||||
}
|
||||
return this.QueryInterface(aIID);
|
||||
},
|
||||
set request(request) {
|
||||
this._request = request;
|
||||
},
|
||||
get request() {
|
||||
return this._request;
|
||||
},
|
||||
promptDeviceSelection: function(request) {
|
||||
this._request = request;
|
||||
sendAsyncMessage('device-prompt');
|
||||
},
|
||||
simulateSelect: function() {
|
||||
this._request.select(mockedDevice);
|
||||
},
|
||||
simulateCancel: function() {
|
||||
this._request.cancel();
|
||||
}
|
||||
};
|
||||
|
||||
const mockedSessionTransport = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationSessionTransport,
|
||||
Ci.nsIFactory]),
|
||||
createInstance: function(aOuter, aIID) {
|
||||
if (aOuter) {
|
||||
throw Components.results.NS_ERROR_NO_AGGREGATION;
|
||||
}
|
||||
return this.QueryInterface(aIID);
|
||||
},
|
||||
set callback(callback) {
|
||||
this._callback = callback;
|
||||
},
|
||||
get callback() {
|
||||
return this._callback;
|
||||
},
|
||||
get selfAddress() {
|
||||
return this._selfAddress;
|
||||
},
|
||||
initWithSocketTransport: function(transport, callback) {
|
||||
sendAsyncMessage('data-transport-initialized');
|
||||
this._callback = callback;
|
||||
this.simulateTransportReady();
|
||||
},
|
||||
initWithChannelDescription: function(description, callback) {
|
||||
this._callback = callback;
|
||||
|
||||
var addresses = description.QueryInterface(Ci.nsIPresentationChannelDescription).tcpAddress;
|
||||
this._selfAddress = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsINetAddr]),
|
||||
address: (addresses.length > 0) ?
|
||||
addresses.queryElementAt(0, Ci.nsISupportsCString).data : "",
|
||||
port: description.QueryInterface(Ci.nsIPresentationChannelDescription).tcpPort,
|
||||
};
|
||||
},
|
||||
send: function(data) {
|
||||
var binaryStream = Cc["@mozilla.org/binaryinputstream;1"].
|
||||
createInstance(Ci.nsIBinaryInputStream);
|
||||
binaryStream.setInputStream(data);
|
||||
var message = binaryStream.readBytes(binaryStream.available());
|
||||
sendAsyncMessage('message-sent', message);
|
||||
},
|
||||
close: function(reason) {
|
||||
sendAsyncMessage('data-transport-closed', reason);
|
||||
this._callback.QueryInterface(Ci.nsIPresentationSessionTransportCallback).notifyTransportClosed(reason);
|
||||
},
|
||||
simulateTransportReady: function() {
|
||||
this._callback.QueryInterface(Ci.nsIPresentationSessionTransportCallback).notifyTransportReady();
|
||||
},
|
||||
simulateIncomingMessage: function(message) {
|
||||
this._callback.QueryInterface(Ci.nsIPresentationSessionTransportCallback).notifyData(message);
|
||||
},
|
||||
};
|
||||
|
||||
const mockedNetworkInfo = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInfo]),
|
||||
getAddresses: function(ips, prefixLengths) {
|
||||
ips.value = ["127.0.0.1"];
|
||||
prefixLengths.value = [0];
|
||||
return 1;
|
||||
},
|
||||
};
|
||||
|
||||
const mockedNetworkManager = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkManager,
|
||||
Ci.nsIFactory]),
|
||||
createInstance: function(aOuter, aIID) {
|
||||
if (aOuter) {
|
||||
throw Components.results.NS_ERROR_NO_AGGREGATION;
|
||||
}
|
||||
return this.QueryInterface(aIID);
|
||||
},
|
||||
get activeNetworkInfo() {
|
||||
return mockedNetworkInfo;
|
||||
},
|
||||
};
|
||||
|
||||
var requestPromise = null;
|
||||
|
||||
const mockedRequestUIGlue = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationRequestUIGlue,
|
||||
Ci.nsIFactory]),
|
||||
createInstance: function(aOuter, aIID) {
|
||||
if (aOuter) {
|
||||
throw Components.results.NS_ERROR_NO_AGGREGATION;
|
||||
}
|
||||
return this.QueryInterface(aIID);
|
||||
},
|
||||
sendRequest: function(aUrl, aSessionId) {
|
||||
sendAsyncMessage('receiver-launching', aSessionId);
|
||||
return requestPromise;
|
||||
},
|
||||
};
|
||||
|
||||
// Register mocked factories.
|
||||
const uuidGenerator = Cc["@mozilla.org/uuid-generator;1"]
|
||||
.getService(Ci.nsIUUIDGenerator);
|
||||
const originalFactoryData = [];
|
||||
originalFactoryData.push(registerMockedFactory("@mozilla.org/presentation-device/prompt;1",
|
||||
uuidGenerator.generateUUID(),
|
||||
mockedDevicePrompt));
|
||||
originalFactoryData.push(registerMockedFactory("@mozilla.org/network/server-socket;1",
|
||||
uuidGenerator.generateUUID(),
|
||||
mockedServerSocket));
|
||||
originalFactoryData.push(registerMockedFactory("@mozilla.org/presentation/presentationsessiontransport;1",
|
||||
uuidGenerator.generateUUID(),
|
||||
mockedSessionTransport));
|
||||
originalFactoryData.push(registerMockedFactory("@mozilla.org/network/manager;1",
|
||||
uuidGenerator.generateUUID(),
|
||||
mockedNetworkManager));
|
||||
originalFactoryData.push(registerMockedFactory("@mozilla.org/presentation/requestuiglue;1",
|
||||
uuidGenerator.generateUUID(),
|
||||
mockedRequestUIGlue));
|
||||
|
||||
function tearDown() {
|
||||
requestPromise = null;
|
||||
mockedServerSocket.listener = null;
|
||||
mockedControlChannel.listener = null;
|
||||
mockedDevice.listener = null;
|
||||
mockedDevicePrompt.request = null;
|
||||
mockedSessionTransport.callback = null;
|
||||
|
||||
var deviceManager = Cc['@mozilla.org/presentation-device/manager;1']
|
||||
.getService(Ci.nsIPresentationDeviceManager);
|
||||
deviceManager.QueryInterface(Ci.nsIPresentationDeviceListener).removeDevice(mockedDevice);
|
||||
|
||||
// Register original factories.
|
||||
for (var data in originalFactoryData) {
|
||||
registerOriginalFactory(data.contractId, data.mockedClassId,
|
||||
data.mockedFactory, data.originalClassId,
|
||||
data.originalFactory);
|
||||
}
|
||||
|
||||
sendAsyncMessage('teardown-complete');
|
||||
}
|
||||
|
||||
addMessageListener('trigger-device-add', function() {
|
||||
var deviceManager = Cc['@mozilla.org/presentation-device/manager;1']
|
||||
.getService(Ci.nsIPresentationDeviceManager);
|
||||
deviceManager.QueryInterface(Ci.nsIPresentationDeviceListener).addDevice(mockedDevice);
|
||||
});
|
||||
|
||||
addMessageListener('trigger-device-prompt-select', function() {
|
||||
mockedDevicePrompt.simulateSelect();
|
||||
});
|
||||
|
||||
addMessageListener('trigger-device-prompt-cancel', function() {
|
||||
mockedDevicePrompt.simulateCancel();
|
||||
});
|
||||
|
||||
addMessageListener('trigger-incoming-session-request', function(url) {
|
||||
mockedDevice.simulateSessionRequest(url, sessionId, mockedControlChannel);
|
||||
});
|
||||
|
||||
addMessageListener('trigger-incoming-offer', function() {
|
||||
mockedControlChannel.simulateOnOffer();
|
||||
});
|
||||
|
||||
addMessageListener('trigger-incoming-answer', function() {
|
||||
mockedControlChannel.simulateOnAnswer();
|
||||
});
|
||||
|
||||
addMessageListener('trigger-incoming-transport', function() {
|
||||
mockedServerSocket.simulateOnSocketAccepted(mockedServerSocket, mockedSocketTransport);
|
||||
});
|
||||
|
||||
addMessageListener('trigger-control-channel-close', function(reason) {
|
||||
mockedControlChannel.close(reason);
|
||||
});
|
||||
|
||||
addMessageListener('trigger-data-transport-close', function(reason) {
|
||||
mockedSessionTransport.close(reason);
|
||||
});
|
||||
|
||||
addMessageListener('trigger-incoming-message', function(message) {
|
||||
mockedSessionTransport.simulateIncomingMessage(message);
|
||||
});
|
||||
|
||||
addMessageListener('teardown', function() {
|
||||
tearDown();
|
||||
});
|
||||
|
||||
var obs = Cc["@mozilla.org/observer-service;1"]
|
||||
.getService(Ci.nsIObserverService);
|
||||
obs.addObserver(function observer(aSubject, aTopic, aData) {
|
||||
obs.removeObserver(observer, aTopic);
|
||||
|
||||
requestPromise = aSubject;
|
||||
}, 'setup-request-promise', false);
|
|
@ -0,0 +1,77 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for B2G Presentation Session API at receiver side</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="content"></div>
|
||||
<script type="application/javascript;version=1.7">
|
||||
|
||||
"use strict";
|
||||
|
||||
function is(a, b, msg) {
|
||||
window.parent.postMessage((a === b ? 'OK ' : 'KO ') + msg, '*');
|
||||
}
|
||||
|
||||
function ok(a, msg) {
|
||||
window.parent.postMessage((a ? 'OK ' : 'KO ') + msg, '*');
|
||||
}
|
||||
|
||||
function info(msg) {
|
||||
window.parent.postMessage('INFO ' + msg, '*');
|
||||
}
|
||||
|
||||
function command(msg) {
|
||||
window.parent.postMessage('COMMAND ' + JSON.stringify(msg), '*');
|
||||
}
|
||||
|
||||
function finish() {
|
||||
window.parent.postMessage('DONE', '*');
|
||||
}
|
||||
|
||||
var session;
|
||||
|
||||
function testSessionAvailable() {
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
ok(navigator.presentation, "navigator.presentation should be available.");
|
||||
|
||||
session = navigator.presentation.session;
|
||||
ok(session.id, "Session ID should be set: " + session.id);
|
||||
is(session.state, "disconnected", "Session state at receiver side should be disconnected by default.");
|
||||
aResolve();
|
||||
});
|
||||
}
|
||||
|
||||
function testSessionReady() {
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
session.onstatechange = function() {
|
||||
session.onstatechange = null;
|
||||
is(session.state, "connected", "Session state should become connected.");
|
||||
aResolve();
|
||||
};
|
||||
|
||||
command({ name: 'trigger-incoming-offer' });
|
||||
});
|
||||
}
|
||||
|
||||
function testCloseSession() {
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
session.onstatechange = function() {
|
||||
session.onstatechange = null;
|
||||
is(session.state, "terminated", "Session should be terminated.");
|
||||
aResolve();
|
||||
};
|
||||
|
||||
session.close();
|
||||
});
|
||||
}
|
||||
|
||||
testSessionAvailable().
|
||||
then(testSessionReady).
|
||||
then(testCloseSession).
|
||||
then(finish);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,77 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for B2G Presentation Session API at receiver side (OOP)</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="content"></div>
|
||||
<script type="application/javascript;version=1.7">
|
||||
|
||||
"use strict";
|
||||
|
||||
function is(a, b, msg) {
|
||||
alert((a === b ? 'OK ' : 'KO ') + msg);
|
||||
}
|
||||
|
||||
function ok(a, msg) {
|
||||
alert((a ? 'OK ' : 'KO ') + msg);
|
||||
}
|
||||
|
||||
function info(msg) {
|
||||
alert('INFO ' + msg);
|
||||
}
|
||||
|
||||
function command(msg) {
|
||||
alert('COMMAND ' + JSON.stringify(msg));
|
||||
}
|
||||
|
||||
function finish() {
|
||||
alert('DONE');
|
||||
}
|
||||
|
||||
var session;
|
||||
|
||||
function testSessionAvailable() {
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
ok(navigator.presentation, "navigator.presentation should be available.");
|
||||
|
||||
session = navigator.presentation.session;
|
||||
ok(session.id, "Session ID should be set: " + session.id);
|
||||
is(session.state, "disconnected", "Session state at receiver side should be disconnected by default.");
|
||||
aResolve();
|
||||
});
|
||||
}
|
||||
|
||||
function testSessionReady() {
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
session.onstatechange = function() {
|
||||
session.onstatechange = null;
|
||||
is(session.state, "connected", "Session state should become connected.");
|
||||
aResolve();
|
||||
};
|
||||
|
||||
command({ name: 'trigger-incoming-offer' });
|
||||
});
|
||||
}
|
||||
|
||||
function testCloseSession() {
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
session.onstatechange = function() {
|
||||
session.onstatechange = null;
|
||||
is(session.state, "terminated", "Session should be terminated.");
|
||||
aResolve();
|
||||
};
|
||||
|
||||
session.close();
|
||||
});
|
||||
}
|
||||
|
||||
testSessionAvailable().
|
||||
then(testSessionReady).
|
||||
then(testCloseSession).
|
||||
then(finish);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,65 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for startSession errors of B2G Presentation API at receiver side</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="content"></div>
|
||||
<script type="application/javascript;version=1.7">
|
||||
|
||||
"use strict";
|
||||
|
||||
function is(a, b, msg) {
|
||||
window.parent.postMessage((a === b ? 'OK ' : 'KO ') + msg, '*');
|
||||
}
|
||||
|
||||
function ok(a, msg) {
|
||||
window.parent.postMessage((a ? 'OK ' : 'KO ') + msg, '*');
|
||||
}
|
||||
|
||||
function info(msg) {
|
||||
window.parent.postMessage('INFO ' + msg, '*');
|
||||
}
|
||||
|
||||
function command(msg) {
|
||||
window.parent.postMessage('COMMAND ' + JSON.stringify(msg), '*');
|
||||
}
|
||||
|
||||
function finish() {
|
||||
window.parent.postMessage('DONE', '*');
|
||||
}
|
||||
|
||||
var session;
|
||||
|
||||
function testSessionAvailable() {
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
ok(navigator.presentation, "navigator.presentation should be available.");
|
||||
|
||||
session = navigator.presentation.session;
|
||||
ok(session.id, "Session ID should be set: " + session.id);
|
||||
is(session.state, "disconnected", "Session state at receiver side should be disconnected by default.");
|
||||
aResolve();
|
||||
});
|
||||
}
|
||||
|
||||
function testUnexpectedControlChannelClose() {
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
session.onstatechange = function() {
|
||||
session.onstatechange = null;
|
||||
is(session.state, "terminated", "Session state should become terminated.");
|
||||
aResolve();
|
||||
};
|
||||
|
||||
// Trigger the control channel to be closed with error code.
|
||||
command({ name: 'trigger-control-channel-close', data: 0x80004004 /* NS_ERROR_ABORT */ });
|
||||
});
|
||||
}
|
||||
|
||||
testSessionAvailable().
|
||||
then(testUnexpectedControlChannelClose).
|
||||
then(finish);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,6 +1,24 @@
|
|||
[DEFAULT]
|
||||
support-files =
|
||||
PresentationDeviceInfoChromeScript.js
|
||||
PresentationSessionChromeScript.js
|
||||
file_presentation_receiver.html
|
||||
file_presentation_receiver_oop.html
|
||||
file_presentation_receiver_start_session_error.html
|
||||
|
||||
[test_presentation_device_info.html]
|
||||
[test_presentation_device_info_permission.html]
|
||||
[test_presentation_sender_disconnect.html]
|
||||
skip-if = toolkit == 'android' # Bug 1129785
|
||||
[test_presentation_sender_start_session_error.html]
|
||||
skip-if = toolkit == 'android' # Bug 1129785
|
||||
[test_presentation_sender.html]
|
||||
skip-if = toolkit == 'android' # Bug 1129785
|
||||
[test_presentation_receiver_start_session_error.html]
|
||||
skip-if = (e10s || toolkit == 'gonk' || toolkit == 'android') # Bug 1129785
|
||||
[test_presentation_receiver_start_session_timeout.html]
|
||||
skip-if = (e10s || toolkit == 'gonk' || toolkit == 'android') # Bug 1129785
|
||||
[test_presentation_receiver.html]
|
||||
skip-if = (e10s || toolkit == 'gonk' || toolkit == 'android') # Bug 1129785
|
||||
[test_presentation_receiver_oop.html]
|
||||
skip-if = (e10s || toolkit == 'gonk' || toolkit == 'android') # Bug 1129785
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
<!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 Session API at receiver side</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1069230">Test for B2G Presentation Session API at receiver side</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script type="application/javascript">
|
||||
|
||||
'use strict';
|
||||
|
||||
var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('PresentationSessionChromeScript.js'));
|
||||
var receiverUrl = SimpleTest.getTestFileURL('file_presentation_receiver.html');
|
||||
|
||||
var obs = SpecialPowers.Cc["@mozilla.org/observer-service;1"]
|
||||
.getService(SpecialPowers.Ci.nsIObserverService);
|
||||
|
||||
function setup() {
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
gScript.sendAsyncMessage('trigger-device-add');
|
||||
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.setAttribute('src', receiverUrl);
|
||||
|
||||
// This event is triggered when the iframe calls "postMessage".
|
||||
window.addEventListener('message', function listener(aEvent) {
|
||||
var message = aEvent.data;
|
||||
if (/^OK /.exec(message)) {
|
||||
ok(true, "Message from iframe: " + message);
|
||||
} else if (/^KO /.exec(message)) {
|
||||
ok(false, "Message from iframe: " + message);
|
||||
} else if (/^INFO /.exec(message)) {
|
||||
info("Message from iframe: " + message);
|
||||
} 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.");
|
||||
window.removeEventListener('message', listener);
|
||||
|
||||
teardown();
|
||||
}
|
||||
}, false);
|
||||
|
||||
var promise = new Promise(function(aResolve, aReject) {
|
||||
document.body.appendChild(iframe);
|
||||
|
||||
aResolve(iframe);
|
||||
});
|
||||
obs.notifyObservers(promise, 'setup-request-promise', null);
|
||||
|
||||
gScript.addMessageListener('offer-received', function offerReceivedHandler() {
|
||||
gScript.removeMessageListener('offer-received', offerReceivedHandler);
|
||||
info("An offer is received.");
|
||||
});
|
||||
|
||||
gScript.addMessageListener('control-channel-closed', function controlChannelClosedHandler(aReason) {
|
||||
gScript.removeMessageListener('control-channel-closed', controlChannelClosedHandler);
|
||||
is(aReason, SpecialPowers.Cr.NS_OK, "The control channel is closed normally.");
|
||||
});
|
||||
|
||||
gScript.addMessageListener('data-transport-closed', function dataTransportClosedHandler(aReason) {
|
||||
gScript.removeMessageListener('data-transport-closed', dataTransportClosedHandler);
|
||||
is(aReason, SpecialPowers.Cr.NS_OK, "The data transport should be closed normally.");
|
||||
});
|
||||
|
||||
aResolve();
|
||||
});
|
||||
}
|
||||
|
||||
function testIncomingSessionRequest() {
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
gScript.addMessageListener('receiver-launching', function launchReceiverHandler(aSessionId) {
|
||||
gScript.removeMessageListener('receiver-launching', launchReceiverHandler);
|
||||
info("Trying to launch receiver page.");
|
||||
|
||||
aResolve();
|
||||
});
|
||||
|
||||
gScript.sendAsyncMessage('trigger-incoming-session-request', receiverUrl);
|
||||
});
|
||||
}
|
||||
|
||||
function teardown() {
|
||||
gScript.addMessageListener('teardown-complete', function teardownCompleteHandler() {
|
||||
gScript.removeMessageListener('teardown-complete', teardownCompleteHandler);
|
||||
gScript.destroy();
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
gScript.sendAsyncMessage('teardown');
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
setup().
|
||||
then(testIncomingSessionRequest);
|
||||
}
|
||||
|
||||
SimpleTest.expectAssertions(0, 5);
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPermissions([
|
||||
{type: 'presentation-device-manage', allow: false, context: document},
|
||||
{type: 'presentation', allow: true, context: document},
|
||||
], function() {
|
||||
SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
|
||||
["dom.ignore_webidl_scope_checks", true],
|
||||
["dom.presentation.test.enabled", true],
|
||||
["dom.presentation.test.stage", 0]]},
|
||||
runTests);
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,131 @@
|
|||
<!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 Session API at receiver side (OOP)</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1069230">Test B2G Presentation Session API at receiver side (OOP)</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script type="application/javascript">
|
||||
|
||||
'use strict';
|
||||
|
||||
var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('PresentationSessionChromeScript.js'));
|
||||
var receiverUrl = SimpleTest.getTestFileURL('file_presentation_receiver_oop.html');
|
||||
|
||||
var obs = SpecialPowers.Cc["@mozilla.org/observer-service;1"]
|
||||
.getService(SpecialPowers.Ci.nsIObserverService);
|
||||
|
||||
function setup() {
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
gScript.sendAsyncMessage('trigger-device-add');
|
||||
|
||||
SpecialPowers.addPermission('presentation', true, { url: receiverUrl,
|
||||
appId: SpecialPowers.Ci.nsIScriptSecurityManager.NO_APP_ID,
|
||||
isInBrowserElement: true });
|
||||
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.setAttribute('remote', 'true');
|
||||
iframe.setAttribute('mozbrowser', 'true');
|
||||
iframe.setAttribute('src', receiverUrl);
|
||||
|
||||
// This event is triggered when the iframe calls "alert".
|
||||
iframe.addEventListener('mozbrowsershowmodalprompt', function listener(aEvent) {
|
||||
var message = aEvent.detail.message;
|
||||
if (/^OK /.exec(message)) {
|
||||
ok(true, "Message from iframe: " + message);
|
||||
} else if (/^KO /.exec(message)) {
|
||||
ok(false, "Message from iframe: " + message);
|
||||
} else if (/^INFO /.exec(message)) {
|
||||
info("Message from iframe: " + message);
|
||||
} 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.");
|
||||
iframe.removeEventListener('mozbrowsershowmodalprompt', listener);
|
||||
|
||||
teardown();
|
||||
}
|
||||
}, false);
|
||||
|
||||
var promise = new Promise(function(aResolve, aReject) {
|
||||
document.body.appendChild(iframe);
|
||||
|
||||
aResolve(iframe);
|
||||
});
|
||||
obs.notifyObservers(promise, 'setup-request-promise', null);
|
||||
|
||||
gScript.addMessageListener('offer-received', function offerReceivedHandler() {
|
||||
gScript.removeMessageListener('offer-received', offerReceivedHandler);
|
||||
info("An offer is received.");
|
||||
});
|
||||
|
||||
gScript.addMessageListener('control-channel-closed', function controlChannelClosedHandler(aReason) {
|
||||
gScript.removeMessageListener('control-channel-closed', controlChannelClosedHandler);
|
||||
is(aReason, SpecialPowers.Cr.NS_OK, "The control channel is closed normally.");
|
||||
});
|
||||
|
||||
gScript.addMessageListener('data-transport-closed', function dataTransportClosedHandler(aReason) {
|
||||
gScript.removeMessageListener('data-transport-closed', dataTransportClosedHandler);
|
||||
is(aReason, SpecialPowers.Cr.NS_OK, "The data transport should be closed normally.");
|
||||
});
|
||||
|
||||
aResolve();
|
||||
});
|
||||
}
|
||||
|
||||
function testIncomingSessionRequest() {
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
gScript.addMessageListener('receiver-launching', function launchReceiverHandler(aSessionId) {
|
||||
gScript.removeMessageListener('receiver-launching', launchReceiverHandler);
|
||||
info("Trying to launch receiver page.");
|
||||
|
||||
aResolve();
|
||||
});
|
||||
|
||||
gScript.sendAsyncMessage('trigger-incoming-session-request', receiverUrl);
|
||||
});
|
||||
}
|
||||
|
||||
function teardown() {
|
||||
gScript.addMessageListener('teardown-complete', function teardownCompleteHandler() {
|
||||
gScript.removeMessageListener('teardown-complete', teardownCompleteHandler);
|
||||
gScript.destroy();
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
gScript.sendAsyncMessage('teardown');
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
setup().
|
||||
then(testIncomingSessionRequest);
|
||||
}
|
||||
|
||||
SimpleTest.expectAssertions(0, 5);
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPermissions([
|
||||
{type: 'presentation-device-manage', allow: false, context: document},
|
||||
{type: 'presentation', allow: true, context: document},
|
||||
{type: 'browser', allow: true, context: document},
|
||||
], function() {
|
||||
SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
|
||||
["dom.ignore_webidl_scope_checks", true],
|
||||
["dom.presentation.test.enabled", true],
|
||||
["dom.presentation.test.stage", 0],
|
||||
["dom.mozBrowserFramesEnabled", true],
|
||||
["dom.ipc.browser_frames.oop_by_default", true]]},
|
||||
runTests);
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,110 @@
|
|||
<!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 startSession errors of B2G Presentation API at receiver side</title>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1069230">Test for startSession errors of B2G Presentation API at receiver side</a>
|
||||
<script type="application/javascript;version=1.8">
|
||||
|
||||
'use strict';
|
||||
|
||||
var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('PresentationSessionChromeScript.js'));
|
||||
var receiverUrl = SimpleTest.getTestFileURL('file_presentation_receiver_start_session_error.html');
|
||||
|
||||
var obs = SpecialPowers.Cc["@mozilla.org/observer-service;1"]
|
||||
.getService(SpecialPowers.Ci.nsIObserverService);
|
||||
var session;
|
||||
|
||||
function setup() {
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
gScript.sendAsyncMessage('trigger-device-add');
|
||||
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.setAttribute('src', receiverUrl);
|
||||
|
||||
// This event is triggered when the iframe calls "postMessage".
|
||||
window.addEventListener('message', function listener(aEvent) {
|
||||
var message = aEvent.data;
|
||||
if (/^OK /.exec(message)) {
|
||||
ok(true, "Message from iframe: " + message);
|
||||
} else if (/^KO /.exec(message)) {
|
||||
ok(false, "Message from iframe: " + message);
|
||||
} else if (/^INFO /.exec(message)) {
|
||||
info("Message from iframe: " + message);
|
||||
} 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.");
|
||||
window.removeEventListener('message', listener);
|
||||
|
||||
teardown();
|
||||
}
|
||||
}, false);
|
||||
|
||||
var promise = new Promise(function(aResolve, aReject) {
|
||||
document.body.appendChild(iframe);
|
||||
|
||||
aResolve(iframe);
|
||||
});
|
||||
obs.notifyObservers(promise, 'setup-request-promise', null);
|
||||
|
||||
gScript.addMessageListener('control-channel-closed', function controlChannelClosedHandler(aReason) {
|
||||
gScript.removeMessageListener('control-channel-closed', controlChannelClosedHandler);
|
||||
is(aReason, 0x80004004 /* NS_ERROR_ABORT */, "The control channel is closed abnormally.");
|
||||
});
|
||||
|
||||
aResolve();
|
||||
});
|
||||
}
|
||||
|
||||
function testIncomingSessionRequest() {
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
gScript.addMessageListener('receiver-launching', function launchReceiverHandler(aSessionId) {
|
||||
gScript.removeMessageListener('receiver-launching', launchReceiverHandler);
|
||||
info("Trying to launch receiver page.");
|
||||
|
||||
aResolve();
|
||||
});
|
||||
|
||||
gScript.sendAsyncMessage('trigger-incoming-session-request', receiverUrl);
|
||||
});
|
||||
}
|
||||
|
||||
function teardown() {
|
||||
gScript.addMessageListener('teardown-complete', function teardownCompleteHandler() {
|
||||
gScript.removeMessageListener('teardown-complete', teardownCompleteHandler);
|
||||
gScript.destroy();
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
gScript.sendAsyncMessage('teardown');
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
setup().
|
||||
then(testIncomingSessionRequest);
|
||||
}
|
||||
|
||||
SimpleTest.expectAssertions(0, 5);
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPermissions([
|
||||
{type: 'presentation-device-manage', allow: false, context: document},
|
||||
{type: 'presentation', allow: true, context: document},
|
||||
], function() {
|
||||
SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
|
||||
["dom.ignore_webidl_scope_checks", true],
|
||||
["dom.presentation.test.enabled", true],
|
||||
["dom.presentation.test.stage", 0]]},
|
||||
runTests);
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,84 @@
|
|||
<!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 startSession timeout of B2G Presentation API at receiver side</title>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1069230">Test for startSession timeout of B2G Presentation API at receiver side</a>
|
||||
<script type="application/javascript;version=1.8">
|
||||
|
||||
'use strict';
|
||||
|
||||
var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('PresentationSessionChromeScript.js'));
|
||||
|
||||
var obs = SpecialPowers.Cc["@mozilla.org/observer-service;1"]
|
||||
.getService(SpecialPowers.Ci.nsIObserverService);
|
||||
|
||||
function setup() {
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
gScript.sendAsyncMessage('trigger-device-add');
|
||||
|
||||
var promise = new Promise(function(aResolve, aReject) {
|
||||
// In order to trigger timeout, do not resolve the promise.
|
||||
});
|
||||
obs.notifyObservers(promise, 'setup-request-promise', null);
|
||||
|
||||
aResolve();
|
||||
});
|
||||
}
|
||||
|
||||
function testIncomingSessionRequestReceiverLaunchTimeout() {
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
gScript.addMessageListener('receiver-launching', function launchReceiverHandler(aSessionId) {
|
||||
gScript.removeMessageListener('receiver-launching', launchReceiverHandler);
|
||||
info("Trying to launch receiver page.");
|
||||
});
|
||||
|
||||
gScript.addMessageListener('control-channel-closed', function controlChannelClosedHandler(aReason) {
|
||||
gScript.removeMessageListener('control-channel-closed', controlChannelClosedHandler);
|
||||
is(aReason, 0x80530017 /* NS_ERROR_DOM_TIMEOUT_ERR */, "The control channel is closed due to timeout.");
|
||||
aResolve();
|
||||
});
|
||||
|
||||
gScript.sendAsyncMessage('trigger-incoming-session-request', 'http://example.com');
|
||||
});
|
||||
}
|
||||
|
||||
function teardown() {
|
||||
gScript.addMessageListener('teardown-complete', function teardownCompleteHandler() {
|
||||
gScript.removeMessageListener('teardown-complete', teardownCompleteHandler);
|
||||
gScript.destroy();
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
gScript.sendAsyncMessage('teardown');
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
setup().
|
||||
then(testIncomingSessionRequestReceiverLaunchTimeout).
|
||||
then(teardown);
|
||||
}
|
||||
|
||||
SimpleTest.expectAssertions(0, 5);
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPermissions([
|
||||
{type: 'presentation-device-manage', allow: false, context: document},
|
||||
{type: 'presentation', allow: true, context: document},
|
||||
], function() {
|
||||
SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
|
||||
["dom.ignore_webidl_scope_checks", true],
|
||||
["dom.presentation.test.enabled", true],
|
||||
["dom.presentation.test.stage", 0],
|
||||
["presentation.receiver.loading.timeout", 10]]},
|
||||
runTests);
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,167 @@
|
|||
<!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="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/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 presentation;
|
||||
var session;
|
||||
|
||||
function testSetup() {
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
presentation.onavailablechange = function(aIsAvailable) {
|
||||
presentation.onavailablechange = null;
|
||||
ok(aIsAvailable, "Device should be available.");
|
||||
aResolve();
|
||||
};
|
||||
|
||||
gScript.sendAsyncMessage('trigger-device-add');
|
||||
});
|
||||
}
|
||||
|
||||
function testStartSession() {
|
||||
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.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() {
|
||||
gScript.removeMessageListener('offer-sent', offerSentHandler);
|
||||
info("An 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');
|
||||
});
|
||||
|
||||
presentation.startSession("http://example.com").then(
|
||||
function(aSession) {
|
||||
session = aSession;
|
||||
ok(session, "Session should be availlable.");
|
||||
ok(session.id, "Session ID should be set.");
|
||||
is(session.state, "connected", "Session state at sender side should be connected by default.");
|
||||
aResolve();
|
||||
},
|
||||
function(aError) {
|
||||
ok(false, "Error occurred when starting session: " + 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();
|
||||
});
|
||||
|
||||
session.send(outgoingMessage);
|
||||
});
|
||||
}
|
||||
|
||||
function testIncomingMessage() {
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
const incomingMessage = "test incoming message";
|
||||
|
||||
session.addEventListener('message', function messageHandler(aEvent) {
|
||||
session.removeEventListener('message', messageHandler);
|
||||
is(aEvent.data, incomingMessage, "An incoming message should be received.");
|
||||
aResolve();
|
||||
});
|
||||
|
||||
gScript.sendAsyncMessage('trigger-incoming-message', incomingMessage);
|
||||
});
|
||||
}
|
||||
|
||||
function testCloseSession() {
|
||||
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);
|
||||
});
|
||||
|
||||
session.onstatechange = function() {
|
||||
session.onstatechange = null;
|
||||
is(session.state, "terminated", "Session should be terminated.");
|
||||
aResolve();
|
||||
};
|
||||
|
||||
session.close();
|
||||
});
|
||||
}
|
||||
|
||||
function teardown() {
|
||||
gScript.addMessageListener('teardown-complete', function teardownCompleteHandler() {
|
||||
gScript.removeMessageListener('teardown-complete', teardownCompleteHandler);
|
||||
gScript.destroy();
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
gScript.sendAsyncMessage('teardown');
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
ok(navigator.presentation, "navigator.presentation should be available.");
|
||||
presentation = navigator.presentation;
|
||||
|
||||
testSetup().
|
||||
then(testStartSession).
|
||||
then(testSend).
|
||||
then(testIncomingMessage).
|
||||
then(testCloseSession).
|
||||
then(teardown);
|
||||
}
|
||||
|
||||
SimpleTest.expectAssertions(0, 5);
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPermissions([
|
||||
{type: 'presentation-device-manage', allow: false, context: document},
|
||||
{type: 'presentation', allow: true, context: document},
|
||||
], function() {
|
||||
SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
|
||||
["dom.ignore_webidl_scope_checks", true],
|
||||
["dom.presentation.test.enabled", true],
|
||||
["dom.presentation.test.stage", 0]]},
|
||||
runTests);
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,150 @@
|
|||
<!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 session disconnection of B2G Presentation API at sender side</title>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1069230">Test for session disconnection of 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 presentation;
|
||||
var session;
|
||||
|
||||
function testSetup() {
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
presentation.onavailablechange = function(aIsAvailable) {
|
||||
presentation.onavailablechange = null;
|
||||
ok(aIsAvailable, "Device should be available.");
|
||||
aResolve();
|
||||
};
|
||||
|
||||
gScript.sendAsyncMessage('trigger-device-add');
|
||||
});
|
||||
}
|
||||
|
||||
function testStartSession() {
|
||||
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.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() {
|
||||
gScript.removeMessageListener('offer-sent', offerSentHandler);
|
||||
info("An offer is sent out.");
|
||||
gScript.sendAsyncMessage('trigger-incoming-answer');
|
||||
});
|
||||
|
||||
gScript.addMessageListener('answer-received', function answerReceivedHandler() {
|
||||
gScript.removeMessageListener('answer-received', answerReceivedHandler);
|
||||
info("An answer is received.");
|
||||
gScript.sendAsyncMessage('trigger-incoming-transport');
|
||||
});
|
||||
|
||||
gScript.addMessageListener('data-transport-initialized', function dataTransportInitializedHandler() {
|
||||
gScript.removeMessageListener('data-transport-initialized', dataTransportInitializedHandler);
|
||||
info("Data transport channel is initialized.");
|
||||
});
|
||||
|
||||
presentation.startSession("http://example.com").then(
|
||||
function(aSession) {
|
||||
session = aSession;
|
||||
ok(session, "Session should be availlable.");
|
||||
ok(session.id, "Session ID should be set.");
|
||||
is(session.state, "connected", "Session state at sender side should be connected by default.");
|
||||
aResolve();
|
||||
},
|
||||
function(aError) {
|
||||
ok(false, "Error occurred when starting session: " + aError);
|
||||
teardown();
|
||||
aReject();
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function testSessionDisconnection() {
|
||||
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);
|
||||
});
|
||||
|
||||
session.onstatechange = function() {
|
||||
session.onstatechange = null;
|
||||
is(session.state, "disconnected", "Session should be disconnected.");
|
||||
aResolve();
|
||||
};
|
||||
|
||||
gScript.sendAsyncMessage('trigger-data-transport-close', SpecialPowers.Cr.NS_ERROR_FAILURE);
|
||||
});
|
||||
}
|
||||
|
||||
function testCloseSession() {
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
session.onstatechange = function() {
|
||||
session.onstatechange = null;
|
||||
is(session.state, "terminated", "Session should be terminated.");
|
||||
aResolve();
|
||||
};
|
||||
|
||||
session.close();
|
||||
});
|
||||
}
|
||||
|
||||
function teardown() {
|
||||
gScript.addMessageListener('teardown-complete', function teardownCompleteHandler() {
|
||||
gScript.removeMessageListener('teardown-complete', teardownCompleteHandler);
|
||||
gScript.destroy();
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
gScript.sendAsyncMessage('teardown');
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
ok(navigator.presentation, "navigator.presentation should be available.");
|
||||
presentation = navigator.presentation;
|
||||
|
||||
testSetup().
|
||||
then(testStartSession).
|
||||
then(testSessionDisconnection).
|
||||
then(testCloseSession).
|
||||
then(teardown);
|
||||
}
|
||||
|
||||
SimpleTest.expectAssertions(0, 5);
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPermissions([
|
||||
{type: 'presentation-device-manage', allow: false, context: document},
|
||||
{type: 'presentation', allow: true, context: document},
|
||||
], function() {
|
||||
SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
|
||||
["dom.ignore_webidl_scope_checks", true],
|
||||
["dom.presentation.test.enabled", true],
|
||||
["dom.presentation.test.stage", 0]]},
|
||||
runTests);
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,239 @@
|
|||
<!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 startSession errors of B2G Presentation API at sender side</title>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1069230">Test for startSession errors of 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 presentation;
|
||||
|
||||
function setup() {
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
presentation.onavailablechange = function(aIsAvailable) {
|
||||
presentation.onavailablechange = null;
|
||||
ok(aIsAvailable, "Device should be available.");
|
||||
aResolve();
|
||||
};
|
||||
|
||||
gScript.sendAsyncMessage('trigger-device-add');
|
||||
});
|
||||
}
|
||||
|
||||
function testStartSessionNoAvailableDevice() {
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
presentation.startSession("http://example.com").then(
|
||||
function(aSession) {
|
||||
ok(false, "startSession shouldn't succeed in this case.");
|
||||
aReject();
|
||||
},
|
||||
function(aError) {
|
||||
is(aError.name, "InvalidStateError", "InvalidStateError is expected when starting session.");
|
||||
aResolve();
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function testStartSessionCancelPrompt() {
|
||||
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-cancel');
|
||||
});
|
||||
|
||||
presentation.startSession("http://example.com").then(
|
||||
function(aSession) {
|
||||
ok(false, "startSession shouldn't succeed in this case.");
|
||||
aReject();
|
||||
},
|
||||
function(aError) {
|
||||
is(aError.name, "NS_ERROR_DOM_PROP_ACCESS_DENIED", "NS_ERROR_DOM_PROP_ACCESS_DENIED is expected when starting session.");
|
||||
aResolve();
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function testStartSessionUnexpectedControlChannelCloseBeforeDataTransportInit() {
|
||||
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.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() {
|
||||
gScript.removeMessageListener('offer-sent', offerSentHandler);
|
||||
info("An offer is sent out.");
|
||||
gScript.sendAsyncMessage('trigger-control-channel-close', SpecialPowers.Cr.NS_ERROR_FAILURE);
|
||||
});
|
||||
|
||||
presentation.startSession("http://example.com").then(
|
||||
function(aSession) {
|
||||
ok(false, "startSession shouldn't succeed in this case.");
|
||||
aReject();
|
||||
},
|
||||
function(aError) {
|
||||
is(aError.name, "NS_ERROR_FAILURE", "NS_ERROR_FAILURE is expected when starting session.");
|
||||
aResolve();
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function testStartSessionUnexpectedControlChannelCloseBeforeDataTransportReady() {
|
||||
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.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() {
|
||||
gScript.removeMessageListener('offer-sent', offerSentHandler);
|
||||
info("An offer is sent out.");
|
||||
gScript.sendAsyncMessage('trigger-incoming-transport');
|
||||
});
|
||||
|
||||
gScript.addMessageListener('data-transport-initialized', function dataTransportInitializedHandler() {
|
||||
gScript.removeMessageListener('data-transport-initialized', dataTransportInitializedHandler);
|
||||
info("Data transport channel is initialized.");
|
||||
gScript.sendAsyncMessage('trigger-control-channel-close', SpecialPowers.Cr.NS_ERROR_ABORT);
|
||||
});
|
||||
|
||||
gScript.addMessageListener('data-transport-closed', function dataTransportClosedHandler(aReason) {
|
||||
gScript.removeMessageListener('data-transport-closed', dataTransportClosedHandler);
|
||||
info("The data transport is closed. " + aReason);
|
||||
});
|
||||
|
||||
presentation.startSession("http://example.com").then(
|
||||
function(aSession) {
|
||||
ok(false, "startSession shouldn't succeed in this case.");
|
||||
aReject();
|
||||
},
|
||||
function(aError) {
|
||||
is(aError.name, "NS_ERROR_ABORT", "NS_ERROR_ABORT is expected when starting session.");
|
||||
aResolve();
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function testStartSessionUnexpectedDataTransportClose() {
|
||||
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.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() {
|
||||
gScript.removeMessageListener('offer-sent', offerSentHandler);
|
||||
info("An offer is sent out.");
|
||||
gScript.sendAsyncMessage('trigger-incoming-transport');
|
||||
});
|
||||
|
||||
gScript.addMessageListener('data-transport-initialized', function dataTransportInitializedHandler() {
|
||||
gScript.removeMessageListener('data-transport-initialized', dataTransportInitializedHandler);
|
||||
info("Data transport channel is initialized.");
|
||||
gScript.sendAsyncMessage('trigger-data-transport-close', SpecialPowers.Cr.NS_ERROR_UNEXPECTED);
|
||||
});
|
||||
|
||||
gScript.addMessageListener('data-transport-closed', function dataTransportClosedHandler(aReason) {
|
||||
gScript.removeMessageListener('data-transport-closed', dataTransportClosedHandler);
|
||||
info("The data transport is closed. " + aReason);
|
||||
});
|
||||
|
||||
presentation.startSession("http://example.com").then(
|
||||
function(aSession) {
|
||||
ok(false, "startSession shouldn't succeed in this case.");
|
||||
aReject();
|
||||
},
|
||||
function(aError) {
|
||||
is(aError.name, "NS_ERROR_UNEXPECTED", "NS_ERROR_UNEXPECTED is expected when starting session.");
|
||||
aResolve();
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function teardown() {
|
||||
gScript.addMessageListener('teardown-complete', function teardownCompleteHandler() {
|
||||
gScript.removeMessageListener('teardown-complete', teardownCompleteHandler);
|
||||
gScript.destroy();
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
gScript.sendAsyncMessage('teardown');
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
ok(navigator.presentation, "navigator.presentation should be available.");
|
||||
presentation = navigator.presentation;
|
||||
|
||||
testStartSessionNoAvailableDevice().
|
||||
then(setup).
|
||||
then(testStartSessionCancelPrompt).
|
||||
then(testStartSessionUnexpectedControlChannelCloseBeforeDataTransportInit).
|
||||
then(testStartSessionUnexpectedControlChannelCloseBeforeDataTransportReady).
|
||||
then(testStartSessionUnexpectedDataTransportClose).
|
||||
then(teardown);
|
||||
}
|
||||
|
||||
SimpleTest.expectAssertions(0, 5);
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPermissions([
|
||||
{type: 'presentation-device-manage', allow: false, context: document},
|
||||
{type: 'presentation', allow: true, context: document},
|
||||
], function() {
|
||||
SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
|
||||
["dom.ignore_webidl_scope_checks", true],
|
||||
["dom.presentation.test.enabled", true],
|
||||
["dom.presentation.test.stage", 0]]},
|
||||
runTests);
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче