michael@0: /* Any copyright is dedicated to the Public Domain. michael@0: * http://creativecommons.org/publicdomain/zero/1.0/ michael@0: */ michael@0: michael@0: // Tests the dialog open by the Options button for addons that provide a michael@0: // custom chrome-like protocol for optionsURL. michael@0: michael@0: let CustomChromeProtocol = { michael@0: scheme: "khrome", michael@0: defaultPort: -1, michael@0: protocolFlags: Ci.nsIProtocolHandler.URI_DANGEROUS_TO_LOAD | michael@0: Ci.nsIProtocolHandler.URI_IS_LOCAL_RESOURCE | michael@0: Ci.nsIProtocolHandler.URI_NORELATIVE | michael@0: Ci.nsIProtocolHandler.URI_NOAUTH, michael@0: michael@0: newURI: function CCP_newURI(aSpec, aOriginCharset, aBaseUri) { michael@0: let uri = Cc["@mozilla.org/network/simple-uri;1"]. michael@0: createInstance(Ci.nsIURI); michael@0: uri.spec = aSpec; michael@0: return uri; michael@0: }, michael@0: michael@0: newChannel: function CCP_newChannel(aURI) { michael@0: let url = "chrome:" + aURI.path; michael@0: let ch = NetUtil.newChannel(url); michael@0: ch.originalURI = aURI; michael@0: return ch; michael@0: }, michael@0: michael@0: allowPort: function CCP_allowPort(aPort, aScheme) { michael@0: return false; michael@0: }, michael@0: michael@0: QueryInterface: XPCOMUtils.generateQI([ michael@0: Ci.nsIProtocolHandler michael@0: ]), michael@0: michael@0: classID: Components.ID("{399cb2d1-05dd-4363-896f-63b78e008cf8}"), michael@0: michael@0: factory: { michael@0: registrar: Components.manager.QueryInterface(Ci.nsIComponentRegistrar), michael@0: michael@0: register: function CCP_register() { michael@0: this.registrar.registerFactory( michael@0: CustomChromeProtocol.classID, michael@0: "CustomChromeProtocol", michael@0: "@mozilla.org/network/protocol;1?name=khrome", michael@0: this michael@0: ); michael@0: }, michael@0: michael@0: unregister: function CCP_register() { michael@0: this.registrar.unregisterFactory(CustomChromeProtocol.classID, this); michael@0: }, michael@0: michael@0: // nsIFactory michael@0: createInstance: function BNPH_createInstance(aOuter, aIID) { michael@0: if (aOuter) { michael@0: throw Components.Exception("Class does not allow aggregation", michael@0: Components.results.NS_ERROR_NO_AGGREGATION); michael@0: } michael@0: return CustomChromeProtocol.QueryInterface(aIID); michael@0: }, michael@0: michael@0: lockFactory: function BNPH_lockFactory(aLock) { michael@0: throw Components.Exception("Function lockFactory is not implemented", michael@0: Components.results.NS_ERROR_NOT_IMPLEMENTED); michael@0: }, michael@0: michael@0: QueryInterface: XPCOMUtils.generateQI([ michael@0: Ci.nsIFactory michael@0: ]) michael@0: } michael@0: } michael@0: michael@0: function test() { michael@0: waitForExplicitFinish(); michael@0: requestLongerTimeout(2); michael@0: michael@0: info("Registering custom chrome-like protocol."); michael@0: CustomChromeProtocol.factory.register(); michael@0: registerCleanupFunction(function () CustomChromeProtocol.factory.unregister()); michael@0: michael@0: const ADDONS_LIST = [ michael@0: { id: "test1@tests.mozilla.org", michael@0: name: "Test add-on 1", michael@0: optionsURL: CHROMEROOT + "addon_prefs.xul" }, michael@0: { id: "test2@tests.mozilla.org", michael@0: name: "Test add-on 2", michael@0: optionsURL: (CHROMEROOT + "addon_prefs.xul").replace("chrome:", "khrome:") }, michael@0: ]; michael@0: michael@0: var gProvider = new MockProvider(); michael@0: gProvider.createAddons(ADDONS_LIST); michael@0: michael@0: open_manager("addons://list/extension", function(aManager) { michael@0: let addonList = aManager.document.getElementById("addon-list"); michael@0: let currentAddon; michael@0: let instantApply = Services.prefs.getBoolPref("browser.preferences.instantApply"); michael@0: michael@0: function getAddonByName(aName) { michael@0: for (let addonItem of addonList.childNodes) { michael@0: if (addonItem.hasAttribute("name") && michael@0: addonItem.getAttribute("name") == aName) michael@0: return addonItem; michael@0: } michael@0: return null; michael@0: } michael@0: michael@0: function observer(aSubject, aTopic, aData) { michael@0: switch (aTopic) { michael@0: case "domwindowclosed": michael@0: // Give the preference window a chance to finish closing before michael@0: // closing the add-ons manager. michael@0: waitForFocus(function () { michael@0: test_next_addon(); michael@0: }); michael@0: break; michael@0: case "domwindowopened": michael@0: let win = aSubject.QueryInterface(Ci.nsIDOMEventTarget); michael@0: waitForFocus(function () { michael@0: // If the openDialog privileges are wrong a new browser window michael@0: // will open, let the test proceed (and fail) rather than timeout. michael@0: if (win.location != currentAddon.optionsURL && michael@0: win.location != "chrome://browser/content/browser.xul") michael@0: return; michael@0: michael@0: is(win.location, currentAddon.optionsURL, michael@0: "The correct addon pref window should have opened"); michael@0: michael@0: let chromeFlags = win.QueryInterface(Ci.nsIInterfaceRequestor). michael@0: getInterface(Ci.nsIWebNavigation). michael@0: QueryInterface(Ci.nsIDocShellTreeItem).treeOwner. michael@0: QueryInterface(Ci.nsIInterfaceRequestor). michael@0: getInterface(Ci.nsIXULWindow).chromeFlags; michael@0: ok(chromeFlags & Ci.nsIWebBrowserChrome.CHROME_OPENAS_CHROME && michael@0: (instantApply || chromeFlags & Ci.nsIWebBrowserChrome.CHROME_OPENAS_DIALOG), michael@0: "Window was open as a chrome dialog."); michael@0: michael@0: win.close(); michael@0: }, win); michael@0: break; michael@0: } michael@0: } michael@0: michael@0: function test_next_addon() { michael@0: currentAddon = ADDONS_LIST.shift(); michael@0: if (!currentAddon) { michael@0: Services.ww.unregisterNotification(observer); michael@0: close_manager(aManager, finish); michael@0: return; michael@0: } michael@0: michael@0: info("Testing " + currentAddon.name); michael@0: let addonItem = getAddonByName(currentAddon.name, addonList); michael@0: let optionsBtn = michael@0: aManager.document.getAnonymousElementByAttribute(addonItem, "anonid", michael@0: "preferences-btn"); michael@0: is(optionsBtn.hidden, false, "Prefs button should be visible.") michael@0: michael@0: addonList.ensureElementIsVisible(addonItem); michael@0: EventUtils.synthesizeMouseAtCenter(optionsBtn, { }, aManager); michael@0: } michael@0: michael@0: Services.ww.registerNotification(observer); michael@0: test_next_addon(); michael@0: }); michael@0: michael@0: }