Bug 1551490 - Run browser_CTP_plugins.js on both XUL and HTML about:addons page. r=aswan,rpl, a=test-only
authorLuca Greco <lgreco@mozilla.com>
Fri, 07 Jun 2019 18:40:13 +0000
changeset 533828 83af41aaeb7df6bfd934b335676e14a9bf191634
parent 533827 633c7ce9740c8f428812052468b8ecaae12b9a14
child 533829 32caceae9cac46abf47f1f19ec5ce00a228aba99
push id11438
push userjcristau@mozilla.com
push dateWed, 12 Jun 2019 17:34:20 +0000
treeherdermozilla-beta@a2fc7a9510bd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaswan, rpl, test-only
bugs1551490
milestone68.0
Bug 1551490 - Run browser_CTP_plugins.js on both XUL and HTML about:addons page. r=aswan,rpl, a=test-only 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);
 }