author | Kris Maglione <maglione.k@gmail.com> |
Sat, 10 Mar 2018 22:52:16 -0800 | |
changeset 407668 | b3689730f6bd8f2af457021e1bd0820c720b9d85 |
parent 407667 | 599c42a12fcc8eee5e531e50cff162e815623329 |
child 407669 | 590b8679be3da45c7923b7b49c2cbddf67222af2 |
push id | 100754 |
push user | maglione.k@gmail.com |
push date | Mon, 12 Mar 2018 20:51:20 +0000 |
treeherder | mozilla-inbound@156cad0b9e17 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mixedpuppy |
bugs | 1444680 |
milestone | 60.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/toolkit/components/extensions/ExtensionXPCShellUtils.jsm +++ b/toolkit/components/extensions/ExtensionXPCShellUtils.jsm @@ -13,16 +13,18 @@ ChromeUtils.import("resource://gre/modul ChromeUtils.defineModuleGetter(this, "AddonManager", "resource://gre/modules/AddonManager.jsm"); ChromeUtils.defineModuleGetter(this, "AddonTestUtils", "resource://testing-common/AddonTestUtils.jsm"); ChromeUtils.defineModuleGetter(this, "Extension", "resource://gre/modules/Extension.jsm"); ChromeUtils.defineModuleGetter(this, "FileUtils", "resource://gre/modules/FileUtils.jsm"); +ChromeUtils.defineModuleGetter(this, "MessageChannel", + "resource://gre/modules/MessageChannel.jsm"); ChromeUtils.defineModuleGetter(this, "Schemas", "resource://gre/modules/Schemas.jsm"); ChromeUtils.defineModuleGetter(this, "Services", "resource://gre/modules/Services.jsm"); ChromeUtils.defineModuleGetter(this, "TestUtils", "resource://testing-common/TestUtils.jsm"); XPCOMUtils.defineLazyGetter(this, "Management", () => { @@ -50,28 +52,36 @@ let BASE_MANIFEST = Object.freeze({ "manifest_version": 2, "name": "name", "version": "0", }); function frameScript() { + ChromeUtils.import("resource://gre/modules/MessageChannel.jsm"); ChromeUtils.import("resource://gre/modules/Services.jsm"); Services.obs.notifyObservers(this, "tab-content-frameloader-created"); + const messageListener = { + async receiveMessage({target, messageName, recipient, data, name}) { + /* globals content */ + let resp = await content.fetch(data.url, data.options); + return resp.text(); + }, + }; + MessageChannel.addListener(this, "Test:Fetch", messageListener); + // eslint-disable-next-line mozilla/balanced-listeners, no-undef addEventListener("MozHeapMinimize", () => { Services.obs.notifyObservers(null, "memory-pressure", "heap-minimize"); }, true, true); } -const FRAME_SCRIPT = `data:text/javascript,(${encodeURI(frameScript)}).call(this)`; - let kungFuDeathGrip = new Set(); function promiseBrowserLoaded(browser, url, redirectUrl) { return new Promise(resolve => { const listener = { QueryInterface: XPCOMUtils.generateQI([Ci.nsISupportsWeakReference, Ci.nsIWebProgressListener]), onStateChange(webProgress, request, stateFlags, statusCode) { let requestUrl = request.URI ? request.URI.spec : webProgress.DOMWindow.location.href; @@ -134,29 +144,43 @@ class ContentPage { if (this.remote) { awaitFrameLoader = promiseEvent(browser, "XULFrameLoaderCreated"); browser.setAttribute("remote", "true"); } chromeDoc.documentElement.appendChild(browser); await awaitFrameLoader; - browser.messageManager.loadFrameScript(FRAME_SCRIPT, true); + this.browser = browser; + + this.loadFrameScript(frameScript); + + return browser; + } - this.browser = browser; - return browser; + sendMessage(msg, data) { + return MessageChannel.sendMessage(this.browser.messageManager, msg, data); + } + + loadFrameScript(func) { + let frameScript = `data:text/javascript,(${encodeURI(func)}).call(this)`; + this.browser.messageManager.loadFrameScript(frameScript, true); } async loadURL(url, redirectUrl = undefined) { await this.browserReady; this.browser.loadURI(url); return promiseBrowserLoaded(this.browser, url, redirectUrl); } + async fetch(url, options) { + return this.sendMessage("Test:Fetch", {url, options}); + } + async close() { await this.browserReady; let {messageManager} = this.browser; this.browser = null; this.windowlessBrowser.close(); @@ -612,16 +636,18 @@ var ExtensionTestUtils = { profileDir: null, init(scope) { this.currentScope = scope; this.profileDir = scope.do_get_profile(); + this.fetchScopes = new Map(); + // We need to load at least one frame script into every message // manager to ensure that the scriptable wrapper for its global gets // created before we try to access it externally. If we don't, we // fail sanity checks on debug builds the first time we try to // create a wrapper, because we should never have a global without a // cached wrapper. Services.mm.loadFrameScript("data:text/javascript,//", true); @@ -644,16 +670,19 @@ var ExtensionTestUtils = { Services.dirsvc.registerProvider(dirProvider); scope.registerCleanupFunction(() => { tmpD.remove(true); Services.dirsvc.unregisterProvider(dirProvider); this.currentScope = null; + + return Promise.all(Array.from(this.fetchScopes.values(), + promise => promise.then(scope => scope.close()))); }); }, addonManagerStarted: false, mockAppInfo() { const {updateAppInfo} = ChromeUtils.import("resource://testing-common/AppInfo.jsm", {}); updateAppInfo({ @@ -691,16 +720,27 @@ var ExtensionTestUtils = { get remoteContentScripts() { return REMOTE_CONTENT_SCRIPTS; }, set remoteContentScripts(val) { REMOTE_CONTENT_SCRIPTS = !!val; }, + async fetch(origin, url, options) { + let fetchScopePromise = this.fetchScopes.get(origin); + if (!fetchScopePromise) { + fetchScopePromise = this.loadContentPage(origin); + this.fetchScopes.set(origin, fetchScopePromise); + } + + let fetchScope = await fetchScopePromise; + return fetchScope.sendMessage("Test:Fetch", {url, options}); + }, + /** * Loads a content page into a hidden docShell. * * @param {string} url * The URL to load. * @param {object} [options = {}] * @param {ExtensionWrapper} [options.extension] * If passed, load the URL as an extension page for the given
--- a/toolkit/components/extensions/test/xpcshell/test_ext_i18n_css.js +++ b/toolkit/components/extensions/test/xpcshell/test_ext_i18n_css.js @@ -91,44 +91,33 @@ let extensionData = { async function test_i18n_css(options = {}) { extensionData.useAddonManager = options.useAddonManager; let extension = ExtensionTestUtils.loadExtension(extensionData); await extension.startup(); let cssURL = await extension.awaitMessage("ready"); - function fetch(url) { - return new Promise((resolve, reject) => { - let xhr = new XMLHttpRequest(); - xhr.overrideMimeType("text/plain"); - xhr.open("GET", url); - xhr.onload = () => { resolve(xhr.responseText); }; - xhr.onerror = reject; - xhr.send(); - }); - } + let contentPage = await ExtensionTestUtils.loadContentPage(`${BASE_URL}/file_sample.html`); - let css = await fetch(cssURL); + let css = await contentPage.fetch(cssURL); equal(css, "body { max-width: 42px; }", "CSS file localized in mochitest scope"); - let contentPage = await ExtensionTestUtils.loadContentPage(`${BASE_URL}/file_sample.html`); - let maxWidth = await extension.awaitMessage("content-maxWidth"); equal(maxWidth, "42px", "stylesheet correctly applied"); - await contentPage.close(); - cssURL = cssURL.replace(/foo.css$/, "locale.css"); - css = await fetch(cssURL); + css = await contentPage.fetch(cssURL); equal(css, '* { content: "en-US ltr rtl left right" }', "CSS file localized in mochitest scope"); + await contentPage.close(); + // We don't currently have a good way to mock this. if (false) { const DIR = "intl.uidirection"; // We don't wind up actually switching the chrome registry locale, since we // don't have a chrome package for Hebrew. So just override it, and force // RTL directionality. const origReqLocales = Services.locale.getRequestedLocales();
--- a/toolkit/components/extensions/test/xpcshell/test_ext_webRequest_filterResponseData.js +++ b/toolkit/components/extensions/test/xpcshell/test_ext_webRequest_filterResponseData.js @@ -3,34 +3,32 @@ const HOSTS = new Set([ "example.com", "example.org", "example.net", ]); const server = createHttpServer({hosts: HOSTS}); +const FETCH_ORIGIN = "http://example.com/dummy"; + server.registerPathHandler("/redirect", (request, response) => { let params = new URLSearchParams(request.queryString); response.setStatusLine(request.httpVersion, 302, "Moved Temporarily"); response.setHeader("Location", params.get("redirect_uri")); response.setHeader("Access-Control-Allow-Origin", "*"); }); server.registerPathHandler("/dummy", (request, response) => { response.setStatusLine(request.httpVersion, 200, "OK"); response.setHeader("Access-Control-Allow-Origin", "*"); response.write("ok"); }); -Cu.importGlobalProperties(["fetch"]); - add_task(async function() { - const {fetch} = Cu.Sandbox("http://example.com/", {wantGlobalProperties: ["fetch"]}); - let extension = ExtensionTestUtils.loadExtension({ background() { let pending = []; browser.webRequest.onBeforeRequest.addListener( data => { let filter = browser.webRequest.filterResponseData(data.requestId); @@ -83,18 +81,17 @@ add_task(async function() { ["http://example.com/dummy", "http://example.com/dummy"], ["http://example.org/dummy", "http://example.org/dummy"], ["http://example.net/dummy", "ok"], ["http://example.com/redirect?redirect_uri=http://example.com/dummy", "http://example.com/dummy"], ["http://example.com/redirect?redirect_uri=http://example.org/dummy", "http://example.org/dummy"], ["http://example.com/redirect?redirect_uri=http://example.net/dummy", "ok"], ["http://example.net/redirect?redirect_uri=http://example.com/dummy", "http://example.com/dummy"], ].map(async ([url, expectedResponse]) => { - let resp = await fetch(url); - let text = await resp.text(); + let text = await ExtensionTestUtils.fetch(FETCH_ORIGIN, url); equal(text, expectedResponse, `Expected response for ${url}`); }); await Promise.all(results); extension.sendMessage("done"); await extension.awaitFinish("stream-filter"); await extension.unload();