Bug 1335272 - prep: factor out registering about: pages into BTU, r=jaws
MozReview-Commit-ID: 2B2j5xcbSWt
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -89,19 +89,16 @@ support-files =
!/toolkit/mozapps/extensions/test/xpinstall/corrupt.xpi
!/toolkit/mozapps/extensions/test/xpinstall/incompatible.xpi
!/toolkit/mozapps/extensions/test/xpinstall/installtrigger.html
!/toolkit/mozapps/extensions/test/xpinstall/redirect.sjs
!/toolkit/mozapps/extensions/test/xpinstall/restartless-unsigned.xpi
!/toolkit/mozapps/extensions/test/xpinstall/restartless.xpi
!/toolkit/mozapps/extensions/test/xpinstall/theme.xpi
!/toolkit/mozapps/extensions/test/xpinstall/slowinstall.sjs
- file_about_child.html
- file_about_parent.html
- file_register_about_page.js
[browser_aboutAccounts.js]
skip-if = os == "linux" # Bug 958026
support-files =
content_aboutAccounts.js
[browser_aboutCertError.js]
[browser_aboutNetError.js]
[browser_aboutSupport_newtab_security_state.js]
@@ -422,16 +419,19 @@ skip-if = true # Bug 1005420 - fails int
skip-if = (os == "win" && !debug)
[browser_web_channel.js]
[browser_windowopen_reflows.js]
[browser_zbug569342.js]
skip-if = e10s || debug # Bug 1094240 - has findbar-related failures
[browser_registerProtocolHandler_notification.js]
[browser_addCertException.js]
[browser_e10s_about_page_triggeringprincipal.js]
+support-files =
+ file_about_child.html
+ file_about_parent.html
[browser_e10s_switchbrowser.js]
[browser_e10s_about_process.js]
[browser_e10s_chrome_process.js]
[browser_e10s_javascript.js]
[browser_blockHPKP.js]
tags = psm
[browser_windowactivation.js]
[browser_contextmenu_childprocess.js]
--- a/browser/base/content/test/general/browser_e10s_about_page_triggeringprincipal.js
+++ b/browser/base/content/test/general/browser_e10s_about_page_triggeringprincipal.js
@@ -1,26 +1,24 @@
"use strict";
-Cu.import("resource://gre/modules/Services.jsm");
+
+const kChildPage = getRootDirectory(gTestPath) + "file_about_child.html";
+const kParentPage = getRootDirectory(gTestPath) + "file_about_parent.html";
-registerCleanupFunction(function() {
- Services.ppmm.broadcastAsyncMessage("AboutPrincipalTest:Unregister");
- BrowserTestUtils.waitForMessage(Services.ppmm, "AboutPrincipalTest:Unregistered").then(
- Services.ppmm.removeDelayedProcessScript(
- "chrome://mochitests/content/browser/browser/base/content/test/general/file_register_about_page.js"
- )
- );
-});
+const kAboutPagesRegistered = Promise.all([
+ BrowserTestUtils.registerAboutPage(
+ registerCleanupFunction, "test-about-principal-child", kChildPage,
+ Ci.nsIAboutModule.URI_MUST_LOAD_IN_CHILD | Ci.nsIAboutModule.ALLOW_SCRIPT),
+ BrowserTestUtils.registerAboutPage(
+ registerCleanupFunction, "test-about-principal-parent", kParentPage,
+ Ci.nsIAboutModule.ALLOW_SCRIPT)
+]);
add_task(function* test_principal_click() {
- Services.ppmm.loadProcessScript(
- "chrome://mochitests/content/browser/browser/base/content/test/general/file_register_about_page.js",
- true
- );
-
+ yield kAboutPagesRegistered;
yield BrowserTestUtils.withNewTab("about:test-about-principal-parent", function*(browser) {
let loadPromise = BrowserTestUtils.browserLoaded(browser, false, "about:test-about-principal-child");
let myLink = browser.contentDocument.getElementById("aboutchildprincipal");
myLink.click();
yield loadPromise;
yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function*() {
let channel = content.document.docShell.currentDocumentChannel;
@@ -39,16 +37,17 @@ add_task(function* test_principal_click(
let loadingPrincipal = channel.loadInfo.loadingPrincipal;
is(loadingPrincipal, null,
"sanity check - load of TYPE_DOCUMENT must have a null loadingPrincipal");
});
});
});
add_task(function* test_principal_ctrl_click() {
+ yield kAboutPagesRegistered;
yield SpecialPowers.pushPrefEnv({
"set": [["security.sandbox.content.level", 1]],
});
yield BrowserTestUtils.withNewTab("about:test-about-principal-parent", function*(browser) {
let loadPromise = BrowserTestUtils.waitForNewTab(gBrowser, "about:test-about-principal-child");
// simulate ctrl+click
BrowserTestUtils.synthesizeMouseAtCenter("#aboutchildprincipal",
@@ -75,16 +74,17 @@ add_task(function* test_principal_ctrl_c
is(loadingPrincipal, null,
"sanity check - load of TYPE_DOCUMENT must have a null loadingPrincipal");
});
yield BrowserTestUtils.removeTab(tab);
});
});
add_task(function* test_principal_right_click_open_link_in_new_tab() {
+ yield kAboutPagesRegistered;
yield SpecialPowers.pushPrefEnv({
"set": [["security.sandbox.content.level", 1]],
});
yield BrowserTestUtils.withNewTab("about:test-about-principal-parent", function*(browser) {
let loadPromise = BrowserTestUtils.waitForNewTab(gBrowser, "about:test-about-principal-child");
// simulate right-click open link in tab
deleted file mode 100644
--- a/browser/base/content/test/general/file_register_about_page.js
+++ /dev/null
@@ -1,81 +0,0 @@
-const { interfaces: Ci, results: Cr, manager: Cm, utils: Cu } = Components;
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-function AboutPage(chromeURL, aboutHost, classID, description, uriFlags) {
- this.chromeURL = chromeURL;
- this.aboutHost = aboutHost;
- this.classID = Components.ID(classID);
- this.description = description;
- this.uriFlags = uriFlags;
-}
-
-AboutPage.prototype = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]),
- getURIFlags(aURI) { // eslint-disable-line no-unused-vars
- return this.uriFlags;
- },
-
- newChannel(aURI, aLoadInfo) {
- let newURI = Services.io.newURI(this.chromeURL);
- let channel = Services.io.newChannelFromURIWithLoadInfo(newURI,
- aLoadInfo);
- channel.originalURI = aURI;
-
- if (this.uriFlags & Ci.nsIAboutModule.URI_SAFE_FOR_UNTRUSTED_CONTENT) {
- channel.owner = null;
- }
- return channel;
- },
-
- createInstance(outer, iid) {
- if (outer !== null) {
- throw Cr.NS_ERROR_NO_AGGREGATION;
- }
- return this.QueryInterface(iid);
- },
-
- register() {
- Cm.QueryInterface(Ci.nsIComponentRegistrar).registerFactory(
- this.classID, this.description,
- "@mozilla.org/network/protocol/about;1?what=" + this.aboutHost, this);
- },
-
- unregister() {
- Cm.QueryInterface(Ci.nsIComponentRegistrar).unregisterFactory(
- this.classID, this);
- }
-};
-
-/* exported AboutPrincipalTest */
-var AboutPrincipalTest = {};
-
-XPCOMUtils.defineLazyGetter(AboutPrincipalTest, "aboutChild", () =>
- new AboutPage("chrome://mochitests/content/browser/browser/base/content/test/general/file_about_child.html",
- "test-about-principal-child",
- "{df6cbd19-c95b-4011-874b-315347c0832c}",
- "About Principal Child Test",
- Ci.nsIAboutModule.URI_MUST_LOAD_IN_CHILD |
- Ci.nsIAboutModule.ALLOW_SCRIPT)
-
-);
-
-XPCOMUtils.defineLazyGetter(AboutPrincipalTest, "aboutParent", () =>
- new AboutPage("chrome://mochitests/content/browser/browser/base/content/test/general/file_about_parent.html",
- "test-about-principal-parent",
- "{15e1a03d-9f94-4352-bfb8-94216140d3ab}",
- "About Principal Parent Test",
- Ci.nsIAboutModule.ALLOW_SCRIPT)
-);
-
-AboutPrincipalTest.aboutParent.register();
-AboutPrincipalTest.aboutChild.register();
-
-function onUnregisterMessage() {
- removeMessageListener("AboutPrincipalTest:Unregister", onUnregisterMessage);
- AboutPrincipalTest.aboutParent.unregister();
- AboutPrincipalTest.aboutChild.unregister();
- sendAsyncMessage("AboutPrincipalTest:Unregistered");
-}
-
-addMessageListener("AboutPrincipalTest:Unregister", onUnregisterMessage);
--- a/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm
+++ b/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm
@@ -37,16 +37,19 @@ XPCOMUtils.defineLazyModuleGetter(this,
// some cases.
Cu.permitCPOWsInScope(this);
var gSendCharCount = 0;
var gSynthesizeKeyCount = 0;
var gSynthesizeCompositionCount = 0;
var gSynthesizeCompositionChangeCount = 0;
+const kAboutPageRegistrationContentScript =
+ "chrome://mochikit/content/tests/BrowserTestUtils/content-about-page-utils.js";
+
this.BrowserTestUtils = {
/**
* Loads a page in a new tab, executes a Task and closes the tab.
*
* @param options
* An object or string.
* If this is a string it is the url to open and will be opened in the
* currently active browser window.
@@ -1263,9 +1266,67 @@ this.BrowserTestUtils = {
return new Promise((resolve) => {
addEventListener("MozAfterPaint", function onPaint() {
removeEventListener("MozAfterPaint", onPaint);
resolve();
})
});
});
},
+
+ _knownAboutPages: new Set(),
+ _loadedAboutContentScript: false,
+ /**
+ * Registers an about: page with particular flags in both the parent
+ * and any content processes. Returns a promise that resolves when
+ * registration is complete.
+ *
+ * @param registerCleanupFunction (Function)
+ * The test framework doesn't keep its cleanup stuff anywhere accessible,
+ * so the first argument is a reference to your cleanup registration
+ * function, allowing us to clean up after you if necessary.
+ * @param aboutModule (String)
+ * The name of the about page.
+ * @param pageURI (String)
+ * The URI the about: page should point to.
+ * @param flags (Number)
+ * The nsIAboutModule flags to use for registration.
+ * @returns Promise that resolves when registration has finished.
+ */
+ registerAboutPage(registerCleanupFunction, aboutModule, pageURI, flags) {
+ // Return a promise that resolves when registration finished.
+ const kRegistrationMsgId = "browser-test-utils:about-registration:registered";
+ let rv = this.waitForMessage(Services.ppmm, kRegistrationMsgId, msg => {
+ return msg.data == aboutModule;
+ });
+ // Load a script that registers our page, then send it a message to execute the registration.
+ if (!this._loadedAboutContentScript) {
+ Services.ppmm.loadProcessScript(kAboutPageRegistrationContentScript, true);
+ this._loadedAboutContentScript = true;
+ registerCleanupFunction(this._removeAboutPageRegistrations.bind(this));
+ }
+ Services.ppmm.broadcastAsyncMessage("browser-test-utils:about-registration:register",
+ {aboutModule, pageURI, flags});
+ return rv.then(() => {
+ this._knownAboutPages.add(aboutModule);
+ });
+ },
+
+ unregisterAboutPage(aboutModule) {
+ if (!this._knownAboutPages.has(aboutModule)) {
+ return Promise.reject(new Error("We don't think this about page exists!"));
+ }
+ const kUnregistrationMsgId = "browser-test-utils:about-registration:unregistered";
+ let rv = this.waitForMessage(Services.ppmm, kUnregistrationMsgId, msg => {
+ return msg.data == aboutModule;
+ });
+ Services.ppmm.broadcastAsyncMessage("browser-test-utils:about-registration:unregister",
+ aboutModule);
+ return rv.then(() => this._knownAboutPages.delete(aboutModule));
+ },
+
+ *_removeAboutPageRegistrations() {
+ for (let aboutModule of this._knownAboutPages) {
+ yield this.unregisterAboutPage(aboutModule);
+ }
+ Services.ppmm.removeDelayedProcessScript(kAboutPageRegistrationContentScript);
+ },
};
new file mode 100644
--- /dev/null
+++ b/testing/mochitest/BrowserTestUtils/content/content-about-page-utils.js
@@ -0,0 +1,76 @@
+"use strict";
+
+var {classes: Cc, interfaces: Ci, utils: Cu, manager: Cm} = Components;
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+const { generateUUID } = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
+
+function AboutPage(aboutHost, chromeURL, uriFlags) {
+ this.chromeURL = chromeURL;
+ this.aboutHost = aboutHost;
+ this.classID = Components.ID(generateUUID().number);
+ this.description = "BrowserTestUtils: " + aboutHost;
+ this.uriFlags = uriFlags;
+}
+
+AboutPage.prototype = {
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]),
+ getURIFlags(aURI) { // eslint-disable-line no-unused-vars
+ return this.uriFlags;
+ },
+
+ newChannel(aURI, aLoadInfo) {
+ let newURI = Services.io.newURI(this.chromeURL);
+ let channel = Services.io.newChannelFromURIWithLoadInfo(newURI,
+ aLoadInfo);
+ channel.originalURI = aURI;
+
+ if (this.uriFlags & Ci.nsIAboutModule.URI_SAFE_FOR_UNTRUSTED_CONTENT) {
+ channel.owner = null;
+ }
+ return channel;
+ },
+
+ createInstance(outer, iid) {
+ if (outer !== null) {
+ throw Cr.NS_ERROR_NO_AGGREGATION;
+ }
+ return this.QueryInterface(iid);
+ },
+
+ register() {
+ Cm.QueryInterface(Ci.nsIComponentRegistrar).registerFactory(
+ this.classID, this.description,
+ "@mozilla.org/network/protocol/about;1?what=" + this.aboutHost, this);
+ },
+
+ unregister() {
+ Cm.QueryInterface(Ci.nsIComponentRegistrar).unregisterFactory(
+ this.classID, this);
+ }
+};
+
+const gRegisteredPages = new Map();
+
+addMessageListener("browser-test-utils:about-registration:register", msg => {
+ let {aboutModule, pageURI, flags} = msg.data;
+ if (gRegisteredPages.has(aboutModule)) {
+ gRegisteredPages.get(aboutModule).unregister();
+ }
+ let moduleObj = new AboutPage(aboutModule, pageURI, flags);
+ moduleObj.register();
+ gRegisteredPages.set(aboutModule, moduleObj);
+ sendAsyncMessage("browser-test-utils:about-registration:registered", aboutModule);
+});
+
+addMessageListener("browser-test-utils:about-registration:unregister", msg => {
+ let aboutModule = msg.data;
+ let moduleObj = gRegisteredPages.get(aboutModule);
+ if (moduleObj) {
+ moduleObj.unregister();
+ gRegisteredPages.delete(aboutModule);
+ }
+ sendAsyncMessage("browser-test-utils:about-registration:unregistered", aboutModule);
+});
--- a/testing/mochitest/jar.mn
+++ b/testing/mochitest/jar.mn
@@ -37,10 +37,11 @@ mochikit.jar:
content/tests/SimpleTest/TestRunner.js (tests/SimpleTest/TestRunner.js)
content/tests/SimpleTest/iframe-between-tests.html (tests/SimpleTest/iframe-between-tests.html)
content/tests/SimpleTest/WindowSnapshot.js (tests/SimpleTest/WindowSnapshot.js)
content/tests/SimpleTest/MockObjects.js (tests/SimpleTest/MockObjects.js)
content/tests/SimpleTest/NativeKeyCodes.js (tests/SimpleTest/NativeKeyCodes.js)
content/tests/SimpleTest/paint_listener.js (tests/SimpleTest/paint_listener.js)
content/tests/SimpleTest/docshell_helpers.js (../../docshell/test/chrome/docshell_helpers.js)
content/tests/BrowserTestUtils/content-task.js (BrowserTestUtils/content/content-task.js)
+ content/tests/BrowserTestUtils/content-about-page-utils.js (BrowserTestUtils/content/content-about-page-utils.js)
content/tests/BrowserTestUtils/content-utils.js (BrowserTestUtils/content/content-utils.js)
--- a/testing/mochitest/tests/browser/browser.ini
+++ b/testing/mochitest/tests/browser/browser.ini
@@ -1,16 +1,18 @@
[DEFAULT]
support-files =
head.js
[browser_browserLoaded_content_loaded.js]
[browser_add_task.js]
[browser_async.js]
[browser_BrowserTestUtils.js]
+support-files =
+ dummy.html
[browser_head.js]
[browser_pass.js]
[browser_parameters.js]
[browser_popupNode.js]
[browser_popupNode_check.js]
[browser_privileges.js]
[browser_sanityException.js]
[browser_sanityException2.js]
--- a/testing/mochitest/tests/browser/browser_BrowserTestUtils.js
+++ b/testing/mochitest/tests/browser/browser_BrowserTestUtils.js
@@ -42,8 +42,29 @@ add_task(function* () {
cancelled = yield BrowserTestUtils.synthesizeMouseAtCenter("body > div", { type: "mouseup" }, browser);
details = yield getLastEventDetails(browser);
is(details, "div,40,84", "synthesizeMouseAtCenter mouseup with complex selector");
ok(!cancelled, "synthesizeMouseAtCenter mouseup with complex selector cancelled");
gBrowser.removeTab(tab);
});
+
+add_task(function* () {
+ yield BrowserTestUtils.registerAboutPage(
+ registerCleanupFunction, "about-pages-are-cool",
+ getRootDirectory(gTestPath) + "dummy.html", 0);
+ let tab = yield BrowserTestUtils.openNewForegroundTab(
+ gBrowser, "about:about-pages-are-cool", true);
+ ok(tab, "Successfully created an about: page and loaded it.");
+ yield BrowserTestUtils.removeTab(tab);
+ try {
+ yield BrowserTestUtils.unregisterAboutPage("about-pages-are-cool");
+ ok(true, "Successfully unregistered the about page.");
+ } catch (ex) {
+ ok(false, "Should not throw unregistering a known about: page");
+ }
+ yield BrowserTestUtils.unregisterAboutPage("random-other-about-page").then(() => {
+ ok(false, "Should not have succeeded unregistering an unknown about: page.");
+ }, () => {
+ ok(true, "Should have returned a rejected promise trying to unregister an unknown about page");
+ });
+});
new file mode 100644
--- /dev/null
+++ b/testing/mochitest/tests/browser/dummy.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+ <title>This is a dummy page</title>
+ <meta charset="utf-8">
+ <body>This is a dummy page</body>
+</html>