author | Tim Taubert <ttaubert@mozilla.com> |
Wed, 19 Sep 2012 08:51:18 +0200 | |
changeset 114224 | 80499f04e875f18710102fefbfb97dc7bbf4cad0 |
parent 114220 | 16ea931000aea941aed8aa374830ec2f3c24284d (current diff) |
parent 114223 | 7907bdc1be3cfe836b799cbe47ea7d99d0b7f795 (diff) |
child 114339 | 0c8ac138706ebf11ed4dcce231f45a5942efc567 |
child 114350 | 90cc14017766749cf5635c9a2c244d8d75902020 |
push id | 239 |
push user | akeybl@mozilla.com |
push date | Thu, 03 Jan 2013 21:54:43 +0000 |
treeherder | mozilla-release@3a7b66445659 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
milestone | 18.0a1 |
first release with | nightly linux32
80499f04e875
/
18.0a1
/
20120919030602
/
files
nightly linux64
80499f04e875
/
18.0a1
/
20120919030602
/
files
nightly mac
80499f04e875
/
18.0a1
/
20120919030602
/
files
nightly win32
80499f04e875
/
18.0a1
/
20120919030602
/
files
nightly win64
80499f04e875
/
18.0a1
/
20120919030602
/
files
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
releases | nightly linux32
18.0a1
/
20120919030602
/
pushlog to previous
nightly linux64
18.0a1
/
20120919030602
/
pushlog to previous
nightly mac
18.0a1
/
20120919030602
/
pushlog to previous
nightly win32
18.0a1
/
20120919030602
/
pushlog to previous
nightly win64
18.0a1
/
20120919030602
/
pushlog to previous
|
--- a/browser/devtools/webconsole/test/Makefile.in +++ b/browser/devtools/webconsole/test/Makefile.in @@ -100,16 +100,17 @@ MOCHITEST_BROWSER_FILES = \ browser_webconsole_bug_663443_panel_title.js \ browser_webconsole_bug_660806_history_nav.js \ browser_webconsole_bug_651501_document_body_autocomplete.js \ browser_webconsole_bug_653531_highlighter_console_helper.js \ browser_webconsole_bug_659907_console_dir.js \ browser_webconsole_bug_664131_console_group.js \ browser_webconsole_bug_704295.js \ browser_webconsole_bug_658368_time_methods.js \ + browser_webconsole_bug_764572_output_open_url.js \ browser_webconsole_bug_622303_persistent_filters.js \ browser_webconsole_window_zombie.js \ browser_cached_messages.js \ browser_bug664688_sandbox_update_after_navigation.js \ browser_webconsole_menustatus.js \ browser_result_format_as_string.js \ browser_webconsole_bug_737873_mixedcontent.js \ browser_output_breaks_after_console_dir_uninspectable.js \
new file mode 100644 --- /dev/null +++ b/browser/devtools/webconsole/test/browser_webconsole_bug_764572_output_open_url.js @@ -0,0 +1,226 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// This is a test for the Open URL context menu item +// that is shown for network requests +const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-console.html" +const COMMAND_NAME = "consoleCmd_openURL"; +const CONTEXT_MENU_ID = "#menu_openURL"; + +let HUD = null, outputNode = null, contextMenu = null; + +function test() { + addTab(TEST_URI); + browser.addEventListener("load", function onLoad() { + browser.removeEventListener("load", onLoad, true); + openConsole(null, consoleOpened); + }, true); +} + +function consoleOpened(aHud) { + HUD = aHud; + outputNode = aHud.outputNode; + contextMenu = HUD.iframeWindow.document.getElementById("output-contextmenu"); + + executeSoon(testOnNotNetActivity); +} + +function testOnNotNetActivity() { + HUD.jsterm.clearOutput(); + + outputNode = HUD.outputNode; + let console = content.wrappedJSObject.console; + console.log("bug 764572"); + + testOnNotNetActivity_command(); +} +function testOnNotNetActivity_command () { + waitForSuccess({ + name: "show no net activity in console", + validatorFn: function () { + return outputNode.textContent.indexOf("bug 764572") > -1; + }, + successFn: function () { + outputNode.focus(); + outputNode.selectedItem = outputNode.querySelector(".webconsole-msg-log"); + + // check whether the command is disable + goUpdateCommand(COMMAND_NAME); + let controller = top.document.commandDispatcher. + getControllerForCommand(COMMAND_NAME); + + let isDisabled = !controller || !controller.isCommandEnabled("consoleCmd_openURL"); + ok(isDisabled, COMMAND_NAME + " should be disabled."); + executeSoon(testOnNotNetActivity_contextmenu); + }, + failureFn: testOnNotNetActivity_contextmenu, + }); +} +function testOnNotNetActivity_contextmenu() { + let target = outputNode.querySelector(".webconsole-msg-log"); + + outputNode.focus(); + outputNode.selectedItem = target; + + waitForOpenContextMenu(contextMenu, { + target: target, + successFn: function () { + let isHidden = contextMenu.querySelector(CONTEXT_MENU_ID).hidden; + ok(isHidden, CONTEXT_MENU_ID + "should be hidden."); + + closeContextMenu(contextMenu); + executeSoon(testOnNetActivity); + }, + failureFn: function(){ + closeContextMenu(contextMenu); + executeSoon(testOnNetActivity); + }, + }); +} + +function testOnNetActivity() { + HUD.jsterm.clearOutput(); + + // reload the url to show net activity in console. + content.location.reload(); + + testOnNetActivity_command(); +} + +function testOnNetActivity_command() { + waitForSuccess({ + name: "show TEST_URI's net activity in console", + validatorFn: function () { + outputNode.focus(); + outputNode.selectedItem = outputNode.querySelector(".webconsole-msg-network"); + + let item = outputNode.selectedItem; + return item && item.url; + }, + successFn: function () { + outputNode.focus(); + + // set up the event handler for TabOpen + gBrowser.tabContainer.addEventListener("TabOpen", function onOpen(aEvent) { + gBrowser.tabContainer.removeEventListener("TabOpen", onOpen, true); + + let tab = aEvent.target; + onTabOpen(tab); + }, true); + + // check whether the command is enable + goUpdateCommand(COMMAND_NAME); + let controller = top.document.commandDispatcher. + getControllerForCommand(COMMAND_NAME); + ok(controller.isCommandEnabled("consoleCmd_openURL"), COMMAND_NAME + " should be enabled."); + + // try to open url. + goDoCommand(COMMAND_NAME); + }, + failureFn: testOnNetActivity_contextmenu, + }); +} + +// check TabOpen event +function onTabOpen(aTab) { + waitForSuccess({ + name: "complete to initialize the opening tab", + validatorFn: function() + { + // wait to complete initializing the opend tab. + let url = aTab.linkedBrowser.currentURI.spec; + return url === TEST_URI; + }, + successFn: function() + { + gBrowser.removeTab(aTab); + executeSoon(testOnNetActivity_contextmenu); + }, + failureFn: testOnNetActivity_contextmenu, + }); +} + +function testOnNetActivity_contextmenu() { + let target = outputNode.querySelector(".webconsole-msg-network"); + + outputNode.focus(); + outputNode.selectedItem = target; + + waitForOpenContextMenu(contextMenu, { + target: target, + successFn: function () { + let isShown = !contextMenu.querySelector(CONTEXT_MENU_ID).hidden; + ok(isShown, CONTEXT_MENU_ID + "should be shown."); + + closeContextMenu(contextMenu); + executeSoon(finalizeTest); + }, + failureFn: function(){ + closeContextMenu(contextMenu); + executeSoon(finalizeTest); + }, + }); +} + +function finalizeTest() { + HUD = null; + outputNode = null; + contextMenu = null + finishTest(); +} + +/** + * Polls a given function waiting for opening context menu. + * + * @Param {nsIDOMElement} aContextMenu + * @param object aOptions + * Options object with the following properties: + * - successFn + * A function called if opening the given context menu - success to return. + * - failureFn + * A function called if not opening the given context menu - fails to return. + * - target + * The target element for showing a context menu. + * - timeout + * Timeout for popup shown, in milliseconds. Default is 5000. + */ +function waitForOpenContextMenu(aContextMenu, aOptions) { + let start = Date.now(); + let timeout = aOptions.timeout || 5000; + let targetElement = aOptions.target; + + if (!aContextMenu) { + ok(false, "Can't get a context menu."); + aOptions.failureFn(); + return; + } + if (!targetElement) { + ok(false, "Can't get a target element."); + aOptions.failureFn(); + return; + } + + function onPopupShown() { + aContextMenu.removeEventListener("popupshown", onPopupShown); + clearTimeout(onTimeout); + aOptions.successFn(); + } + + + aContextMenu.addEventListener("popupshown", onPopupShown); + + let onTimeout = setTimeout(function(){ + aContextMenu.removeEventListener("popupshown", onPopupShown); + aOptions.failureFn(); + }, timeout); + + // open a context menu. + let eventDetails = { type : "contextmenu", button : 2}; + EventUtils.synthesizeMouse(targetElement, 2, 2, + eventDetails, targetElement.ownerDocument.defaultView); +} + +function closeContextMenu (aContextMenu) { + aContextMenu.hidePopup(); +}
--- a/browser/devtools/webconsole/webconsole.js +++ b/browser/devtools/webconsole/webconsole.js @@ -1301,16 +1301,17 @@ WebConsoleFrame.prototype = { linkNode.appendChild(statusNode); let clipboardText = request.method + " " + request.url; let messageNode = this.createMessageNode(CATEGORY_NETWORK, severity, msgNode, null, null, clipboardText); messageNode._connectionId = entry.connection; + messageNode.url = request.url; this.makeOutputMessageLink(messageNode, function WCF_net_message_link() { if (!messageNode._panelOpen) { this.openNetworkPanel(messageNode, networkInfo.httpActivity); } }.bind(this)); networkInfo.node = messageNode; @@ -2302,16 +2303,30 @@ WebConsoleFrame.prototype = { strings.push("[" + timestampString + "] " + item.clipboardText); } } clipboardHelper.copyString(strings.join("\n"), this.document); }, /** + * Open the selected item's URL in a new tab. + */ + openSelectedItemInTab: function WCF_openSelectedItemInTab() + { + let item = this.outputNode.selectedItem; + + if (!item || !item.url) { + return; + } + + this.owner.openLink(item.url); + }, + + /** * Destroy the HUD object. Call this method to avoid memory leaks when the Web * Console is closed. */ destroy: function WCF_destroy() { if (this.jsterm) { this.jsterm.destroy(); } @@ -3436,41 +3451,57 @@ CommandController.prototype = { /** * Selects all the text in the HUD output. */ selectAll: function CommandController_selectAll() { this.owner.outputNode.selectAll(); }, + /** + * Open the URL of the selected message in a new tab. + */ + openURL: function CommandController_openURL() + { + this.owner.openSelectedItemInTab(); + }, + supportsCommand: function CommandController_supportsCommand(aCommand) { return this.isCommandEnabled(aCommand); }, isCommandEnabled: function CommandController_isCommandEnabled(aCommand) { switch (aCommand) { case "cmd_copy": // Only enable "copy" if nodes are selected. return this.owner.outputNode.selectedCount > 0; + case "consoleCmd_openURL": { + // Only enable "open url" if node is Net Activity. + let selectedItem = this.owner.outputNode.selectedItem; + return selectedItem && selectedItem.url; + } case "cmd_fontSizeEnlarge": case "cmd_fontSizeReduce": case "cmd_fontSizeReset": case "cmd_selectAll": return true; } }, doCommand: function CommandController_doCommand(aCommand) { switch (aCommand) { case "cmd_copy": this.copy(); break; + case "consoleCmd_openURL": + this.openURL(); + break; case "cmd_selectAll": this.selectAll(); break; case "cmd_fontSizeEnlarge": this.owner.changeFontSize("+"); break; case "cmd_fontSizeReduce": this.owner.changeFontSize("-"); @@ -3483,8 +3514,119 @@ CommandController.prototype = { }; function gSequenceId() { return gSequenceId.n++; } gSequenceId.n = 0; + +function goUpdateConsoleCommands() { + goUpdateCommand("consoleCmd_openURL"); +} + + + +/////////////////////////////////////////////////////////////////////////////// +// Context Menu +/////////////////////////////////////////////////////////////////////////////// + +const CONTEXTMENU_ID = "output-contextmenu"; + +/* + * ConsoleContextMenu: This handle to show/hide a context menu item. + */ +let ConsoleContextMenu = { + /* + * Handle to show/hide context menu item. + * + * @param nsIDOMEvent aEvent + */ + build: function CCM_build(aEvent) + { + let popup = aEvent.target; + if (popup.id !== CONTEXTMENU_ID) { + return; + } + + let view = document.querySelector(".hud-output-node"); + let metadata = this.getSelectionMetadata(view); + + for (let i = 0, l = popup.childNodes.length; i < l; ++i) { + let element = popup.childNodes[i]; + element.hidden = this.shouldHideMenuItem(element, metadata); + } + }, + + /* + * Get selection information from the view. + * + * @param nsIDOMElement aView + * This should be <xul:richlistbox>. + * + * @return object + * Selection metadata. + */ + getSelectionMetadata: function CCM_getSelectionMetadata(aView) + { + let metadata = { + selectionType: "", + selection: new Set(), + }; + let selectedItems = aView.selectedItems; + + metadata.selectionType = (selectedItems > 1) ? "multiple" : "single"; + + let selection = metadata.selection; + for (let item of selectedItems) { + switch (item.category) { + case CATEGORY_NETWORK: + selection.add("network"); + break; + case CATEGORY_CSS: + selection.add("css"); + break; + case CATEGORY_JS: + selection.add("js"); + break; + case CATEGORY_WEBDEV: + selection.add("webdev"); + break; + } + } + + return metadata; + }, + + /* + * Determine if an item should be hidden. + * + * @param nsIDOMElement aMenuItem + * @param object aMetadata + * @return boolean + * Whether the given item should be hidden or not. + */ + shouldHideMenuItem: function CCM_shouldHideMenuItem(aMenuItem, aMetadata) + { + let selectionType = aMenuItem.getAttribute("selectiontype"); + if (selectionType && !aMetadata.selectionType == selectionType) { + return true; + } + + let selection = aMenuItem.getAttribute("selection"); + if (!selection) { + return false; + } + + let shouldHide = true; + let itemData = selection.split("|"); + for (let type of aMetadata.selection) { + // check whether this menu item should show or not. + if (itemData.indexOf(type) !== -1) { + shouldHide = false; + break; + } + } + + return shouldHide; + }, +};
--- a/browser/devtools/webconsole/webconsole.xul +++ b/browser/devtools/webconsole/webconsole.xul @@ -16,36 +16,45 @@ title="&window.title;" windowtype="devtools:webconsole" persist="screenX screenY width height sizemode"> <script type="text/javascript" src="chrome://global/content/globalOverlay.js"/> <script type="text/javascript" src="webconsole.js"/> <commandset id="editMenuCommands"/> - <commandset> + <commandset id="consoleCommands" + commandupdater="true" + events="richlistbox-select" + oncommandupdate="goUpdateConsoleCommands();"> + <command id="consoleCmd_openURL" + oncommand="goDoCommand('consoleCmd_openURL');"/> <command id="cmd_fullZoomEnlarge" oncommand="goDoCommand('cmd_fontSizeEnlarge');"/> <command id="cmd_fullZoomReduce" oncommand="goDoCommand('cmd_fontSizeReduce');"/> <command id="cmd_fullZoomReset" oncommand="goDoCommand('cmd_fontSizeReset');"/> </commandset> <keyset id="fontSizeChangeSet"> <key id="key_fullZoomReduce" key="&fullZoomReduceCmd.commandkey;" command="cmd_fullZoomReduce" modifiers="accel"/> <key key="&fullZoomReduceCmd.commandkey2;" command="cmd_fullZoomReduce" modifiers="accel"/> <key id="key_fullZoomEnlarge" key="&fullZoomEnlargeCmd.commandkey;" command="cmd_fullZoomEnlarge" modifiers="accel"/> <key key="&fullZoomEnlargeCmd.commandkey2;" command="cmd_fullZoomEnlarge" modifiers="accel"/> <key key="&fullZoomEnlargeCmd.commandkey3;" command="cmd_fullZoomEnlarge" modifiers="accel"/> <key id="key_fullZoomReset" key="&fullZoomResetCmd.commandkey;" command="cmd_fullZoomReset" modifiers="accel"/> <key key="&fullZoomResetCmd.commandkey2;" command="cmd_fullZoomReset" modifiers="accel"/> </keyset> <keyset id="editMenuKeys"/> <popupset id="mainPopupSet"> - <menupopup id="output-contextmenu"> + <menupopup id="output-contextmenu" + onpopupshowing="ConsoleContextMenu.build(event);"> <menuitem id="saveBodiesContextMenu" type="checkbox" label="&saveBodies.label;" accesskey="&saveBodies.accesskey;"/> + <menuitem id="menu_openURL" label="&openURL.label;" + accesskey="&openURL.accesskey;" command="consoleCmd_openURL" + selection="network" selectionType="single"/> <menuitem id="menu_copy"/> <menuitem id="menu_selectAll"/> </menupopup> </popupset> <vbox class="hud-outer-wrapper" flex="1"> <vbox class="hud-console-wrapper" flex="1"> <toolbar class="hud-console-filter-toolbar devtools-toolbar" mode="full">
--- a/browser/locales/en-US/chrome/browser/devtools/webConsole.dtd +++ b/browser/locales/en-US/chrome/browser/devtools/webConsole.dtd @@ -27,16 +27,21 @@ <!ENTITY networkPanel.responseImage "Received Image"> <!ENTITY networkPanel.responseImageCached "Cached Image"> <!-- LOCALIZATION NOTE (saveBodies.label): You can see this string in the Web - Console context menu. --> <!ENTITY saveBodies.label "Log Request and Response Bodies"> <!ENTITY saveBodies.accesskey "L"> +<!-- LOCALIZATION NOTE (openURL.label): You can see this string in the Web + - Console context menu. --> +<!ENTITY openURL.label "Open URL in New Tab"> +<!ENTITY openURL.accesskey "T"> + <!-- LOCALIZATION NOTE (btnPageNet.label): This string is used for the menu - button that allows users to toggle the network logging output. - This string and the following strings toggle various kinds of output - filters. --> <!ENTITY btnPageNet.label "Net"> <!ENTITY btnPageNet.tooltip "Log network access"> <!ENTITY btnPageCSS.label "CSS"> <!ENTITY btnPageCSS.tooltip "Log CSS parsing errors">
--- a/toolkit/mozapps/extensions/AddonManager.jsm +++ b/toolkit/mozapps/extensions/AddonManager.jsm @@ -1927,87 +1927,139 @@ var AddonManagerInternal = { if (this.typeListeners[pos] == aListener) this.typeListeners.splice(pos, 1); else pos++; } }, get addonTypes() { + if (!gStarted) + throw Components.Exception("AddonManager is not initialized", + Cr.NS_ERROR_NOT_INITIALIZED); + return this.typesProxy; }, get autoUpdateDefault() { + if (!gStarted) + throw Components.Exception("AddonManager is not initialized", + Cr.NS_ERROR_NOT_INITIALIZED); + return gAutoUpdateDefault; }, set autoUpdateDefault(aValue) { + if (!gStarted) + throw Components.Exception("AddonManager is not initialized", + Cr.NS_ERROR_NOT_INITIALIZED); + aValue = !!aValue; if (aValue != gAutoUpdateDefault) Services.prefs.setBoolPref(PREF_EM_AUTOUPDATE_DEFAULT, aValue); return aValue; }, get checkCompatibility() { + if (!gStarted) + throw Components.Exception("AddonManager is not initialized", + Cr.NS_ERROR_NOT_INITIALIZED); + return gCheckCompatibility; }, set checkCompatibility(aValue) { + if (!gStarted) + throw Components.Exception("AddonManager is not initialized", + Cr.NS_ERROR_NOT_INITIALIZED); + aValue = !!aValue; if (aValue != gCheckCompatibility) { if (!aValue) Services.prefs.setBoolPref(PREF_EM_CHECK_COMPATIBILITY, false); else Services.prefs.clearUserPref(PREF_EM_CHECK_COMPATIBILITY); } return aValue; }, get strictCompatibility() { + if (!gStarted) + throw Components.Exception("AddonManager is not initialized", + Cr.NS_ERROR_NOT_INITIALIZED); + return gStrictCompatibility; }, set strictCompatibility(aValue) { + if (!gStarted) + throw Components.Exception("AddonManager is not initialized", + Cr.NS_ERROR_NOT_INITIALIZED); + aValue = !!aValue; if (aValue != gStrictCompatibility) Services.prefs.setBoolPref(PREF_EM_STRICT_COMPATIBILITY, aValue); return aValue; }, get checkUpdateSecurityDefault() { + if (!gStarted) + throw Components.Exception("AddonManager is not initialized", + Cr.NS_ERROR_NOT_INITIALIZED); + return gCheckUpdateSecurityDefault; }, get checkUpdateSecurity() { + if (!gStarted) + throw Components.Exception("AddonManager is not initialized", + Cr.NS_ERROR_NOT_INITIALIZED); + return gCheckUpdateSecurity; }, set checkUpdateSecurity(aValue) { + if (!gStarted) + throw Components.Exception("AddonManager is not initialized", + Cr.NS_ERROR_NOT_INITIALIZED); + aValue = !!aValue; if (aValue != gCheckUpdateSecurity) { if (aValue != gCheckUpdateSecurityDefault) Services.prefs.setBoolPref(PREF_EM_CHECK_UPDATE_SECURITY, aValue); else Services.prefs.clearUserPref(PREF_EM_CHECK_UPDATE_SECURITY); } return aValue; }, get updateEnabled() { + if (!gStarted) + throw Components.Exception("AddonManager is not initialized", + Cr.NS_ERROR_NOT_INITIALIZED); + return gUpdateEnabled; }, set updateEnabled(aValue) { + if (!gStarted) + throw Components.Exception("AddonManager is not initialized", + Cr.NS_ERROR_NOT_INITIALIZED); + aValue = !!aValue; if (aValue != gUpdateEnabled) Services.prefs.setBoolPref(PREF_EM_UPDATE_ENABLED, aValue); return aValue; }, get hotfixID() { + if (!gStarted) + throw Components.Exception("AddonManager is not initialized", + Cr.NS_ERROR_NOT_INITIALIZED); + return gHotfixID; }, }; /** * Should not be used outside of core Mozilla code. This is a private API for * the startup and platform integration code to use. Refer to the methods on * AddonManagerInternal for documentation however note that these methods are @@ -2335,16 +2387,20 @@ var AddonManager = { /** * Determines whether an Addon should auto-update or not. * * @param aAddon * The Addon representing the add-on * @return true if the addon should auto-update, false otherwise. */ shouldAutoUpdate: function AM_shouldAutoUpdate(aAddon) { + if (!gStarted) + throw Components.Exception("AddonManager is not initialized", + Cr.NS_ERROR_NOT_INITIALIZED); + if (!aAddon || typeof aAddon != "object") throw Components.Exception("aAddon must be specified", Cr.NS_ERROR_INVALID_ARG); if (!("applyBackgroundUpdates" in aAddon)) return false; if (aAddon.applyBackgroundUpdates == AddonManager.AUTOUPDATE_ENABLE) return true;
--- a/toolkit/mozapps/extensions/test/xpcshell/test_shutdown.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_shutdown.js @@ -1,60 +1,78 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ // Verify that API functions fail if the Add-ons Manager isn't initialised. -const IGNORE = ["escapeAddonURI", "shouldAutoUpdate", "getStartupChanges", - "addTypeListener", "removeTypeListener", - "addAddonListener", "removeAddonListener", - "addInstallListener", "removeInstallListener", - "addManagerListener", "removeManagerListener"]; +const IGNORE = { + funcs: ["escapeAddonURI", "getStartupChanges", "addTypeListener", + "removeTypeListener", "addAddonListener", "removeAddonListener", + "addInstallListener", "removeInstallListener", "addManagerListener", + "removeManagerListener"], + getters: ["__AddonManagerInternal__"], + setters: [] +}; -const IGNORE_PRIVATE = ["AddonAuthor", "AddonCompatibilityOverride", - "AddonScreenshot", "AddonType", "startup", "shutdown", - "registerProvider", "unregisterProvider", - "addStartupChange", "removeStartupChange"]; +const IGNORE_PRIVATE = { + funcs: ["AddonAuthor", "AddonCompatibilityOverride", "AddonScreenshot", + "AddonType", "startup", "shutdown", "registerProvider", + "unregisterProvider", "addStartupChange", "removeStartupChange"], + getters: [], + setters: [] +}; + -function test_functions() { - for (let prop in AddonManager) { - if (typeof AddonManager[prop] != "function") - continue; - if (IGNORE.indexOf(prop) != -1) - continue; +function test_functions(aObjName, aIgnore) { + let obj = this[aObjName]; + for (let prop in obj) { + let desc = Object.getOwnPropertyDescriptor(obj, prop); + + if (typeof desc.value == "function") { + if (aIgnore.funcs.indexOf(prop) != -1) + continue; - try { - do_print("AddonManager." + prop); - AddonManager[prop](); - do_throw(prop + " did not throw an exception"); - } - catch (e) { - if (e.result != Components.results.NS_ERROR_NOT_INITIALIZED) - do_throw(prop + " threw an unexpected exception: " + e); - } - } - - for (let prop in AddonManagerPrivate) { - if (typeof AddonManagerPrivate[prop] != "function") - continue; - if (IGNORE_PRIVATE.indexOf(prop) != -1) - continue; - - try { - do_print("AddonManagerPrivate." + prop); - AddonManagerPrivate[prop](); - do_throw(prop + " did not throw an exception"); - } - catch (e) { - if (e.result != Components.results.NS_ERROR_NOT_INITIALIZED) - do_throw(prop + " threw an unexpected exception: " + e); + try { + do_print(aObjName + "." + prop + "()"); + obj[prop](); + do_throw(prop + " did not throw an exception"); + } + catch (e) { + if (e.result != Components.results.NS_ERROR_NOT_INITIALIZED) + do_throw(prop + " threw an unexpected exception: " + e); + } + } else { + if (typeof desc.get == "function" && aIgnore.getters.indexOf(prop) == -1) { + do_print(aObjName + "." + prop + " getter"); + try { + let temp = obj[prop]; + do_throw(prop + " did not throw an exception"); + } + catch (e) { + if (e.result != Components.results.NS_ERROR_NOT_INITIALIZED) + do_throw(prop + " threw an unexpected exception: " + e); + } + } + if (typeof desc.set == "function" && aIgnore.setters.indexOf(prop) == -1) { + do_print(aObjName + "." + prop + " setter"); + try { + obj[prop] = "i am the walrus"; + do_throw(prop + " did not throw an exception"); + } + catch (e) { + if (e.result != Components.results.NS_ERROR_NOT_INITIALIZED) + do_throw(prop + " threw an unexpected exception: " + e); + } + } } } } function run_test() { createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2"); - test_functions(); + test_functions("AddonManager", IGNORE); + test_functions("AddonManagerPrivate", IGNORE_PRIVATE); startupManager(); shutdownManager(); - test_functions(); + test_functions("AddonManager", IGNORE); + test_functions("AddonManagerPrivate", IGNORE_PRIVATE); }
--- a/toolkit/mozapps/extensions/test/xpcshell/test_updatecheck.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_updatecheck.js @@ -13,16 +13,17 @@ function run_test() { createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2"); // Create and configure the HTTP server. testserver = new HttpServer(); testserver.registerDirectory("/data/", do_get_file("data")); testserver.start(4444); do_test_pending(); + startupManager(); run_test_1(); } function end_test() { testserver.stop(do_test_finished); } // Test that a basic update check returns the expected available updates