inspector-helpers.js (3479B)
1 /* exported attachURL, promiseDone, 2 promiseOnce, 3 addTest, addAsyncTest, 4 runNextTest, _documentWalker */ 5 "use strict"; 6 7 const { require } = ChromeUtils.importESModule( 8 "resource://devtools/shared/loader/Loader.sys.mjs" 9 ); 10 const { 11 CommandsFactory, 12 } = require("resource://devtools/shared/commands/commands-factory.js"); 13 const { 14 DevToolsServer, 15 } = require("resource://devtools/server/devtools-server.js"); 16 const { BrowserTestUtils } = ChromeUtils.importESModule( 17 "resource://testing-common/BrowserTestUtils.sys.mjs" 18 ); 19 const { 20 DocumentWalker: _documentWalker, 21 } = require("resource://devtools/server/actors/inspector/document-walker.js"); 22 23 // Always log packets when running tests. 24 Services.prefs.setBoolPref("devtools.debugger.log", true); 25 SimpleTest.registerCleanupFunction(function () { 26 Services.prefs.clearUserPref("devtools.debugger.log"); 27 }); 28 29 if (!DevToolsServer.initialized) { 30 DevToolsServer.init(); 31 DevToolsServer.registerAllActors(); 32 SimpleTest.registerCleanupFunction(function () { 33 DevToolsServer.destroy(); 34 }); 35 } 36 37 var gAttachCleanups = []; 38 39 SimpleTest.registerCleanupFunction(function () { 40 for (const cleanup of gAttachCleanups) { 41 cleanup(); 42 } 43 }); 44 45 /** 46 * Open a tab, load the url, wait for it to signal its readiness, 47 * connect to this tab via DevTools protocol and return. 48 * 49 * Returns an object with a few helpful attributes: 50 * - commands {Object}: The commands object defined by modules from devtools/shared/commands 51 * - target {TargetFront}: The current top-level target front. 52 * - doc {HtmlDocument}: the tab's document that got opened 53 */ 54 async function attachURL(url) { 55 // Get the current browser window 56 const gBrowser = Services.wm.getMostRecentBrowserWindow().gBrowser; 57 58 // open the url in a new tab, save a reference to the new inner window global object 59 // and wait for it to load. The tests rely on this window object to send a "ready" 60 // event to its opener (the test page). This window reference is used within 61 // the test tab, to reference the webpage being tested against, which is in another 62 // tab. 63 const windowOpened = BrowserTestUtils.waitForNewTab(gBrowser, url); 64 const win = window.open(url, "_blank"); 65 await windowOpened; 66 67 const commands = await CommandsFactory.forTab(gBrowser.selectedTab); 68 await commands.targetCommand.startListening(); 69 70 const cleanup = async function () { 71 await commands.destroy(); 72 if (win) { 73 win.close(); 74 } 75 }; 76 77 gAttachCleanups.push(cleanup); 78 return { 79 commands, 80 target: commands.targetCommand.targetFront, 81 doc: win.document, 82 }; 83 } 84 85 function promiseOnce(target, event) { 86 return new Promise(resolve => { 87 target.on(event, (...args) => { 88 if (args.length === 1) { 89 resolve(args[0]); 90 } else { 91 resolve(args); 92 } 93 }); 94 }); 95 } 96 97 function promiseDone(currentPromise) { 98 currentPromise.catch(err => { 99 ok(false, "Promise failed: " + err); 100 if (err.stack) { 101 dump(err.stack); 102 } 103 SimpleTest.finish(); 104 }); 105 } 106 107 var _tests = []; 108 function addTest(test) { 109 _tests.push(test); 110 } 111 112 function addAsyncTest(generator) { 113 _tests.push(() => generator().catch(ok.bind(null, false))); 114 } 115 116 function runNextTest() { 117 if (!_tests.length) { 118 SimpleTest.finish(); 119 return; 120 } 121 const fn = _tests.shift(); 122 try { 123 fn(); 124 } catch (ex) { 125 info( 126 "Test function " + 127 (fn.name ? "'" + fn.name + "' " : "") + 128 "threw an exception: " + 129 ex 130 ); 131 } 132 }