Loading browser/base/content/browser.js +3 −49 Original line number Diff line number Diff line Loading @@ -2878,24 +2878,6 @@ var BrowserOnClick = { } }, handleEvent(event) { if (!event.isTrusted || // Don't trust synthetic events event.button == 2) { return; } let originalTarget = event.originalTarget; let ownerDoc = originalTarget.ownerDocument; if (!ownerDoc) { return; } if (gMultiProcessBrowser && ownerDoc.documentURI.toLowerCase() == "about:newtab") { this.onE10sAboutNewTab(event, ownerDoc); } }, receiveMessage(msg) { switch (msg.name) { case "Browser:CertExceptionError": Loading Loading @@ -3082,28 +3064,6 @@ var BrowserOnClick = { } }, /** * This functions prevents navigation from happening directly through the <a> * link in about:newtab (which is loaded in the parent and therefore would load * the next page also in the parent) and instructs the browser to open the url * in the current tab which will make it update the remoteness of the tab. */ onE10sAboutNewTab(event, ownerDoc) { let isTopFrame = (ownerDoc.defaultView.parent === ownerDoc.defaultView); if (!isTopFrame) { return; } let anchorTarget = event.originalTarget.parentNode; if (anchorTarget instanceof HTMLAnchorElement && anchorTarget.classList.contains("newtab-link")) { event.preventDefault(); let where = whereToOpenLink(event, false, false); openLinkIn(anchorTarget.href, where, { charset: ownerDoc.characterSet, referrerURI: ownerDoc.documentURIObject }); } }, ignoreWarningButton(reason) { // Allow users to override and continue through to the site, // but add a notify bar as a reminder, so that they don't lose Loading Loading @@ -4924,13 +4884,9 @@ var TabsProgressListener = { } } // Attach a listener to watch for "click" events bubbling up from error // pages and other similar pages (like about:newtab). This lets us fix bugs // like 401575 which require error page UI to do privileged things, without // letting error pages have any privilege themselves. // We can't look for this during onLocationChange since at that point the // document URI is not yet the about:-uri of the error page. // We used to listen for clicks in the browser here, but when that // became unnecessary, removing the code below caused focus issues. // This code should be removed. Tracked in bug 1337794. let isRemoteBrowser = aBrowser.isRemoteBrowser; // We check isRemoteBrowser here to avoid requesting the doc CPOW let doc = isRemoteBrowser ? null : aWebProgress.DOMWindow.document; Loading @@ -4945,11 +4901,9 @@ var TabsProgressListener = { // STATE_STOP may be received twice for documents, thus store an // attribute to ensure handling it just once. doc.documentElement.setAttribute("hasBrowserHandlers", "true"); aBrowser.addEventListener("click", BrowserOnClick, true); aBrowser.addEventListener("pagehide", function onPageHide(event) { if (event.target.defaultView.frameElement) return; aBrowser.removeEventListener("click", BrowserOnClick, true); aBrowser.removeEventListener("pagehide", onPageHide, true); if (event.target.documentElement) event.target.documentElement.removeAttribute("hasBrowserHandlers"); Loading browser/base/content/test/general/browser.ini +5 −2 Original line number Diff line number Diff line Loading @@ -81,6 +81,8 @@ support-files = browser_webext_update2.xpi browser_webext_update_icon1.xpi browser_webext_update_icon2.xpi browser_webext_update_perms1.xpi browser_webext_update_perms2.xpi browser_webext_update.json !/image/test/mochitest/blue.png !/toolkit/content/tests/browser/common/mockTransfer.js Loading Loading @@ -252,7 +254,8 @@ skip-if = os == "mac" # decoder doctor isn't implemented on osx skip-if = true # browser_drag.js is disabled, as it needs to be updated for the new behavior from bug 320638. [browser_extension_permissions.js] [browser_extension_sideloading.js] [browser_extension_update.js] [browser_extension_update_background.js] [browser_extension_update_interactive.js] [browser_favicon_change.js] [browser_favicon_change_not_in_document.js] [browser_findbarClose.js] Loading Loading @@ -349,7 +352,7 @@ skip-if = os == 'linux' # Bug 1304272 [browser_tab_detach_restore.js] [browser_tab_drag_drop_perwindow.js] [browser_tab_dragdrop.js] skip-if = buildapp == 'mulet' || (e10s && (debug || asan)) # Bug 1312436 skip-if = buildapp == 'mulet' || (e10s && (debug || os == 'linux')) # Bug 1312436 [browser_tab_dragdrop2.js] [browser_tabbar_big_widgets.js] skip-if = os == "linux" || os == "mac" # No tabs in titlebar on linux Loading browser/base/content/test/general/browser_extension_sideloading.js +26 −38 Original line number Diff line number Diff line Loading @@ -71,25 +71,6 @@ class MockProvider { } } function promiseViewLoaded(tab, viewid) { let win = tab.linkedBrowser.contentWindow; if (win.gViewController && !win.gViewController.isLoading && win.gViewController.currentViewId == viewid) { return Promise.resolve(); } return new Promise(resolve => { function listener() { if (win.gViewController.currentViewId != viewid) { return; } win.document.removeEventListener("ViewChanged", listener); resolve(); } win.document.addEventListener("ViewChanged", listener); }); } function promisePopupNotificationShown(name) { return new Promise(resolve => { function popupshown() { Loading Loading @@ -169,6 +150,17 @@ add_task(function* () { ExtensionsUI.emit("change"); }); // Navigate away from the starting page to force about:addons to load // in a new tab during the tests below. gBrowser.selectedBrowser.loadURI("about:robots"); yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); registerCleanupFunction(function*() { // Return to about:blank when we're done gBrowser.selectedBrowser.loadURI("about:blank"); yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); }); let changePromise = new Promise(resolve => { ExtensionsUI.on("change", function listener() { ExtensionsUI.off("change", listener); Loading @@ -189,22 +181,20 @@ add_task(function* () { is(addons.children.length, 2, "Have 2 menu entries for sideloaded extensions"); // Click the first sideloaded extension let tabPromise = BrowserTestUtils.waitForNewTab(gBrowser, "about:addons"); let popupPromise = promisePopupNotificationShown("addon-webext-permissions"); addons.children[0].click(); // about:addons should load and go to the list of extensions let tab = yield tabPromise; is(tab.linkedBrowser.currentURI.spec, "about:addons", "Newly opened tab is at about:addons"); // When we get the permissions prompt, we should be at the extensions // list in about:addons let panel = yield popupPromise; is(gBrowser.currentURI.spec, "about:addons", "Foreground tab is at about:addons"); const VIEW = "addons://list/extension"; yield promiseViewLoaded(tab, VIEW); let win = tab.linkedBrowser.contentWindow; let win = gBrowser.selectedBrowser.contentWindow; ok(!win.gViewController.isLoading, "about:addons view is fully loaded"); is(win.gViewController.currentViewId, VIEW, "about:addons is at extensions list"); // Wait for the permission prompt and cancel it let panel = yield popupPromise; // Check the contents of the notification, then choose "Cancel" let icon = panel.getAttribute("icon"); is(icon, ICON_URL, "Permissions notification has the addon icon"); Loading @@ -219,7 +209,7 @@ add_task(function* () { is(addon1.userDisabled, true, "Addon 1 should still be disabled"); is(addon2.userDisabled, true, "Addon 2 should still be disabled"); yield BrowserTestUtils.removeTab(tab); yield BrowserTestUtils.removeTab(gBrowser.selectedTab); // Should still have 1 entry in the hamburger menu yield PanelUI.show(); Loading @@ -227,23 +217,21 @@ add_task(function* () { addons = document.getElementById("PanelUI-footer-addons"); is(addons.children.length, 1, "Have 1 menu entry for sideloaded extensions"); // Click the second sideloaded extension tabPromise = BrowserTestUtils.waitForNewTab(gBrowser, "about:addons"); // Click the second sideloaded extension and wait for the notification popupPromise = promisePopupNotificationShown("addon-webext-permissions"); addons.children[0].click(); tab = yield tabPromise; is(tab.linkedBrowser.currentURI.spec, "about:addons", "Newly opened tab is at about:addons"); panel = yield popupPromise; isnot(menuButton.getAttribute("badge-status"), "addon-alert", "Should no longer have addon alert badge"); yield promiseViewLoaded(tab, VIEW); win = tab.linkedBrowser.contentWindow; // Again we should be at the extentions list in about:addons is(gBrowser.currentURI.spec, "about:addons", "Foreground tab is at about:addons"); win = gBrowser.selectedBrowser.contentWindow; ok(!win.gViewController.isLoading, "about:addons view is fully loaded"); is(win.gViewController.currentViewId, VIEW, "about:addons is at extensions list"); // Wait for the permission prompt and accept it this time panel = yield popupPromise; // Check the notification contents, this time accept the install icon = panel.getAttribute("icon"); is(icon, DEFAULT_ICON_URL, "Permissions notification has the default icon"); disablePromise = promiseSetDisabled(mock2); Loading @@ -256,5 +244,5 @@ add_task(function* () { is(addon1.userDisabled, true, "Addon 1 should still be disabled"); is(addon2.userDisabled, false, "Addon 2 should now be enabled"); yield BrowserTestUtils.removeTab(tab); yield BrowserTestUtils.removeTab(gBrowser.selectedTab); }); browser/base/content/test/general/browser_extension_update.js→browser/base/content/test/general/browser_extension_update_background.js +40 −98 Original line number Diff line number Diff line Loading @@ -74,8 +74,8 @@ function promiseInstallEvent(addon, event) { } // Set some prefs that apply to all the tests in this file add_task(function setup() { return SpecialPowers.pushPrefEnv({set: [ add_task(function* setup() { yield SpecialPowers.pushPrefEnv({set: [ // We don't have pre-pinned certificates for the local mochitest server ["extensions.install.requireBuiltInCerts", false], ["extensions.update.requireBuiltInCerts", false], Loading @@ -83,6 +83,17 @@ add_task(function setup() { // XXX remove this when prompts are enabled by default ["extensions.webextPermissionPrompts", true], ]}); // Navigate away from the initial page so that about:addons always // opens in a new tab during tests gBrowser.selectedBrowser.loadURI("about:robots"); yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); registerCleanupFunction(function*() { // Return to about:blank when we're done gBrowser.selectedBrowser.loadURI("about:blank"); yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); }); }); // Helper function to test background updates. Loading Loading @@ -123,7 +134,7 @@ function* backgroundUpdateTest(url, id, checkIconFn) { // about:addons should load and go to the list of extensions let tab = yield tabPromise; is(tab.linkedBrowser.currentURI.spec, "about:addons"); is(tab.linkedBrowser.currentURI.spec, "about:addons", "Browser is at about:addons"); const VIEW = "addons://list/extension"; yield promiseViewLoaded(tab, VIEW); Loading Loading @@ -211,114 +222,45 @@ function checkNonDefaultIcon(icon) { add_task(() => backgroundUpdateTest(`${URL_BASE}/browser_webext_update_icon1.xpi`, ID_ICON, checkNonDefaultIcon)); // Helper function to test a specific scenario for interactive updates. // `checkFn` is a callable that triggers a check for updates. // `autoUpdate` specifies whether the test should be run with // updates applied automatically or not. function* interactiveUpdateTest(autoUpdate, checkFn) { // Test that an update that adds new non-promptable permissions is just // applied without showing a notification dialog. add_task(function*() { yield SpecialPowers.pushPrefEnv({set: [ ["extensions.update.autoUpdateDefault", autoUpdate], // Turn on background updates ["extensions.update.enabled", true], // Point updates to the local mochitest server ["extensions.update.url", `${URL_BASE}/browser_webext_update.json`], ["extensions.update.background.url", `${URL_BASE}/browser_webext_update.json`], ]}); // Trigger an update check, manually applying the update if we're testing // without auto-update. function* triggerUpdate(win, addon) { let manualUpdatePromise; if (!autoUpdate) { manualUpdatePromise = new Promise(resolve => { let listener = { onNewInstall() { AddonManager.removeInstallListener(listener); resolve(); }, }; AddonManager.addInstallListener(listener); }); } checkFn(win, addon); if (manualUpdatePromise) { yield manualUpdatePromise; let item = win.document.getElementById("addon-list") .children.find(_item => _item.value == ID); EventUtils.synthesizeMouseAtCenter(item._updateBtn, {}, win); } } // Install version 1.0 of the test extension let addon = yield promiseInstallAddon(`${URL_BASE}/browser_webext_update1.xpi`); ok(addon, "Addon was installed"); is(addon.version, "1.0", "Version 1 of the addon is installed"); // Open add-ons manager and navigate to extensions list let loadPromise = new Promise(resolve => { let listener = (subject, topic) => { if (subject.location.href == "about:addons") { Services.obs.removeObserver(listener, topic); resolve(subject); } }; Services.obs.addObserver(listener, "EM-loaded", false); }); let tab = gBrowser.addTab("about:addons"); gBrowser.selectedTab = tab; let win = yield loadPromise; let addon = yield promiseInstallAddon(`${URL_BASE}/browser_webext_update_perms1.xpi`); const VIEW = "addons://list/extension"; let viewPromise = promiseViewLoaded(tab, VIEW); win.loadView(VIEW); yield viewPromise; ok(addon, "Addon was installed"); // Trigger an update check let popupPromise = promisePopupNotificationShown("addon-webext-permissions"); yield triggerUpdate(win, addon); let panel = yield popupPromise; let sawPopup = false; PopupNotifications.panel.addEventListener("popupshown", () => sawPopup = true, {once: true}); // Click the cancel button, wait to see the cancel event let cancelPromise = promiseInstallEvent(addon, "onInstallCancelled"); panel.secondaryButton.click(); yield cancelPromise; // Trigger an update check and wait for the update to be applied. let updatePromise = promiseInstallEvent(addon, "onInstallEnded"); AddonManagerPrivate.backgroundUpdateCheck(); yield updatePromise; addon = yield AddonManager.getAddonByID(ID); is(addon.version, "1.0", "Should still be running the old version"); // There should be no notifications about the update is(getBadgeStatus(), "", "Should not have addon alert badge"); // Trigger a new update check popupPromise = promisePopupNotificationShown("addon-webext-permissions"); yield triggerUpdate(win, addon); yield PanelUI.show(); let addons = document.getElementById("PanelUI-footer-addons"); is(addons.children.length, 0, "Have 0 updates in the PanelUI menu"); yield PanelUI.hide(); // This time, accept the upgrade let updatePromise = promiseInstallEvent(addon, "onInstallEnded"); panel = yield popupPromise; panel.button.click(); ok(!sawPopup, "Should not have seen permissions notification"); addon = yield updatePromise; is(addon.version, "2.0", "Should have upgraded"); addon = yield AddonManager.getAddonByID("update_perms@tests.mozilla.org"); is(addon.version, "2.0", "Update should have applied"); yield BrowserTestUtils.removeTab(tab); addon.uninstall(); yield SpecialPowers.popPrefEnv(); } // Invoke the "Check for Updates" menu item function checkAll(win) { win.gViewController.doCommand("cmd_findAllUpdates"); } // Test "Check for Updates" with both auto-update settings add_task(() => interactiveUpdateTest(true, checkAll)); add_task(() => interactiveUpdateTest(false, checkAll)); // Invoke an invidual extension's "Find Updates" menu item function checkOne(win, addon) { win.gViewController.doCommand("cmd_findItemUpdates", addon); } // Test "Find Updates" with both auto-update settings add_task(() => interactiveUpdateTest(true, checkOne)); add_task(() => interactiveUpdateTest(false, checkOne)); }); browser/base/content/test/general/browser_extension_update_interactive.js 0 → 100644 +192 −0 Original line number Diff line number Diff line const {AddonManagerPrivate} = Cu.import("resource://gre/modules/AddonManager.jsm", {}); const URL_BASE = "https://example.com/browser/browser/base/content/test/general"; const ID = "update@tests.mozilla.org"; function promiseInstallAddon(url) { return AddonManager.getInstallForURL(url, null, "application/x-xpinstall") .then(install => { ok(install, "Created install"); return new Promise(resolve => { install.addListener({ onInstallEnded(_install, addon) { resolve(addon); }, }); install.install(); }); }); } function promiseViewLoaded(tab, viewid) { let win = tab.linkedBrowser.contentWindow; if (win.gViewController && !win.gViewController.isLoading && win.gViewController.currentViewId == viewid) { return Promise.resolve(); } return new Promise(resolve => { function listener() { if (win.gViewController.currentViewId != viewid) { return; } win.document.removeEventListener("ViewChanged", listener); resolve(); } win.document.addEventListener("ViewChanged", listener); }); } function promisePopupNotificationShown(name) { return new Promise(resolve => { function popupshown() { let notification = PopupNotifications.getNotification(name); if (!notification) { return; } ok(notification, `${name} notification shown`); ok(PopupNotifications.isPanelOpen, "notification panel open"); PopupNotifications.panel.removeEventListener("popupshown", popupshown); resolve(PopupNotifications.panel.firstChild); } PopupNotifications.panel.addEventListener("popupshown", popupshown); }); } function promiseInstallEvent(addon, event) { return new Promise(resolve => { let listener = {}; listener[event] = (install, ...args) => { if (install.addon.id == addon.id) { AddonManager.removeInstallListener(listener); resolve(...args); } }; AddonManager.addInstallListener(listener); }); } // Set some prefs that apply to all the tests in this file add_task(function* setup() { yield SpecialPowers.pushPrefEnv({set: [ // We don't have pre-pinned certificates for the local mochitest server ["extensions.install.requireBuiltInCerts", false], ["extensions.update.requireBuiltInCerts", false], // XXX remove this when prompts are enabled by default ["extensions.webextPermissionPrompts", true], ]}); }); // Helper function to test a specific scenario for interactive updates. // `checkFn` is a callable that triggers a check for updates. // `autoUpdate` specifies whether the test should be run with // updates applied automatically or not. function* interactiveUpdateTest(autoUpdate, checkFn) { yield SpecialPowers.pushPrefEnv({set: [ ["extensions.update.autoUpdateDefault", autoUpdate], // Point updates to the local mochitest server ["extensions.update.url", `${URL_BASE}/browser_webext_update.json`], ]}); // Trigger an update check, manually applying the update if we're testing // without auto-update. function* triggerUpdate(win, addon) { let manualUpdatePromise; if (!autoUpdate) { manualUpdatePromise = new Promise(resolve => { let listener = { onNewInstall() { AddonManager.removeInstallListener(listener); resolve(); }, }; AddonManager.addInstallListener(listener); }); } checkFn(win, addon); if (manualUpdatePromise) { yield manualUpdatePromise; let item = win.document.getElementById("addon-list") .children.find(_item => _item.value == ID); EventUtils.synthesizeMouseAtCenter(item._updateBtn, {}, win); } } // Install version 1.0 of the test extension let addon = yield promiseInstallAddon(`${URL_BASE}/browser_webext_update1.xpi`); ok(addon, "Addon was installed"); is(addon.version, "1.0", "Version 1 of the addon is installed"); // Open add-ons manager and navigate to extensions list let loadPromise = new Promise(resolve => { let listener = (subject, topic) => { if (subject.location.href == "about:addons") { Services.obs.removeObserver(listener, topic); resolve(subject); } }; Services.obs.addObserver(listener, "EM-loaded", false); }); let tab = gBrowser.addTab("about:addons"); gBrowser.selectedTab = tab; let win = yield loadPromise; const VIEW = "addons://list/extension"; let viewPromise = promiseViewLoaded(tab, VIEW); win.loadView(VIEW); yield viewPromise; // Trigger an update check let popupPromise = promisePopupNotificationShown("addon-webext-permissions"); yield triggerUpdate(win, addon); let panel = yield popupPromise; // Click the cancel button, wait to see the cancel event let cancelPromise = promiseInstallEvent(addon, "onInstallCancelled"); panel.secondaryButton.click(); yield cancelPromise; addon = yield AddonManager.getAddonByID(ID); is(addon.version, "1.0", "Should still be running the old version"); // Trigger a new update check popupPromise = promisePopupNotificationShown("addon-webext-permissions"); yield triggerUpdate(win, addon); // This time, accept the upgrade let updatePromise = promiseInstallEvent(addon, "onInstallEnded"); panel = yield popupPromise; panel.button.click(); addon = yield updatePromise; is(addon.version, "2.0", "Should have upgraded"); yield BrowserTestUtils.removeTab(tab); addon.uninstall(); yield SpecialPowers.popPrefEnv(); } // Invoke the "Check for Updates" menu item function checkAll(win) { win.gViewController.doCommand("cmd_findAllUpdates"); } // Test "Check for Updates" with both auto-update settings add_task(() => interactiveUpdateTest(true, checkAll)); add_task(() => interactiveUpdateTest(false, checkAll)); // Invoke an invidual extension's "Find Updates" menu item function checkOne(win, addon) { win.gViewController.doCommand("cmd_findItemUpdates", addon); } // Test "Find Updates" with both auto-update settings add_task(() => interactiveUpdateTest(true, checkOne)); add_task(() => interactiveUpdateTest(false, checkOne)); Loading
browser/base/content/browser.js +3 −49 Original line number Diff line number Diff line Loading @@ -2878,24 +2878,6 @@ var BrowserOnClick = { } }, handleEvent(event) { if (!event.isTrusted || // Don't trust synthetic events event.button == 2) { return; } let originalTarget = event.originalTarget; let ownerDoc = originalTarget.ownerDocument; if (!ownerDoc) { return; } if (gMultiProcessBrowser && ownerDoc.documentURI.toLowerCase() == "about:newtab") { this.onE10sAboutNewTab(event, ownerDoc); } }, receiveMessage(msg) { switch (msg.name) { case "Browser:CertExceptionError": Loading Loading @@ -3082,28 +3064,6 @@ var BrowserOnClick = { } }, /** * This functions prevents navigation from happening directly through the <a> * link in about:newtab (which is loaded in the parent and therefore would load * the next page also in the parent) and instructs the browser to open the url * in the current tab which will make it update the remoteness of the tab. */ onE10sAboutNewTab(event, ownerDoc) { let isTopFrame = (ownerDoc.defaultView.parent === ownerDoc.defaultView); if (!isTopFrame) { return; } let anchorTarget = event.originalTarget.parentNode; if (anchorTarget instanceof HTMLAnchorElement && anchorTarget.classList.contains("newtab-link")) { event.preventDefault(); let where = whereToOpenLink(event, false, false); openLinkIn(anchorTarget.href, where, { charset: ownerDoc.characterSet, referrerURI: ownerDoc.documentURIObject }); } }, ignoreWarningButton(reason) { // Allow users to override and continue through to the site, // but add a notify bar as a reminder, so that they don't lose Loading Loading @@ -4924,13 +4884,9 @@ var TabsProgressListener = { } } // Attach a listener to watch for "click" events bubbling up from error // pages and other similar pages (like about:newtab). This lets us fix bugs // like 401575 which require error page UI to do privileged things, without // letting error pages have any privilege themselves. // We can't look for this during onLocationChange since at that point the // document URI is not yet the about:-uri of the error page. // We used to listen for clicks in the browser here, but when that // became unnecessary, removing the code below caused focus issues. // This code should be removed. Tracked in bug 1337794. let isRemoteBrowser = aBrowser.isRemoteBrowser; // We check isRemoteBrowser here to avoid requesting the doc CPOW let doc = isRemoteBrowser ? null : aWebProgress.DOMWindow.document; Loading @@ -4945,11 +4901,9 @@ var TabsProgressListener = { // STATE_STOP may be received twice for documents, thus store an // attribute to ensure handling it just once. doc.documentElement.setAttribute("hasBrowserHandlers", "true"); aBrowser.addEventListener("click", BrowserOnClick, true); aBrowser.addEventListener("pagehide", function onPageHide(event) { if (event.target.defaultView.frameElement) return; aBrowser.removeEventListener("click", BrowserOnClick, true); aBrowser.removeEventListener("pagehide", onPageHide, true); if (event.target.documentElement) event.target.documentElement.removeAttribute("hasBrowserHandlers"); Loading
browser/base/content/test/general/browser.ini +5 −2 Original line number Diff line number Diff line Loading @@ -81,6 +81,8 @@ support-files = browser_webext_update2.xpi browser_webext_update_icon1.xpi browser_webext_update_icon2.xpi browser_webext_update_perms1.xpi browser_webext_update_perms2.xpi browser_webext_update.json !/image/test/mochitest/blue.png !/toolkit/content/tests/browser/common/mockTransfer.js Loading Loading @@ -252,7 +254,8 @@ skip-if = os == "mac" # decoder doctor isn't implemented on osx skip-if = true # browser_drag.js is disabled, as it needs to be updated for the new behavior from bug 320638. [browser_extension_permissions.js] [browser_extension_sideloading.js] [browser_extension_update.js] [browser_extension_update_background.js] [browser_extension_update_interactive.js] [browser_favicon_change.js] [browser_favicon_change_not_in_document.js] [browser_findbarClose.js] Loading Loading @@ -349,7 +352,7 @@ skip-if = os == 'linux' # Bug 1304272 [browser_tab_detach_restore.js] [browser_tab_drag_drop_perwindow.js] [browser_tab_dragdrop.js] skip-if = buildapp == 'mulet' || (e10s && (debug || asan)) # Bug 1312436 skip-if = buildapp == 'mulet' || (e10s && (debug || os == 'linux')) # Bug 1312436 [browser_tab_dragdrop2.js] [browser_tabbar_big_widgets.js] skip-if = os == "linux" || os == "mac" # No tabs in titlebar on linux Loading
browser/base/content/test/general/browser_extension_sideloading.js +26 −38 Original line number Diff line number Diff line Loading @@ -71,25 +71,6 @@ class MockProvider { } } function promiseViewLoaded(tab, viewid) { let win = tab.linkedBrowser.contentWindow; if (win.gViewController && !win.gViewController.isLoading && win.gViewController.currentViewId == viewid) { return Promise.resolve(); } return new Promise(resolve => { function listener() { if (win.gViewController.currentViewId != viewid) { return; } win.document.removeEventListener("ViewChanged", listener); resolve(); } win.document.addEventListener("ViewChanged", listener); }); } function promisePopupNotificationShown(name) { return new Promise(resolve => { function popupshown() { Loading Loading @@ -169,6 +150,17 @@ add_task(function* () { ExtensionsUI.emit("change"); }); // Navigate away from the starting page to force about:addons to load // in a new tab during the tests below. gBrowser.selectedBrowser.loadURI("about:robots"); yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); registerCleanupFunction(function*() { // Return to about:blank when we're done gBrowser.selectedBrowser.loadURI("about:blank"); yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); }); let changePromise = new Promise(resolve => { ExtensionsUI.on("change", function listener() { ExtensionsUI.off("change", listener); Loading @@ -189,22 +181,20 @@ add_task(function* () { is(addons.children.length, 2, "Have 2 menu entries for sideloaded extensions"); // Click the first sideloaded extension let tabPromise = BrowserTestUtils.waitForNewTab(gBrowser, "about:addons"); let popupPromise = promisePopupNotificationShown("addon-webext-permissions"); addons.children[0].click(); // about:addons should load and go to the list of extensions let tab = yield tabPromise; is(tab.linkedBrowser.currentURI.spec, "about:addons", "Newly opened tab is at about:addons"); // When we get the permissions prompt, we should be at the extensions // list in about:addons let panel = yield popupPromise; is(gBrowser.currentURI.spec, "about:addons", "Foreground tab is at about:addons"); const VIEW = "addons://list/extension"; yield promiseViewLoaded(tab, VIEW); let win = tab.linkedBrowser.contentWindow; let win = gBrowser.selectedBrowser.contentWindow; ok(!win.gViewController.isLoading, "about:addons view is fully loaded"); is(win.gViewController.currentViewId, VIEW, "about:addons is at extensions list"); // Wait for the permission prompt and cancel it let panel = yield popupPromise; // Check the contents of the notification, then choose "Cancel" let icon = panel.getAttribute("icon"); is(icon, ICON_URL, "Permissions notification has the addon icon"); Loading @@ -219,7 +209,7 @@ add_task(function* () { is(addon1.userDisabled, true, "Addon 1 should still be disabled"); is(addon2.userDisabled, true, "Addon 2 should still be disabled"); yield BrowserTestUtils.removeTab(tab); yield BrowserTestUtils.removeTab(gBrowser.selectedTab); // Should still have 1 entry in the hamburger menu yield PanelUI.show(); Loading @@ -227,23 +217,21 @@ add_task(function* () { addons = document.getElementById("PanelUI-footer-addons"); is(addons.children.length, 1, "Have 1 menu entry for sideloaded extensions"); // Click the second sideloaded extension tabPromise = BrowserTestUtils.waitForNewTab(gBrowser, "about:addons"); // Click the second sideloaded extension and wait for the notification popupPromise = promisePopupNotificationShown("addon-webext-permissions"); addons.children[0].click(); tab = yield tabPromise; is(tab.linkedBrowser.currentURI.spec, "about:addons", "Newly opened tab is at about:addons"); panel = yield popupPromise; isnot(menuButton.getAttribute("badge-status"), "addon-alert", "Should no longer have addon alert badge"); yield promiseViewLoaded(tab, VIEW); win = tab.linkedBrowser.contentWindow; // Again we should be at the extentions list in about:addons is(gBrowser.currentURI.spec, "about:addons", "Foreground tab is at about:addons"); win = gBrowser.selectedBrowser.contentWindow; ok(!win.gViewController.isLoading, "about:addons view is fully loaded"); is(win.gViewController.currentViewId, VIEW, "about:addons is at extensions list"); // Wait for the permission prompt and accept it this time panel = yield popupPromise; // Check the notification contents, this time accept the install icon = panel.getAttribute("icon"); is(icon, DEFAULT_ICON_URL, "Permissions notification has the default icon"); disablePromise = promiseSetDisabled(mock2); Loading @@ -256,5 +244,5 @@ add_task(function* () { is(addon1.userDisabled, true, "Addon 1 should still be disabled"); is(addon2.userDisabled, false, "Addon 2 should now be enabled"); yield BrowserTestUtils.removeTab(tab); yield BrowserTestUtils.removeTab(gBrowser.selectedTab); });
browser/base/content/test/general/browser_extension_update.js→browser/base/content/test/general/browser_extension_update_background.js +40 −98 Original line number Diff line number Diff line Loading @@ -74,8 +74,8 @@ function promiseInstallEvent(addon, event) { } // Set some prefs that apply to all the tests in this file add_task(function setup() { return SpecialPowers.pushPrefEnv({set: [ add_task(function* setup() { yield SpecialPowers.pushPrefEnv({set: [ // We don't have pre-pinned certificates for the local mochitest server ["extensions.install.requireBuiltInCerts", false], ["extensions.update.requireBuiltInCerts", false], Loading @@ -83,6 +83,17 @@ add_task(function setup() { // XXX remove this when prompts are enabled by default ["extensions.webextPermissionPrompts", true], ]}); // Navigate away from the initial page so that about:addons always // opens in a new tab during tests gBrowser.selectedBrowser.loadURI("about:robots"); yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); registerCleanupFunction(function*() { // Return to about:blank when we're done gBrowser.selectedBrowser.loadURI("about:blank"); yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); }); }); // Helper function to test background updates. Loading Loading @@ -123,7 +134,7 @@ function* backgroundUpdateTest(url, id, checkIconFn) { // about:addons should load and go to the list of extensions let tab = yield tabPromise; is(tab.linkedBrowser.currentURI.spec, "about:addons"); is(tab.linkedBrowser.currentURI.spec, "about:addons", "Browser is at about:addons"); const VIEW = "addons://list/extension"; yield promiseViewLoaded(tab, VIEW); Loading Loading @@ -211,114 +222,45 @@ function checkNonDefaultIcon(icon) { add_task(() => backgroundUpdateTest(`${URL_BASE}/browser_webext_update_icon1.xpi`, ID_ICON, checkNonDefaultIcon)); // Helper function to test a specific scenario for interactive updates. // `checkFn` is a callable that triggers a check for updates. // `autoUpdate` specifies whether the test should be run with // updates applied automatically or not. function* interactiveUpdateTest(autoUpdate, checkFn) { // Test that an update that adds new non-promptable permissions is just // applied without showing a notification dialog. add_task(function*() { yield SpecialPowers.pushPrefEnv({set: [ ["extensions.update.autoUpdateDefault", autoUpdate], // Turn on background updates ["extensions.update.enabled", true], // Point updates to the local mochitest server ["extensions.update.url", `${URL_BASE}/browser_webext_update.json`], ["extensions.update.background.url", `${URL_BASE}/browser_webext_update.json`], ]}); // Trigger an update check, manually applying the update if we're testing // without auto-update. function* triggerUpdate(win, addon) { let manualUpdatePromise; if (!autoUpdate) { manualUpdatePromise = new Promise(resolve => { let listener = { onNewInstall() { AddonManager.removeInstallListener(listener); resolve(); }, }; AddonManager.addInstallListener(listener); }); } checkFn(win, addon); if (manualUpdatePromise) { yield manualUpdatePromise; let item = win.document.getElementById("addon-list") .children.find(_item => _item.value == ID); EventUtils.synthesizeMouseAtCenter(item._updateBtn, {}, win); } } // Install version 1.0 of the test extension let addon = yield promiseInstallAddon(`${URL_BASE}/browser_webext_update1.xpi`); ok(addon, "Addon was installed"); is(addon.version, "1.0", "Version 1 of the addon is installed"); // Open add-ons manager and navigate to extensions list let loadPromise = new Promise(resolve => { let listener = (subject, topic) => { if (subject.location.href == "about:addons") { Services.obs.removeObserver(listener, topic); resolve(subject); } }; Services.obs.addObserver(listener, "EM-loaded", false); }); let tab = gBrowser.addTab("about:addons"); gBrowser.selectedTab = tab; let win = yield loadPromise; let addon = yield promiseInstallAddon(`${URL_BASE}/browser_webext_update_perms1.xpi`); const VIEW = "addons://list/extension"; let viewPromise = promiseViewLoaded(tab, VIEW); win.loadView(VIEW); yield viewPromise; ok(addon, "Addon was installed"); // Trigger an update check let popupPromise = promisePopupNotificationShown("addon-webext-permissions"); yield triggerUpdate(win, addon); let panel = yield popupPromise; let sawPopup = false; PopupNotifications.panel.addEventListener("popupshown", () => sawPopup = true, {once: true}); // Click the cancel button, wait to see the cancel event let cancelPromise = promiseInstallEvent(addon, "onInstallCancelled"); panel.secondaryButton.click(); yield cancelPromise; // Trigger an update check and wait for the update to be applied. let updatePromise = promiseInstallEvent(addon, "onInstallEnded"); AddonManagerPrivate.backgroundUpdateCheck(); yield updatePromise; addon = yield AddonManager.getAddonByID(ID); is(addon.version, "1.0", "Should still be running the old version"); // There should be no notifications about the update is(getBadgeStatus(), "", "Should not have addon alert badge"); // Trigger a new update check popupPromise = promisePopupNotificationShown("addon-webext-permissions"); yield triggerUpdate(win, addon); yield PanelUI.show(); let addons = document.getElementById("PanelUI-footer-addons"); is(addons.children.length, 0, "Have 0 updates in the PanelUI menu"); yield PanelUI.hide(); // This time, accept the upgrade let updatePromise = promiseInstallEvent(addon, "onInstallEnded"); panel = yield popupPromise; panel.button.click(); ok(!sawPopup, "Should not have seen permissions notification"); addon = yield updatePromise; is(addon.version, "2.0", "Should have upgraded"); addon = yield AddonManager.getAddonByID("update_perms@tests.mozilla.org"); is(addon.version, "2.0", "Update should have applied"); yield BrowserTestUtils.removeTab(tab); addon.uninstall(); yield SpecialPowers.popPrefEnv(); } // Invoke the "Check for Updates" menu item function checkAll(win) { win.gViewController.doCommand("cmd_findAllUpdates"); } // Test "Check for Updates" with both auto-update settings add_task(() => interactiveUpdateTest(true, checkAll)); add_task(() => interactiveUpdateTest(false, checkAll)); // Invoke an invidual extension's "Find Updates" menu item function checkOne(win, addon) { win.gViewController.doCommand("cmd_findItemUpdates", addon); } // Test "Find Updates" with both auto-update settings add_task(() => interactiveUpdateTest(true, checkOne)); add_task(() => interactiveUpdateTest(false, checkOne)); });
browser/base/content/test/general/browser_extension_update_interactive.js 0 → 100644 +192 −0 Original line number Diff line number Diff line const {AddonManagerPrivate} = Cu.import("resource://gre/modules/AddonManager.jsm", {}); const URL_BASE = "https://example.com/browser/browser/base/content/test/general"; const ID = "update@tests.mozilla.org"; function promiseInstallAddon(url) { return AddonManager.getInstallForURL(url, null, "application/x-xpinstall") .then(install => { ok(install, "Created install"); return new Promise(resolve => { install.addListener({ onInstallEnded(_install, addon) { resolve(addon); }, }); install.install(); }); }); } function promiseViewLoaded(tab, viewid) { let win = tab.linkedBrowser.contentWindow; if (win.gViewController && !win.gViewController.isLoading && win.gViewController.currentViewId == viewid) { return Promise.resolve(); } return new Promise(resolve => { function listener() { if (win.gViewController.currentViewId != viewid) { return; } win.document.removeEventListener("ViewChanged", listener); resolve(); } win.document.addEventListener("ViewChanged", listener); }); } function promisePopupNotificationShown(name) { return new Promise(resolve => { function popupshown() { let notification = PopupNotifications.getNotification(name); if (!notification) { return; } ok(notification, `${name} notification shown`); ok(PopupNotifications.isPanelOpen, "notification panel open"); PopupNotifications.panel.removeEventListener("popupshown", popupshown); resolve(PopupNotifications.panel.firstChild); } PopupNotifications.panel.addEventListener("popupshown", popupshown); }); } function promiseInstallEvent(addon, event) { return new Promise(resolve => { let listener = {}; listener[event] = (install, ...args) => { if (install.addon.id == addon.id) { AddonManager.removeInstallListener(listener); resolve(...args); } }; AddonManager.addInstallListener(listener); }); } // Set some prefs that apply to all the tests in this file add_task(function* setup() { yield SpecialPowers.pushPrefEnv({set: [ // We don't have pre-pinned certificates for the local mochitest server ["extensions.install.requireBuiltInCerts", false], ["extensions.update.requireBuiltInCerts", false], // XXX remove this when prompts are enabled by default ["extensions.webextPermissionPrompts", true], ]}); }); // Helper function to test a specific scenario for interactive updates. // `checkFn` is a callable that triggers a check for updates. // `autoUpdate` specifies whether the test should be run with // updates applied automatically or not. function* interactiveUpdateTest(autoUpdate, checkFn) { yield SpecialPowers.pushPrefEnv({set: [ ["extensions.update.autoUpdateDefault", autoUpdate], // Point updates to the local mochitest server ["extensions.update.url", `${URL_BASE}/browser_webext_update.json`], ]}); // Trigger an update check, manually applying the update if we're testing // without auto-update. function* triggerUpdate(win, addon) { let manualUpdatePromise; if (!autoUpdate) { manualUpdatePromise = new Promise(resolve => { let listener = { onNewInstall() { AddonManager.removeInstallListener(listener); resolve(); }, }; AddonManager.addInstallListener(listener); }); } checkFn(win, addon); if (manualUpdatePromise) { yield manualUpdatePromise; let item = win.document.getElementById("addon-list") .children.find(_item => _item.value == ID); EventUtils.synthesizeMouseAtCenter(item._updateBtn, {}, win); } } // Install version 1.0 of the test extension let addon = yield promiseInstallAddon(`${URL_BASE}/browser_webext_update1.xpi`); ok(addon, "Addon was installed"); is(addon.version, "1.0", "Version 1 of the addon is installed"); // Open add-ons manager and navigate to extensions list let loadPromise = new Promise(resolve => { let listener = (subject, topic) => { if (subject.location.href == "about:addons") { Services.obs.removeObserver(listener, topic); resolve(subject); } }; Services.obs.addObserver(listener, "EM-loaded", false); }); let tab = gBrowser.addTab("about:addons"); gBrowser.selectedTab = tab; let win = yield loadPromise; const VIEW = "addons://list/extension"; let viewPromise = promiseViewLoaded(tab, VIEW); win.loadView(VIEW); yield viewPromise; // Trigger an update check let popupPromise = promisePopupNotificationShown("addon-webext-permissions"); yield triggerUpdate(win, addon); let panel = yield popupPromise; // Click the cancel button, wait to see the cancel event let cancelPromise = promiseInstallEvent(addon, "onInstallCancelled"); panel.secondaryButton.click(); yield cancelPromise; addon = yield AddonManager.getAddonByID(ID); is(addon.version, "1.0", "Should still be running the old version"); // Trigger a new update check popupPromise = promisePopupNotificationShown("addon-webext-permissions"); yield triggerUpdate(win, addon); // This time, accept the upgrade let updatePromise = promiseInstallEvent(addon, "onInstallEnded"); panel = yield popupPromise; panel.button.click(); addon = yield updatePromise; is(addon.version, "2.0", "Should have upgraded"); yield BrowserTestUtils.removeTab(tab); addon.uninstall(); yield SpecialPowers.popPrefEnv(); } // Invoke the "Check for Updates" menu item function checkAll(win) { win.gViewController.doCommand("cmd_findAllUpdates"); } // Test "Check for Updates" with both auto-update settings add_task(() => interactiveUpdateTest(true, checkAll)); add_task(() => interactiveUpdateTest(false, checkAll)); // Invoke an invidual extension's "Find Updates" menu item function checkOne(win, addon) { win.gViewController.doCommand("cmd_findItemUpdates", addon); } // Test "Find Updates" with both auto-update settings add_task(() => interactiveUpdateTest(true, checkOne)); add_task(() => interactiveUpdateTest(false, checkOne));