/* exported attachURL, promiseDone, promiseOnce, addTest, addAsyncTest, runNextTest, _documentWalker, createResourceWatcher */ "use strict"; const { require } = ChromeUtils.import("resource://devtools/shared/Loader.jsm"); const { TargetFactory } = require("devtools/client/framework/target"); const { DevToolsServer } = require("devtools/server/devtools-server"); const { BrowserTestUtils, } = require("resource://testing-common/BrowserTestUtils.jsm"); const { DocumentWalker: _documentWalker, } = require("devtools/server/actors/inspector/document-walker"); const { TargetList } = require("devtools/shared/resources/target-list"); const { ResourceWatcher, } = require("devtools/shared/resources/resource-watcher"); const Services = require("Services"); // Always log packets when running tests. Services.prefs.setBoolPref("devtools.debugger.log", true); SimpleTest.registerCleanupFunction(function() { Services.prefs.clearUserPref("devtools.debugger.log"); }); if (!DevToolsServer.initialized) { DevToolsServer.init(); DevToolsServer.registerAllActors(); SimpleTest.registerCleanupFunction(function() { DevToolsServer.destroy(); }); } var gAttachCleanups = []; SimpleTest.registerCleanupFunction(function() { for (const cleanup of gAttachCleanups) { cleanup(); } }); /** * Add a new test tab in the browser and load the given url. * @return Promise a promise that resolves to the new target representing * the page currently opened. */ async function getTargetForSelectedTab(gBrowser) { const selectedTab = gBrowser.selectedTab; await BrowserTestUtils.browserLoaded(selectedTab.linkedBrowser); return TargetFactory.forTab(selectedTab); } /** * Open a tab, load the url, wait for it to signal its readiness, * find the tab with the devtools server, and call the callback. * * Returns a function which can be called to close the opened ta * and disconnect its devtools client. */ async function attachURL(url) { // Get the current browser window const gBrowser = Services.wm.getMostRecentWindow("navigator:browser") .gBrowser; // open the url in a new tab, save a reference to the new inner window global object // and wait for it to load. The tests rely on this window object to send a "ready" // event to its opener (the test page). This window reference is used within // the test tab, to reference the webpage being tested against, which is in another // tab. const windowOpened = BrowserTestUtils.waitForNewTab(gBrowser, url); const win = window.open(url, "_blank"); await windowOpened; const target = await getTargetForSelectedTab(gBrowser); await target.attach(); const cleanup = async function() { await target.destroy(); if (win) { win.close(); } }; gAttachCleanups.push(cleanup); return { target, doc: win.document }; } function promiseOnce(target, event) { return new Promise(resolve => { target.on(event, (...args) => { if (args.length === 1) { resolve(args[0]); } else { resolve(args); } }); }); } function promiseDone(currentPromise) { currentPromise.catch(err => { ok(false, "Promise failed: " + err); if (err.stack) { dump(err.stack); } SimpleTest.finish(); }); } var _tests = []; function addTest(test) { _tests.push(test); } function addAsyncTest(generator) { _tests.push(() => generator().catch(ok.bind(null, false))); } function runNextTest() { if (_tests.length == 0) { SimpleTest.finish(); return; } const fn = _tests.shift(); try { fn(); } catch (ex) { info( "Test function " + (fn.name ? "'" + fn.name + "' " : "") + "threw an exception: " + ex ); } } function createResourceWatcher(target) { const targetList = new TargetList(target.client.mainRoot, target); return new ResourceWatcher(targetList); }