| <!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> |