blob: d3ed47f978cd58560b2965758f9add215de7bcd3 [file] [log] [blame]
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<script src="../../resources/js-test-pre.js"></script>
<script src="./resources/promise-utils.js"></script>
</head>
<body>
<script>
var pc;
var desc;
var candidate;
var selector;
var reason;
var detailedErrors;
description("Test various arguments to RTCPeerConnection overloaded functions");
shouldNotThrow("pc = new RTCPeerConnection({iceServers:[{urls:'stun:foo.com'}]});");
function testCreateOfferOrAnswer(functionName) {
return new Promise(function (resolve) {
debug(`*** Test ${functionName}`);
promiseShouldNotRejectWithTypeError(`pc.${functionName}()`)
.then(function () {
return promiseShouldNotRejectWithTypeError(`pc.${functionName}(emptyFunc, emptyFunc)`);
})
.then(function () {
return promiseShouldNotRejectWithTypeError(`pc.${functionName}(null)`);
})
.then(function () {
return promiseShouldNotRejectWithTypeError(`pc.${functionName}(undefined)`);
})
.then(function () {
return promiseShouldNotRejectWithTypeError(`pc.${functionName}({})`);
})
.then(function () {
return promiseShouldNotRejectWithTypeError(`pc.${functionName}(emptyFunc, emptyFunc, null)`);
})
.then(function () {
return promiseShouldNotRejectWithTypeError(`pc.${functionName}(emptyFunc, emptyFunc, undefined)`);
})
.then(function () {
return promiseShouldNotRejectWithTypeError(`pc.${functionName}(emptyFunc, emptyFunc, {})`);
})
.then(function () {
debug("*** Options object must be last")
reason = `TypeError: Argument 1 ('successCallback') to RTCPeerConnection.${functionName} must be a function`;
return promiseShouldReject(`pc.${functionName}({}, emptyFunc, emptyFunc)`, "reason");
})
.then(function () {
debug("*** Callbacks are not nullable");
reason = `TypeError: Argument 2 ('errorCallback') to RTCPeerConnection.${functionName} must be a function`;
return promiseShouldReject(`pc.${functionName}(emptyFunc, null)`, "reason");
})
.then(function () {
reason = `TypeError: Argument 1 ('successCallback') to RTCPeerConnection.${functionName} must be a function`;
return promiseShouldReject(`pc.${functionName}(null, emptyFunc)`, "reason");
})
.then(function () {
reason = `TypeError: Argument 1 ('successCallback') to RTCPeerConnection.${functionName} must be a function`;
return promiseShouldReject(`pc.${functionName}(null, null)`, "reason");
})
.then(function () {
debug("*** Bad input");
reason = `TypeError: Argument 1 ('successCallback') to RTCPeerConnection.${functionName} must be a function`;
return promiseShouldReject(`pc.${functionName}({}, emptyFunc)`, "reason");
})
.then(function () {
reason = `TypeError: Argument 2 ('errorCallback') to RTCPeerConnection.${functionName} must be a function`;
return promiseShouldReject(`pc.${functionName}(emptyFunc, {})`, "reason");
})
.then(function () {
reason = `TypeError: Argument 1 ('options') to RTCPeerConnection.${functionName} must be a dictionary`;
return promiseShouldReject(`pc.${functionName}(1)`, "reason");
})
.then(function () {
reason = `TypeError: Argument 3 ('options') to RTCPeerConnection.${functionName} must be a dictionary`;
return promiseShouldReject(`pc.${functionName}(emptyFunc, emptyFunc, 1)`, "reason");
})
.then(function () {
debug("");
resolve();
})
.catch(function (error) {
testFailed(`Unexpected error in ${functionName} promise chain: ${error}`);
resolve();
});
});
}
function testSetLocalOrRemoteDescription(functionName) {
return new Promise(function (resolve) {
debug(`*** Test ${functionName}`);
desc = new RTCSessionDescription({type:'offer', sdp:'x'});
promiseShouldNotRejectWithTypeError(`pc.${functionName}(desc)`)
.then(function () {
return promiseShouldNotRejectWithTypeError(`pc.${functionName}(desc, emptyFunc, emptyFunc)`);
})
.then(function () {
return badInputFull(functionName, "desc", {
"arg1": `TypeError: Argument 1 ('description') to RTCPeerConnection.${functionName} must be an instance of RTCSessionDescription`,
"arg2": `TypeError: Argument 2 ('successCallback') to RTCPeerConnection.${functionName} must be a function`,
"arg3": `TypeError: Argument 3 ('errorCallback') to RTCPeerConnection.${functionName} must be a function`
});
})
.then(function () {
debug("");
resolve();
})
.catch(function (error) {
testFailed(`Unexpected error in ${functionName} promise chain: ${error}`);
resolve();
});
});
}
// badInputFull checks for void, null, and badInput()
function badInputFull(functionName, firstArg, detailedErrorsArg) {
detailedErrors = detailedErrorsArg;
return new Promise(function (resolve) {
debug(`*** ${firstArg} is not optional`);
promiseShouldReject(`pc.${functionName}()`, "'TypeError: Not enough arguments'")
.then(function () {
debug(`*** ${firstArg} is not nullable`);
return promiseShouldReject(`pc.${functionName}(null)`, "detailedErrors.arg1");
})
.then(function () {
return promiseShouldReject(`pc.${functionName}(null, emptyFunc, emptyFunc)`, "detailedErrors.arg1");
})
.then(function () {
return badInput(functionName, firstArg, detailedErrorsArg);
})
.then(function () {
resolve();
})
.catch(function (error) {
testFailed(`Unexpected error in promise chain: ${error}`);
resolve();
});
});
}
// badInputVoid checks for void, and badInput()
function badInputVoid(functionName, firstArg, detailedErrorsArg) {
detailedErrors = detailedErrorsArg;
return new Promise(function (resolve) {
debug(`*** ${firstArg} is not optional`);
promiseShouldReject(`pc.${functionName}()`, "'TypeError: Not enough arguments'")
.then(function () {
return badInput(functionName, firstArg, detailedErrorsArg);
})
.then(function () {
resolve();
})
.catch(function (error) {
testFailed(`Unexpected error in promise chain: ${error}`);
resolve();
});
});
}
function badInput(functionName, firstArg, detailedErrorsArg) {
detailedErrors = detailedErrorsArg;
return promiseShouldReject(`pc.${functionName}(1)`, "detailedErrors.arg1")
.then(function () {
debug(`*** Bad input as ${firstArg}`);
return promiseShouldReject(`pc.${functionName}('foo')`, "detailedErrors.arg1");
})
.then(function () {
return promiseShouldReject(`pc.${functionName}('foo', emptyFunc, emptyFunc)`, "detailedErrors.arg1");
})
.then(function () {
return promiseShouldReject(`pc.${functionName}(1)`, "detailedErrors.arg1");
})
.then(function () {
return promiseShouldReject(`pc.${functionName}(1, emptyFunc, emptyFunc)`, "detailedErrors.arg1");
})
.catch(function (error) {
testFailed(`Unexpected error in promise chain: ${error}`);
});
}
function testAddIceCandidate() {
return new Promise(function (resolve) {
debug("*** Test addIceCandidate");
candidate = new RTCIceCandidate({ "candidate": "foo", "sdpMid": "bar" });
promiseShouldNotRejectWithTypeError("pc.addIceCandidate(candidate)")
.then(function () {
return promiseShouldNotRejectWithTypeError("pc.addIceCandidate(candidate, emptyFunc, emptyFunc)");
})
.then(function () {
return promiseShouldNotRejectWithTypeError("pc.addIceCandidate(null)");
})
.then(function () {
return promiseShouldNotRejectWithTypeError("pc.addIceCandidate(null, emptyFunc, emptyFunc)");
})
.then(function () {
return badInputVoid("addIceCandidate", "candidate", {
"arg1": "TypeError: Argument 1 ('candidate') to RTCPeerConnection.addIceCandidate must be an instance of RTCIceCandidate",
"arg2": "TypeError: Argument 2 ('successCallback') to RTCPeerConnection.addIceCandidate must be a function",
"arg3": "TypeError: Argument 3 ('errorCallback') to RTCPeerConnection.addIceCandidate must be a function"
});
})
.then(function () {
debug("");
resolve();
})
.catch(function (error) {
testFailed(`Unexpected error in testAddIceCandidate promise chain: ${error}`);
resolve();
});
});
}
function testGetStats() {
return new Promise(function (resolve) {
debug("*** Test getStats");
navigator.mediaDevices.getUserMedia({ "video": true })
.then(function (stream) {
selector = stream.getTracks()[0];
return Promise.resolve();
})
.then(function () {
return promiseShouldNotRejectWithTypeError("pc.getStats()");
})
.then(function () {
return promiseShouldNotRejectWithTypeError("pc.getStats(null)");
})
.then(function () {
return promiseShouldNotRejectWithTypeError("pc.getStats(selector)");
})
.then(function () {
return promiseShouldNotRejectWithTypeError("pc.getStats(null, emptyFunc, emptyFunc)");
})
.then(function () {
return promiseShouldNotRejectWithTypeError("pc.getStats(selector, emptyFunc, emptyFunc)");
})
.then(function () {
return badInput("getStats", "selector", {
"arg1": "TypeError: Argument 1 ('selector') to RTCPeerConnection.getStats must be an instance of MediaStreamTrack",
"arg2": "TypeError: Argument 2 ('successCallback') to RTCPeerConnection.getStats must be a function",
"arg3": "TypeError: Argument 3 ('errorCallback') to RTCPeerConnection.getStats must be a function"
});
})
.then(function () {
debug("");
resolve();
})
.catch(function (error) {
testFailed(`Unexpected error in testGetStats promise chain: ${error}`);
resolve();
});
})
}
function emptyFunc() { }
if (window.testRunner)
testRunner.setUserMediaPermission(true);
else {
debug("This test can not be run without the testRunner");
finishJSTest();
}
testCreateOfferOrAnswer("createOffer")
.then(function () {
return testCreateOfferOrAnswer("createAnswer");
})
.then(function () {
return testSetLocalOrRemoteDescription("setLocalDescription");
})
.then(function () {
return testSetLocalOrRemoteDescription("setRemoteDescription");
})
.then(function () {
return testAddIceCandidate();
})
.then(function () {
return testGetStats();
})
.then(function () {
finishJSTest();
})
.catch(function () {
finishJSTest();
});
window.jsTestIsAsync = true;
window.successfullyParsed = true;
</script>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>