test_imagecapture.html (3872B)
1 <!DOCTYPE HTML> 2 <html> 3 <!-- 4 https://bugzilla.mozilla.org/show_bug.cgi?id=1041393 5 --> 6 <head> 7 <meta charset="utf-8"> 8 <title>ImageCapture tests</title> 9 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> 10 <script src="/tests/SimpleTest/SimpleTest.js"></script> 11 <script type="text/javascript" src="gUM_support.js"></script> 12 </head> 13 <body> 14 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1041393">ImageCapture tests</a> 15 <script type="application/javascript"> 16 17 // Check if the callback returns even no JS reference on it. 18 async function gcTest(track) { 19 const repeat = 100; 20 const promises = []; 21 for (let i = 0; i < repeat; ++i) { 22 const imageCapture = new ImageCapture(track); 23 promises.push(new Promise((resolve, reject) => { 24 imageCapture.onphoto = resolve; 25 imageCapture.onerror = () => 26 reject(new Error(`takePhoto gcTest failure for capture ${i}`)); 27 })); 28 imageCapture.takePhoto(); 29 } 30 info("Call gc "); 31 SpecialPowers.gc(); 32 await Promise.all(promises); 33 } 34 35 // Continue calling takePhoto() in rapid succession. 36 async function rapidTest(track) { 37 const repeat = 100; 38 const imageCapture = new ImageCapture(track); 39 // "error" can fire synchronously in `takePhoto` 40 const errorPromise = new Promise(r => imageCapture.onerror = r); 41 for (let i = 0; i < repeat; ++i) { 42 imageCapture.takePhoto(); 43 } 44 for (let i = 0; i < repeat; ++i) { 45 await Promise.race([ 46 new Promise(r => imageCapture.onphoto = r), 47 errorPromise.then(() => Promise.reject(new Error("Capture failed"))), 48 ]); 49 } 50 } 51 52 // Check if the blob is decodable. 53 async function blobTest(track) { 54 const imageCapture = new ImageCapture(track); 55 // "error" can fire synchronously in `takePhoto` 56 const errorPromise = new Promise(r => imageCapture.onerror = r); 57 imageCapture.takePhoto(); 58 const blob = await Promise.race([ 59 new Promise(r => imageCapture.onphoto = r), 60 errorPromise.then(() => Promise.reject(new Error("Capture failed"))), 61 ]); 62 63 const img = new Image(); 64 img.src = URL.createObjectURL(blob.data); 65 await new Promise((resolve, reject) => { 66 img.onload = resolve; 67 img.onerror = () => reject(new Error("Decode failed")); 68 }); 69 } 70 71 // It should return an error event after disabling video track. 72 async function trackTest(track) { 73 const imageCapture = new ImageCapture(track); 74 track.enabled = false; 75 try { 76 const errorPromise = new Promise(r => imageCapture.onerror = r); 77 imageCapture.takePhoto(); 78 const error = await Promise.race([ 79 errorPromise, 80 new Promise(r => imageCapture.onphoto = r).then( 81 () => Promise.reject(new Error("Disabled video track should fail"))), 82 ]); 83 is(error.imageCaptureError.code, error.imageCaptureError.PHOTO_ERROR, 84 "Expected error code") 85 } finally { 86 track.enabled = true; 87 } 88 } 89 90 async function init() { 91 // Use loopback camera if available, otherwise fake. 92 // MediaTrackGraph will be the backend of ImageCapture. 93 await setupGetUserMediaTestPrefs(); 94 let stream = await navigator.mediaDevices.getUserMedia({video: true}); 95 return stream.getVideoTracks()[0]; 96 } 97 98 async function start() { 99 try { 100 const track = await init(); 101 info("ImageCapture track disable test."); 102 await trackTest(track); 103 info("ImageCapture blob test."); 104 await blobTest(track); 105 info("ImageCapture rapid takePhoto() test."); 106 await rapidTest(track); 107 info("ImageCapture multiple instances test."); 108 await gcTest(track); 109 } catch (e) { 110 ok(false, "Unexpected error during test: " + e); 111 } finally { 112 SimpleTest.finish(); 113 } 114 } 115 116 SimpleTest.requestCompleteLog(); 117 SimpleTest.waitForExplicitFinish(); 118 119 SpecialPowers.pushPrefEnv({ 120 "set": [ 121 ["dom.imagecapture.enabled", true], 122 ["media.navigator.permission.disabled", true], 123 ], 124 }, start); 125 </script> 126 </pre> 127 </body> 128 </html>