head.js (4579B)
1 "use strict"; 2 3 const { Subprocess } = ChromeUtils.importESModule( 4 "resource://gre/modules/Subprocess.sys.mjs" 5 ); 6 7 const TEMP_DIR = Services.dirsvc.get("TmpD", Ci.nsIFile).path; 8 9 const screenshotPath = PathUtils.join(TEMP_DIR, "headless_test_screenshot.png"); 10 11 async function runFirefox(args) { 12 const XRE_EXECUTABLE_FILE = "XREExeF"; 13 const firefoxExe = Services.dirsvc.get(XRE_EXECUTABLE_FILE, Ci.nsIFile).path; 14 const NS_APP_PREFS_50_FILE = "PrefF"; 15 const mochiPrefsFile = Services.dirsvc.get(NS_APP_PREFS_50_FILE, Ci.nsIFile); 16 const mochiPrefsPath = mochiPrefsFile.path; 17 const mochiPrefsName = mochiPrefsFile.leafName; 18 const profilePath = PathUtils.join( 19 TEMP_DIR, 20 "headless_test_screenshot_profile" 21 ); 22 const prefsPath = PathUtils.join(profilePath, mochiPrefsName); 23 const firefoxArgs = ["-profile", profilePath]; 24 25 await IOUtils.makeDirectory(profilePath); 26 await IOUtils.copy(mochiPrefsPath, prefsPath); 27 let proc = await Subprocess.call({ 28 command: firefoxExe, 29 arguments: firefoxArgs.concat(args), 30 // Disable leak detection to avoid intermittent failure bug 1331152. 31 environmentAppend: true, 32 environment: { 33 ASAN_OPTIONS: 34 "detect_leaks=0:quarantine_size=50331648:malloc_context_size=5", 35 // Don't enable Marionette. 36 MOZ_MARIONETTE: null, 37 }, 38 }); 39 let stdout; 40 while ((stdout = await proc.stdout.readString())) { 41 dump(`>>> ${stdout}\n`); 42 } 43 let { exitCode } = await proc.wait(); 44 is(exitCode, 0, "Firefox process should exit with code 0"); 45 await IOUtils.remove(profilePath, { recursive: true }); 46 } 47 48 async function testFileCreationPositive(args, path) { 49 await runFirefox(args); 50 51 let saved = IOUtils.exists(path); 52 ok(saved, "A screenshot should be saved as " + path); 53 if (!saved) { 54 return; 55 } 56 57 let info = await IOUtils.stat(path); 58 Assert.greater(info.size, 0, "Screenshot should not be an empty file"); 59 await IOUtils.remove(path); 60 } 61 62 async function testFileCreationNegative(args, path) { 63 await runFirefox(args); 64 65 let saved = await IOUtils.exists(path); 66 ok(!saved, "A screenshot should not be saved"); 67 await IOUtils.remove(path); 68 } 69 70 async function testWindowSizePositive(width, height) { 71 let size = String(width); 72 if (height) { 73 size += "," + height; 74 } 75 76 await runFirefox([ 77 "-url", 78 "http://mochi.test:8888/browser/browser/components/shell/test/headless.html", 79 "-screenshot", 80 screenshotPath, 81 "-window-size", 82 size, 83 ]); 84 85 let saved = await IOUtils.exists(screenshotPath); 86 ok(saved, "A screenshot should be saved in the tmp directory"); 87 if (!saved) { 88 return; 89 } 90 91 let data = await IOUtils.read(screenshotPath); 92 await new Promise(resolve => { 93 let blob = new Blob([data], { type: "image/png" }); 94 let reader = new FileReader(); 95 reader.onloadend = function () { 96 let screenshot = new Image(); 97 screenshot.onload = function () { 98 is( 99 screenshot.width, 100 width, 101 "Screenshot should be " + width + " pixels wide" 102 ); 103 if (height) { 104 is( 105 screenshot.height, 106 height, 107 "Screenshot should be " + height + " pixels tall" 108 ); 109 } 110 resolve(); 111 }; 112 screenshot.src = reader.result; 113 }; 114 reader.readAsDataURL(blob); 115 }); 116 await IOUtils.remove(screenshotPath); 117 } 118 119 async function testGreen(url, path) { 120 await runFirefox(["-url", url, `--screenshot=${path}`]); 121 122 let saved = await IOUtils.exists(path); 123 ok(saved, "A screenshot should be saved in the tmp directory"); 124 if (!saved) { 125 return; 126 } 127 128 let data = await IOUtils.read(path); 129 let image = await new Promise(resolve => { 130 let blob = new Blob([data], { type: "image/png" }); 131 let reader = new FileReader(); 132 reader.onloadend = function () { 133 let screenshot = new Image(); 134 screenshot.onload = function () { 135 resolve(screenshot); 136 }; 137 screenshot.src = reader.result; 138 }; 139 reader.readAsDataURL(blob); 140 }); 141 let canvas = document.createElement("canvas"); 142 canvas.width = image.naturalWidth; 143 canvas.height = image.naturalHeight; 144 let ctx = canvas.getContext("2d"); 145 ctx.drawImage(image, 0, 0); 146 let imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); 147 let rgba = imageData.data; 148 149 let found = false; 150 for (let i = 0; i < rgba.length; i += 4) { 151 if (rgba[i] === 0 && rgba[i + 1] === 255 && rgba[i + 2] === 0) { 152 found = true; 153 break; 154 } 155 } 156 ok(found, "There should be a green pixel in the screenshot."); 157 158 await IOUtils.remove(path); 159 }