diff options
Diffstat (limited to 'toolkit/components/addoncompat/tests/addon/bootstrap.js')
-rw-r--r-- | toolkit/components/addoncompat/tests/addon/bootstrap.js | 653 |
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) -{ -} - |