Bug 1551490 - Rename browser_bug562797 to browser_history_navigation and run on XUL and HTML about:addons. r=kmag,rpl, a=test-only
authorLuca Greco <lgreco@mozilla.com>
Sun, 09 Jun 2019 23:50:18 +0000
changeset 536899 fd69d7d0f0d080ffe71b6539b95103c106a28fb0
parent 536898 0cc06358290da5c2b93e6407e7eeb6d4ff49b1d6
child 536900 9688b1081c1db3d73d08418b2e78508ec7778d03
push id2082
push userffxbld-merge
push dateMon, 01 Jul 2019 08:34:18 +0000
treeherdermozilla-release@2fb19d0466d2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskmag, rpl, test-only
bugs1551490, 562797
milestone68.0
Bug 1551490 - Rename browser_bug562797 to browser_history_navigation and run on XUL and HTML about:addons. r=kmag,rpl, a=test-only Depends on D31780 Differential Revision: https://phabricator.services.mozilla.com/D31782
toolkit/mozapps/extensions/test/browser/browser.ini
toolkit/mozapps/extensions/test/browser/browser_bug562797.js
toolkit/mozapps/extensions/test/browser/browser_history_navigation.js
toolkit/mozapps/extensions/test/browser/discovery/api_response_empty.json
--- a/toolkit/mozapps/extensions/test/browser/browser.ini
+++ b/toolkit/mozapps/extensions/test/browser/browser.ini
@@ -5,16 +5,17 @@ support-files =
   addons/browser_dragdrop2.xpi
   addons/browser_dragdrop_incompat.xpi
   addons/browser_installssl.xpi
   addons/browser_theme.xpi
   addons/options_signed.xpi
   addons/options_signed/*
   addon_prefs.xul
   discovery/api_response.json
+  discovery/api_response_empty.json
   discovery/small-1x1.png
   discovery.html
   head.js
   more_options.xul
   options.xul
   plugin_test.html
   redirect.sjs
   releaseNotes.xhtml
@@ -40,17 +41,16 @@ generated-files =
   addons/browser_installssl.xpi
   addons/browser_theme.xpi
   addons/options_signed.xpi
 
 [browser_CTP_plugins.js]
 tags = blocklist
 [browser_about_debugging_link.js]
 [browser_bug523784.js]
-[browser_bug562797.js]
 [browser_bug562890.js]
 skip-if = os == 'win' && !debug # Disabled on Windows opt/PGO builds due to intermittent failures (bug 1135866)
 [browser_bug562899.js]
 [browser_bug562992.js]
 [browser_bug567127.js]
 skip-if = (!debug && os == 'win') #Bug 1489496
 [browser_bug567137.js]
 [browser_bug570760.js]
@@ -72,16 +72,17 @@ skip-if = os == "linux" && !debug # Bug 
 [browser_discovery_clientid.js]
 [browser_dragdrop.js]
 [browser_extension_sideloading_permission.js]
 [browser_file_xpi_no_process_switch.js]
 skip-if = true # Bug 1449071 - Frequent failures
 [browser_globalwarnings.js]
 [browser_gmpProvider.js]
 skip-if = os == 'linux' && !debug # Bug 1398766
+[browser_history_navigation.js]
 [browser_html_abuse_report.js]
 [browser_html_detail_view.js]
 [browser_html_discover_view.js]
 [browser_html_discover_view_clientid.js]
 [browser_html_discover_view_prefs.js]
 [browser_html_list_view.js]
 [browser_html_list_view_recommendations.js]
 [browser_html_message_bar.js]
rename from toolkit/mozapps/extensions/test/browser/browser_bug562797.js
rename to toolkit/mozapps/extensions/test/browser/browser_history_navigation.js
--- a/toolkit/mozapps/extensions/test/browser/browser_bug562797.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_history_navigation.js
@@ -3,18 +3,46 @@
  */
 
 /* eslint max-nested-callbacks: ["warn", 12] */
 
 /**
  * Tests that history navigation works for the add-ons manager.
  */
 
-const MAIN_URL = "https://example.com/" + RELATIVE_DIR + "discovery.html";
-const SECOND_URL = "https://example.com/" + RELATIVE_DIR + "releaseNotes.xhtml";
+requestLongerTimeout(2);
+
+const {AddonTestUtils} = ChromeUtils.import("resource://testing-common/AddonTestUtils.jsm");
+
+AddonTestUtils.initMochitest(this);
+
+const MAIN_URL = `https://example.com/${RELATIVE_DIR}discovery.html`;
+const SECOND_URL = `https://example.com/${RELATIVE_DIR}releaseNotes.xhtml`;
+const DISCOAPI_URL = `http://example.com/${RELATIVE_DIR}/discovery/api_response_empty.json`;
+
+// Clearing this pref is currently done from a cleanup function registered
+// by the head.js file.
+Services.prefs.setCharPref(PREF_DISCOVERURL, MAIN_URL);
+
+var gProvider = new MockProvider();
+gProvider.createAddons([{
+  id: "test1@tests.mozilla.org",
+  name: "Test add-on 1",
+  description: "foo",
+}, {
+  id: "test2@tests.mozilla.org",
+  name: "Test add-on 2",
+  description: "bar",
+}, {
+  id: "test3@tests.mozilla.org",
+  name: "Test add-on 3",
+  type: "theme",
+  description: "bar",
+}]);
+
 
 var gLoadCompleteCallback = null;
 
 var gProgressListener = {
   onStateChange(aWebProgress, aRequest, aStateFlags, aStatus) {
     // Only care about the network stop status events
     if (!(aStateFlags & (Ci.nsIWebProgressListener.STATE_IS_NETWORK)) ||
         !(aStateFlags & (Ci.nsIWebProgressListener.STATE_STOP)))
@@ -61,53 +89,16 @@ function clickLink(aManager, aId, aCallb
     EventUtils.sendMouseEvent({type: "click"}, link);
   });
   if (aCallback) {
     promise.then(aCallback);
   }
   return promise;
 }
 
-function test() {
-  requestLongerTimeout(2);
-
-  waitForExplicitFinish();
-
-  Services.prefs.setCharPref(PREF_DISCOVERURL, MAIN_URL);
-
-  SpecialPowers.pushPrefEnv({"set": [
-      ["dom.ipc.processCount", 1],
-      ["security.allow_eval_with_system_principal", true],
-    ]}, () => {
-    var gProvider = new MockProvider();
-    gProvider.createAddons([{
-      id: "test1@tests.mozilla.org",
-      name: "Test add-on 1",
-      description: "foo",
-    },
-    {
-      id: "test2@tests.mozilla.org",
-      name: "Test add-on 2",
-      description: "bar",
-    },
-    {
-      id: "test3@tests.mozilla.org",
-      name: "Test add-on 3",
-      type: "theme",
-      description: "bar",
-    }]);
-  });
-
-  run_next_test();
-}
-
-function end_test() {
-  finish();
-}
-
 function go_back() {
   gBrowser.goBack();
 }
 
 function go_back_backspace() {
     EventUtils.synthesizeKey("KEY_Backspace");
 }
 
@@ -123,119 +114,182 @@ function check_state(canGoBack, canGoFor
   is(gBrowser.canGoBack, canGoBack, "canGoBack should be correct");
   is(gBrowser.canGoForward, canGoForward, "canGoForward should be correct");
 }
 
 function is_in_list(aManager, view, canGoBack, canGoForward) {
   var doc = aManager.document;
 
   is(doc.getElementById("categories").selectedItem.value, view, "Should be on the right category");
-  is(get_current_view(aManager).id, "list-view", "Should be on the right view");
+
+  if (aManager.useHtmlViews) {
+    is(get_current_view(aManager).id, "html-view-browser",
+       "the current view should be set to the HTML about:addons browser");
+    const doc = aManager.getHtmlBrowser().contentDocument;
+    ok(doc.querySelector("addon-list"), "Got a list-view in the HTML about:addons browser");
+  } else {
+    is(get_current_view(aManager).id, "list-view", "Should be on the right view");
+  }
 
   check_state(canGoBack, canGoForward);
 }
 
 function is_in_detail(aManager, view, canGoBack, canGoForward) {
   var doc = aManager.document;
 
   is(doc.getElementById("categories").selectedItem.value, view, "Should be on the right category");
-  is(get_current_view(aManager).id, "detail-view", "Should be on the right view");
+
+  if (aManager.useHtmlViews) {
+    is(get_current_view(aManager).id, "html-view-browser",
+       "the current view should be set to the HTML about:addons browser");
+    const doc = aManager.getHtmlBrowser().contentDocument;
+    is(doc.querySelectorAll("addon-card").length, 1,
+       "Got a detail-view in the HTML about:addons browser");
+  } else {
+    is(get_current_view(aManager).id, "detail-view", "Should be on the right view");
+  }
 
   check_state(canGoBack, canGoForward);
 }
 
 function is_in_discovery(aManager, url, canGoBack, canGoForward) {
-  var browser = aManager.document.getElementById("discover-browser");
-
-  is(aManager.document.getElementById("discover-view").selectedPanel, browser,
-     "Browser should be visible");
+  if (Services.prefs.getBoolPref("extensions.htmlaboutaddons.discover.enabled")) {
+    is(get_current_view(aManager).id, "html-view-browser",
+       "the current view should be set to the HTML about:addons browser");
+    const doc = aManager.getHtmlBrowser().contentDocument;
+    ok(doc.querySelector("discovery-pane"),
+       "Got a discovery panel in the HTML about:addons browser");
+  } else {
+    var browser = aManager.document.getElementById("discover-browser");
 
-  var spec = browser.currentURI.spec;
-  var pos = spec.indexOf("#");
-  if (pos != -1)
-    spec = spec.substring(0, pos);
+    is(aManager.document.getElementById("discover-view").selectedPanel, browser,
+      "Browser should be visible");
 
-  is(spec, url, "Should have loaded the right url");
+    var spec = browser.currentURI.spec;
+    var pos = spec.indexOf("#");
+    if (pos != -1)
+      spec = spec.substring(0, pos);
+
+    is(spec, url, "Should have loaded the right url");
+  }
 
   check_state(canGoBack, canGoForward);
 }
 
-function double_click_addon_element(aManager, aId) {
+async function expand_addon_element(aManager, aId) {
   var addon = get_addon_element(aManager, aId);
-  addon.parentNode.ensureElementIsVisible(addon);
-  EventUtils.synthesizeMouseAtCenter(addon, { clickCount: 1 }, aManager);
-  EventUtils.synthesizeMouseAtCenter(addon, { clickCount: 2 }, aManager);
+  if (aManager.useHtmlViews) {
+    addon.click();
+  } else {
+    addon.parentNode.ensureElementIsVisible(addon);
+    EventUtils.synthesizeMouseAtCenter(addon, { clickCount: 1 }, aManager);
+    EventUtils.synthesizeMouseAtCenter(addon, { clickCount: 2 }, aManager);
+  }
+}
+
+function wait_for_page_show(browser) {
+  let promise = new Promise(resolve => {
+    let removeFunc;
+    let listener = () => {
+      removeFunc();
+      resolve();
+    };
+    removeFunc = BrowserTestUtils.addContentEventListener(
+      browser, "pageshow", listener, false,
+      (event) => event.target.location == "http://example.com/",
+      false, false);
+  });
+  return promise;
+}
+
+async function runTestOnPrefEnvs(prefEnvs, testFn) {
+  for (const [message, prefEnv] of prefEnvs) {
+    info(`${message}: ${JSON.stringify(prefEnv)}`);
+    await SpecialPowers.pushPrefEnv(prefEnv);
+    await testFn();
+    await SpecialPowers.popPrefEnv();
+  }
 }
 
 // Tests simple forward and back navigation and that the right heading and
 // category is selected
-add_test(async function() {
-  let aManager = await open_manager("addons://list/extension");
-  info("Part 1");
-  is_in_list(aManager, "addons://list/extension", false, false);
-
-  EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-plugin"), { }, aManager);
+add_task(async function test_navigate_history() {
+  await runTestOnPrefEnvs([
+    ["Test on XUL about:addons", {
+      set: [["extensions.htmlaboutaddons.enabled", false]],
+    }],
+    ["Test on HTML about:addons", {
+      set: [["extensions.htmlaboutaddons.enabled", true]],
+    }],
+  ], async () => {
+    let aManager = await open_manager("addons://list/extension");
+    info("Part 1");
+    is_in_list(aManager, "addons://list/extension", false, false);
 
-  aManager = await wait_for_view_load(aManager);
-  info("Part 2");
-  is_in_list(aManager, "addons://list/plugin", true, false);
+    EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-plugin"), { }, aManager);
 
-  go_back();
+    aManager = await wait_for_view_load(aManager);
+    info("Part 2");
+    is_in_list(aManager, "addons://list/plugin", true, false);
 
-  aManager = await wait_for_view_load(aManager);
-  info("Part 3");
-  is_in_list(aManager, "addons://list/extension", false, true);
+    go_back();
 
-  go_forward();
+    aManager = await wait_for_view_load(aManager);
+    info("Part 3");
+    is_in_list(aManager, "addons://list/extension", false, true);
 
-  aManager = await wait_for_view_load(aManager);
-  info("Part 4");
-  is_in_list(aManager, "addons://list/plugin", true, false);
+    go_forward();
 
-  go_back();
+    aManager = await wait_for_view_load(aManager);
+    info("Part 4");
+    is_in_list(aManager, "addons://list/plugin", true, false);
 
-  aManager = await wait_for_view_load(aManager);
-  info("Part 5");
-  is_in_list(aManager, "addons://list/extension", false, true);
+    go_back();
 
-  double_click_addon_element(aManager, "test1@tests.mozilla.org");
+    aManager = await wait_for_view_load(aManager);
+    info("Part 5");
+    is_in_list(aManager, "addons://list/extension", false, true);
 
-  aManager = await wait_for_view_load(aManager);
-  info("Part 6");
-  is_in_detail(aManager, "addons://list/extension", true, false);
+    await expand_addon_element(aManager, "test1@tests.mozilla.org");
 
-  go_back();
+    aManager = await wait_for_view_load(aManager);
+    info("Part 6");
+    is_in_detail(aManager, "addons://list/extension", true, false);
 
-  aManager = await wait_for_view_load(aManager);
-  info("Part 7");
-  is_in_list(aManager, "addons://list/extension", false, true);
+    go_back();
 
-  close_manager(aManager, run_next_test);
+    aManager = await wait_for_view_load(aManager);
+    info("Part 7");
+    is_in_list(aManager, "addons://list/extension", false, true);
+
+    await close_manager(aManager);
+  });
 });
 
 // Tests that browsing to the add-ons manager from a website and going back works
-add_test(function() {
-  function promiseManagerLoaded(manager) {
-    return new Promise(resolve => {
-      wait_for_manager_load(manager, resolve);
-    });
-  }
-
-  (async function() {
+add_task(async function test_navigate_between_webpage_and_aboutaddons() {
+  await runTestOnPrefEnvs([
+    ["Test on XUL about:addons", {
+      set: [["extensions.htmlaboutaddons.enabled", false]],
+    }],
+    ["Test on HTML about:addons", {
+      set: [["extensions.htmlaboutaddons.enabled", true]],
+    }],
+  ], async () => {
     info("Part 1");
     await BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/", true, true);
 
     info("Part 2");
     ok(!gBrowser.canGoBack, "Should not be able to go back");
     ok(!gBrowser.canGoForward, "Should not be able to go forward");
 
     await BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "about:addons");
     await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
 
-    let manager = await promiseManagerLoaded(gBrowser.contentWindow.wrappedJSObject);
+    let manager = await wait_for_manager_load(gBrowser.contentWindow);
 
     info("Part 3");
     is_in_list(manager, "addons://list/extension", true, false);
 
     // XXX: This is less than ideal, as it's currently difficult to deal with
     // the browser frame switching between remote/non-remote in e10s mode.
     let promiseLoaded;
     if (gMultiProcessBrowser) {
@@ -251,154 +305,180 @@ add_test(function() {
     is(gBrowser.currentURI.spec, "http://example.com/", "Should be showing the webpage");
     ok(!gBrowser.canGoBack, "Should not be able to go back");
     ok(gBrowser.canGoForward, "Should be able to go forward");
 
     promiseLoaded = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
     go_forward(manager);
     await promiseLoaded;
 
-    manager = await promiseManagerLoaded(gBrowser.contentWindow.wrappedJSObject);
+    manager = gBrowser.selectedBrowser.contentWindow;
     info("Part 5");
     is_in_list(manager, "addons://list/extension", true, false);
 
-    close_manager(manager, run_next_test);
-  })();
+    await close_manager(manager);
+  });
 });
 
 // Tests simple forward and back navigation and that the right heading and
 // category is selected -- Keyboard navigation [Bug 565359]
 // Only add the test if the backspace key navigates back and addon-manager
 // loaded in a tab
-add_test(async function() {
+add_task(async function test_keyboard_history_navigation() {
   if (Services.prefs.getIntPref("browser.backspace_action") != 0) {
-    run_next_test();
+    info("Test skipped on browser.backspace_action != 0");
     return;
   }
 
-  let aManager = await open_manager("addons://list/extension");
-  info("Part 1");
-  is_in_list(aManager, "addons://list/extension", false, false);
-
-  EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-plugin"), { }, aManager);
+  await runTestOnPrefEnvs([
+    ["Test on XUL about:addons", {
+      set: [["extensions.htmlaboutaddons.enabled", false]],
+    }],
+    ["Test on HTML about:addons", {
+      set: [["extensions.htmlaboutaddons.enabled", true]],
+    }],
+  ], async () => {
+    let aManager = await open_manager("addons://list/extension");
+    info("Part 1");
+    is_in_list(aManager, "addons://list/extension", false, false);
 
-  aManager = await wait_for_view_load(aManager);
-  info("Part 2");
-  is_in_list(aManager, "addons://list/plugin", true, false);
+    EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-plugin"), { }, aManager);
 
-  go_back_backspace();
+    aManager = await wait_for_view_load(aManager);
+    info("Part 2");
+    is_in_list(aManager, "addons://list/plugin", true, false);
 
-  aManager = await wait_for_view_load(aManager);
-  info("Part 3");
-  is_in_list(aManager, "addons://list/extension", false, true);
+    go_back_backspace();
 
-  go_forward_backspace();
+    aManager = await wait_for_view_load(aManager);
+    info("Part 3");
+    is_in_list(aManager, "addons://list/extension", false, true);
 
-  aManager = await wait_for_view_load(aManager);
-  info("Part 4");
-  is_in_list(aManager, "addons://list/plugin", true, false);
+    go_forward_backspace();
 
-  go_back_backspace();
+    aManager = await wait_for_view_load(aManager);
+    info("Part 4");
+    is_in_list(aManager, "addons://list/plugin", true, false);
 
-  aManager = await wait_for_view_load(aManager);
-  info("Part 5");
-  is_in_list(aManager, "addons://list/extension", false, true);
+    go_back_backspace();
 
-  double_click_addon_element(aManager, "test1@tests.mozilla.org");
+    aManager = await wait_for_view_load(aManager);
+    info("Part 5");
+    is_in_list(aManager, "addons://list/extension", false, true);
 
-  aManager = await wait_for_view_load(aManager);
-  info("Part 6");
-  is_in_detail(aManager, "addons://list/extension", true, false);
+    await expand_addon_element(aManager, "test1@tests.mozilla.org");
 
-  go_back_backspace();
+    aManager = await wait_for_view_load(aManager);
+    info("Part 6");
+    is_in_detail(aManager, "addons://list/extension", true, false);
 
-  aManager = await wait_for_view_load(aManager);
-  info("Part 7");
-  is_in_list(aManager, "addons://list/extension", false, true);
+    go_back_backspace();
 
-  close_manager(aManager, run_next_test);
+    aManager = await wait_for_view_load(aManager);
+    info("Part 7");
+    is_in_list(aManager, "addons://list/extension", false, true);
+
+    await close_manager(aManager);
+  });
 });
 
-
 // Tests that opening a custom first view only stores a single history entry
-add_test(async function() {
-  let aManager = await open_manager("addons://list/plugin");
-  info("Part 1");
-  is_in_list(aManager, "addons://list/plugin", false, false);
-
-  EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-extension"), { }, aManager);
+add_task(async function test_single_history_entry() {
+  await runTestOnPrefEnvs([
+    ["Test on XUL about:addons", {
+      set: [["extensions.htmlaboutaddons.enabled", false]],
+    }],
+    ["Test on HTML about:addons", {
+      set: [["extensions.htmlaboutaddons.enabled", true]],
+    }],
+  ], async () => {
+    let aManager = await open_manager("addons://list/plugin");
+    info("Part 1");
+    is_in_list(aManager, "addons://list/plugin", false, false);
 
-  aManager = await wait_for_view_load(aManager);
-  info("Part 2");
-  is_in_list(aManager, "addons://list/extension", true, false);
+    EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-extension"), { }, aManager);
 
-  go_back();
+    aManager = await wait_for_view_load(aManager);
+    info("Part 2");
+    is_in_list(aManager, "addons://list/extension", true, false);
+
+    go_back();
 
-  aManager = await wait_for_view_load(aManager);
-  info("Part 3");
-  is_in_list(aManager, "addons://list/plugin", false, true);
+    aManager = await wait_for_view_load(aManager);
+    info("Part 3");
+    is_in_list(aManager, "addons://list/plugin", false, true);
 
-  close_manager(aManager, run_next_test);
+    await close_manager(aManager);
+  });
 });
 
-
 // Tests that opening a view while the manager is already open adds a new
 // history entry
-add_test(async function() {
-  let aManager = await open_manager("addons://list/extension");
-  info("Part 1");
-  is_in_list(aManager, "addons://list/extension", false, false);
-
-  aManager.loadView("addons://list/plugin");
+add_task(async function test_new_history_entry_while_opened() {
+  await runTestOnPrefEnvs([
+    ["Test on XUL about:addons", {
+      set: [["extensions.htmlaboutaddons.enabled", false]],
+    }],
+    ["Test on HTML about:addons", {
+      set: [["extensions.htmlaboutaddons.enabled", true]],
+    }],
+  ], async () => {
+    let aManager = await open_manager("addons://list/extension");
+    info("Part 1");
+    is_in_list(aManager, "addons://list/extension", false, false);
 
-  aManager = await wait_for_view_load(aManager);
-  info("Part 2");
-  is_in_list(aManager, "addons://list/plugin", true, false);
-
-  go_back();
-
-  aManager = await wait_for_view_load(aManager);
-  info("Part 3");
-  is_in_list(aManager, "addons://list/extension", false, true);
-
-  go_forward();
+    aManager.loadView("addons://list/plugin");
 
-  aManager = await wait_for_view_load(aManager);
-  info("Part 4");
-  is_in_list(aManager, "addons://list/plugin", true, false);
+    aManager = await wait_for_view_load(aManager);
+    info("Part 2");
+    is_in_list(aManager, "addons://list/plugin", true, false);
 
-  close_manager(aManager, run_next_test);
-});
+    go_back();
+
+    aManager = await wait_for_view_load(aManager);
+    info("Part 3");
+    is_in_list(aManager, "addons://list/extension", false, true);
 
-function wait_for_page_show(browser) {
-  let promise = new Promise(resolve => {
-    let removeFunc;
-    let listener = () => {
-      removeFunc();
-      resolve();
-    };
-    removeFunc = BrowserTestUtils.addContentEventListener(browser, "pageshow", listener, false,
-                                                          (event) => event.target.location == "http://example.com/",
-                                                          false, false);
+    go_forward();
+
+    aManager = await wait_for_view_load(aManager);
+    info("Part 4");
+    is_in_list(aManager, "addons://list/plugin", true, false);
+
+    await close_manager(aManager);
   });
-  return promise;
-}
+});
 
 // Tests than navigating to a website and then going back returns to the
 // previous view
-add_test(async function() {
-  let aManager = await open_manager("addons://list/plugin");
-  info("Part 1");
-  is_in_list(aManager, "addons://list/plugin", false, false);
+add_task(async function test_navigate_back_from_website() {
+  await runTestOnPrefEnvs([
+    ["Test on XUL about:addons", {
+      set: [
+        ["extensions.htmlaboutaddons.enabled", false],
+        ["security.allow_eval_with_system_principal", true],
+      ],
+    }],
+    ["Test on HTML about:addons", {
+      set: [
+        ["extensions.htmlaboutaddons.enabled", true],
+        ["security.allow_eval_with_system_principal", true],
+      ],
+    }],
+  ], async () => {
+    let aManager = await open_manager("addons://list/plugin");
+    info("Part 1");
+    is_in_list(aManager, "addons://list/plugin", false, false);
 
-  BrowserTestUtils.loadURI(gBrowser, "http://example.com/");
-  wait_for_page_show(gBrowser.selectedBrowser).then(() => {
+    BrowserTestUtils.loadURI(gBrowser, "http://example.com/");
+    await wait_for_page_show(gBrowser.selectedBrowser);
+
     info("Part 2");
 
-    executeSoon(function() {
+    await new Promise(resolve => executeSoon(function() {
       ok(gBrowser.canGoBack, "Should be able to go back");
       ok(!gBrowser.canGoForward, "Should not be able to go forward");
 
       go_back();
 
       gBrowser.addEventListener("pageshow", async function listener(event) {
         if (event.target.location != "about:addons")
           return;
@@ -421,274 +501,403 @@ add_test(async function() {
             gBrowser.addEventListener("pageshow", async function listener(event) {
               if (event.target.location != "about:addons")
                 return;
               gBrowser.removeEventListener("pageshow", listener);
               aManager = await wait_for_view_load(gBrowser.contentWindow.wrappedJSObject);
               info("Part 5");
               is_in_list(aManager, "addons://list/plugin", false, true);
 
-              close_manager(aManager, run_next_test);
+              resolve();
             });
           });
         });
       });
-    });
+    }));
+
+    await close_manager(aManager);
   });
 });
 
 // Tests that refreshing a list view does not affect the history
-add_test(async function() {
-  let aManager = await open_manager("addons://list/extension");
-  info("Part 1");
-  is_in_list(aManager, "addons://list/extension", false, false);
-
-  EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-plugin"), { }, aManager);
+add_task(async function test_refresh_listview_donot_add_history_entries() {
+  await runTestOnPrefEnvs([
+    ["Test on XUL about:addons", {
+      set: [["extensions.htmlaboutaddons.enabled", false]],
+    }],
+    ["Test on HTML about:addons", {
+      set: [["extensions.htmlaboutaddons.enabled", true]],
+    }],
+  ], async () => {
+    let aManager = await open_manager("addons://list/extension");
+    info("Part 1");
+    is_in_list(aManager, "addons://list/extension", false, false);
 
-  aManager = await wait_for_view_load(aManager);
-  info("Part 2");
-  is_in_list(aManager, "addons://list/plugin", true, false);
+    EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-plugin"), { }, aManager);
 
-  gBrowser.reload();
-  gBrowser.addEventListener("pageshow", async function listener(event) {
-    if (event.target.location != "about:addons")
-      return;
-    gBrowser.removeEventListener("pageshow", listener);
-
-    aManager = await wait_for_view_load(gBrowser.contentWindow.wrappedJSObject);
-    info("Part 3");
+    aManager = await wait_for_view_load(aManager);
+    info("Part 2");
     is_in_list(aManager, "addons://list/plugin", true, false);
 
-    go_back();
-    aManager = await wait_for_view_load(aManager);
-    info("Part 4");
-    is_in_list(aManager, "addons://list/extension", false, true);
+    await new Promise(resolve => {
+      gBrowser.reload();
+      gBrowser.addEventListener("pageshow", async function listener(event) {
+        if (event.target.location != "about:addons")
+          return;
+        gBrowser.removeEventListener("pageshow", listener);
 
-    close_manager(aManager, run_next_test);
+        aManager = await wait_for_view_load(gBrowser.contentWindow.wrappedJSObject);
+        info("Part 3");
+        is_in_list(aManager, "addons://list/plugin", true, false);
+
+        go_back();
+        aManager = await wait_for_view_load(aManager);
+        info("Part 4");
+        is_in_list(aManager, "addons://list/extension", false, true);
+        resolve();
+      });
+    });
+
+    await close_manager(aManager);
   });
 });
 
 // Tests that refreshing a detail view does not affect the history
-add_test(async function() {
-  let aManager = await open_manager(null);
-  info("Part 1");
-  is_in_list(aManager, "addons://list/extension", false, false);
-
-  double_click_addon_element(aManager, "test1@tests.mozilla.org");
+add_task(async function test_refresh_detailview_donot_add_history_entries() {
+  await runTestOnPrefEnvs([
+    ["Test on XUL about:addons", {
+      set: [["extensions.htmlaboutaddons.enabled", false]],
+    }],
+    ["Test on HTML about:addons", {
+      set: [["extensions.htmlaboutaddons.enabled", true]],
+    }],
+  ], async () => {
+    let aManager = await open_manager(null);
+    info("Part 1");
+    is_in_list(aManager, "addons://list/extension", false, false);
 
-  aManager = await wait_for_view_load(aManager);
-  info("Part 2");
-  is_in_detail(aManager, "addons://list/extension", true, false);
+    await expand_addon_element(aManager, "test1@tests.mozilla.org");
 
-  gBrowser.reload();
-  gBrowser.addEventListener("pageshow", async function listener(event) {
-    if (event.target.location != "about:addons")
-      return;
-    gBrowser.removeEventListener("pageshow", listener);
-
-    aManager = await wait_for_view_load(gBrowser.contentWindow.wrappedJSObject);
-    info("Part 3");
+    aManager = await wait_for_view_load(aManager);
+    info("Part 2");
     is_in_detail(aManager, "addons://list/extension", true, false);
 
-    go_back();
-    aManager = await wait_for_view_load(aManager);
-    info("Part 4");
-    is_in_list(aManager, "addons://list/extension", false, true);
+    await new Promise(resolve => {
+      gBrowser.reload();
+      gBrowser.addEventListener("pageshow", async function listener(event) {
+        if (event.target.location != "about:addons")
+          return;
+        gBrowser.removeEventListener("pageshow", listener);
 
-    close_manager(aManager, run_next_test);
+        aManager = await wait_for_view_load(gBrowser.contentWindow.wrappedJSObject);
+        info("Part 3");
+        is_in_detail(aManager, "addons://list/extension", true, false);
+
+        go_back();
+        aManager = await wait_for_view_load(aManager);
+        info("Part 4");
+        is_in_list(aManager, "addons://list/extension", false, true);
+        resolve();
+      });
+    });
+
+    await close_manager(aManager);
   });
 });
 
 // Tests that removing an extension from the detail view goes back and doesn't
 // allow you to go forward again.
-add_test(async function() {
-  let aManager = await open_manager("addons://list/extension");
-  info("Part 1");
-  is_in_list(aManager, "addons://list/extension", false, false);
+add_task(async function test_history_on_detailview_extension_removed() {
+  await runTestOnPrefEnvs([
+    ["Test on XUL about:addons", {
+      set: [["extensions.htmlaboutaddons.enabled", false]],
+    }],
+    ["Test on HTML about:addons", {
+      set: [["extensions.htmlaboutaddons.enabled", true]],
+    }],
+  ], async () => {
+    let aManager = await open_manager("addons://list/extension");
 
-  double_click_addon_element(aManager, "test1@tests.mozilla.org");
+    info("Part 1");
+    is_in_list(aManager, "addons://list/extension", false, false);
+
+    await expand_addon_element(aManager, "test1@tests.mozilla.org");
+
+    aManager = await wait_for_view_load(aManager);
+    info("Part 2");
+    is_in_detail(aManager, "addons://list/extension", true, false);
 
-  aManager = await wait_for_view_load(aManager);
-  info("Part 2");
-  is_in_detail(aManager, "addons://list/extension", true, false);
+    if (aManager.useHtmlViews) {
+      const doc = aManager.getHtmlBrowser().contentDocument;
+      const addonCard = doc.querySelector('addon-card[addon-id="test1@tests.mozilla.org"]');
+      const promptService = mockPromptService();
+      promptService._response = 0;
+      addonCard.querySelector("[action=remove]").click();
+    } else {
+      EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("detail-uninstall-btn"),
+                                         { }, aManager);
+    }
 
-  EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("detail-uninstall-btn"),
-                                     { }, aManager);
+    await wait_for_view_load(aManager);
+    is_in_list(aManager, "addons://list/extension", true, false);
 
-  await wait_for_view_load(aManager);
-  is_in_list(aManager, "addons://list/extension", true, false);
+    const addon = await AddonManager.getAddonByID("test1@tests.mozilla.org");
+    addon.cancelUninstall();
 
-  close_manager(aManager, run_next_test);
+    await close_manager(aManager);
+  });
 });
 
 // Tests that opening the manager opens the last view
-add_test(async function() {
-  let aManager = await open_manager("addons://list/plugin");
-  info("Part 1");
-  is_in_list(aManager, "addons://list/plugin", false, false);
+add_task(async function test_open_last_view() {
+  await runTestOnPrefEnvs([
+    ["Test on XUL about:addons", {
+      set: [["extensions.htmlaboutaddons.enabled", false]],
+    }],
+    ["Test on HTML about:addons", {
+      set: [["extensions.htmlaboutaddons.enabled", true]],
+    }],
+  ], async () => {
+    let aManager = await open_manager("addons://list/plugin");
+    info("Part 1");
+    is_in_list(aManager, "addons://list/plugin", false, false);
 
-  await close_manager(aManager);
-  aManager = await open_manager(null);
-  info("Part 2");
-  is_in_list(aManager, "addons://list/plugin", false, false);
+    await close_manager(aManager);
+    aManager = await open_manager(null);
+    info("Part 2");
+    is_in_list(aManager, "addons://list/plugin", false, false);
 
-  close_manager(aManager, run_next_test);
+    await close_manager(aManager);
+  });
 });
 
 // Tests that navigating the discovery page works when that was the first view
-add_test(async function() {
-  let aManager = await open_manager("addons://discover/");
-  info("1");
-  is_in_discovery(aManager, MAIN_URL, false, false);
+add_task(async function test_discopane_first_history_entry() {
+  await runTestOnPrefEnvs([
+    ["Test on XUL about:addons", {
+      set: [
+        ["extensions.htmlaboutaddons.enabled", false],
+        ["extensions.htmlaboutaddons.discover.enabled", false],
+      ],
+    }],
+    ["Test on HTML about:addons", {
+      set: [
+        ["extensions.htmlaboutaddons.enabled", true],
+        ["extensions.htmlaboutaddons.discover.enabled", true],
+        ["extensions.getAddons.discovery.api_url", DISCOAPI_URL],
+      ],
+    }],
+  ], async () => {
+    let aManager = await open_manager("addons://discover/");
+    info("1");
+    is_in_discovery(aManager, MAIN_URL, false, false);
 
-  await clickLink(aManager, "link-good");
-  info("2");
-  is_in_discovery(aManager, SECOND_URL, true, false);
+    let waitLoaded;
+    const isLegacyDiscoPane = !Services.prefs.getBoolPref("extensions.htmlaboutaddons.discover.enabled");
 
-  // Execute go_back only after waitForLoad() has had a chance to setup
-  // its listeners.
-  executeSoon(go_back);
-
-  await waitForLoad(aManager);
-  info("3");
-  is_in_discovery(aManager, MAIN_URL, false, true);
+    if (isLegacyDiscoPane) {
+      // This is a test for an old version of the discovery panel that was actually
+      // navigating links, skip if using the HTML about:addons.
+      await clickLink(aManager, "link-good");
+      info("2");
+      is_in_discovery(aManager, SECOND_URL, true, false);
 
-  // Execute go_forward only after waitForLoad() has had a chance to setup
-  // its listeners.
-  executeSoon(go_forward);
+      waitLoaded = waitForLoad(aManager);
+      // Execute go_back only after waitForLoad() has had a chance to setup
+      // its listeners.
+      executeSoon(go_back);
+      info("3");
+      await waitLoaded;
+      is_in_discovery(aManager, MAIN_URL, false, true);
 
-  await waitForLoad(aManager);
-  is_in_discovery(aManager, SECOND_URL, true, false);
+      // Execute go_forward only after waitForLoad() has had a chance to setup
+      // its listeners.
+      waitLoaded = waitForLoad(aManager);
+      executeSoon(go_forward);
 
-  EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-plugin"), { }, aManager);
+      await waitLoaded;
+      is_in_discovery(aManager, SECOND_URL, true, false);
+    }
 
-  aManager = await wait_for_view_load(aManager);
-  is_in_list(aManager, "addons://list/plugin", true, false);
+    EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-plugin"), { }, aManager);
 
-  go_back();
+    aManager = await wait_for_view_load(aManager);
+    is_in_list(aManager, "addons://list/plugin", true, false);
 
-  aManager = await wait_for_view_load(aManager);
-  is_in_discovery(aManager, SECOND_URL, true, true);
+    if (isLegacyDiscoPane) {
+      go_back();
+
+      aManager = await wait_for_view_load(aManager);
+      is_in_discovery(aManager, SECOND_URL, true, true);
 
-  go_back();
+      waitLoaded = waitForLoad(aManager);
+    }
 
-  await waitForLoad(aManager);
-  is_in_discovery(aManager, MAIN_URL, false, true);
+    go_back();
+    await waitLoaded;
+    aManager = await wait_for_view_load(aManager);
 
-  close_manager(aManager, run_next_test);
+    is_in_discovery(aManager, MAIN_URL, false, true);
+
+    await close_manager(aManager);
+  });
 });
 
 // Tests that navigating the discovery page works when that was the second view
-add_test(async function() {
-  let aManager = await open_manager("addons://list/plugin");
-  is_in_list(aManager, "addons://list/plugin", false, false);
-
-  EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-discover"), { }, aManager);
+add_task(async function test_discopane_second_history_entry() {
+  await runTestOnPrefEnvs([
+    ["Test on XUL about:addons", {
+      set: [
+        ["extensions.htmlaboutaddons.enabled", false],
+        ["extensions.htmlaboutaddons.discover.enabled", false],
+      ],
+    }],
+    ["Test on HTML about:addons", {
+      set: [
+        ["extensions.htmlaboutaddons.enabled", true],
+        ["extensions.htmlaboutaddons.discover.enabled", true],
+        ["extensions.getAddons.discovery.api_url", DISCOAPI_URL],
+      ],
+    }],
+  ], async () => {
+    let aManager = await open_manager("addons://list/plugin");
+    is_in_list(aManager, "addons://list/plugin", false, false);
 
-  aManager = await wait_for_view_load(aManager);
-  is_in_discovery(aManager, MAIN_URL, true, false);
-
-  await clickLink(aManager, "link-good");
-  is_in_discovery(aManager, SECOND_URL, true, false);
+    EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-discover"), { }, aManager);
 
-  // Execute go_back only after waitForLoad() has had a chance to setup
-  // its listeners.
-  executeSoon(go_back);
+    aManager = await wait_for_view_load(aManager);
+    is_in_discovery(aManager, MAIN_URL, true, false);
+
+    const isLegacyDiscoPane = !Services.prefs.getBoolPref("extensions.htmlaboutaddons.discover.enabled");
 
-  await waitForLoad(aManager);
-  is_in_discovery(aManager, MAIN_URL, true, true);
+    // This is a test for an old version of the discovery panel that was actually
+    // navigating links.
+    if (isLegacyDiscoPane) {
+      await clickLink(aManager, "link-good");
+      is_in_discovery(aManager, SECOND_URL, true, false);
 
-  // Execute go_forward only after waitForLoad() has had a chance to setup
-  // its listeners.
-  executeSoon(go_forward);
+      // Execute go_back only after waitForLoad() has had a chance to setup
+      // its listeners.
+      executeSoon(go_back);
+
+      await waitForLoad(aManager);
+      is_in_discovery(aManager, MAIN_URL, true, true);
 
-  await waitForLoad(aManager);
-  is_in_discovery(aManager, SECOND_URL, true, false);
+      // Execute go_forward only after waitForLoad() has had a chance to setup
+      // its listeners.
+      executeSoon(go_forward);
 
-  EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-plugin"), { }, aManager);
+      await waitForLoad(aManager);
+      is_in_discovery(aManager, SECOND_URL, true, false);
+    }
 
-  aManager = await wait_for_view_load(aManager);
-  is_in_list(aManager, "addons://list/plugin", true, false);
+    EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-plugin"), { }, aManager);
+
+    aManager = await wait_for_view_load(aManager);
+    is_in_list(aManager, "addons://list/plugin", true, false);
 
-  go_back();
+    if (isLegacyDiscoPane) {
+      go_back();
+
+      aManager = await wait_for_view_load(aManager);
+      is_in_discovery(aManager, SECOND_URL, true, true);
 
-  aManager = await wait_for_view_load(aManager);
-  is_in_discovery(aManager, SECOND_URL, true, true);
+      go_back();
 
-  go_back();
+      await waitForLoad(aManager);
+      is_in_discovery(aManager, MAIN_URL, true, true);
 
-  await waitForLoad(aManager);
-  is_in_discovery(aManager, MAIN_URL, true, true);
+      go_back();
 
-  go_back();
+      aManager = await wait_for_view_load(aManager);
+      is_in_list(aManager, "addons://list/plugin", false, true);
+
+      go_forward();
 
-  aManager = await wait_for_view_load(aManager);
-  is_in_list(aManager, "addons://list/plugin", false, true);
+      aManager = await wait_for_view_load(aManager);
+      is_in_discovery(aManager, MAIN_URL, true, true);
 
-  go_forward();
+      // Execute go_forward only after waitForLoad() has had a chance to setup
+      // its listeners.
+      executeSoon(go_forward);
 
-  aManager = await wait_for_view_load(aManager);
-  is_in_discovery(aManager, MAIN_URL, true, true);
+      await waitForLoad(aManager);
+      is_in_discovery(aManager, SECOND_URL, true, true);
+    } else {
+      go_back();
 
-  // Execute go_forward only after waitForLoad() has had a chance to setup
-  // its listeners.
-  executeSoon(go_forward);
+      aManager = await wait_for_view_load(aManager);
+      is_in_discovery(aManager, MAIN_URL, true, true);
+
+      go_back();
 
-  await waitForLoad(aManager);
-  is_in_discovery(aManager, SECOND_URL, true, true);
+      aManager = await wait_for_view_load(aManager);
+      is_in_list(aManager, "addons://list/plugin", false, true);
+    }
 
-  close_manager(aManager, run_next_test);
+    await close_manager(aManager);
+  });
 });
 
-// Tests that refreshing the disicovery pane integrates properly with history
-add_test(async function() {
-  let aManager = await open_manager("addons://list/plugin");
-  is_in_list(aManager, "addons://list/plugin", false, false);
+// Tests that refreshing the discovery pane integrates properly with history
+add_task(async function test_legacy_discopane_history_navigation() {
+  await runTestOnPrefEnvs([
+    ["Test on XUL about:addons", {
+      set: [
+        ["extensions.htmlaboutaddons.enabled", false],
+        ["extensions.htmlaboutaddons.discover.enabled", false],
+      ],
+    }],
+  ], async () => {
+    let aManager = await open_manager("addons://list/plugin");
 
-  EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-discover"), { }, aManager);
+    is_in_list(aManager, "addons://list/plugin", false, false);
 
-  aManager = await wait_for_view_load(aManager);
-  is_in_discovery(aManager, MAIN_URL, true, false);
+    EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-discover"), { }, aManager);
 
-  await clickLink(aManager, "link-good");
-  is_in_discovery(aManager, SECOND_URL, true, false);
+    aManager = await wait_for_view_load(aManager);
+    is_in_discovery(aManager, MAIN_URL, true, false);
 
-  EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-discover"), { }, aManager);
+    await clickLink(aManager, "link-good");
+    is_in_discovery(aManager, SECOND_URL, true, false);
+
+    EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-discover"), { }, aManager);
 
-  await waitForLoad(aManager);
-  is_in_discovery(aManager, MAIN_URL, true, false);
-
-  go_back();
+    await waitForLoad(aManager);
+    is_in_discovery(aManager, MAIN_URL, true, false);
 
-  await waitForLoad(aManager);
-  is_in_discovery(aManager, SECOND_URL, true, true);
+    go_back();
 
-  go_back();
+    await waitForLoad(aManager);
+    is_in_discovery(aManager, SECOND_URL, true, true);
 
-  await waitForLoad(aManager);
-  is_in_discovery(aManager, MAIN_URL, true, true);
+    go_back();
 
-  go_back();
+    await waitForLoad(aManager);
+    is_in_discovery(aManager, MAIN_URL, true, true);
+
+    go_back();
 
-  aManager = await wait_for_view_load(aManager);
-  is_in_list(aManager, "addons://list/plugin", false, true);
+    aManager = await wait_for_view_load(aManager);
+    is_in_list(aManager, "addons://list/plugin", false, true);
 
-  go_forward();
+    go_forward();
 
-  aManager = await wait_for_view_load(aManager);
-  is_in_discovery(aManager, MAIN_URL, true, true);
+    aManager = await wait_for_view_load(aManager);
+    is_in_discovery(aManager, MAIN_URL, true, true);
 
-  // Execute go_forward only after waitForLoad() has had a chance to setup
-  // its listeners.
-  executeSoon(go_forward);
+    // Execute go_forward only after waitForLoad() has had a chance to setup
+    // its listeners.
+    executeSoon(go_forward);
 
-  await waitForLoad(aManager);
-  is_in_discovery(aManager, SECOND_URL, true, true);
+    await waitForLoad(aManager);
+    is_in_discovery(aManager, SECOND_URL, true, true);
 
-  // Execute go_forward only after waitForLoad() has had a chance to setup
-  // its listeners.
-  executeSoon(go_forward);
+    // Execute go_forward only after waitForLoad() has had a chance to setup
+    // its listeners.
+    executeSoon(go_forward);
 
-  await waitForLoad(aManager);
-  is_in_discovery(aManager, MAIN_URL, true, false);
+    await waitForLoad(aManager);
+    is_in_discovery(aManager, MAIN_URL, true, false);
 
-  close_manager(aManager, run_next_test);
+    await close_manager(aManager);
+  });
 });
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/browser/discovery/api_response_empty.json
@@ -0,0 +1,1 @@
+{"results": []}