summaryrefslogtreecommitdiffstats
path: root/toolkit/components/addoncompat/tests/addon/bootstrap.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/addoncompat/tests/addon/bootstrap.js')
-rw-r--r--toolkit/components/addoncompat/tests/addon/bootstrap.js653
1 files changed, 0 insertions, 653 deletions
diff --git a/toolkit/components/addoncompat/tests/addon/bootstrap.js b/toolkit/components/addoncompat/tests/addon/bootstrap.js
deleted file mode 100644
index 5e69fee22..000000000
--- a/toolkit/components/addoncompat/tests/addon/bootstrap.js
+++ /dev/null
@@ -1,653 +0,0 @@
-var Cc = Components.classes;
-var Ci = Components.interfaces;
-var Cu = Components.utils;
-var Cr = Components.results;
-
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/BrowserUtils.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-const baseURL = "http://mochi.test:8888/browser/" +
- "toolkit/components/addoncompat/tests/browser/";
-
-var contentSecManager = Cc["@mozilla.org/contentsecuritymanager;1"]
- .getService(Ci.nsIContentSecurityManager);
-
-function forEachWindow(f)
-{
- let wins = Services.wm.getEnumerator("navigator:browser");
- while (wins.hasMoreElements()) {
- let win = wins.getNext();
- f(win);
- }
-}
-
-function addLoadListener(target, listener)
-{
- target.addEventListener("load", function handler(event) {
- target.removeEventListener("load", handler, true);
- return listener(event);
- }, true);
-}
-
-var gWin;
-var gBrowser;
-var ok, is, info;
-
-function removeTab(tab, done)
-{
- // Remove the tab in a different turn of the event loop. This way
- // the nested event loop in removeTab doesn't conflict with the
- // event listener shims.
- gWin.setTimeout(() => {
- gBrowser.removeTab(tab);
- done();
- }, 0);
-}
-
-// Make sure that the shims for window.content, browser.contentWindow,
-// and browser.contentDocument are working.
-function testContentWindow()
-{
- return new Promise(function(resolve, reject) {
- const url = baseURL + "browser_addonShims_testpage.html";
- let tab = gBrowser.addTab(url);
- gBrowser.selectedTab = tab;
- let browser = tab.linkedBrowser;
- addLoadListener(browser, function handler() {
- ok(gWin.content, "content is defined on chrome window");
- ok(browser.contentWindow, "contentWindow is defined");
- ok(browser.contentDocument, "contentWindow is defined");
- is(gWin.content, browser.contentWindow, "content === contentWindow");
- ok(browser.webNavigation.sessionHistory, "sessionHistory is defined");
-
- ok(browser.contentDocument.getElementById("link"), "link present in document");
-
- // FIXME: Waiting on bug 1073631.
- // is(browser.contentWindow.wrappedJSObject.global, 3, "global available on document");
-
- removeTab(tab, resolve);
- });
- });
-}
-
-// Test for bug 1060046 and bug 1072607. We want to make sure that
-// adding and removing listeners works as expected.
-function testListeners()
-{
- return new Promise(function(resolve, reject) {
- const url1 = baseURL + "browser_addonShims_testpage.html";
- const url2 = baseURL + "browser_addonShims_testpage2.html";
-
- let tab = gBrowser.addTab(url2);
- let browser = tab.linkedBrowser;
- addLoadListener(browser, function handler() {
- function dummyHandler() {}
-
- // Test that a removed listener stays removed (bug
- // 1072607). We're looking to make sure that adding and removing
- // a listener here doesn't cause later listeners to fire more
- // than once.
- for (let i = 0; i < 5; i++) {
- gBrowser.addEventListener("load", dummyHandler, true);
- gBrowser.removeEventListener("load", dummyHandler, true);
- }
-
- // We also want to make sure that this listener doesn't fire
- // after it's removed.
- let loadWithRemoveCount = 0;
- addLoadListener(browser, function handler1(event) {
- loadWithRemoveCount++;
- is(event.target.documentURI, url1, "only fire for first url");
- });
-
- // Load url1 and then url2. We want to check that:
- // 1. handler1 only fires for url1.
- // 2. handler2 only fires once for url1 (so the second time it
- // fires should be for url2).
- let loadCount = 0;
- browser.addEventListener("load", function handler2(event) {
- loadCount++;
- if (loadCount == 1) {
- is(event.target.documentURI, url1, "first load is for first page loaded");
- browser.loadURI(url2);
- } else {
- gBrowser.removeEventListener("load", handler2, true);
-
- is(event.target.documentURI, url2, "second load is for second page loaded");
- is(loadWithRemoveCount, 1, "load handler is only called once");
-
- removeTab(tab, resolve);
- }
- }, true);
-
- browser.loadURI(url1);
- });
- });
-}
-
-// Test for bug 1059207. We want to make sure that adding a capturing
-// listener and a non-capturing listener to the same element works as
-// expected.
-function testCapturing()
-{
- return new Promise(function(resolve, reject) {
- let capturingCount = 0;
- let nonCapturingCount = 0;
-
- function capturingHandler(event) {
- is(capturingCount, 0, "capturing handler called once");
- is(nonCapturingCount, 0, "capturing handler called before bubbling handler");
- capturingCount++;
- }
-
- function nonCapturingHandler(event) {
- is(capturingCount, 1, "bubbling handler called after capturing handler");
- is(nonCapturingCount, 0, "bubbling handler called once");
- nonCapturingCount++;
- }
-
- gBrowser.addEventListener("mousedown", capturingHandler, true);
- gBrowser.addEventListener("mousedown", nonCapturingHandler, false);
-
- const url = baseURL + "browser_addonShims_testpage.html";
- let tab = gBrowser.addTab(url);
- let browser = tab.linkedBrowser;
- addLoadListener(browser, function handler() {
- let win = browser.contentWindow;
- let event = win.document.createEvent("MouseEvents");
- event.initMouseEvent("mousedown", true, false, win, 1,
- 1, 0, 0, 0, // screenX, screenY, clientX, clientY
- false, false, false, false, // ctrlKey, altKey, shiftKey, metaKey
- 0, null); // buttonCode, relatedTarget
-
- let element = win.document.getElementById("output");
- element.dispatchEvent(event);
-
- is(capturingCount, 1, "capturing handler fired");
- is(nonCapturingCount, 1, "bubbling handler fired");
-
- gBrowser.removeEventListener("mousedown", capturingHandler, true);
- gBrowser.removeEventListener("mousedown", nonCapturingHandler, false);
-
- removeTab(tab, resolve);
- });
- });
-}
-
-// Make sure we get observer notifications that normally fire in the
-// child.
-function testObserver()
-{
- return new Promise(function(resolve, reject) {
- let observerFired = 0;
-
- function observer(subject, topic, data) {
- Services.obs.removeObserver(observer, "document-element-inserted");
- observerFired++;
- }
- Services.obs.addObserver(observer, "document-element-inserted", false);
-
- let count = 0;
- const url = baseURL + "browser_addonShims_testpage.html";
- let tab = gBrowser.addTab(url);
- let browser = tab.linkedBrowser;
- browser.addEventListener("load", function handler() {
- count++;
- if (count == 1) {
- browser.reload();
- } else {
- browser.removeEventListener("load", handler);
-
- is(observerFired, 1, "got observer notification");
-
- removeTab(tab, resolve);
- }
- }, true);
- });
-}
-
-// Test for bug 1072472. Make sure that creating a sandbox to run code
-// in the content window works. This is essentially a test for
-// Greasemonkey.
-function testSandbox()
-{
- return new Promise(function(resolve, reject) {
- const url = baseURL + "browser_addonShims_testpage.html";
- let tab = gBrowser.addTab(url);
- let browser = tab.linkedBrowser;
- browser.addEventListener("load", function handler() {
- browser.removeEventListener("load", handler);
-
- let sandbox = Cu.Sandbox(browser.contentWindow,
- {sandboxPrototype: browser.contentWindow,
- wantXrays: false});
- Cu.evalInSandbox("const unsafeWindow = window;", sandbox);
- Cu.evalInSandbox("document.getElementById('output').innerHTML = 'hello';", sandbox);
-
- is(browser.contentDocument.getElementById("output").innerHTML, "hello",
- "sandbox code ran successfully");
-
- // Now try a sandbox with expanded principals.
- sandbox = Cu.Sandbox([browser.contentWindow],
- {sandboxPrototype: browser.contentWindow,
- wantXrays: false});
- Cu.evalInSandbox("const unsafeWindow = window;", sandbox);
- Cu.evalInSandbox("document.getElementById('output').innerHTML = 'hello2';", sandbox);
-
- is(browser.contentDocument.getElementById("output").innerHTML, "hello2",
- "EP sandbox code ran successfully");
-
- removeTab(tab, resolve);
- }, true);
- });
-}
-
-// Test for bug 1095305. We just want to make sure that loading some
-// unprivileged content from an add-on package doesn't crash.
-function testAddonContent()
-{
- let chromeRegistry = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
- .getService(Components.interfaces.nsIChromeRegistry);
- let base = chromeRegistry.convertChromeURL(BrowserUtils.makeURI("chrome://addonshim1/content/"));
-
- let res = Services.io.getProtocolHandler("resource")
- .QueryInterface(Ci.nsIResProtocolHandler);
- res.setSubstitution("addonshim1", base);
-
- return new Promise(function(resolve, reject) {
- const url = "resource://addonshim1/page.html";
- let tab = gBrowser.addTab(url);
- let browser = tab.linkedBrowser;
- addLoadListener(browser, function handler() {
- res.setSubstitution("addonshim1", null);
- removeTab(tab, resolve);
- });
- });
-}
-
-
-// Test for bug 1102410. We check that multiple nsIAboutModule's can be
-// registered in the parent, and that the child can browse to each of
-// the registered about: pages.
-function testAboutModuleRegistration()
-{
- let Registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
-
- let modulesToUnregister = new Map();
-
- function TestChannel(uri, aLoadInfo, aboutName) {
- this.aboutName = aboutName;
- this.loadInfo = aLoadInfo;
- this.URI = this.originalURI = uri;
- }
-
- TestChannel.prototype = {
- asyncOpen: function(listener, context) {
- let stream = this.open();
- let runnable = {
- run: () => {
- try {
- listener.onStartRequest(this, context);
- } catch (e) {}
- try {
- listener.onDataAvailable(this, context, stream, 0, stream.available());
- } catch (e) {}
- try {
- listener.onStopRequest(this, context, Cr.NS_OK);
- } catch (e) {}
- }
- };
- Services.tm.currentThread.dispatch(runnable, Ci.nsIEventTarget.DISPATCH_NORMAL);
- },
-
- asyncOpen2: function(listener) {
- // throws an error if security checks fail
- var outListener = contentSecManager.performSecurityCheck(this, listener);
- return this.asyncOpen(outListener, null);
- },
-
- open: function() {
- function getWindow(channel) {
- try
- {
- if (channel.notificationCallbacks)
- return channel.notificationCallbacks.getInterface(Ci.nsILoadContext).associatedWindow;
- } catch (e) {}
-
- try
- {
- if (channel.loadGroup && channel.loadGroup.notificationCallbacks)
- return channel.loadGroup.notificationCallbacks.getInterface(Ci.nsILoadContext).associatedWindow;
- } catch (e) {}
-
- return null;
- }
-
- let data = `<html><h1>${this.aboutName}</h1></html>`;
- let wnd = getWindow(this);
- if (!wnd)
- throw Cr.NS_ERROR_UNEXPECTED;
-
- let stream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream);
- stream.setData(data, data.length);
- return stream;
- },
-
- open2: function() {
- // throws an error if security checks fail
- contentSecManager.performSecurityCheck(this, null);
- return this.open();
- },
-
- isPending: function() {
- return false;
- },
- cancel: function() {
- throw Cr.NS_ERROR_NOT_IMPLEMENTED;
- },
- suspend: function() {
- throw Cr.NS_ERROR_NOT_IMPLEMENTED;
- },
- resume: function() {
- throw Cr.NS_ERROR_NOT_IMPLEMENTED;
- },
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIChannel, Ci.nsIRequest])
- };
-
- /**
- * This function creates a new nsIAboutModule and registers it. Callers
- * should also call unregisterModules after using this function to clean
- * up the nsIAboutModules at the end of this test.
- *
- * @param aboutName
- * This will be the string after about: used to refer to this module.
- * For example, if aboutName is foo, you can refer to this module by
- * browsing to about:foo.
- *
- * @param uuid
- * A unique identifer string for this module. For example,
- * "5f3a921b-250f-4ac5-a61c-8f79372e6063"
- */
- let createAndRegisterAboutModule = function(aboutName, uuid) {
-
- let AboutModule = function() {};
-
- AboutModule.prototype = {
- classID: Components.ID(uuid),
- classDescription: `Testing About Module for about:${aboutName}`,
- contractID: `@mozilla.org/network/protocol/about;1?what=${aboutName}`,
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]),
-
- newChannel: (aURI, aLoadInfo) => {
- return new TestChannel(aURI, aLoadInfo, aboutName);
- },
-
- getURIFlags: (aURI) => {
- return Ci.nsIAboutModule.URI_SAFE_FOR_UNTRUSTED_CONTENT |
- Ci.nsIAboutModule.ALLOW_SCRIPT;
- },
- };
-
- let factory = {
- createInstance: function(outer, iid) {
- if (outer) {
- throw Cr.NS_ERROR_NO_AGGREGATION;
- }
- return new AboutModule();
- },
- };
-
- Registrar.registerFactory(AboutModule.prototype.classID,
- AboutModule.prototype.classDescription,
- AboutModule.prototype.contractID,
- factory);
-
- modulesToUnregister.set(AboutModule.prototype.classID,
- factory);
- };
-
- /**
- * Unregisters any nsIAboutModules registered with
- * createAndRegisterAboutModule.
- */
- let unregisterModules = () => {
- for (let [classID, factory] of modulesToUnregister) {
- Registrar.unregisterFactory(classID, factory);
- }
- };
-
- /**
- * Takes a browser, and sends it a framescript to attempt to
- * load some about: pages. The frame script will send a test:result
- * message on completion, passing back a data object with:
- *
- * {
- * pass: true
- * }
- *
- * on success, and:
- *
- * {
- * pass: false,
- * errorMsg: message,
- * }
- *
- * on failure.
- *
- * @param browser
- * The browser to send the framescript to.
- */
- let testAboutModulesWork = (browser) => {
- let testConnection = () => {
- let request = new content.XMLHttpRequest();
- try {
- request.open("GET", "about:test1", false);
- request.send(null);
- if (request.status != 200) {
- throw (`about:test1 response had status ${request.status} - expected 200`);
- }
- if (request.responseText.indexOf("test1") == -1) {
- throw (`about:test1 response had result ${request.responseText}`);
- }
-
- request = new content.XMLHttpRequest();
- request.open("GET", "about:test2", false);
- request.send(null);
-
- if (request.status != 200) {
- throw (`about:test2 response had status ${request.status} - expected 200`);
- }
- if (request.responseText.indexOf("test2") == -1) {
- throw (`about:test2 response had result ${request.responseText}`);
- }
-
- sendAsyncMessage("test:result", {
- pass: true,
- });
- } catch (e) {
- sendAsyncMessage("test:result", {
- pass: false,
- errorMsg: e.toString(),
- });
- }
- };
-
- return new Promise((resolve, reject) => {
- let mm = browser.messageManager;
- mm.addMessageListener("test:result", function onTestResult(message) {
- mm.removeMessageListener("test:result", onTestResult);
- if (message.data.pass) {
- ok(true, "Connections to about: pages were successful");
- } else {
- ok(false, message.data.errorMsg);
- }
- resolve();
- });
- mm.loadFrameScript("data:,(" + testConnection.toString() + ")();", false);
- });
- }
-
- // Here's where the actual test is performed.
- return new Promise((resolve, reject) => {
- createAndRegisterAboutModule("test1", "5f3a921b-250f-4ac5-a61c-8f79372e6063");
- createAndRegisterAboutModule("test2", "d7ec0389-1d49-40fa-b55c-a1fc3a6dbf6f");
-
- // This needs to be a chrome-privileged page that loads in the
- // content process. It needs chrome privs because otherwise the
- // XHRs for about:test[12] will fail with a privilege error
- // despite the presence of URI_SAFE_FOR_UNTRUSTED_CONTENT.
- let newTab = gBrowser.addTab("chrome://addonshim1/content/page.html");
- gBrowser.selectedTab = newTab;
- let browser = newTab.linkedBrowser;
-
- addLoadListener(browser, function() {
- testAboutModulesWork(browser).then(() => {
- unregisterModules();
- removeTab(newTab, resolve);
- });
- });
- });
-}
-
-function testProgressListener()
-{
- const url = baseURL + "browser_addonShims_testpage.html";
-
- let sawGlobalLocChange = false;
- let sawTabsLocChange = false;
-
- let globalListener = {
- onLocationChange: function(webProgress, request, uri) {
- if (uri.spec == url) {
- sawGlobalLocChange = true;
- ok(request instanceof Ci.nsIHttpChannel, "Global listener channel is an HTTP channel");
- }
- },
- };
-
- let tabsListener = {
- onLocationChange: function(browser, webProgress, request, uri) {
- if (uri.spec == url) {
- sawTabsLocChange = true;
- ok(request instanceof Ci.nsIHttpChannel, "Tab listener channel is an HTTP channel");
- }
- },
- };
-
- gBrowser.addProgressListener(globalListener);
- gBrowser.addTabsProgressListener(tabsListener);
- info("Added progress listeners");
-
- return new Promise(function(resolve, reject) {
- let tab = gBrowser.addTab(url);
- gBrowser.selectedTab = tab;
- addLoadListener(tab.linkedBrowser, function handler() {
- ok(sawGlobalLocChange, "Saw global onLocationChange");
- ok(sawTabsLocChange, "Saw tabs onLocationChange");
-
- gBrowser.removeProgressListener(globalListener);
- gBrowser.removeTabsProgressListener(tabsListener);
- removeTab(tab, resolve);
- });
- });
-}
-
-function testRootTreeItem()
-{
- return new Promise(function(resolve, reject) {
- const url = baseURL + "browser_addonShims_testpage.html";
- let tab = gBrowser.addTab(url);
- gBrowser.selectedTab = tab;
- let browser = tab.linkedBrowser;
- addLoadListener(browser, function handler() {
- let win = browser.contentWindow;
-
- // Add-ons love this crap.
- let root = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIWebNavigation)
- .QueryInterface(Components.interfaces.nsIDocShellTreeItem)
- .rootTreeItem
- .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIDOMWindow);
- is(root, gWin, "got correct chrome window");
-
- removeTab(tab, resolve);
- });
- });
-}
-
-function testImportNode()
-{
- return new Promise(function(resolve, reject) {
- const url = baseURL + "browser_addonShims_testpage.html";
- let tab = gBrowser.addTab(url);
- gBrowser.selectedTab = tab;
- let browser = tab.linkedBrowser;
- addLoadListener(browser, function handler() {
- let node = gWin.document.createElement("div");
- let doc = browser.contentDocument;
- let result;
- try {
- result = doc.importNode(node, false);
- } catch (e) {
- ok(false, "importing threw an exception");
- }
- if (browser.isRemoteBrowser) {
- is(result, node, "got expected import result");
- }
-
- removeTab(tab, resolve);
- });
- });
-}
-
-function runTests(win, funcs)
-{
- ok = funcs.ok;
- is = funcs.is;
- info = funcs.info;
-
- gWin = win;
- gBrowser = win.gBrowser;
-
- return testContentWindow().
- then(testListeners).
- then(testCapturing).
- then(testObserver).
- then(testSandbox).
- then(testAddonContent).
- then(testAboutModuleRegistration).
- then(testProgressListener).
- then(testRootTreeItem).
- then(testImportNode).
- then(Promise.resolve());
-}
-
-/*
- bootstrap.js API
-*/
-
-function startup(aData, aReason)
-{
- forEachWindow(win => {
- win.runAddonShimTests = (funcs) => runTests(win, funcs);
- });
-}
-
-function shutdown(aData, aReason)
-{
- forEachWindow(win => {
- delete win.runAddonShimTests;
- });
-}
-
-function install(aData, aReason)
-{
-}
-
-function uninstall(aData, aReason)
-{
-}
-