Bug 1551490 - Run browser_CTP_plugins.js on both XUL and HTML about:addons page. r=aswan,rpl
authorLuca Greco <lgreco@mozilla.com>
Fri, 07 Jun 2019 18:40:13 +0000
changeset 478004 7654a4fe63b6f446ed8dca820d26ec96d918a8e2
parent 478003 06890fefc1d34bd383edd8029fb579a17aa44a68
child 478005 49f83d8848ff00d0fa1245f2f2d71654a85e3d70
push id36133
push userrmaries@mozilla.com
push dateMon, 10 Jun 2019 09:38:15 +0000
treeherdermozilla-central@7a44faddc33d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaswan, rpl
bugs1551490
milestone69.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1551490 - Run browser_CTP_plugins.js on both XUL and HTML about:addons page. r=aswan,rpl Depends on D31776 Differential Revision: https://phabricator.services.mozilla.com/D31777
toolkit/mozapps/extensions/test/browser/browser_CTP_plugins.js
--- a/toolkit/mozapps/extensions/test/browser/browser_CTP_plugins.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_CTP_plugins.js
@@ -1,8 +1,14 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+// Test plugin blocking.
+
 const gHttpTestRoot = "http://127.0.0.1:8888/" + RELATIVE_DIR + "/";
 const {AddonTestUtils} = ChromeUtils.import("resource://testing-common/AddonTestUtils.jsm");
 
 function updateBlocklist(aURL, aCallback) {
   var observer = function() {
     Services.obs.removeObserver(observer, "plugin-blocklist-updated");
     SimpleTest.executeSoon(aCallback);
   };
@@ -32,176 +38,300 @@ function updateBlocklist(aURL, aCallback
 var _originalBlocklistURL = null;
 function setAndUpdateBlocklist(aURL, aCallback) {
   if (!_originalBlocklistURL) {
     _originalBlocklistURL = Services.prefs.getCharPref("extensions.blocklist.url");
   }
   updateBlocklist(aURL, aCallback);
 }
 
-function resetBlocklist(aCallback) {
+function resetBlocklist() {
   Services.prefs.setCharPref("extensions.blocklist.url", _originalBlocklistURL);
 }
 
-function getPluginUI(plugin, anonid) {
+function getXULPluginUI(plugin, anonid) {
   if (plugin.openOrClosedShadowRoot &&
       plugin.openOrClosedShadowRoot.isUAWidget()) {
     return plugin.openOrClosedShadowRoot.getElementById(anonid);
   }
   return plugin.ownerDocument.
     getAnonymousElementByAttribute(plugin, "anonid", anonid);
 }
 
-add_task(async function() {
-  SpecialPowers.pushPrefEnv({"set": [
+function assertPluginActiveState({managerWindow, pluginId, expectedActivateState}) {
+  let pluginEl = get_addon_element(managerWindow, pluginId);
+  ok(pluginEl, `Got the about:addon entry for "${pluginId}"`);
+
+  if (managerWindow.useHtmlViews) {
+    const pluginOptions = pluginEl.querySelector("plugin-options");
+    const pluginCheckedItem = pluginOptions.querySelector("panel-item[checked]");
+    is(pluginCheckedItem.getAttribute("action"), expectedActivateState,
+       `plugin should have ${expectedActivateState} state selected`);
+  } else {
+    // Assertions for the XUL about:addons views.
+    pluginEl.parentNode.ensureElementIsVisible(pluginEl);
+    let enableButton = getXULPluginUI(pluginEl, "enable-btn");
+    let disableButton = getXULPluginUI(pluginEl, "disable-btn");
+    is_element_hidden(enableButton, "enable button should be hidden");
+    is_element_hidden(disableButton, "disable button should be hidden");
+    let menu = getXULPluginUI(pluginEl, "state-menulist");
+    is_element_visible(menu, "state menu should be visible");
+    let activateItem = getXULPluginUI(pluginEl, `${expectedActivateState}-menuitem`);
+    ok(activateItem, `Got a menu item for the ${expectedActivateState} plugin activate state`);
+    is(menu.selectedItem, activateItem, `state menu should have '${expectedActivateState}' selected`);
+  }
+}
+
+function setPluginActivateState({managerWindow, pluginId, activateState}) {
+  let pluginEl = get_addon_element(managerWindow, pluginId);
+  ok(pluginEl, `Got the about:addon entry for "${pluginId}"`);
+
+  if (managerWindow.useHtmlViews) {
+    // Activate plugin on the HTML about:addons views.
+    let activateAction = pluginEl.querySelector(`[action="${activateState}"]`);
+    ok(activateAction, `Got element for ${activateState} plugin action`);
+    activateAction.click();
+  } else {
+    // Activate plugin on the XUL about:addons views.
+    let activateItem = getXULPluginUI(pluginEl, `${activateState}-menuitem`);
+    ok(activateItem, `Got a menu item for the ${activateState} plugin activate state`);
+    let menu = getXULPluginUI(pluginEl, "state-menulist");
+    menu.selectedItem = activateItem;
+    activateItem.doCommand();
+  }
+}
+
+async function assertPluginAppDisabled({managerWindow, pluginId}) {
+  const pluginEl = get_addon_element(managerWindow, pluginId);
+  ok(pluginEl, `Got the about:addon entry for "${pluginId}"`);
+
+  if (managerWindow.useHtmlViews) {
+    // Open the options menu (needed to check the disabled buttons).
+    const pluginOptions = pluginEl.querySelector("plugin-options");
+    pluginOptions.querySelector("panel-list").open = true;
+    // tests all buttons disabled (besides the checked one and the expand action)
+    // are expected to be disabled if locked is true.
+    for (const item of pluginOptions.querySelectorAll("panel-item:not([hidden])")) {
+      const actionName = item.getAttribute("action");
+      if (!item.hasAttribute("checked") && actionName !== "expand" &&
+          actionName !== "preferences") {
+        ok(item.shadowRoot.querySelector("button").disabled,
+           `Plugin action "${actionName}" should be disabled`);
+      }
+    }
+    pluginOptions.querySelector("panel-list").open = false;
+  } else {
+    // Assertions for the XUL about:addons views.
+    let menu = getXULPluginUI(pluginEl, "state-menulist");
+    pluginEl.parentNode.ensureElementIsVisible(pluginEl);
+    menu = getXULPluginUI(pluginEl, "state-menulist");
+    is(menu.disabled, true, "state menu should be disabled");
+
+    EventUtils.synthesizeMouseAtCenter(pluginEl, {}, managerWindow);
+    await BrowserTestUtils.waitForEvent(managerWindow.document, "ViewChanged");
+
+    menu = managerWindow.document.getElementById("detail-state-menulist");
+    is(menu.disabled, true, "detail state menu should be disabled");
+  }
+}
+
+async function getTestPluginAddon() {
+  const plugins = await AddonManager.getAddonsByTypes(["plugin"]);
+
+  for (const plugin of plugins) {
+    if (plugin.name == "Test Plug-in") {
+      return plugin;
+    }
+  }
+
+  return undefined;
+}
+
+async function test_CTP_plugins(aboutAddonsType) {
+  await SpecialPowers.pushPrefEnv({"set": [
     ["plugins.click_to_play", true],
-    ["extensions.blocklist.suppressUI", true],
-    ["extensions.blocklist.useXML", true],
   ]});
-  registerCleanupFunction(async function() {
-    let pluginTag = getTestPluginTag();
-    pluginTag.enabledState = Ci.nsIPluginTag.STATE_ENABLED;
-    await new Promise(resolve => {
-      setAndUpdateBlocklist(gHttpTestRoot + "blockNoPlugins.xml", resolve);
-    });
-    resetBlocklist();
-  });
   let pluginTag = getTestPluginTag();
   pluginTag.enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY;
-  await checkPlugins();
-
-  pluginTag.enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY;
-  SpecialPowers.pushPrefEnv({set: [
-    ["extensions.blocklist.useXML", false],
-  ]});
-  await checkPlugins();
-});
-
-async function checkPlugins() {
   let managerWindow = await open_manager("addons://list/plugin");
 
-  let plugins = await AddonManager.getAddonsByTypes(["plugin"]);
+  let testPluginAddon = await getTestPluginAddon();
+  isnot(testPluginAddon, null, "part2: Test Plug-in should exist");
 
-  let testPluginId;
-  for (let plugin of plugins) {
-    if (plugin.name == "Test Plug-in") {
-      testPluginId = plugin.id;
-      break;
-    }
-  }
-  ok(testPluginId, "part2: Test Plug-in should exist");
-
-  let testPlugin = await AddonManager.getAddonByID(testPluginId);
-  isnot(testPlugin, null, "part2.1: Test Plug-in should exist");
+  let testPluginId = testPluginAddon.id;
 
   let pluginEl = get_addon_element(managerWindow, testPluginId);
-  pluginEl.parentNode.ensureElementIsVisible(pluginEl);
-  let enableButton = getPluginUI(pluginEl, "enable-btn");
-  is_element_hidden(enableButton, "part3: enable button should not be visible");
-  let disableButton = getPluginUI(pluginEl, "disable-btn");
-  is_element_hidden(disableButton, "part3: disable button should not be visible");
-  let menu = getPluginUI(pluginEl, "state-menulist");
-  is_element_visible(menu, "part3: state menu should be visible");
-  let askToActivateItem = getPluginUI(pluginEl, "ask-to-activate-menuitem");
-  is(menu.selectedItem, askToActivateItem, "part3: state menu should have 'Ask To Activate' selected");
+  ok(pluginEl, `Got the about:addon entry for "${testPluginId}"`);
+
+  info("part3: test plugin add-on actions status");
+  assertPluginActiveState({
+    managerWindow,
+    pluginId: testPluginId,
+    expectedActivateState: "ask-to-activate",
+  });
 
   let pluginTab = await BrowserTestUtils.openNewForegroundTab(gBrowser, gHttpTestRoot + "plugin_test.html");
   let pluginBrowser = pluginTab.linkedBrowser;
 
   let condition = () => PopupNotifications.getNotification("click-to-play-plugins", pluginBrowser);
   await BrowserTestUtils.waitForCondition(condition, "part4: should have a click-to-play notification");
 
   BrowserTestUtils.removeTab(pluginTab);
 
-  let alwaysActivateItem = getPluginUI(pluginEl, "always-activate-menuitem");
-  menu.selectedItem = alwaysActivateItem;
-  alwaysActivateItem.doCommand();
+  setPluginActivateState({
+    managerWindow,
+    pluginId: testPluginId,
+    activateState: "always-activate",
+  });
 
   pluginTab = await BrowserTestUtils.openNewForegroundTab(gBrowser, gHttpTestRoot + "plugin_test.html");
 
   await ContentTask.spawn(pluginTab.linkedBrowser, null, async function() {
     let testPlugin = content.document.getElementById("test");
     ok(testPlugin, "part5: should have a plugin element in the page");
     let objLoadingContent = testPlugin.QueryInterface(Ci.nsIObjectLoadingContent);
     let condition = () => objLoadingContent.activated;
     await ContentTaskUtils.waitForCondition(condition, "part5: waited too long for plugin to activate");
     ok(objLoadingContent.activated, "part6: plugin should be activated");
   });
 
   BrowserTestUtils.removeTab(pluginTab);
 
-  let neverActivateItem = getPluginUI(pluginEl, "never-activate-menuitem");
-  menu.selectedItem = neverActivateItem;
-  neverActivateItem.doCommand();
+  setPluginActivateState({
+    managerWindow,
+    pluginId: testPluginId,
+    activateState: "never-activate",
+  });
 
   pluginTab = await BrowserTestUtils.openNewForegroundTab(gBrowser, gHttpTestRoot + "plugin_test.html");
   pluginBrowser = pluginTab.linkedBrowser;
 
   await ContentTask.spawn(pluginTab.linkedBrowser, null, async function() {
     let testPlugin = content.document.getElementById("test");
     ok(testPlugin, "part7: should have a plugin element in the page");
     let objLoadingContent = testPlugin.QueryInterface(Ci.nsIObjectLoadingContent);
     ok(!objLoadingContent.activated, "part7: plugin should not be activated");
   });
 
   BrowserTestUtils.removeTab(pluginTab);
 
-  EventUtils.synthesizeMouseAtCenter(pluginEl, {}, managerWindow);
-  await BrowserTestUtils.waitForEvent(managerWindow.document, "ViewChanged");
+  info("part8: test plugin state is never-activate");
+  assertPluginActiveState({
+    managerWindow,
+    pluginId: testPluginId,
+    expectedActivateState: "never-activate",
+  });
 
-  is_element_hidden(enableButton, "part8: detail enable button should be hidden");
-  is_element_hidden(disableButton, "part8: detail disable button should be hidden");
-  is_element_visible(menu, "part8: detail state menu should be visible");
-  is(menu.selectedItem, neverActivateItem, "part8: state menu should have 'Never Activate' selected");
-
-  menu.selectedItem = alwaysActivateItem;
-  alwaysActivateItem.doCommand();
+  info("part9: set plugin state to always-activate");
+  setPluginActivateState({
+    managerWindow,
+    pluginId: testPluginId,
+    activateState: "always-activate",
+  });
 
   pluginTab = await BrowserTestUtils.openNewForegroundTab(gBrowser, gHttpTestRoot + "plugin_test.html");
   pluginBrowser = pluginTab.linkedBrowser;
 
   await ContentTask.spawn(pluginTab.linkedBrowser, null, async function() {
     let testPlugin = content.document.getElementById("test");
     ok(testPlugin, "part9: should have a plugin element in the page");
     let objLoadingContent = testPlugin.QueryInterface(Ci.nsIObjectLoadingContent);
     let condition = () => objLoadingContent.activated;
     await ContentTaskUtils.waitForCondition(condition, "part9: waited too long for plugin to activate");
     ok(objLoadingContent.activated, "part10: plugin should be activated");
   });
 
   BrowserTestUtils.removeTab(pluginTab);
 
-  menu.selectedItem = askToActivateItem;
-  askToActivateItem.doCommand();
+  setPluginActivateState({
+    managerWindow,
+    pluginId: testPluginId,
+    activateState: "ask-to-activate",
+  });
 
   pluginTab = await BrowserTestUtils.openNewForegroundTab(gBrowser, gHttpTestRoot + "plugin_test.html");
   pluginBrowser = pluginTab.linkedBrowser;
 
   condition = () => PopupNotifications.getNotification("click-to-play-plugins", pluginBrowser);
   await BrowserTestUtils.waitForCondition(condition, "part11: should have a click-to-play notification");
 
   BrowserTestUtils.removeTab(pluginTab);
+  await close_manager(managerWindow);
+  await SpecialPowers.popPrefEnv();
+}
 
-  // causes appDisabled to be set
-  managerWindow = await new Promise(resolve => {
-    setAndUpdateBlocklist(gHttpTestRoot + "blockPluginHard.xml",
-      async () => {
-        await close_manager(managerWindow);
-        open_manager("addons://list/plugin", resolve);
-      }
-    );
+add_task(async function test_CTP_plugins_XUL_aboutaddons() {
+  await SpecialPowers.pushPrefEnv({
+    set: [["extensions.htmlaboutaddons.enabled", false]],
+  });
+  await test_CTP_plugins("XUL");
+  await SpecialPowers.popPrefEnv();
+});
+
+add_task(async function test_CTP_plugins_HTML_aboutaddons() {
+  await SpecialPowers.pushPrefEnv({
+    set: [["extensions.htmlaboutaddons.enabled", true]],
+  });
+  await test_CTP_plugins("HTML");
+  await SpecialPowers.popPrefEnv();
+});
+
+add_task(async function test_blocklisted_plugin_disabled() {
+  async function ensurePluginEnabled() {
+    let pluginTag = getTestPluginTag();
+    pluginTag.enabledState = Ci.nsIPluginTag.STATE_ENABLED;
+    await new Promise(resolve => {
+      setAndUpdateBlocklist(gHttpTestRoot + "blockNoPlugins.xml", resolve);
+    });
+    resetBlocklist();
+  }
+
+  await SpecialPowers.pushPrefEnv({
+    set: [
+      ["extensions.blocklist.suppressUI", true],
+      ["extensions.blocklist.useXML", true],
+    ],
   });
 
-  pluginEl = get_addon_element(managerWindow, testPluginId);
-  pluginEl.parentNode.ensureElementIsVisible(pluginEl);
-  menu = getPluginUI(pluginEl, "state-menulist");
-  is(menu.disabled, true, "part12: state menu should be disabled");
+  // Causes appDisabled to be set.
+  await new Promise(async resolve => {
+    // Ensure to reset the blocklist if this test exits earlier because
+    // of a failure.
+    registerCleanupFunction(ensurePluginEnabled);
+    setAndUpdateBlocklist(gHttpTestRoot + "blockPluginHard.xml", resolve);
+  });
+
+  await checkPlugins();
 
-  EventUtils.synthesizeMouseAtCenter(pluginEl, {}, managerWindow);
-  await BrowserTestUtils.waitForEvent(managerWindow.document, "ViewChanged");
+  await SpecialPowers.pushPrefEnv({
+    set: [["extensions.blocklist.useXML", false]],
+  });
+  await checkPlugins();
+
+  // Clear the blocklist and all prefs on the stack.
+  await ensurePluginEnabled();
+  // Using flushPrefEnv instead of 2x popPrefEnv to work around bug 1557397.
+  await SpecialPowers.flushPrefEnv();
+});
 
-  menu = managerWindow.document.getElementById("detail-state-menulist");
-  is(menu.disabled, true, "part13: detail state menu should be disabled");
+async function checkPlugins() {
+  let testPluginAddon = await getTestPluginAddon();
+  isnot(testPluginAddon, null, "Test Plug-in should exist");
+  let testPluginId = testPluginAddon.id;
+
+  let managerWindow;
 
-  managerWindow.close();
-  await new Promise(resolve =>
-    setAndUpdateBlocklist(gHttpTestRoot + "blockNoPlugins.xml", resolve));
+  info("Test blocklisted plugin actions disabled in XUL about:addons");
+  await SpecialPowers.pushPrefEnv({
+    set: [["extensions.htmlaboutaddons.enabled", false]],
+  });
+  managerWindow = await open_manager("addons://list/plugin");
+  await assertPluginAppDisabled({managerWindow, pluginId: testPluginId});
+  await close_manager(managerWindow);
+
+  info("Test blocklisted plugin actions disabled in HTML about:addons");
+  await SpecialPowers.pushPrefEnv({
+    set: [["extensions.htmlaboutaddons.enabled", true]],
+  });
+  managerWindow = await open_manager("addons://list/plugin");
+  await assertPluginAppDisabled({managerWindow, pluginId: testPluginId});
+  await close_manager(managerWindow);
 }