123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415 |
- const {CFRPageActions} =
- ChromeUtils.import("resource://activity-stream/lib/CFRPageActions.jsm");
- const {ASRouterTriggerListeners} =
- ChromeUtils.import("resource://activity-stream/lib/ASRouterTriggerListeners.jsm");
- const {ASRouter} =
- ChromeUtils.import("resource://activity-stream/lib/ASRouter.jsm");
- const createDummyRecommendation = ({action, category, heading_text}) => ({
- content: {
- category,
- notification_text: "Mochitest",
- heading_text: heading_text || "Mochitest",
- info_icon: {
- label: {attributes: {tooltiptext: "Why am I seeing this"}},
- sumo_path: "extensionrecommendations",
- },
- addon: {
- id: "addon-id",
- title: "Addon name",
- icon: "foo",
- author: "Author name",
- amo_url: "https://example.com",
- },
- descriptionDetails: {steps: []},
- text: "Mochitest",
- buttons: {
- primary: {
- label: {
- value: "OK",
- attributes: {accesskey: "O"},
- },
- action: {
- type: action.type,
- data: {},
- },
- },
- secondary: [{
- label: {
- value: "Cancel",
- attributes: {accesskey: "C"},
- },
- }, {
- label: {
- value: "Cancel 1",
- attributes: {accesskey: "A"},
- },
- }, {
- label: {
- value: "Cancel 2",
- attributes: {accesskey: "B"},
- },
- }],
- },
- },
- });
- function checkCFRFeaturesElements(notification) {
- Assert.ok(notification.hidden === false, "Panel should be visible");
- Assert.ok(notification.getAttribute("data-notification-category") === "cfrFeatures", "Panel have corret data attribute");
- Assert.ok(notification.querySelector("#cfr-notification-footer-pintab-animation-container"), "Pin tab animation exists");
- Assert.ok(notification.querySelector("#cfr-notification-feature-steps"), "Pin tab steps");
- }
- function checkCFRAddonsElements(notification) {
- Assert.ok(notification.hidden === false, "Panel should be visible");
- Assert.ok(notification.getAttribute("data-notification-category") === "cfrAddons", "Panel have corret data attribute");
- Assert.ok(notification.querySelector("#cfr-notification-footer-text-and-addon-info"), "Panel should have addon info container");
- Assert.ok(notification.querySelector("#cfr-notification-footer-filled-stars"), "Panel should have addon rating info");
- Assert.ok(notification.querySelector("#cfr-notification-author"), "Panel should have author info");
- }
- function clearNotifications() {
- for (let notification of PopupNotifications._currentNotifications) {
- notification.remove();
- }
- // Clicking the primary action also removes the notification
- Assert.equal(PopupNotifications._currentNotifications.length, 0,
- "Should have removed the notification");
- }
- function trigger_cfr_panel(browser, trigger, {action = {type: "FOO"}, heading_text, category = "cfrAddons"} = {}) { // a fake action type will result in the action being ignored
- const recommendation = createDummyRecommendation({action, category, heading_text});
- if (category !== "cfrAddons") {
- delete recommendation.content.addon;
- }
- clearNotifications();
- return CFRPageActions.addRecommendation(
- browser,
- trigger,
- recommendation,
- // Use the real AS dispatch method to trigger real notifications
- ASRouter.dispatch
- );
- }
- add_task(async function setup() {
- // Store it in order to restore to the original value
- const {_fetchLatestAddonVersion} = CFRPageActions;
- // Prevent fetching the real addon url and making a network request
- CFRPageActions._fetchLatestAddonVersion = x => "http://example.com";
- registerCleanupFunction(() => {
- CFRPageActions._fetchLatestAddonVersion = _fetchLatestAddonVersion;
- });
- });
- add_task(async function test_cfr_notification_show() {
- // addRecommendation checks that scheme starts with http and host matches
- let browser = gBrowser.selectedBrowser;
- await BrowserTestUtils.loadURI(browser, "http://example.com/");
- await BrowserTestUtils.browserLoaded(browser, false, "http://example.com/");
- const response = await trigger_cfr_panel(browser, "example.com");
- Assert.ok(response, "Should return true if addRecommendation checks were successful");
- const showPanel = BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
- // Open the panel
- document.getElementById("contextual-feature-recommendation").click();
- await showPanel;
- Assert.ok(document.getElementById("contextual-feature-recommendation-notification").hidden === false,
- "Panel should be visible");
- // Check there is a primary button and click it. It will trigger the callback.
- Assert.ok(document.getElementById("contextual-feature-recommendation-notification").button);
- let hidePanel = BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden");
- document.getElementById("contextual-feature-recommendation-notification").button.click();
- await hidePanel;
- // Clicking the primary action also removes the notification
- Assert.equal(PopupNotifications._currentNotifications.length, 0,
- "Should have removed the notification");
- });
- add_task(async function test_cfr_notification_show() {
- // addRecommendation checks that scheme starts with http and host matches
- let browser = gBrowser.selectedBrowser;
- await BrowserTestUtils.loadURI(browser, "http://example.com/");
- await BrowserTestUtils.browserLoaded(browser, false, "http://example.com/");
- let response = await trigger_cfr_panel(browser, "example.com", {heading_text: "First Message"});
- Assert.ok(response, "Should return true if addRecommendation checks were successful");
- const showPanel = BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
- // Try adding another message
- response = await trigger_cfr_panel(browser, "example.com", {heading_text: "Second Message"});
- Assert.equal(response, false, "Should return false if second call did not add the message");
- // Open the panel
- document.getElementById("contextual-feature-recommendation").click();
- await showPanel;
- Assert.ok(document.getElementById("contextual-feature-recommendation-notification").hidden === false,
- "Panel should be visible");
- Assert.equal(document.getElementById("cfr-notification-header-label").value, "First Message",
- "The first message should be visible");
- // Check there is a primary button and click it. It will trigger the callback.
- Assert.ok(document.getElementById("contextual-feature-recommendation-notification").button);
- let hidePanel = BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden");
- document.getElementById("contextual-feature-recommendation-notification").button.click();
- await hidePanel;
- // Clicking the primary action also removes the notification
- Assert.equal(PopupNotifications._currentNotifications.length, 0,
- "Should have removed the notification");
- });
- add_task(async function test_cfr_addon_install() {
- // addRecommendation checks that scheme starts with http and host matches
- const browser = gBrowser.selectedBrowser;
- await BrowserTestUtils.loadURI(browser, "http://example.com/");
- await BrowserTestUtils.browserLoaded(browser, false, "http://example.com/");
- const response = await trigger_cfr_panel(browser, "example.com", {action: {type: "INSTALL_ADDON_FROM_URL"}});
- Assert.ok(response, "Should return true if addRecommendation checks were successful");
- const showPanel = BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
- // Open the panel
- document.getElementById("contextual-feature-recommendation").click();
- await showPanel;
- Assert.ok(document.getElementById("contextual-feature-recommendation-notification").hidden === false,
- "Panel should be visible");
- checkCFRAddonsElements(document.getElementById("contextual-feature-recommendation-notification"));
- // Check there is a primary button and click it. It will trigger the callback.
- Assert.ok(document.getElementById("contextual-feature-recommendation-notification").button);
- const hidePanel = BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden");
- document.getElementById("contextual-feature-recommendation-notification").button.click();
- await hidePanel;
- await BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
- let [notification] = PopupNotifications.panel.childNodes;
- // Trying to install the addon will trigger a progress popup or an error popup if
- // running the test multiple times in a row
- Assert.ok(notification.id === "addon-progress-notification" ||
- notification.id === "addon-install-failed-notification", "Should try to install the addon");
- // This removes the `Addon install failure` notifications
- while (PopupNotifications._currentNotifications.length) {
- PopupNotifications.remove(PopupNotifications._currentNotifications[0]);
- }
- // There should be no more notifications left
- Assert.equal(PopupNotifications._currentNotifications.length, 0,
- "Should have removed the notification");
- });
- add_task(async function test_cfr_pin_tab_notification_show() {
- // addRecommendation checks that scheme starts with http and host matches
- let browser = gBrowser.selectedBrowser;
- await BrowserTestUtils.loadURI(browser, "http://example.com/");
- await BrowserTestUtils.browserLoaded(browser, false, "http://example.com/");
- const response = await trigger_cfr_panel(browser, "example.com", {action: {type: "PIN_CURRENT_TAB"}, category: "cfrFeatures"});
- Assert.ok(response, "Should return true if addRecommendation checks were successful");
- const showPanel = BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
- // Open the panel
- document.getElementById("contextual-feature-recommendation").click();
- await showPanel;
- const notification = document.getElementById("contextual-feature-recommendation-notification");
- checkCFRFeaturesElements(notification);
- // Check there is a primary button and click it. It will trigger the callback.
- Assert.ok(notification.button);
- let hidePanel = BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden");
- document.getElementById("contextual-feature-recommendation-notification").button.click();
- await hidePanel;
- await BrowserTestUtils.waitForCondition(() => gBrowser.selectedTab.pinned, "Primary action should pin tab");
- Assert.ok(gBrowser.selectedTab.pinned, "Current tab should be pinned");
- gBrowser.unpinTab(gBrowser.selectedTab);
- // Clicking the primary action also removes the notification
- Assert.equal(PopupNotifications._currentNotifications.length, 0,
- "Should have removed the notification");
- });
- add_task(async function test_cfr_features_and_addon_show() {
- // addRecommendation checks that scheme starts with http and host matches
- let browser = gBrowser.selectedBrowser;
- await BrowserTestUtils.loadURI(browser, "http://example.com/");
- await BrowserTestUtils.browserLoaded(browser, false, "http://example.com/");
- // Trigger Feature CFR
- let response = await trigger_cfr_panel(browser, "example.com", {action: {type: "PIN_CURRENT_TAB"}, category: "cfrFeatures"});
- Assert.ok(response, "Should return true if addRecommendation checks were successful");
- let showPanel = BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
- // Open the panel
- document.getElementById("contextual-feature-recommendation").click();
- await showPanel;
- const notification = document.getElementById("contextual-feature-recommendation-notification");
- checkCFRFeaturesElements(notification);
- // Check there is a primary button and click it. It will trigger the callback.
- Assert.ok(notification.button);
- let hidePanel = BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden");
- document.getElementById("contextual-feature-recommendation-notification").button.click();
- await hidePanel;
- // Clicking the primary action also removes the notification
- Assert.equal(PopupNotifications._currentNotifications.length, 0,
- "Should have removed the notification");
- // Trigger Addon CFR
- response = await trigger_cfr_panel(browser, "example.com");
- Assert.ok(response, "Should return true if addRecommendation checks were successful");
- showPanel = BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
- // Open the panel
- document.getElementById("contextual-feature-recommendation").click();
- await showPanel;
- Assert.ok(document.getElementById("contextual-feature-recommendation-notification").hidden === false,
- "Panel should be visible");
- checkCFRAddonsElements(document.getElementById("contextual-feature-recommendation-notification"));
- // Check there is a primary button and click it. It will trigger the callback.
- Assert.ok(notification.button);
- hidePanel = BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden");
- document.getElementById("contextual-feature-recommendation-notification").button.click();
- await hidePanel;
- // Clicking the primary action also removes the notification
- Assert.equal(PopupNotifications._currentNotifications.length, 0,
- "Should have removed the notification");
- });
- add_task(async function test_cfr_addon_and_features_show() {
- // addRecommendation checks that scheme starts with http and host matches
- let browser = gBrowser.selectedBrowser;
- await BrowserTestUtils.loadURI(browser, "http://example.com/");
- await BrowserTestUtils.browserLoaded(browser, false, "http://example.com/");
- // Trigger Feature CFR
- let response = await trigger_cfr_panel(browser, "example.com");
- Assert.ok(response, "Should return true if addRecommendation checks were successful");
- let showPanel = BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
- // Open the panel
- document.getElementById("contextual-feature-recommendation").click();
- await showPanel;
- const notification = document.getElementById("contextual-feature-recommendation-notification");
- checkCFRAddonsElements(notification);
- // Check there is a primary button and click it. It will trigger the callback.
- Assert.ok(notification.button);
- let hidePanel = BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden");
- document.getElementById("contextual-feature-recommendation-notification").button.click();
- await hidePanel;
- // Clicking the primary action also removes the notification
- Assert.equal(PopupNotifications._currentNotifications.length, 0,
- "Should have removed the notification");
- // Trigger Addon CFR
- response = await trigger_cfr_panel(browser, "example.com", {action: {type: "PIN_CURRENT_TAB"}, category: "cfrFeatures"});
- Assert.ok(response, "Should return true if addRecommendation checks were successful");
- showPanel = BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
- // Open the panel
- document.getElementById("contextual-feature-recommendation").click();
- await showPanel;
- Assert.ok(document.getElementById("contextual-feature-recommendation-notification").hidden === false,
- "Panel should be visible");
- checkCFRFeaturesElements(document.getElementById("contextual-feature-recommendation-notification"));
- // Check there is a primary button and click it. It will trigger the callback.
- Assert.ok(notification.button);
- hidePanel = BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden");
- document.getElementById("contextual-feature-recommendation-notification").button.click();
- await hidePanel;
- // Clicking the primary action also removes the notification
- Assert.equal(PopupNotifications._currentNotifications.length, 0,
- "Should have removed the notification");
- });
- add_task(async function test_onLocationChange_cb() {
- let count = 0;
- const triggerHandler = () => ++count;
- const TEST_URL = "https://example.com/browser/browser/components/newtab/test/browser/blue_page.html";
- ASRouterTriggerListeners.get("openURL").init(triggerHandler, ["example.com"]);
- const browser = gBrowser.selectedBrowser;
- await BrowserTestUtils.loadURI(browser, "http://example.com/");
- await BrowserTestUtils.browserLoaded(browser, false, "http://example.com/");
- Assert.equal(count, 1, "Count navigation to example.com");
- // Anchor scroll triggers a location change event with the same document
- // https://searchfox.org/mozilla-central/rev/8848b9741fc4ee4e9bc3ae83ea0fc048da39979f/uriloader/base/nsIWebProgressListener.idl#400-403
- await BrowserTestUtils.loadURI(browser, "http://example.com/#foo");
- await BrowserTestUtils.waitForLocationChange(gBrowser, "http://example.com/#foo");
- Assert.equal(count, 1, "It should ignore same page navigation");
- await BrowserTestUtils.loadURI(browser, TEST_URL);
- await BrowserTestUtils.browserLoaded(browser, false, TEST_URL);
- Assert.equal(count, 2, "We moved to a new document");
- });
- add_task(async function test_matchPattern() {
- let count = 0;
- const triggerHandler = () => ++count;
- const frequentVisitsTrigger = ASRouterTriggerListeners.get("frequentVisits");
- frequentVisitsTrigger.init(triggerHandler, [], ["*://*.example.com/"]);
- const browser = gBrowser.selectedBrowser;
- await BrowserTestUtils.loadURI(browser, "http://example.com/");
- await BrowserTestUtils.browserLoaded(browser, false, "http://example.com/");
- await BrowserTestUtils.waitForCondition(() => frequentVisitsTrigger._visits.get("example.com").length === 1, "Registered pattern matched the current location");
- await BrowserTestUtils.loadURI(browser, "about:config");
- await BrowserTestUtils.browserLoaded(browser, false, "about:config");
- await BrowserTestUtils.waitForCondition(() => frequentVisitsTrigger._visits.get("example.com").length === 1, "Navigated to a new page but not a match");
- await BrowserTestUtils.loadURI(browser, "http://example.com/");
- await BrowserTestUtils.browserLoaded(browser, false, "http://example.com/");
- await BrowserTestUtils.waitForCondition(() => frequentVisitsTrigger._visits.get("example.com").length === 1, "Navigated to a location that matches the pattern but within 15 mins");
- await BrowserTestUtils.loadURI(browser, "http://www.example.com/");
- await BrowserTestUtils.browserLoaded(browser, false, "http://www.example.com/");
- await BrowserTestUtils.waitForCondition(() => frequentVisitsTrigger._visits.get("www.example.com").length === 1, "www.example.com is a different host that also matches the pattern.");
- await BrowserTestUtils.waitForCondition(() => frequentVisitsTrigger._visits.get("example.com").length === 1, "www.example.com is a different host that also matches the pattern.");
- });
- add_task(async function test_providerNames() {
- const providersBranch = "browser.newtabpage.activity-stream.asrouter.providers.";
- const cfrProviderPrefs = Services.prefs.getChildList(providersBranch);
- for (const prefName of cfrProviderPrefs) {
- const prefValue = JSON.parse(Services.prefs.getStringPref(prefName));
- if (prefValue.id) { // Snippets are disabled in tests and value is set to []
- Assert.equal(prefValue.id, prefName.slice(providersBranch.length), "Provider id and pref name do not match");
- }
- }
- });
|