test_autoplay_policy.html (5596B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <title>Autoplay policy test</title> 5 <script src="/tests/SimpleTest/SimpleTest.js"></script> 6 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 7 <script type="text/javascript" src="manifest.js"></script> 8 </head> 9 <body> 10 <pre id="test"> 11 12 <script> 13 /* import-globals-from ../../../test/manifest.js */ 14 let manager = new MediaTestManager; 15 16 gTestPrefs.push(["media.autoplay.default", SpecialPowers.Ci.nsIAutoplay.BLOCKED], 17 ["media.autoplay.blocking_policy", 0]); 18 19 window.info = function(msg, token) { 20 SimpleTest.info(msg + ", token=" + token); 21 } 22 23 window.is = function(valA, valB, msg, token) { 24 SimpleTest.is(valA, valB, msg + ", token=" + token); 25 } 26 27 window.ok = function(val, msg, token) { 28 SimpleTest.ok(val, msg + ", token=" + token); 29 } 30 31 /** 32 * test files and paremeters 33 */ 34 var autoplayTests = [ 35 /* video */ 36 { name: "gizmo.mp4", type: "video/mp4", hasAudio:true }, 37 { name: "gizmo-noaudio.mp4", type: "video/mp4", hasAudio:false }, 38 { name: "gizmo.webm", type: "video/webm", hasAudio:true }, 39 { name: "gizmo-noaudio.webm", type: "video/webm", hasAudio:false }, 40 /* audio */ 41 { name: "small-shot.ogg", type: "audio/ogg", hasAudio:true }, 42 { name: "small-shot.m4a", type: "audio/mp4", hasAudio:true }, 43 { name: "small-shot.mp3", type: "audio/mpeg", hasAudio:true }, 44 { name: "small-shot.flac", type: "audio/flac", hasAudio:true }, 45 ]; 46 47 var autoplayParams = [ 48 { volume: 1.0, muted: false, preload: "none" }, 49 { volume: 0.0, muted: false, preload: "none" }, 50 { volume: 1.0, muted: true, preload: "none" }, 51 { volume: 0.0, muted: true, preload: "none" }, 52 { volume: 1.0, muted: false, preload: "metadata" }, 53 { volume: 0.0, muted: false, preload: "metadata" }, 54 { volume: 1.0, muted: true, preload: "metadata" }, 55 { volume: 0.0, muted: true, preload: "metadata" }, 56 ]; 57 58 function createTestArray() 59 { 60 var tests = []; 61 for (let test of autoplayTests) { 62 for (let param of autoplayParams) { 63 tests.push({ 64 name: test.name, 65 type: test.type, 66 hasAudio: test.hasAudio, 67 volume: param.volume, 68 muted: param.muted, 69 preload: param.preload, 70 }); 71 } 72 } 73 return tests; 74 } 75 76 /** 77 * Main test function for different autoplay cases without user interaction. 78 * 79 * When the pref "media.autoplay.default" is 1 and the pref 80 * "media.autoplay.blocking_policy" is 0, we only allow 81 * audible media to autoplay after the website has been activated by specific 82 * user gestures. However, inaudible media won't be restricted. 83 * 84 * Audible means the volume is not zero, or muted is not true for the video with 85 * audio track. For media without loading metadata, we can't know whether it has 86 * audio track or not, so we would also regard it as audible media. 87 * 88 * Inaudible means the volume is zero, or the muted is true, or the video without 89 * audio track. 90 */ 91 async function runTest(test, token) { 92 manager.started(token); 93 94 await testPlay(test, token); 95 await testAutoplayKeyword(test, token); 96 97 manager.finished(token); 98 } 99 100 manager.runTests(createTestArray(), runTest); 101 102 /** 103 * Different test scenarios 104 */ 105 async function testPlay(test, token) { 106 info("### start testPlay", token); 107 info(`volume=${test.volume}, muted=${test.muted}, ` + 108 `preload=${test.preload}, hasAudio=${test.hasAudio}`, token); 109 110 let element = document.createElement(getMajorMimeType(test.type)); 111 element.volume = test.volume; 112 element.muted = test.muted; 113 element.src = test.name; 114 document.body.appendChild(element); 115 116 // Only need to test preload when calling play(), because media with 'autoplay' 117 // keyword always starts after loading enough data. 118 const preLoadNone = test.preload == "none"; 119 if (!preLoadNone) { 120 info("### wait for loading metadata", token); 121 await once(element, "loadedmetadata"); 122 } 123 124 let isAudible = (preLoadNone || test.hasAudio) && 125 test.volume != 0.0 && 126 !test.muted; 127 let state = isAudible? "audible" : "non-audible"; 128 info(`### calling play() for ${state} media`, token); 129 let promise = element.play(); 130 if (isAudible) { 131 await promise.catch(function(error) { 132 ok(element.paused, `${state} media fail to start via play()`, token); 133 is(error.name, "NotAllowedError", "rejected play promise", token); 134 }); 135 } else { 136 // since we just want to check the value of 'paused', we don't need to wait 137 // resolved play promise. (it's equal to wait for 'playing' event) 138 await once(element, "play"); 139 ok(!element.paused, `${state} media start via play()`, token); 140 } 141 142 removeNodeAndSource(element); 143 } 144 145 async function testAutoplayKeyword(test, token) { 146 info("### start testAutoplayKeyword", token); 147 info(`volume=${test.volume}, muted=${test.muted}, ` + 148 `hasAudio=${test.hasAudio}`, token); 149 150 let element = document.createElement(getMajorMimeType(test.type)); 151 element.autoplay = true; 152 element.volume = test.volume; 153 element.muted = test.muted; 154 element.src = test.name; 155 document.body.appendChild(element); 156 157 let isAudible = test.hasAudio && 158 test.volume != 0.0 && 159 !test.muted; 160 let state = isAudible? "audible" : "non-audible"; 161 info(`### wait to autoplay for ${state} media`, token); 162 if (isAudible) { 163 await once(element, "canplay"); 164 ok(element.paused, `can not start with 'autoplay' keyword for ${state} media`, token); 165 } else { 166 await once(element, "play"); 167 ok(!element.paused, `start with 'autoplay' keyword for ${state} media`, token); 168 } 169 170 removeNodeAndSource(element); 171 } 172 173 </script>