test_mediarecorder_principals.html (4642B)
1 <!DOCTYPE HTML> 2 <html> 3 <!-- 4 https://bugzilla.mozilla.org/show_bug.cgi?id=489415 5 --> 6 <head> 7 <title>Test for MediaRecorder Reaction to Principal Change</title> 8 <script src="/tests/SimpleTest/SimpleTest.js"></script> 9 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> 10 <script type="text/javascript" src="manifest.js"></script> 11 </head> 12 <body> 13 <div> 14 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1018299">Test for MediaRecorder Principal Handling</a> 15 </div> 16 17 <pre id="test"> 18 <script type="text/javascript"> 19 SimpleTest.waitForExplicitFinish(); 20 21 let throwOutside = e => setTimeout(() => { throw e; }); 22 23 // Loading data from a resource that changes origins while streaming should 24 // be detected by the media cache and result in a null principal so that the 25 // MediaRecorder usages below fail. 26 27 // This test relies on midflight-redirect.sjs returning the the first quarter of 28 // the resource as a byte range response, and then hanging up, and when Firefox 29 // requests the remainder midflight-redirect.sjs serves a redirect to another origin. 30 31 async function testPrincipals(resource) { 32 if (!resource) { 33 todo(false, "No types supported"); 34 return; 35 } 36 await testPrincipals1(resource); 37 await testPrincipals2(resource); 38 } 39 40 function makeVideo() { 41 let video = document.createElement("video"); 42 video.preload = "metadata"; 43 video.controls = true; 44 document.body.appendChild(video); 45 return video; 46 } 47 48 // First test: Load file from same-origin first, then get redirected to 49 // another origin before attempting to record stream. 50 async function testPrincipals1(resource) { 51 let video = makeVideo(); 52 video.src = 53 "http://mochi.test:8888/tests/dom/media/test/midflight-redirect.sjs" + 54 "?resource=" + resource.name + "&type=" + resource.type; 55 56 let errorBarrier = once(video, "error"); 57 // Wait for the video to load to metadata. We can then start capturing. 58 // Must also handle the download bursting and hitting the error before we 59 // reach loadedmetadata. Normally we reach loadedmetadata first, but 60 // rarely we hit the redirect first. 61 await Promise.race([once(video, "loadedmetadata"), errorBarrier]); 62 63 let rec = new MediaRecorder(video.mozCaptureStreamUntilEnded()); 64 video.play(); 65 66 // Wait until we hit a playback error. This means our download has hit the redirect. 67 await errorBarrier; 68 69 // Try to record, it should be blocked with a security error. 70 try { 71 rec.start(); 72 ok(false, "mediaRecorder.start() must throw SecurityError, but didn't throw at all"); 73 } catch (ex) { 74 is(ex.name, "SecurityError", "mediaRecorder.start() must throw SecurityError"); 75 } 76 removeNodeAndSource(video); 77 } 78 79 // Second test: Load file from same-origin first, but record ASAP, before 80 // getting redirected to another origin. 81 async function testPrincipals2(resource) { 82 let video = makeVideo(); 83 video.src = 84 "http://mochi.test:8888/tests/dom/media/test/midflight-redirect.sjs" + 85 "?resource=" + resource.name + "&type=" + resource.type; 86 87 // Wait for the video to load to metadata. We can then start capturing. 88 // Must also handle the download bursting and hitting the error before we 89 // reach loadedmetadata. Normally we reach loadedmetadata first, but 90 // rarely we hit the redirect first. 91 await Promise.race([once(video, "loadedmetadata"), once(video, "error")]); 92 93 let ended = false; 94 once(video, "ended", () => ended = true); 95 96 // Start capturing. It should work. 97 let rec; 98 let errorBarrier; 99 try { 100 rec = new MediaRecorder(video.mozCaptureStreamUntilEnded()); 101 errorBarrier = nextEvent(rec, "error"); 102 rec.start(); 103 ok(true, "mediaRecorder.start() should not throw here, and didn't"); 104 } catch (ex) { 105 ok(false, "mediaRecorder.start() unexpectedly threw " + ex.name + " (" + ex.message + ")"); 106 } 107 108 // Play the video, this should result in a SecurityError on the recorder. 109 let hasStopped = once(rec, "stop"); 110 video.play(); 111 let error = (await errorBarrier).error; 112 is(error.name, "SecurityError", "mediaRecorder.onerror must fire SecurityError"); 113 ok(error.stack.includes('test_mediarecorder_principals.html'), 114 'Events fired from onerror should include an error with a stack trace indicating ' + 115 'an error in this test'); 116 is(ended, false, "Playback should not have reached end"); 117 await hasStopped; 118 is(ended, false, "Playback should definitely not have reached end"); 119 120 removeNodeAndSource(video); 121 } 122 123 testPrincipals({ name:"pixel_aspect_ratio.mp4", type:"video/mp4", duration:28 }) 124 .catch(e => throwOutside(e)) 125 .then(() => SimpleTest.finish()); 126 127 </script> 128 </pre> 129 130 </body> 131 </html>