diff options
Diffstat (limited to 'dom/media/autoplay/test/mochitest/test_autoplay_policy.html')
-rw-r--r-- | dom/media/autoplay/test/mochitest/test_autoplay_policy.html | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/dom/media/autoplay/test/mochitest/test_autoplay_policy.html b/dom/media/autoplay/test/mochitest/test_autoplay_policy.html new file mode 100644 index 0000000000..dae388b21d --- /dev/null +++ b/dom/media/autoplay/test/mochitest/test_autoplay_policy.html @@ -0,0 +1,174 @@ + +<!DOCTYPE HTML> +<html> +<head> + <title>Autoplay policy test</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> + +<script> +/* import-globals-from ../../../test/manifest.js */ +let manager = new MediaTestManager; + +gTestPrefs.push(["media.autoplay.default", SpecialPowers.Ci.nsIAutoplay.BLOCKED], + ["media.autoplay.blocking_policy", 0]); + +window.info = function(msg, token) { + SimpleTest.info(msg + ", token=" + token); +} + +window.is = function(valA, valB, msg, token) { + SimpleTest.is(valA, valB, msg + ", token=" + token); +} + +window.ok = function(val, msg, token) { + SimpleTest.ok(val, msg + ", token=" + token); +} + +/** + * test files and paremeters + */ +var autoplayTests = [ + /* video */ + { name: "gizmo.mp4", type: "video/mp4", hasAudio:true }, + { name: "gizmo-noaudio.mp4", type: "video/mp4", hasAudio:false }, + { name: "gizmo.webm", type: "video/webm", hasAudio:true }, + { name: "gizmo-noaudio.webm", type: "video/webm", hasAudio:false }, + /* audio */ + { name: "small-shot.ogg", type: "audio/ogg", hasAudio:true }, + { name: "small-shot.m4a", type: "audio/mp4", hasAudio:true }, + { name: "small-shot.mp3", type: "audio/mpeg", hasAudio:true }, + { name: "small-shot.flac", type: "audio/flac", hasAudio:true }, +]; + +var autoplayParams = [ + { volume: 1.0, muted: false, preload: "none" }, + { volume: 0.0, muted: false, preload: "none" }, + { volume: 1.0, muted: true, preload: "none" }, + { volume: 0.0, muted: true, preload: "none" }, + { volume: 1.0, muted: false, preload: "metadata" }, + { volume: 0.0, muted: false, preload: "metadata" }, + { volume: 1.0, muted: true, preload: "metadata" }, + { volume: 0.0, muted: true, preload: "metadata" }, +]; + +function createTestArray() +{ + var tests = []; + for (let test of autoplayTests) { + for (let param of autoplayParams) { + tests.push({ + name: test.name, + type: test.type, + hasAudio: test.hasAudio, + volume: param.volume, + muted: param.muted, + preload: param.preload, + }); + } + } + return tests; +} + +/** + * Main test function for different autoplay cases without user interaction. + * + * When the pref "media.autoplay.default" is 1 and the pref + * "media.autoplay.blocking_policy" is 0, we only allow + * audible media to autoplay after the website has been activated by specific + * user gestures. However, inaudible media won't be restricted. + * + * Audible means the volume is not zero, or muted is not true for the video with + * audio track. For media without loading metadata, we can't know whether it has + * audio track or not, so we would also regard it as audible media. + * + * Inaudible means the volume is zero, or the muted is true, or the video without + * audio track. + */ +async function runTest(test, token) { + manager.started(token); + + await testPlay(test, token); + await testAutoplayKeyword(test, token); + + manager.finished(token); +} + +manager.runTests(createTestArray(), runTest); + +/** + * Different test scenarios + */ +async function testPlay(test, token) { + info("### start testPlay", token); + info(`volume=${test.volume}, muted=${test.muted}, ` + + `preload=${test.preload}, hasAudio=${test.hasAudio}`, token); + + let element = document.createElement(getMajorMimeType(test.type)); + element.volume = test.volume; + element.muted = test.muted; + element.src = test.name; + document.body.appendChild(element); + + // Only need to test preload when calling play(), because media with 'autoplay' + // keyword always starts after loading enough data. + const preLoadNone = test.preload == "none"; + if (!preLoadNone) { + info("### wait for loading metadata", token); + await once(element, "loadedmetadata"); + } + + let isAudible = (preLoadNone || test.hasAudio) && + test.volume != 0.0 && + !test.muted; + let state = isAudible? "audible" : "non-audible"; + info(`### calling play() for ${state} media`, token); + let promise = element.play(); + if (isAudible) { + await promise.catch(function(error) { + ok(element.paused, `${state} media fail to start via play()`, token); + is(error.name, "NotAllowedError", "rejected play promise", token); + }); + } else { + // since we just want to check the value of 'paused', we don't need to wait + // resolved play promise. (it's equal to wait for 'playing' event) + await once(element, "play"); + ok(!element.paused, `${state} media start via play()`, token); + } + + removeNodeAndSource(element); +} + +async function testAutoplayKeyword(test, token) { + info("### start testAutoplayKeyword", token); + info(`volume=${test.volume}, muted=${test.muted}, ` + + `hasAudio=${test.hasAudio}`, token); + + let element = document.createElement(getMajorMimeType(test.type)); + element.autoplay = true; + element.volume = test.volume; + element.muted = test.muted; + element.src = test.name; + document.body.appendChild(element); + + let isAudible = test.hasAudio && + test.volume != 0.0 && + !test.muted; + let state = isAudible? "audible" : "non-audible"; + info(`### wait to autoplay for ${state} media`, token); + if (isAudible) { + await once(element, "canplay"); + ok(element.paused, `can not start with 'autoplay' keyword for ${state} media`, token); + } else { + await once(element, "play"); + ok(!element.paused, `start with 'autoplay' keyword for ${state} media`, token); + } + + removeNodeAndSource(element); +} + +</script> |