From 525563aa111e95c9507c35e624c836e919c3e1ef Mon Sep 17 00:00:00 2001 From: Andreas Pehrson Date: Wed, 13 May 2015 14:04:51 +0800 Subject: [PATCH] Bug 1032848 - Part 3: Add tests for HTMLCanvasElement::CaptureStream. r=mt, r=jgilbert, r=jesup --- dom/canvas/test/captureStream_common.js | 174 +++++++++++++++ .../test_canvas2d_crossorigin.html | 114 ++++++---- .../crossorigin/test_video_crossorigin.html | 154 ++++++++------ .../image_red_crossorigin_credentials.png | Bin 0 -> 87 bytes ...e_red_crossorigin_credentials.png^headers^ | 2 + dom/canvas/test/mochitest.ini | 4 + dom/canvas/test/test_capture.html | 111 ++++++++++ dom/canvas/test/webgl-mochitest.ini | 2 + .../test/webgl-mochitest/test_capture.html | 200 ++++++++++++++++++ dom/canvas/test/webgl-mochitest/webgl-util.js | 6 +- dom/media/tests/mochitest/head.js | 1 + dom/media/tests/mochitest/mochitest.ini | 4 + ...eerConnection_captureStream_canvas_2d.html | 55 +++++ ...Connection_captureStream_canvas_webgl.html | 108 ++++++++++ 14 files changed, 828 insertions(+), 107 deletions(-) create mode 100644 dom/canvas/test/captureStream_common.js create mode 100644 dom/canvas/test/image_red_crossorigin_credentials.png create mode 100644 dom/canvas/test/image_red_crossorigin_credentials.png^headers^ create mode 100644 dom/canvas/test/test_capture.html create mode 100644 dom/canvas/test/webgl-mochitest/test_capture.html create mode 100644 dom/media/tests/mochitest/test_peerConnection_captureStream_canvas_2d.html create mode 100644 dom/media/tests/mochitest/test_peerConnection_captureStream_canvas_webgl.html diff --git a/dom/canvas/test/captureStream_common.js b/dom/canvas/test/captureStream_common.js new file mode 100644 index 00000000000..a19f4725734 --- /dev/null +++ b/dom/canvas/test/captureStream_common.js @@ -0,0 +1,174 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +/* + * Util base class to help test a captured canvas element. Initializes the + * output canvas (used for testing the color of video elements), and optionally + * overrides the default element |width| and |height|. + */ +function CaptureStreamTestHelper(width, height) { + this.cout = document.createElement('canvas'); + if (width) { + this.elemWidth = width; + } + if (height) { + this.elemHeight = height; + } + this.cout.width = this.elemWidth; + this.cout.height = this.elemHeight; + document.body.appendChild(this.cout); +} + +CaptureStreamTestHelper.prototype = { + /* Predefined colors for use in the methods below. */ + black: { data: [0, 0, 0, 255], name: "black" }, + green: { data: [0, 255, 0, 255], name: "green" }, + red: { data: [255, 0, 0, 255], name: "red" }, + + /* Default element size for createAndAppendElement() */ + elemWidth: 100, + elemHeight: 100, + + /* Request a frame from the stream played by |video|. */ + requestFrame: function (video) { + info("Requesting frame from " + video.id); + video.mozSrcObject.requestFrame(); + }, + + /* Tests the top left pixel of |video| against |refData|. Format [R,G,B,A]. */ + testPixel: function (video, refData, threshold) { + var ctxout = this.cout.getContext('2d'); + ctxout.drawImage(video, 0, 0); + var pixel = ctxout.getImageData(0, 0, 1, 1).data; + return pixel.every((val, i) => Math.abs(val - refData[i]) <= threshold); + }, + + /* + * Returns a promise that resolves when the pixel matches. Use |threshold| + * for fuzzy matching the color on each channel, in the range [0,255]. + */ + waitForPixel: function (video, refColor, threshold, infoString) { + return new Promise(resolve => { + info("Testing " + video.id + " against [" + refColor.data.join(',') + "]"); + CaptureStreamTestHelper2D.prototype.clear.call(this, this.cout); + video.ontimeupdate = () => { + if (this.testPixel(video, refColor.data, threshold)) { + ok(true, video.id + " " + infoString); + video.ontimeupdate = null; + resolve(); + } + }; + }); + }, + + /* + * Returns a promise that resolves after |timeout| ms of playback or when a + * pixel of |video| becomes the color |refData|. The test is failed if the + * timeout is not reached. + */ + waitForPixelToTimeout: function (video, refColor, threshold, timeout, infoString) { + return new Promise(resolve => { + info("Waiting for " + video.id + " to time out after " + timeout + + "ms against [" + refColor.data.join(',') + "] - " + refColor.name); + CaptureStreamTestHelper2D.prototype.clear.call(this, this.cout); + var startTime = video.currentTime; + video.ontimeupdate = () => { + if (this.testPixel(video, refColor.data, threshold)) { + ok(false, video.id + " " + infoString); + video.ontimeupdate = null; + resolve(); + } else if (video.currentTime > startTime + (timeout / 1000.0)) { + ok(true, video.id + " " + infoString); + video.ontimeupdate = null; + resolve(); + } + }; + }); + }, + + /* Create an element of type |type| with id |id| and append it to the body. */ + createAndAppendElement: function (type, id) { + var e = document.createElement(type); + e.id = id; + e.width = this.elemWidth; + e.height = this.elemHeight; + if (type === 'video') { + e.autoplay = true; + } + document.body.appendChild(e); + return e; + }, +} + +/* Sub class holding 2D-Canvas specific helpers. */ +function CaptureStreamTestHelper2D(width, height) { + CaptureStreamTestHelper.call(this, width, height); +} + +CaptureStreamTestHelper2D.prototype = Object.create(CaptureStreamTestHelper.prototype); +CaptureStreamTestHelper2D.prototype.constructor = CaptureStreamTestHelper2D; + +/* Clear all drawn content on |canvas|. */ +CaptureStreamTestHelper2D.prototype.clear = function(canvas) { + var ctx = canvas.getContext('2d'); + ctx.clearRect(0, 0, canvas.width, canvas.height); +}; + +/* Draw the color |color| to the source canvas |canvas|. Format [R,G,B,A]. */ +CaptureStreamTestHelper2D.prototype.drawColor = function(canvas, color) { + var ctx = canvas.getContext('2d'); + var rgba = color.data.slice(); // Copy to not overwrite the original array + info("Drawing color " + rgba.join(',')); + rgba[3] = rgba[3] / 255.0; // Convert opacity to double in range [0,1] + ctx.fillStyle = "rgba(" + rgba.join(',') + ")"; + + // Only fill top left corner to test that output is not flipped or rotated. + ctx.fillRect(0, 0, canvas.width / 2, canvas.height / 2); +}; + +/* Test that the given 2d canvas is NOT origin-clean. */ +CaptureStreamTestHelper2D.prototype.testNotClean = function(canvas) { + var ctx = canvas.getContext('2d'); + var error = "OK"; + try { + var data = ctx.getImageData(0, 0, 1, 1); + } catch(e) { + error = e.name; + } + is(error, "SecurityError", + "Canvas '" + canvas.id + "' should not be origin-clean"); +}; + +/* Sub class holding WebGL specific helpers. */ +function CaptureStreamTestHelperWebGL(width, height) { + CaptureStreamTestHelper.call(this, width, height); +} + +CaptureStreamTestHelperWebGL.prototype = Object.create(CaptureStreamTestHelper.prototype); +CaptureStreamTestHelperWebGL.prototype.constructor = CaptureStreamTestHelperWebGL; + +/* Set the (uniform) color location for future draw calls. */ +CaptureStreamTestHelperWebGL.prototype.setFragmentColorLocation = function(colorLocation) { + this.colorLocation = colorLocation; +}; + +/* Clear the given WebGL context with |color|. */ +CaptureStreamTestHelperWebGL.prototype.clearColor = function(canvas, color) { + info("WebGL: clearColor(" + color.name + ")"); + var gl = canvas.getContext('webgl'); + var conv = color.data.map(i => i / 255.0); + gl.clearColor(conv[0], conv[1], conv[2], conv[3]); + gl.clear(gl.COLOR_BUFFER_BIT); +}; + +/* Set an already setFragmentColorLocation() to |color| and drawArrays() */ +CaptureStreamTestHelperWebGL.prototype.drawColor = function(canvas, color) { + info("WebGL: drawArrays(" + color.name + ")"); + var gl = canvas.getContext('webgl'); + var conv = color.data.map(i => i / 255.0); + gl.uniform4f(this.colorLocation, conv[0], conv[1], conv[2], conv[3]); + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); +}; diff --git a/dom/canvas/test/crossorigin/test_canvas2d_crossorigin.html b/dom/canvas/test/crossorigin/test_canvas2d_crossorigin.html index 6571542be9f..a12bd63960a 100644 --- a/dom/canvas/test/crossorigin/test_canvas2d_crossorigin.html +++ b/dom/canvas/test/crossorigin/test_canvas2d_crossorigin.html @@ -73,6 +73,17 @@ function testImage(url, crossOriginAttribute, expected_error) { "drawImage then get image data on " + url + " with crossOrigin=" + this.crossOrigin); + try { + c.captureStream(0); + actual_error = OK; + } catch (e) { + actual_error = e.name; + } + + verifyError(actual_error, expected_error, + "drawImage then capture stream on " + url + + " with crossOrigin=" + this.crossOrigin); + // Now test patterns c = document.createElement("canvas"); c.width = this.width; @@ -91,6 +102,17 @@ function testImage(url, crossOriginAttribute, expected_error) { "createPattern+fill then get image data on " + url + " with crossOrigin=" + this.crossOrigin); + try { + c.captureStream(0); + actual_error = OK; + } catch (e) { + actual_error = e.name; + } + + verifyError(actual_error, expected_error, + "createPattern+fill then capture stream on " + url + + " with crossOrigin=" + this.crossOrigin); + testDone(); }; @@ -130,56 +152,64 @@ const attrValues = [ [ "foobar", "anonymous" ] ]; -for (var imgIdx = 0; imgIdx < imageFiles.length; ++imgIdx) { - for (var hostnameIdx = 0; hostnameIdx < hostnames.length; ++hostnameIdx) { - var hostnameData = hostnames[hostnameIdx]; - var url = "http://" + hostnameData[0] + testPath + imageFiles[imgIdx][0]; - for (var attrValIdx = 0; attrValIdx < attrValues.length; ++attrValIdx) { - var attrValData = attrValues[attrValIdx]; - // Now compute the expected result - var expected_error; - if (hostnameData[1] == "same-origin") { - // Same-origin; these should all Just Work - expected_error = OK; - } else { - // Cross-origin - is(hostnameData[1], "cross-origin", - "what sort of host is " + hostnameData[0]); - var CORSMode = attrValData[1]; - if (CORSMode == "none") { - // Doesn't matter what headers the server sends; we're not - // using CORS on our end. - expected_error = "SecurityError"; +function beginTest() { + for (var imgIdx = 0; imgIdx < imageFiles.length; ++imgIdx) { + for (var hostnameIdx = 0; hostnameIdx < hostnames.length; ++hostnameIdx) { + var hostnameData = hostnames[hostnameIdx]; + var url = "http://" + hostnameData[0] + testPath + imageFiles[imgIdx][0]; + for (var attrValIdx = 0; attrValIdx < attrValues.length; ++attrValIdx) { + var attrValData = attrValues[attrValIdx]; + // Now compute the expected result + var expected_error; + if (hostnameData[1] == "same-origin") { + // Same-origin; these should all Just Work + expected_error = OK; } else { - // Check whether the server will let us talk to them - var CORSHeaders = imageFiles[imgIdx][1]; - // We're going to look for CORS headers from the server - if (CORSHeaders == "none") { - // No CORS headers from server; load will fail. - expected_error = BAD_URI_ERR; - } else if (CORSHeaders == "allow-all-anon") { - // Server only allows anonymous requests - if (CORSMode == "anonymous") { - expected_error = OK; - } else { - is(CORSMode, "use-credentials", - "What other CORS modes are there?"); - // A load with credentials against a server that only - // allows anonymous loads will fail. - expected_error = BAD_URI_ERR; - } + // Cross-origin + is(hostnameData[1], "cross-origin", + "what sort of host is " + hostnameData[0]); + var CORSMode = attrValData[1]; + if (CORSMode == "none") { + // Doesn't matter what headers the server sends; we're not + // using CORS on our end. + expected_error = "SecurityError"; } else { - is(CORSHeaders, "allow-single-server-creds", - "What other CORS headers could there be?"); - // Our server should allow both anonymous and non-anonymous requests - expected_error = OK; + // Check whether the server will let us talk to them + var CORSHeaders = imageFiles[imgIdx][1]; + // We're going to look for CORS headers from the server + if (CORSHeaders == "none") { + // No CORS headers from server; load will fail. + expected_error = BAD_URI_ERR; + } else if (CORSHeaders == "allow-all-anon") { + // Server only allows anonymous requests + if (CORSMode == "anonymous") { + expected_error = OK; + } else { + is(CORSMode, "use-credentials", + "What other CORS modes are there?"); + // A load with credentials against a server that only + // allows anonymous loads will fail. + expected_error = BAD_URI_ERR; + } + } else { + is(CORSHeaders, "allow-single-server-creds", + "What other CORS headers could there be?"); + // Our server should allow both anonymous and non-anonymous requests + expected_error = OK; + } } } + testImage(url, attrValData[0], expected_error); } - testImage(url, attrValData[0], expected_error); } } } + +var prefs = [ + [ "canvas.capturestream.enabled", true ], +]; +SpecialPowers.pushPrefEnv({ "set" : prefs }, beginTest); + diff --git a/dom/canvas/test/crossorigin/test_video_crossorigin.html b/dom/canvas/test/crossorigin/test_video_crossorigin.html index 200d1fd7f9d..4183d13aa22 100644 --- a/dom/canvas/test/crossorigin/test_video_crossorigin.html +++ b/dom/canvas/test/crossorigin/test_video_crossorigin.html @@ -28,11 +28,7 @@ function createCanvas(width, height) { return c; } -function testCanvasDrawImage(v) { - var c = createCanvas(v.width, v.height); - var ctx = c.getContext("2d"); - ctx.drawImage(v, 0, 0); - +function checkGetImageData(ctx, v) { try { var data = ctx.getImageData(0, 0, 1, 1); ok(true, "drawImage '" + v.src + "' then getImageData with crossOrigin='" + v.crossOrigin + "' worked"); @@ -42,22 +38,54 @@ function testCanvasDrawImage(v) { } } +function checkGetImageDataTainted(ctx, v) { + try { + var data = ctx.getImageData(0, 0, 1, 1); + ok(false, "changing the CORS mode should not allow reading data from remote videos"); + } catch (error) { + ok(error.name === "SecurityError", "changing the CORS mode, drawImage '" + v.src + "' then getImageData with crossOrigin='" + v.crossOrigin + "' failed"); + } +} + +function checkCaptureStream(c, v) { + try { + var stream = c.captureStream(0); + ok(true, "drawImage '" + v.src + "' then captureStream with crossOrigin='" + v.crossOrigin + "' worked"); + } catch(error) { + ok(!v.crossOrigin && error.name === "SecurityError", "drawImage '" + v.src + "' then captureStream with crossOrigin='" + v.crossOrigin + "' failed"); + v.tainted = true; + } +} + +function checkCaptureStreamTainted(c, v) { + try { + var stream = c.captureStream(0); + ok(false, "changing the CORS mode should not allow capturing a stream from remote videos"); + } catch (error) { + ok(error.name === "SecurityError", "changing the CORS mode, drawImage '" + v.src + "' then captureStream with crossOrigin='" + v.crossOrigin + "' failed"); + } +} + +function testCanvasDrawImage(v) { + var c = createCanvas(v.width, v.height); + var ctx = c.getContext("2d"); + ctx.drawImage(v, 0, 0); + + checkGetImageData(ctx, v); + checkCaptureStream(c, v); +} + function testCanvasCreatePattern(v) { var c = createCanvas(v.width, v.height); var ctx = c.getContext("2d"); ctx.fillStyle = ctx.createPattern(v, ""); ctx.fillRect(0, 0, c.width, c.height); - try { - var data = ctx.getImageData(0, 0, 1, 1); - ok(true, "createPattern '" + v.src + "' then getImageData with crossOrigin='" + v.crossOrigin + "' worked"); - } catch(error) { - ok(!v.crossOrigin && error.name === "SecurityError", "createPattern '" + v.src + "' then getImageData with crossOrigin='" + v.crossOrigin + "' failed"); - v.tainted = true; - } + checkGetImageData(ctx, v); + checkCaptureStream(c, v); } -function testWebGL(v) { +function testWebGL(gl, v) { var tex = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, tex); @@ -75,12 +103,8 @@ function testTaintedCanvas(v) { var ctx = c.getContext("2d"); ctx.drawImage(v, 0, 0); - try { - var data = ctx.getImageData(0, 0, 1, 1); - ok(false, "changing the CORS mode should not allow reading data from remote videos"); - } catch (error) { - ok(error.name === "SecurityError", "changing the CORS mode, drawImage '" + v.src + "' then getImageData with crossOrigin='" + v.crossOrigin + "' failed"); - } + checkGetImageDataTainted(ctx, v); + checkCaptureStreamTainted(c, v); } function vidDataSuccess(e) { @@ -88,8 +112,8 @@ function vidDataSuccess(e) { testCanvasDrawImage(e.target); testCanvasCreatePattern(e.target); - if (gl) { - testWebGL(e.target); + if (document.gl) { + testWebGL(document.gl, e.target); } // If we change the CORS mode after loading the file without CORS it should still throw a security error if (e.target.tainted) { @@ -121,7 +145,7 @@ function startTest(test, token) { v.crossOrigin = test.cors; } v.token = token; - manager.started(token); + document.manager.started(token); v.autoplay = true; v.preload = "auto"; v.style.display = "none"; @@ -140,53 +164,59 @@ function startTest(test, token) { function doneTest(e) { var v = e.target; v.parentNode.removeChild(v); - manager.finished(v.token); + document.manager.finished(v.token); } -var videoFile = getPlayableVideo(gSmallTests); -if (!videoFile) { - SimpleTest.finish(); -} -videoFile = "?name=tests/dom/media/test/" + videoFile.name + "&type=" + videoFile.type; +function beginTest() { + var videoFile = getPlayableVideo(gSmallTests); + if (!videoFile) { + SimpleTest.finish(); + } + videoFile = "?name=tests/dom/media/test/" + videoFile.name + "&type=" + videoFile.type; -var gl; -try { - gl = createCanvas(16, 16).getContext("experimental-webgl"); -} catch (ex) { - // Mac OS X 10.5 doesn't support WebGL, so we won't run the WebGL tests + document.manager = new MediaTestManager; + var corsTests = []; + + const host = "http://example.com/tests/dom/canvas/test/crossorigin/video.sjs"; + const serverAttrValues = [ + [ "&cors=none", "none" ], + [ "&cors=anonymous", "anonymous" ], + [ "&cors=use-credentials", "use-credentials" ] + ]; + const clientAttrValues = [ + [ "missing-value-default", "none" ], + [ "", "anonymous" ], + [ "just-crossOrigin-without-value", "anonymous" ], + [ "anonymous", "anonymous" ], + [ "use-credentials", "use-credentials" ], + [ "foobar", "anonymous" ] + ]; + + // Build the video file test array + for (var i = 0; i < serverAttrValues.length; i++) { + for (var n = 0; n < clientAttrValues.length; n++) { + corsTests.push({ + name: host + videoFile + serverAttrValues[i][0], + nameIntent: serverAttrValues[i][1], + cors: clientAttrValues[n][0], + corsIntent: clientAttrValues[n][1] + }); + } + } + try { + document.gl = createCanvas(16, 16).getContext("experimental-webgl"); + } catch (ex) { + // Mac OS X 10.5 doesn't support WebGL, so we won't run the WebGL tests + } + document.manager.runTests(corsTests, startTest); } -var manager = new MediaTestManager; -var corsTests = []; - -const host = "http://example.com/tests/dom/canvas/test/crossorigin/video.sjs"; -const serverAttrValues = [ - [ "&cors=none", "none" ], - [ "&cors=anonymous", "anonymous" ], - [ "&cors=use-credentials", "use-credentials" ] -]; -const clientAttrValues = [ - [ "missing-value-default", "none" ], - [ "", "anonymous" ], - [ "just-crossOrigin-without-value", "anonymous" ], - [ "anonymous", "anonymous" ], - [ "use-credentials", "use-credentials" ], - [ "foobar", "anonymous" ] +var prefs = [ + [ "canvas.capturestream.enabled", true ], ]; -// Build the video file test array -for (var i = 0; i < serverAttrValues.length; i++) { - for (var n = 0; n < clientAttrValues.length; n++) { - corsTests.push({ - name: host + videoFile + serverAttrValues[i][0], - nameIntent: serverAttrValues[i][1], - cors: clientAttrValues[n][0], - corsIntent: clientAttrValues[n][1] - }); - } -} - -manager.runTests(corsTests, startTest); +SimpleTest.waitForExplicitFinish(); +SpecialPowers.pushPrefEnv({ "set" : prefs }, beginTest); diff --git a/dom/canvas/test/image_red_crossorigin_credentials.png b/dom/canvas/test/image_red_crossorigin_credentials.png new file mode 100644 index 0000000000000000000000000000000000000000..a6e195d59cce3c15ef12512bb58ed4f409eb95ae GIT binary patch literal 87 zcmeAS@N?(olHy`uVBq!ia0vp^DL`z*$P6SW{C@KnNHGWagt-1^V32&oX%6J_d%8G= jXow~!NU$zW$Y5e%+QYyoefRMMpcI3rtDnm{r-UW|6k!xK literal 0 HcmV?d00001 diff --git a/dom/canvas/test/image_red_crossorigin_credentials.png^headers^ b/dom/canvas/test/image_red_crossorigin_credentials.png^headers^ new file mode 100644 index 00000000000..a03f99a9c0a --- /dev/null +++ b/dom/canvas/test/image_red_crossorigin_credentials.png^headers^ @@ -0,0 +1,2 @@ +Access-Control-Allow-Origin: http://mochi.test:8888 +Access-Control-Allow-Credentials: true diff --git a/dom/canvas/test/mochitest.ini b/dom/canvas/test/mochitest.ini index e0ad9a528d1..f6e370d5d50 100644 --- a/dom/canvas/test/mochitest.ini +++ b/dom/canvas/test/mochitest.ini @@ -14,6 +14,8 @@ support-files = image_green.png image_red-16x16.png image_red.png + image_red_crossorigin_credentials.png + image_red_crossorigin_credentials.png^headers^ image_redtransparent.png image_rgrg-256x256.png image_rrgg-256x256.png @@ -224,6 +226,8 @@ skip-if = (toolkit == 'gonk' && !debug) || os == 'win' #specialpowers.wrap [test_hitregion_event.html] skip-if = os == "android" || appname == "b2g" [test_canvas_strokeStyle_getter.html] +[test_capture.html] +support-files = captureStream_common.js [test_drawImageIncomplete.html] [test_drawImage_document_domain.html] [test_drawImage_edge_cases.html] diff --git a/dom/canvas/test/test_capture.html b/dom/canvas/test/test_capture.html new file mode 100644 index 00000000000..72e31eb994a --- /dev/null +++ b/dom/canvas/test/test_capture.html @@ -0,0 +1,111 @@ + + + +Canvas2D test: CaptureStream() + + + + + + + diff --git a/dom/canvas/test/webgl-mochitest.ini b/dom/canvas/test/webgl-mochitest.ini index 78339ed0757..b5e1582fdfa 100644 --- a/dom/canvas/test/webgl-mochitest.ini +++ b/dom/canvas/test/webgl-mochitest.ini @@ -9,6 +9,8 @@ support-files = [webgl-mochitest/test_backbuffer_channels.html] fail-if = (os == 'b2g') [webgl-mochitest/test_depth_readpixels.html] +[webgl-mochitest/test_capture.html] +support-files = captureStream_common.js [webgl-mochitest/test_draw.html] [webgl-mochitest/test_fb_param.html] [webgl-mochitest/test_fb_param_crash.html] diff --git a/dom/canvas/test/webgl-mochitest/test_capture.html b/dom/canvas/test/webgl-mochitest/test_capture.html new file mode 100644 index 00000000000..613cc852525 --- /dev/null +++ b/dom/canvas/test/webgl-mochitest/test_capture.html @@ -0,0 +1,200 @@ + + + +WebGL test: CaptureStream() + + + + + + + + + + diff --git a/dom/canvas/test/webgl-mochitest/webgl-util.js b/dom/canvas/test/webgl-mochitest/webgl-util.js index 4c756266ff1..e71d84cfe64 100644 --- a/dom/canvas/test/webgl-mochitest/webgl-util.js +++ b/dom/canvas/test/webgl-mochitest/webgl-util.js @@ -34,19 +34,19 @@ WebGLUtil = (function() { // --------------------------------------------------------------------------- // WebGL helpers - function getWebGL(canvasId, requireConformant) { + function getWebGL(canvasId, requireConformant, attributes) { // `requireConformant` will default to falsey if it is not supplied. var canvas = document.getElementById(canvasId); var gl = null; try { - gl = canvas.getContext('webgl'); + gl = canvas.getContext('webgl', attributes); } catch(e) {} if (!gl && !requireConformant) { try { - gl = canvas.getContext('experimental-webgl'); + gl = canvas.getContext('experimental-webgl', attributes); } catch(e) {} } diff --git a/dom/media/tests/mochitest/head.js b/dom/media/tests/mochitest/head.js index dc5a18a8e5c..4d82546ce41 100644 --- a/dom/media/tests/mochitest/head.js +++ b/dom/media/tests/mochitest/head.js @@ -130,6 +130,7 @@ function setupEnvironment() { window.finish = () => SimpleTest.finish(); SpecialPowers.pushPrefEnv({ 'set': [ + ['canvas.capturestream.enabled', true], ['dom.messageChannel.enabled', true], ['media.peerconnection.enabled', true], ['media.peerconnection.identity.enabled', true], diff --git a/dom/media/tests/mochitest/mochitest.ini b/dom/media/tests/mochitest/mochitest.ini index ef497f1eb66..7611bb85962 100644 --- a/dom/media/tests/mochitest/mochitest.ini +++ b/dom/media/tests/mochitest/mochitest.ini @@ -103,6 +103,10 @@ skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g emulator seems to be to skip-if = buildapp == 'b2g' || buildapp == 'mulet' || os == 'android' # bug 1043403 # Bug 1141029 Mulet parity with B2G Desktop for TC [test_peerConnection_capturedVideo.html] skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g(Bug 960442, video support for WebRTC is disabled on b2g) +[test_peerConnection_captureStream_canvas_2d.html] +skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g(Bug 960442, video support for WebRTC is disabled on b2g) +[test_peerConnection_captureStream_canvas_webgl.html] +skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g(Bug 960442, video support for WebRTC is disabled on b2g) [test_peerConnection_close.html] skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g (Bug 1059867) [test_peerConnection_errorCallbacks.html] diff --git a/dom/media/tests/mochitest/test_peerConnection_captureStream_canvas_2d.html b/dom/media/tests/mochitest/test_peerConnection_captureStream_canvas_2d.html new file mode 100644 index 00000000000..5f76a507bbb --- /dev/null +++ b/dom/media/tests/mochitest/test_peerConnection_captureStream_canvas_2d.html @@ -0,0 +1,55 @@ + + + + + + + +
+
+
+ + diff --git a/dom/media/tests/mochitest/test_peerConnection_captureStream_canvas_webgl.html b/dom/media/tests/mochitest/test_peerConnection_captureStream_canvas_webgl.html new file mode 100644 index 00000000000..b3a753bc4e3 --- /dev/null +++ b/dom/media/tests/mochitest/test_peerConnection_captureStream_canvas_webgl.html @@ -0,0 +1,108 @@ + + + + + + + + +
+
+
+
+
+ +