content-task.js (3542B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 /* eslint-env mozilla/frame-script */ 6 7 "use strict"; 8 9 let { ContentTaskUtils } = ChromeUtils.importESModule( 10 "resource://testing-common/ContentTaskUtils.sys.mjs" 11 ); 12 const { Assert: AssertCls } = ChromeUtils.importESModule( 13 "resource://testing-common/Assert.sys.mjs" 14 ); 15 const { setTimeout } = ChromeUtils.importESModule( 16 "resource://gre/modules/Timer.sys.mjs" 17 ); 18 19 // Injects EventUtils into ContentTask scope. To avoid leaks, this does not hold on 20 // to the window global. This means you **need** to pass the window as an argument to 21 // the individual EventUtils functions. 22 // See SimpleTest/EventUtils.js for documentation. 23 var EventUtils = { 24 _EU_Ci: Ci, 25 _EU_Cc: Cc, 26 KeyboardEvent: content.KeyboardEvent, 27 navigator: content.navigator, 28 setTimeout, 29 window: {}, 30 }; 31 32 EventUtils.synthesizeClick = element => 33 new Promise(resolve => { 34 element.addEventListener( 35 "click", 36 function () { 37 resolve(); 38 }, 39 { once: true } 40 ); 41 42 EventUtils.synthesizeMouseAtCenter( 43 element, 44 { type: "mousedown", isSynthesized: false }, 45 content 46 ); 47 EventUtils.synthesizeMouseAtCenter( 48 element, 49 { type: "mouseup", isSynthesized: false }, 50 content 51 ); 52 }); 53 54 try { 55 Services.scriptloader.loadSubScript( 56 "chrome://mochikit/content/tests/SimpleTest/EventUtils.js", 57 EventUtils 58 ); 59 } catch (e) { 60 // There are some xpcshell tests which may use ContentTask. 61 // Just ignore if loading EventUtils fails. Tests that need it 62 // will fail anyway. 63 EventUtils = null; 64 } 65 66 addMessageListener("content-task:spawn", async function (msg) { 67 let id = msg.data.id; 68 let source = msg.data.runnable || "()=>{}"; 69 70 function getStack(aStack) { 71 let frames = []; 72 for (let frame = aStack; frame; frame = frame.caller) { 73 frames.push(frame.filename + ":" + frame.name + ":" + frame.lineNumber); 74 } 75 return frames.join("\n"); 76 } 77 78 var Assert = new AssertCls((err, message, stack) => { 79 sendAsyncMessage("content-task:test-result", { 80 id, 81 condition: !err, 82 name: err ? err.message : message, 83 stack: getStack(err ? err.stack : stack), 84 }); 85 }); 86 87 /* eslint-disable no-unused-vars */ 88 var ok = Assert.ok.bind(Assert); 89 var is = Assert.equal.bind(Assert); 90 var isnot = Assert.notEqual.bind(Assert); 91 92 function todo(expr, name) { 93 sendAsyncMessage("content-task:test-todo", { id, expr, name }); 94 } 95 96 function todo_is(a, b, name) { 97 sendAsyncMessage("content-task:test-todo_is", { id, a, b, name }); 98 } 99 100 function info(name) { 101 sendAsyncMessage("content-task:test-info", { id, name }); 102 } 103 /* eslint-enable no-unused-vars */ 104 105 // Note that ContentTaskUtils is imported above, so it's also available in the 106 // scope of the eval. 107 // If more variables are made available, don't forget to update 108 // tools/lint/eslint/eslint-plugin-mozilla/lib/rules/import-content-task-globals.js. 109 110 try { 111 let runnablestr = ` 112 (() => { 113 return (${source}); 114 })();`; 115 116 // eslint-disable-next-line no-eval 117 let runnable = eval(runnablestr); 118 let result = await runnable.call(this, msg.data.arg); 119 sendAsyncMessage("content-task:complete", { 120 id, 121 result, 122 }); 123 } catch (ex) { 124 sendAsyncMessage("content-task:complete", { 125 id, 126 error: ex.toString(), 127 }); 128 } 129 });