diff options
Diffstat (limited to 'browser/components/uitour')
32 files changed, 0 insertions, 3534 deletions
diff --git a/browser/components/uitour/test/.eslintrc.js b/browser/components/uitour/test/.eslintrc.js deleted file mode 100644 index c764b133d..000000000 --- a/browser/components/uitour/test/.eslintrc.js +++ /dev/null @@ -1,7 +0,0 @@ -"use strict"; - -module.exports = { - "extends": [ - "../../../../testing/mochitest/browser.eslintrc.js" - ] -}; diff --git a/browser/components/uitour/test/browser.ini b/browser/components/uitour/test/browser.ini deleted file mode 100644 index ae027a738..000000000 --- a/browser/components/uitour/test/browser.ini +++ /dev/null @@ -1,49 +0,0 @@ -[DEFAULT] -support-files = - head.js - image.png - uitour.html - ../UITour-lib.js - -[browser_backgroundTab.js] -[browser_closeTab.js] -[browser_fxa.js] -skip-if = debug || asan # updateAppMenuItem leaks -[browser_no_tabs.js] -[browser_openPreferences.js] -[browser_openSearchPanel.js] -skip-if = true # Bug 1113038 - Intermittent "Popup was opened" -[browser_trackingProtection.js] -skip-if = os == "linux" # Intermittent NS_ERROR_NOT_AVAILABLE [nsIUrlClassifierDBService.beginUpdate] -tag = trackingprotection -support-files = - !/browser/base/content/test/general/benignPage.html - !/browser/base/content/test/general/trackingPage.html -[browser_trackingProtection_tour.js] -tag = trackingprotection -[browser_showMenu_controlCenter.js] -tag = trackingprotection -[browser_UITour.js] -skip-if = os == "linux" # Intermittent failures, bug 951965 -[browser_UITour2.js] -[browser_UITour3.js] -skip-if = os == "linux" # Linux: Bug 986760, Bug 989101. -[browser_UITour_availableTargets.js] -[browser_UITour_annotation_size_attributes.js] -[browser_UITour_defaultBrowser.js] -[browser_UITour_detach_tab.js] -[browser_UITour_forceReaderMode.js] -[browser_UITour_heartbeat.js] -skip-if = os == "win" # Bug 1277107 -[browser_UITour_modalDialog.js] -skip-if = os != "mac" # modal dialog disabling only working on OS X. -[browser_UITour_observe.js] -[browser_UITour_panel_close_annotation.js] -skip-if = true # Disabled due to frequent failures, bugs 1026310 and 1032137 -[browser_UITour_pocket.js] -skip-if = true # Disabled pending removal of pocket UI Tour -[browser_UITour_registerPageID.js] -[browser_UITour_resetProfile.js] -[browser_UITour_showNewTab.js] -[browser_UITour_sync.js] -[browser_UITour_toggleReaderMode.js] diff --git a/browser/components/uitour/test/browser_UITour.js b/browser/components/uitour/test/browser_UITour.js deleted file mode 100644 index 964be0215..000000000 --- a/browser/components/uitour/test/browser_UITour.js +++ /dev/null @@ -1,408 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -var gTestTab; -var gContentAPI; -var gContentWindow; - -Components.utils.import("resource://testing-common/TelemetryArchiveTesting.jsm", this); - -function test() { - UITourTest(); -} - -var tests = [ - function test_untrusted_host(done) { - loadUITourTestPage(function() { - let bookmarksMenu = document.getElementById("bookmarks-menu-button"); - is(bookmarksMenu.open, false, "Bookmark menu should initially be closed"); - - gContentAPI.showMenu("bookmarks"); - is(bookmarksMenu.open, false, "Bookmark menu should not open on a untrusted host"); - - done(); - }, "http://mochi.test:8888/"); - }, - function test_testing_host(done) { - // Add two testing origins intentionally surrounded by whitespace to be ignored. - Services.prefs.setCharPref("browser.uitour.testingOrigins", - "https://test1.example.org, https://test2.example.org:443 "); - - registerCleanupFunction(() => { - Services.prefs.clearUserPref("browser.uitour.testingOrigins"); - }); - function callback(result) { - ok(result, "Callback should be called on a testing origin"); - done(); - } - - loadUITourTestPage(function() { - gContentAPI.getConfiguration("appinfo", callback); - }, "https://test2.example.org/"); - }, - function test_unsecure_host(done) { - loadUITourTestPage(function() { - let bookmarksMenu = document.getElementById("bookmarks-menu-button"); - is(bookmarksMenu.open, false, "Bookmark menu should initially be closed"); - - gContentAPI.showMenu("bookmarks"); - is(bookmarksMenu.open, false, "Bookmark menu should not open on a unsecure host"); - - done(); - }, "http://example.org/"); - }, - function test_unsecure_host_override(done) { - Services.prefs.setBoolPref("browser.uitour.requireSecure", false); - loadUITourTestPage(function() { - let highlight = document.getElementById("UITourHighlight"); - is_element_hidden(highlight, "Highlight should initially be hidden"); - - gContentAPI.showHighlight("urlbar"); - waitForElementToBeVisible(highlight, done, "Highlight should be shown on a unsecure host when override pref is set"); - - Services.prefs.setBoolPref("browser.uitour.requireSecure", true); - }, "http://example.org/"); - }, - function test_disabled(done) { - Services.prefs.setBoolPref("browser.uitour.enabled", false); - - let bookmarksMenu = document.getElementById("bookmarks-menu-button"); - is(bookmarksMenu.open, false, "Bookmark menu should initially be closed"); - - gContentAPI.showMenu("bookmarks"); - is(bookmarksMenu.open, false, "Bookmark menu should not open when feature is disabled"); - - Services.prefs.setBoolPref("browser.uitour.enabled", true); - done(); - }, - function test_highlight(done) { - function test_highlight_2() { - let highlight = document.getElementById("UITourHighlight"); - gContentAPI.hideHighlight(); - - waitForElementToBeHidden(highlight, test_highlight_3, "Highlight should be hidden after hideHighlight()"); - } - function test_highlight_3() { - is_element_hidden(highlight, "Highlight should be hidden after hideHighlight()"); - - gContentAPI.showHighlight("urlbar"); - waitForElementToBeVisible(highlight, test_highlight_4, "Highlight should be shown after showHighlight()"); - } - function test_highlight_4() { - let highlight = document.getElementById("UITourHighlight"); - gContentAPI.showHighlight("backForward"); - waitForElementToBeVisible(highlight, done, "Highlight should be shown after showHighlight()"); - } - - let highlight = document.getElementById("UITourHighlight"); - is_element_hidden(highlight, "Highlight should initially be hidden"); - - gContentAPI.showHighlight("urlbar"); - waitForElementToBeVisible(highlight, test_highlight_2, "Highlight should be shown after showHighlight()"); - }, - function test_highlight_circle(done) { - function check_highlight_size() { - let panel = highlight.parentElement; - let anchor = panel.anchorNode; - let anchorRect = anchor.getBoundingClientRect(); - info("addons target: width: " + anchorRect.width + " height: " + anchorRect.height); - let maxDimension = Math.round(Math.max(anchorRect.width, anchorRect.height)); - let highlightRect = highlight.getBoundingClientRect(); - info("highlight: width: " + highlightRect.width + " height: " + highlightRect.height); - is(Math.round(highlightRect.width), maxDimension, "The width of the highlight should be equal to the largest dimension of the target"); - is(Math.round(highlightRect.height), maxDimension, "The height of the highlight should be equal to the largest dimension of the target"); - is(Math.round(highlightRect.height), Math.round(highlightRect.width), "The height and width of the highlight should be the same to create a circle"); - is(highlight.style.borderRadius, "100%", "The border-radius should be 100% to create a circle"); - done(); - } - let highlight = document.getElementById("UITourHighlight"); - is_element_hidden(highlight, "Highlight should initially be hidden"); - - gContentAPI.showHighlight("addons"); - waitForElementToBeVisible(highlight, check_highlight_size, "Highlight should be shown after showHighlight()"); - }, - function test_highlight_customize_auto_open_close(done) { - let highlight = document.getElementById("UITourHighlight"); - gContentAPI.showHighlight("customize"); - waitForElementToBeVisible(highlight, function checkPanelIsOpen() { - isnot(PanelUI.panel.state, "closed", "Panel should have opened"); - - // Move the highlight outside which should close the app menu. - gContentAPI.showHighlight("appMenu"); - waitForElementToBeVisible(highlight, function checkPanelIsClosed() { - isnot(PanelUI.panel.state, "open", - "Panel should have closed after the highlight moved elsewhere."); - done(); - }, "Highlight should move to the appMenu button"); - }, "Highlight should be shown after showHighlight() for fixed panel items"); - }, - function test_highlight_customize_manual_open_close(done) { - let highlight = document.getElementById("UITourHighlight"); - // Manually open the app menu then show a highlight there. The menu should remain open. - let shownPromise = promisePanelShown(window); - gContentAPI.showMenu("appMenu"); - shownPromise.then(() => { - isnot(PanelUI.panel.state, "closed", "Panel should have opened"); - gContentAPI.showHighlight("customize"); - - waitForElementToBeVisible(highlight, function checkPanelIsStillOpen() { - isnot(PanelUI.panel.state, "closed", "Panel should still be open"); - - // Move the highlight outside which shouldn't close the app menu since it was manually opened. - gContentAPI.showHighlight("appMenu"); - waitForElementToBeVisible(highlight, function () { - isnot(PanelUI.panel.state, "closed", - "Panel should remain open since UITour didn't open it in the first place"); - gContentAPI.hideMenu("appMenu"); - done(); - }, "Highlight should move to the appMenu button"); - }, "Highlight should be shown after showHighlight() for fixed panel items"); - }).then(null, Components.utils.reportError); - }, - function test_highlight_effect(done) { - function waitForHighlightWithEffect(highlightEl, effect, next, error) { - return waitForCondition(() => highlightEl.getAttribute("active") == effect, - next, - error); - } - function checkDefaultEffect() { - is(highlight.getAttribute("active"), "none", "The default should be no effect"); - - gContentAPI.showHighlight("urlbar", "none"); - waitForHighlightWithEffect(highlight, "none", checkZoomEffect, "There should be no effect"); - } - function checkZoomEffect() { - gContentAPI.showHighlight("urlbar", "zoom"); - waitForHighlightWithEffect(highlight, "zoom", () => { - let style = window.getComputedStyle(highlight); - is(style.animationName, "uitour-zoom", "The animation-name should be uitour-zoom"); - checkSameEffectOnDifferentTarget(); - }, "There should be a zoom effect"); - } - function checkSameEffectOnDifferentTarget() { - gContentAPI.showHighlight("appMenu", "wobble"); - waitForHighlightWithEffect(highlight, "wobble", () => { - highlight.addEventListener("animationstart", function onAnimationStart(aEvent) { - highlight.removeEventListener("animationstart", onAnimationStart); - ok(true, "Animation occurred again even though the effect was the same"); - checkRandomEffect(); - }); - gContentAPI.showHighlight("backForward", "wobble"); - }, "There should be a wobble effect"); - } - function checkRandomEffect() { - function waitForActiveHighlight(highlightEl, next, error) { - return waitForCondition(() => highlightEl.hasAttribute("active"), - next, - error); - } - - gContentAPI.hideHighlight(); - gContentAPI.showHighlight("urlbar", "random"); - waitForActiveHighlight(highlight, () => { - ok(highlight.hasAttribute("active"), "The highlight should be active"); - isnot(highlight.getAttribute("active"), "none", "A random effect other than none should have been chosen"); - isnot(highlight.getAttribute("active"), "random", "The random effect shouldn't be 'random'"); - isnot(UITour.highlightEffects.indexOf(highlight.getAttribute("active")), -1, "Check that a supported effect was randomly chosen"); - done(); - }, "There should be an active highlight with a random effect"); - } - - let highlight = document.getElementById("UITourHighlight"); - is_element_hidden(highlight, "Highlight should initially be hidden"); - - gContentAPI.showHighlight("urlbar"); - waitForElementToBeVisible(highlight, checkDefaultEffect, "Highlight should be shown after showHighlight()"); - }, - function test_highlight_effect_unsupported(done) { - function checkUnsupportedEffect() { - is(highlight.getAttribute("active"), "none", "No effect should be used when an unsupported effect is requested"); - done(); - } - - let highlight = document.getElementById("UITourHighlight"); - is_element_hidden(highlight, "Highlight should initially be hidden"); - - gContentAPI.showHighlight("urlbar", "__UNSUPPORTED__"); - waitForElementToBeVisible(highlight, checkUnsupportedEffect, "Highlight should be shown after showHighlight()"); - }, - function test_info_1(done) { - let popup = document.getElementById("UITourTooltip"); - let title = document.getElementById("UITourTooltipTitle"); - let desc = document.getElementById("UITourTooltipDescription"); - let icon = document.getElementById("UITourTooltipIcon"); - let buttons = document.getElementById("UITourTooltipButtons"); - - popup.addEventListener("popupshown", function onPopupShown() { - popup.removeEventListener("popupshown", onPopupShown); - is(popup.popupBoxObject.anchorNode, document.getElementById("urlbar"), "Popup should be anchored to the urlbar"); - is(title.textContent, "test title", "Popup should have correct title"); - is(desc.textContent, "test text", "Popup should have correct description text"); - is(icon.src, "", "Popup should have no icon"); - is(buttons.hasChildNodes(), false, "Popup should have no buttons"); - - popup.addEventListener("popuphidden", function onPopupHidden() { - popup.removeEventListener("popuphidden", onPopupHidden); - - popup.addEventListener("popupshown", function onPopupShown() { - popup.removeEventListener("popupshown", onPopupShown); - done(); - }); - - gContentAPI.showInfo("urlbar", "test title", "test text"); - - }); - gContentAPI.hideInfo(); - }); - - gContentAPI.showInfo("urlbar", "test title", "test text"); - }, - taskify(function* test_info_2() { - let popup = document.getElementById("UITourTooltip"); - let title = document.getElementById("UITourTooltipTitle"); - let desc = document.getElementById("UITourTooltipDescription"); - let icon = document.getElementById("UITourTooltipIcon"); - let buttons = document.getElementById("UITourTooltipButtons"); - - yield showInfoPromise("urlbar", "urlbar title", "urlbar text"); - - is(popup.popupBoxObject.anchorNode, document.getElementById("urlbar"), "Popup should be anchored to the urlbar"); - is(title.textContent, "urlbar title", "Popup should have correct title"); - is(desc.textContent, "urlbar text", "Popup should have correct description text"); - is(icon.src, "", "Popup should have no icon"); - is(buttons.hasChildNodes(), false, "Popup should have no buttons"); - - yield showInfoPromise("search", "search title", "search text"); - - is(popup.popupBoxObject.anchorNode, document.getElementById("searchbar"), "Popup should be anchored to the searchbar"); - is(title.textContent, "search title", "Popup should have correct title"); - is(desc.textContent, "search text", "Popup should have correct description text"); - }), - function test_getConfigurationVersion(done) { - function callback(result) { - let props = ["defaultUpdateChannel", "version"]; - for (let property of props) { - ok(typeof(result[property]) !== "undefined", "Check " + property + " isn't undefined."); - is(result[property], Services.appinfo[property], "Should have the same " + property + " property."); - } - done(); - } - - gContentAPI.getConfiguration("appinfo", callback); - }, - function test_getConfigurationDistribution(done) { - gContentAPI.getConfiguration("appinfo", (result) => { - ok(typeof(result.distribution) !== "undefined", "Check distribution isn't undefined."); - is(result.distribution, "default", "Should be \"default\" without preference set."); - - let defaults = Services.prefs.getDefaultBranch("distribution."); - let testDistributionID = "TestDistribution"; - defaults.setCharPref("id", testDistributionID); - gContentAPI.getConfiguration("appinfo", (result) => { - ok(typeof(result.distribution) !== "undefined", "Check distribution isn't undefined."); - is(result.distribution, testDistributionID, "Should have the distribution as set in preference."); - - done(); - }); - }); - }, - function test_addToolbarButton(done) { - let placement = CustomizableUI.getPlacementOfWidget("panic-button"); - is(placement, null, "default UI has panic button in the palette"); - - gContentAPI.getConfiguration("availableTargets", (data) => { - let available = (data.targets.indexOf("forget") != -1); - ok(!available, "Forget button should not be available by default"); - - gContentAPI.addNavBarWidget("forget", () => { - info("addNavBarWidget callback successfully called"); - - let placement = CustomizableUI.getPlacementOfWidget("panic-button"); - is(placement.area, CustomizableUI.AREA_NAVBAR); - - gContentAPI.getConfiguration("availableTargets", (data) => { - let available = (data.targets.indexOf("forget") != -1); - ok(available, "Forget button should now be available"); - - // Cleanup - CustomizableUI.removeWidgetFromArea("panic-button"); - done(); - }); - }); - }); - }, - function test_search(done) { - Services.search.init(rv => { - if (!Components.isSuccessCode(rv)) { - ok(false, "search service init failed: " + rv); - done(); - return; - } - let defaultEngine = Services.search.defaultEngine; - gContentAPI.getConfiguration("search", data => { - let visibleEngines = Services.search.getVisibleEngines(); - let expectedEngines = visibleEngines.filter((engine) => engine.identifier) - .map((engine) => "searchEngine-" + engine.identifier); - - let engines = data.engines; - ok(Array.isArray(engines), "data.engines should be an array"); - is(engines.sort().toString(), expectedEngines.sort().toString(), - "Engines should be as expected"); - - is(data.searchEngineIdentifier, defaultEngine.identifier, - "the searchEngineIdentifier property should contain the defaultEngine's identifier"); - - let someOtherEngineID = data.engines.filter(t => t != "searchEngine-" + defaultEngine.identifier)[0]; - someOtherEngineID = someOtherEngineID.replace(/^searchEngine-/, ""); - - let observe = function (subject, topic, verb) { - info("browser-search-engine-modified: " + verb); - if (verb == "engine-current") { - is(Services.search.defaultEngine.identifier, someOtherEngineID, "correct engine was switched to"); - done(); - } - }; - Services.obs.addObserver(observe, "browser-search-engine-modified", false); - registerCleanupFunction(() => { - // Clean up - Services.obs.removeObserver(observe, "browser-search-engine-modified"); - Services.search.defaultEngine = defaultEngine; - }); - - gContentAPI.setDefaultSearchEngine(someOtherEngineID); - }); - }); - }, - taskify(function* test_treatment_tag() { - let ac = new TelemetryArchiveTesting.Checker(); - yield ac.promiseInit(); - yield gContentAPI.setTreatmentTag("foobar", "baz"); - // Wait until the treatment telemetry is sent before looking in the archive. - yield BrowserTestUtils.waitForContentEvent(gTestTab.linkedBrowser, "mozUITourNotification", false, - event => event.detail.event === "TreatmentTag:TelemetrySent"); - yield new Promise((resolve) => { - gContentAPI.getTreatmentTag("foobar", (data) => { - is(data.value, "baz", "set and retrieved treatmentTag"); - ac.promiseFindPing("uitour-tag", [ - [["payload", "tagName"], "foobar"], - [["payload", "tagValue"], "baz"], - ]).then((found) => { - ok(found, "Telemetry ping submitted for setTreatmentTag"); - resolve(); - }, (err) => { - ok(false, "Exception finding uitour telemetry ping: " + err); - resolve(); - }); - }); - }); - }), - - // Make sure this test is last in the file so the appMenu gets left open and done will confirm it got tore down. - taskify(function* cleanupMenus() { - let shownPromise = promisePanelShown(window); - gContentAPI.showMenu("appMenu"); - yield shownPromise; - }), -]; diff --git a/browser/components/uitour/test/browser_UITour2.js b/browser/components/uitour/test/browser_UITour2.js deleted file mode 100644 index e74a71afa..000000000 --- a/browser/components/uitour/test/browser_UITour2.js +++ /dev/null @@ -1,83 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -var gTestTab; -var gContentAPI; -var gContentWindow; - -function test() { - UITourTest(); -} - -var tests = [ - function test_info_customize_auto_open_close(done) { - let popup = document.getElementById("UITourTooltip"); - gContentAPI.showInfo("customize", "Customization", "Customize me please!"); - UITour.getTarget(window, "customize").then((customizeTarget) => { - waitForPopupAtAnchor(popup, customizeTarget.node, function checkPanelIsOpen() { - isnot(PanelUI.panel.state, "closed", "Panel should have opened before the popup anchored"); - ok(PanelUI.panel.hasAttribute("noautohide"), "@noautohide on the menu panel should have been set"); - - // Move the info outside which should close the app menu. - gContentAPI.showInfo("appMenu", "Open Me", "You know you want to"); - UITour.getTarget(window, "appMenu").then((target) => { - waitForPopupAtAnchor(popup, target.node, function checkPanelIsClosed() { - isnot(PanelUI.panel.state, "open", - "Panel should have closed after the info moved elsewhere."); - ok(!PanelUI.panel.hasAttribute("noautohide"), "@noautohide on the menu panel should have been cleaned up on close"); - done(); - }, "Info should move to the appMenu button"); - }); - }, "Info panel should be anchored to the customize button"); - }); - }, - function test_info_customize_manual_open_close(done) { - let popup = document.getElementById("UITourTooltip"); - // Manually open the app menu then show an info panel there. The menu should remain open. - let shownPromise = promisePanelShown(window); - gContentAPI.showMenu("appMenu"); - shownPromise.then(() => { - isnot(PanelUI.panel.state, "closed", "Panel should have opened"); - ok(PanelUI.panel.hasAttribute("noautohide"), "@noautohide on the menu panel should have been set"); - gContentAPI.showInfo("customize", "Customization", "Customize me please!"); - - UITour.getTarget(window, "customize").then((customizeTarget) => { - waitForPopupAtAnchor(popup, customizeTarget.node, function checkMenuIsStillOpen() { - isnot(PanelUI.panel.state, "closed", "Panel should still be open"); - ok(PanelUI.panel.hasAttribute("noautohide"), "@noautohide on the menu panel should still be set"); - - // Move the info outside which shouldn't close the app menu since it was manually opened. - gContentAPI.showInfo("appMenu", "Open Me", "You know you want to"); - UITour.getTarget(window, "appMenu").then((target) => { - waitForPopupAtAnchor(popup, target.node, function checkMenuIsStillOpen() { - isnot(PanelUI.panel.state, "closed", - "Menu should remain open since UITour didn't open it in the first place"); - waitForElementToBeHidden(window.PanelUI.panel, () => { - ok(!PanelUI.panel.hasAttribute("noautohide"), "@noautohide on the menu panel should have been cleaned up on close"); - done(); - }); - gContentAPI.hideMenu("appMenu"); - }, "Info should move to the appMenu button"); - }); - }, "Info should be shown after showInfo() for fixed menu panel items"); - }); - }).then(null, Components.utils.reportError); - }, - taskify(function* test_bookmarks_menu() { - let bookmarksMenuButton = document.getElementById("bookmarks-menu-button"); - - is(bookmarksMenuButton.open, false, "Menu should initially be closed"); - gContentAPI.showMenu("bookmarks"); - - yield waitForConditionPromise(() => { - return bookmarksMenuButton.open; - }, "Menu should be visible after showMenu()"); - - gContentAPI.hideMenu("bookmarks"); - yield waitForConditionPromise(() => { - return !bookmarksMenuButton.open; - }, "Menu should be hidden after hideMenu()"); - }), -]; diff --git a/browser/components/uitour/test/browser_UITour3.js b/browser/components/uitour/test/browser_UITour3.js deleted file mode 100644 index b852339f1..000000000 --- a/browser/components/uitour/test/browser_UITour3.js +++ /dev/null @@ -1,181 +0,0 @@ -"use strict"; - -var gTestTab; -var gContentAPI; -var gContentWindow; - -requestLongerTimeout(2); - -add_task(setup_UITourTest); - -add_UITour_task(function* test_info_icon() { - let popup = document.getElementById("UITourTooltip"); - let title = document.getElementById("UITourTooltipTitle"); - let desc = document.getElementById("UITourTooltipDescription"); - let icon = document.getElementById("UITourTooltipIcon"); - let buttons = document.getElementById("UITourTooltipButtons"); - - // Disable the animation to prevent the mouse clicks from hitting the main - // window during the transition instead of the buttons in the popup. - popup.setAttribute("animate", "false"); - - yield showInfoPromise("urlbar", "a title", "some text", "image.png"); - - is(title.textContent, "a title", "Popup should have correct title"); - is(desc.textContent, "some text", "Popup should have correct description text"); - - let imageURL = getRootDirectory(gTestPath) + "image.png"; - imageURL = imageURL.replace("chrome://mochitests/content/", "https://example.org/"); - is(icon.src, imageURL, "Popup should have correct icon shown"); - - is(buttons.hasChildNodes(), false, "Popup should have no buttons"); -}), - -add_UITour_task(function* test_info_buttons_1() { - let popup = document.getElementById("UITourTooltip"); - let title = document.getElementById("UITourTooltipTitle"); - let desc = document.getElementById("UITourTooltipDescription"); - let icon = document.getElementById("UITourTooltipIcon"); - - yield showInfoPromise("urlbar", "another title", "moar text", "./image.png", "makeButtons"); - - is(title.textContent, "another title", "Popup should have correct title"); - is(desc.textContent, "moar text", "Popup should have correct description text"); - - let imageURL = getRootDirectory(gTestPath) + "image.png"; - imageURL = imageURL.replace("chrome://mochitests/content/", "https://example.org/"); - is(icon.src, imageURL, "Popup should have correct icon shown"); - - let buttons = document.getElementById("UITourTooltipButtons"); - is(buttons.childElementCount, 4, "Popup should have four buttons"); - - is(buttons.childNodes[0].nodeName, "label", "Text label should be a <label>"); - is(buttons.childNodes[0].getAttribute("value"), "Regular text", "Text label should have correct value"); - is(buttons.childNodes[0].getAttribute("image"), "", "Text should have no image"); - is(buttons.childNodes[0].className, "", "Text should have no class"); - - is(buttons.childNodes[1].nodeName, "button", "Link should be a <button>"); - is(buttons.childNodes[1].getAttribute("label"), "Link", "Link should have correct label"); - is(buttons.childNodes[1].getAttribute("image"), "", "Link should have no image"); - is(buttons.childNodes[1].className, "button-link", "Check link class"); - - is(buttons.childNodes[2].nodeName, "button", "Button 1 should be a <button>"); - is(buttons.childNodes[2].getAttribute("label"), "Button 1", "First button should have correct label"); - is(buttons.childNodes[2].getAttribute("image"), "", "First button should have no image"); - is(buttons.childNodes[2].className, "", "Button 1 should have no class"); - - is(buttons.childNodes[3].nodeName, "button", "Button 2 should be a <button>"); - is(buttons.childNodes[3].getAttribute("label"), "Button 2", "Second button should have correct label"); - is(buttons.childNodes[3].getAttribute("image"), imageURL, "Second button should have correct image"); - is(buttons.childNodes[3].className, "button-primary", "Check button 2 class"); - - let promiseHidden = promisePanelElementHidden(window, popup); - EventUtils.synthesizeMouseAtCenter(buttons.childNodes[2], {}, window); - yield promiseHidden; - - ok(true, "Popup should close automatically"); - - let returnValue = yield waitForCallbackResultPromise(); - is(returnValue.result, "button1", "Correct callback should have been called"); -}); - -add_UITour_task(function* test_info_buttons_2() { - let popup = document.getElementById("UITourTooltip"); - let title = document.getElementById("UITourTooltipTitle"); - let desc = document.getElementById("UITourTooltipDescription"); - let icon = document.getElementById("UITourTooltipIcon"); - - yield showInfoPromise("urlbar", "another title", "moar text", "./image.png", "makeButtons"); - - is(title.textContent, "another title", "Popup should have correct title"); - is(desc.textContent, "moar text", "Popup should have correct description text"); - - let imageURL = getRootDirectory(gTestPath) + "image.png"; - imageURL = imageURL.replace("chrome://mochitests/content/", "https://example.org/"); - is(icon.src, imageURL, "Popup should have correct icon shown"); - - let buttons = document.getElementById("UITourTooltipButtons"); - is(buttons.childElementCount, 4, "Popup should have four buttons"); - - is(buttons.childNodes[1].getAttribute("label"), "Link", "Link should have correct label"); - is(buttons.childNodes[1].getAttribute("image"), "", "Link should have no image"); - ok(buttons.childNodes[1].classList.contains("button-link"), "Link should have button-link class"); - - is(buttons.childNodes[2].getAttribute("label"), "Button 1", "First button should have correct label"); - is(buttons.childNodes[2].getAttribute("image"), "", "First button should have no image"); - - is(buttons.childNodes[3].getAttribute("label"), "Button 2", "Second button should have correct label"); - is(buttons.childNodes[3].getAttribute("image"), imageURL, "Second button should have correct image"); - - let promiseHidden = promisePanelElementHidden(window, popup); - EventUtils.synthesizeMouseAtCenter(buttons.childNodes[3], {}, window); - yield promiseHidden; - - ok(true, "Popup should close automatically"); - - let returnValue = yield waitForCallbackResultPromise(); - - is(returnValue.result, "button2", "Correct callback should have been called"); -}), - -add_UITour_task(function* test_info_close_button() { - let closeButton = document.getElementById("UITourTooltipClose"); - - yield showInfoPromise("urlbar", "Close me", "X marks the spot", null, null, "makeInfoOptions"); - - EventUtils.synthesizeMouseAtCenter(closeButton, {}, window); - - let returnValue = yield waitForCallbackResultPromise(); - - is(returnValue.result, "closeButton", "Close button callback called"); -}), - -add_UITour_task(function* test_info_target_callback() { - let popup = document.getElementById("UITourTooltip"); - - yield showInfoPromise("appMenu", "I want to know when the target is clicked", "*click*", null, null, "makeInfoOptions"); - - yield PanelUI.show(); - - let returnValue = yield waitForCallbackResultPromise(); - - is(returnValue.result, "target", "target callback called"); - is(returnValue.data.target, "appMenu", "target callback was from the appMenu"); - is(returnValue.data.type, "popupshown", "target callback was from the mousedown"); - - // Cleanup. - yield hideInfoPromise(); - - popup.removeAttribute("animate"); -}), - -add_UITour_task(function* test_getConfiguration_selectedSearchEngine() { - yield new Promise((resolve) => { - Services.search.init(Task.async(function*(rv) { - ok(Components.isSuccessCode(rv), "Search service initialized"); - let engine = Services.search.defaultEngine; - let data = yield getConfigurationPromise("selectedSearchEngine"); - is(data.searchEngineIdentifier, engine.identifier, "Correct engine identifier"); - resolve(); - })); - }); -}); - -add_UITour_task(function* test_setSearchTerm() { - const TERM = "UITour Search Term"; - yield gContentAPI.setSearchTerm(TERM); - - let searchbar = document.getElementById("searchbar"); - // The UITour gets to the searchbar element through a promise, so the value setting - // only happens after a tick. - yield waitForConditionPromise(() => searchbar.value == TERM, "Correct term set"); -}); - -add_UITour_task(function* test_clearSearchTerm() { - yield gContentAPI.setSearchTerm(""); - - let searchbar = document.getElementById("searchbar"); - // The UITour gets to the searchbar element through a promise, so the value setting - // only happens after a tick. - yield waitForConditionPromise(() => searchbar.value == "", "Search term cleared"); -}); diff --git a/browser/components/uitour/test/browser_UITour_annotation_size_attributes.js b/browser/components/uitour/test/browser_UITour_annotation_size_attributes.js deleted file mode 100644 index dbdeb9589..000000000 --- a/browser/components/uitour/test/browser_UITour_annotation_size_attributes.js +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Test that width and height attributes don't get set by widget code on the highlight panel. - */ - -"use strict"; - -var gTestTab; -var gContentAPI; -var gContentWindow; -var highlight = document.getElementById("UITourHighlightContainer"); -var tooltip = document.getElementById("UITourTooltip"); - -add_task(setup_UITourTest); - -add_UITour_task(function* test_highlight_size_attributes() { - yield gContentAPI.showHighlight("appMenu"); - yield elementVisiblePromise(highlight, - "Highlight should be shown after showHighlight() for the appMenu"); - yield gContentAPI.showHighlight("urlbar"); - yield elementVisiblePromise(highlight, "Highlight should be moved to the urlbar"); - yield new Promise((resolve) => { - SimpleTest.executeSoon(() => { - is(highlight.height, "", "Highlight panel should have no explicit height set"); - is(highlight.width, "", "Highlight panel should have no explicit width set"); - resolve(); - }); - }); -}); - -add_UITour_task(function* test_info_size_attributes() { - yield gContentAPI.showInfo("appMenu", "test title", "test text"); - yield elementVisiblePromise(tooltip, "Tooltip should be shown after showInfo() for the appMenu"); - yield gContentAPI.showInfo("urlbar", "new title", "new text"); - yield elementVisiblePromise(tooltip, "Tooltip should be moved to the urlbar"); - yield new Promise((resolve) => { - SimpleTest.executeSoon(() => { - is(tooltip.height, "", "Info panel should have no explicit height set"); - is(tooltip.width, "", "Info panel should have no explicit width set"); - resolve(); - }); - }); -}); diff --git a/browser/components/uitour/test/browser_UITour_availableTargets.js b/browser/components/uitour/test/browser_UITour_availableTargets.js deleted file mode 100644 index a6e96e31f..000000000 --- a/browser/components/uitour/test/browser_UITour_availableTargets.js +++ /dev/null @@ -1,114 +0,0 @@ -"use strict"; - -var gTestTab; -var gContentAPI; -var gContentWindow; - -var hasWebIDE = Services.prefs.getBoolPref("devtools.webide.widget.enabled"); -var hasPocket = Services.prefs.getBoolPref("extensions.pocket.enabled"); - -requestLongerTimeout(2); -add_task(setup_UITourTest); - -add_UITour_task(function* test_availableTargets() { - let data = yield getConfigurationPromise("availableTargets"); - ok_targets(data, [ - "accountStatus", - "addons", - "appMenu", - "backForward", - "bookmarks", - "customize", - "help", - "home", - "devtools", - ...(hasPocket ? ["pocket"] : []), - "privateWindow", - "quit", - "readerMode-urlBar", - "search", - "searchIcon", - "trackingProtection", - "urlbar", - ...(hasWebIDE ? ["webide"] : []) - ]); - - ok(UITour.availableTargetsCache.has(window), - "Targets should now be cached"); -}); - -add_UITour_task(function* test_availableTargets_changeWidgets() { - CustomizableUI.removeWidgetFromArea("bookmarks-menu-button"); - ok(!UITour.availableTargetsCache.has(window), - "Targets should be evicted from cache after widget change"); - let data = yield getConfigurationPromise("availableTargets"); - ok_targets(data, [ - "accountStatus", - "addons", - "appMenu", - "backForward", - "customize", - "help", - "devtools", - "home", - ...(hasPocket ? ["pocket"] : []), - "privateWindow", - "quit", - "readerMode-urlBar", - "search", - "searchIcon", - "trackingProtection", - "urlbar", - ...(hasWebIDE ? ["webide"] : []) - ]); - - ok(UITour.availableTargetsCache.has(window), - "Targets should now be cached again"); - CustomizableUI.reset(); - ok(!UITour.availableTargetsCache.has(window), - "Targets should not be cached after reset"); -}); - -add_UITour_task(function* test_availableTargets_exceptionFromGetTarget() { - // The query function for the "search" target will throw if it's not found. - // Make sure the callback still fires with the other available targets. - CustomizableUI.removeWidgetFromArea("search-container"); - let data = yield getConfigurationPromise("availableTargets"); - // Default minus "search" and "searchIcon" - ok_targets(data, [ - "accountStatus", - "addons", - "appMenu", - "backForward", - "bookmarks", - "customize", - "help", - "home", - "devtools", - ...(hasPocket ? ["pocket"] : []), - "privateWindow", - "quit", - "readerMode-urlBar", - "trackingProtection", - "urlbar", - ...(hasWebIDE ? ["webide"] : []) - ]); - - CustomizableUI.reset(); -}); - -function ok_targets(actualData, expectedTargets) { - // Depending on how soon after page load this is called, the selected tab icon - // may or may not be showing the loading throbber. Check for its presence and - // insert it into expectedTargets if it's visible. - let selectedTabIcon = - document.getAnonymousElementByAttribute(gBrowser.selectedTab, - "anonid", - "tab-icon-image"); - if (selectedTabIcon && UITour.isElementVisible(selectedTabIcon)) - expectedTargets.push("selectedTabIcon"); - - ok(Array.isArray(actualData.targets), "data.targets should be an array"); - is(actualData.targets.sort().toString(), expectedTargets.sort().toString(), - "Targets should be as expected"); -} diff --git a/browser/components/uitour/test/browser_UITour_defaultBrowser.js b/browser/components/uitour/test/browser_UITour_defaultBrowser.js deleted file mode 100644 index 5ebf553b0..000000000 --- a/browser/components/uitour/test/browser_UITour_defaultBrowser.js +++ /dev/null @@ -1,61 +0,0 @@ -"use strict"; - -var gTestTab; -var gContentAPI; -var gContentWindow; -var setDefaultBrowserCalled = false; - -Cc["@mozilla.org/moz/jssubscript-loader;1"] - .getService(Ci.mozIJSSubScriptLoader) - .loadSubScript("chrome://mochikit/content/tests/SimpleTest/MockObjects.js", this); - -function MockShellService() {} -MockShellService.prototype = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIShellService]), - isDefaultBrowser: function(aStartupCheck, aForAllTypes) { return false; }, - setDefaultBrowser: function(aClaimAllTypes, aForAllUsers) { - setDefaultBrowserCalled = true; - }, - shouldCheckDefaultBrowser: false, - canSetDesktopBackground: false, - BACKGROUND_TILE : 1, - BACKGROUND_STRETCH : 2, - BACKGROUND_CENTER : 3, - BACKGROUND_FILL : 4, - BACKGROUND_FIT : 5, - setDesktopBackground: function(aElement, aPosition) {}, - APPLICATION_MAIL : 0, - APPLICATION_NEWS : 1, - openApplication: function(aApplication) {}, - desktopBackgroundColor: 0, - openApplicationWithURI: function(aApplication, aURI) {}, - defaultFeedReader: 0, -}; - -var mockShellService = new MockObjectRegisterer("@mozilla.org/browser/shell-service;1", - MockShellService); - -// Temporarily disabled, see note at test_setDefaultBrowser. -// mockShellService.register(); - -add_task(setup_UITourTest); - -/* This test is disabled (bug 1180714) since the MockObjectRegisterer - is not actually replacing the original ShellService. -add_UITour_task(function* test_setDefaultBrowser() { - try { - yield gContentAPI.setConfiguration("defaultBrowser"); - ok(setDefaultBrowserCalled, "setDefaultBrowser called"); - } finally { - mockShellService.unregister(); - } -}); -*/ - -add_UITour_task(function* test_isDefaultBrowser() { - let shell = Components.classes["@mozilla.org/browser/shell-service;1"] - .getService(Components.interfaces.nsIShellService); - let isDefault = shell.isDefaultBrowser(false); - let data = yield getConfigurationPromise("appinfo"); - is(isDefault, data.defaultBrowser, "gContentAPI result should match shellService.isDefaultBrowser"); -}); diff --git a/browser/components/uitour/test/browser_UITour_detach_tab.js b/browser/components/uitour/test/browser_UITour_detach_tab.js deleted file mode 100644 index b8edf6dc4..000000000 --- a/browser/components/uitour/test/browser_UITour_detach_tab.js +++ /dev/null @@ -1,94 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -/** - * Detaching a tab to a new window shouldn't break the menu panel. - */ - -"use strict"; - -var gTestTab; -var gContentAPI; -var gContentWindow; -var gContentDoc; - -function test() { - registerCleanupFunction(function() { - gContentDoc = null; - }); - UITourTest(); -} - -/** - * When tab is changed we're tearing the tour down. So the UITour client has to always be aware of this - * fact and therefore listens to visibilitychange events. - * In particular this scenario happens for detaching the tab (ie. moving it to a new window). - */ -var tests = [ - taskify(function* test_move_tab_to_new_window() { - const myDocIdentifier = "Hello, I'm a unique expando to identify this document."; - - let highlight = document.getElementById("UITourHighlight"); - let windowDestroyedDeferred = Promise.defer(); - let onDOMWindowDestroyed = (aWindow) => { - if (gContentWindow && aWindow == gContentWindow) { - Services.obs.removeObserver(onDOMWindowDestroyed, "dom-window-destroyed", false); - windowDestroyedDeferred.resolve(); - } - }; - - let browserStartupDeferred = Promise.defer(); - Services.obs.addObserver(function onBrowserDelayedStartup(aWindow) { - Services.obs.removeObserver(onBrowserDelayedStartup, "browser-delayed-startup-finished"); - browserStartupDeferred.resolve(aWindow); - }, "browser-delayed-startup-finished", false); - - yield ContentTask.spawn(gBrowser.selectedBrowser, myDocIdentifier, myDocIdentifier => { - let onVisibilityChange = () => { - if (!content.document.hidden) { - let win = Cu.waiveXrays(content); - win.Mozilla.UITour.showHighlight("appMenu"); - } - }; - content.document.addEventListener("visibilitychange", onVisibilityChange); - content.document.myExpando = myDocIdentifier; - }); - gContentAPI.showHighlight("appMenu"); - - yield elementVisiblePromise(highlight); - - gContentWindow = gBrowser.replaceTabWithWindow(gBrowser.selectedTab); - yield browserStartupDeferred.promise; - - // This highlight should be shown thanks to the visibilitychange listener. - let newWindowHighlight = gContentWindow.document.getElementById("UITourHighlight"); - yield elementVisiblePromise(newWindowHighlight); - - let selectedTab = gContentWindow.gBrowser.selectedTab; - yield ContentTask.spawn(selectedTab.linkedBrowser, myDocIdentifier, myDocIdentifier => { - is(content.document.myExpando, myDocIdentifier, "Document should be selected in new window"); - }); - ok(UITour.tourBrowsersByWindow && UITour.tourBrowsersByWindow.has(gContentWindow), "Window should be known"); - ok(UITour.tourBrowsersByWindow.get(gContentWindow).has(selectedTab.linkedBrowser), "Selected browser should be known"); - - // Need this because gContentAPI in e10s land will try to use gTestTab to - // spawn a content task, which doesn't work if the tab is dead, for obvious - // reasons. - gTestTab = gContentWindow.gBrowser.selectedTab; - - let shownPromise = promisePanelShown(gContentWindow); - gContentAPI.showMenu("appMenu"); - yield shownPromise; - - isnot(gContentWindow.PanelUI.panel.state, "closed", "Panel should be open"); - ok(gContentWindow.PanelUI.contents.children.length > 0, "Panel contents should have children"); - gContentAPI.hideHighlight(); - gContentAPI.hideMenu("appMenu"); - gTestTab = null; - - Services.obs.addObserver(onDOMWindowDestroyed, "dom-window-destroyed", false); - gContentWindow.close(); - - yield windowDestroyedDeferred.promise; - }), -]; diff --git a/browser/components/uitour/test/browser_UITour_forceReaderMode.js b/browser/components/uitour/test/browser_UITour_forceReaderMode.js deleted file mode 100644 index 5b5e883c3..000000000 --- a/browser/components/uitour/test/browser_UITour_forceReaderMode.js +++ /dev/null @@ -1,17 +0,0 @@ -"use strict"; - -var gTestTab; -var gContentAPI; -var gContentWindow; - -add_task(setup_UITourTest); - -add_UITour_task(function*() { - ok(!gBrowser.selectedBrowser.isArticle, "Should not be an article when we start"); - ok(document.getElementById("reader-mode-button").hidden, "Button should be hidden."); - yield gContentAPI.forceShowReaderIcon(); - yield waitForConditionPromise(() => gBrowser.selectedBrowser.isArticle); - ok(gBrowser.selectedBrowser.isArticle, "Should suddenly be an article."); - ok(!document.getElementById("reader-mode-button").hidden, "Button should now be visible."); -}); - diff --git a/browser/components/uitour/test/browser_UITour_heartbeat.js b/browser/components/uitour/test/browser_UITour_heartbeat.js deleted file mode 100644 index 61be1d44b..000000000 --- a/browser/components/uitour/test/browser_UITour_heartbeat.js +++ /dev/null @@ -1,755 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -var gTestTab; -var gContentAPI; -var gContentWindow; - -function getHeartbeatNotification(aId, aChromeWindow = window) { - let notificationBox = aChromeWindow.document.getElementById("high-priority-global-notificationbox"); - // UITour.jsm prefixes the notification box ID with "heartbeat-" to prevent collisions. - return notificationBox.getNotificationWithValue("heartbeat-" + aId); -} - -/** - * Simulate a click on a rating element in the Heartbeat notification. - * - * @param aId - * The id of the notification box. - * @param aScore - * The score related to the rating element we want to click on. - */ -function simulateVote(aId, aScore) { - let notification = getHeartbeatNotification(aId); - - let ratingContainer = notification.childNodes[0]; - ok(ratingContainer, "The notification has a valid rating container."); - - let ratingElement = ratingContainer.getElementsByAttribute("data-score", aScore); - ok(ratingElement[0], "The rating container contains the requested rating element."); - - ratingElement[0].click(); -} - -/** - * Simulate a click on the learn-more link. - * - * @param aId - * The id of the notification box. - */ -function clickLearnMore(aId) { - let notification = getHeartbeatNotification(aId); - - let learnMoreLabel = notification.childNodes[2]; - ok(learnMoreLabel, "The notification has a valid learn more label."); - - learnMoreLabel.click(); -} - -/** - * Remove the notification box. - * - * @param aId - * The id of the notification box to remove. - * @param [aChromeWindow=window] - * The chrome window the notification box is in. - */ -function cleanUpNotification(aId, aChromeWindow = window) { - let notification = getHeartbeatNotification(aId, aChromeWindow); - notification.close(); -} - -/** - * Check telemetry payload for proper format and expected content. - * - * @param aPayload - * The Telemetry payload to verify - * @param aFlowId - * Expected value of the flowId field. - * @param aExpectedFields - * Array of expected fields. No other fields are allowed. - */ -function checkTelemetry(aPayload, aFlowId, aExpectedFields) { - // Basic payload format - is(aPayload.version, 1, "Telemetry ping must have heartbeat version=1"); - is(aPayload.flowId, aFlowId, "Flow ID in the Telemetry ping must match"); - - // Check for superfluous fields - let extraKeys = new Set(Object.keys(aPayload)); - extraKeys.delete("version"); - extraKeys.delete("flowId"); - - // Check for expected fields - for (let field of aExpectedFields) { - ok(field in aPayload, "The payload should have the field '" + field + "'"); - if (field.endsWith("TS")) { - let ts = aPayload[field]; - ok(Number.isInteger(ts) && ts > 0, "Timestamp '" + field + "' must be a natural number"); - } - extraKeys.delete(field); - } - - is(extraKeys.size, 0, "No unexpected fields in the Telemetry payload"); -} - -/** - * Waits for an UITour notification dispatched through |UITour.notify|. This should be - * done with |gContentAPI.observe|. Unfortunately, in e10s, |gContentAPI.observe| doesn't - * allow for multiple calls to the same callback, allowing to catch just the first - * notification. - * - * @param aEventName - * The notification name to wait for. - * @return {Promise} Resolved with the data that comes with the event. - */ -function promiseWaitHeartbeatNotification(aEventName) { - return ContentTask.spawn(gTestTab.linkedBrowser, { aEventName }, - function({ aEventName }) { - return new Promise(resolve => { - addEventListener("mozUITourNotification", function listener(event) { - if (event.detail.event !== aEventName) { - return; - } - removeEventListener("mozUITourNotification", listener, false); - resolve(event.detail.params); - }, false); - }); - }); -} - -/** - * Waits for UITour notifications dispatched through |UITour.notify|. This works like - * |promiseWaitHeartbeatNotification|, but waits for all the passed notifications to - * be received before resolving. If it receives an unaccounted notification, it rejects. - * - * @param events - * An array of expected notification names to wait for. - * @return {Promise} Resolved with the data that comes with the event. Rejects with the - * name of an undesired notification if received. - */ -function promiseWaitExpectedNotifications(events) { - return ContentTask.spawn(gTestTab.linkedBrowser, { events }, - function({ events }) { - let stillToReceive = events; - return new Promise((res, rej) => { - addEventListener("mozUITourNotification", function listener(event) { - if (stillToReceive.includes(event.detail.event)) { - // Filter out the received event. - stillToReceive = stillToReceive.filter(x => x !== event.detail.event); - } else { - removeEventListener("mozUITourNotification", listener, false); - rej(event.detail.event); - } - // We still need to catch some notifications. Don't do anything. - if (stillToReceive.length > 0) { - return; - } - // We don't need to listen for other notifications. Resolve the promise. - removeEventListener("mozUITourNotification", listener, false); - res(); - }, false); - }); - }); -} - -function validateTimestamp(eventName, timestamp) { - info("'" + eventName + "' notification received (timestamp " + timestamp.toString() + ")."); - ok(Number.isFinite(timestamp), "Timestamp must be a number."); -} - -add_task(function* test_setup() { - yield setup_UITourTest(); - requestLongerTimeout(2); - registerCleanupFunction(() => { - Services.prefs.clearUserPref("browser.uitour.surveyDuration"); - }); -}); - -/** - * Check that the "stars" heartbeat UI correctly shows and closes. - */ -add_UITour_task(function* test_heartbeat_stars_show() { - let flowId = "ui-ratefirefox-" + Math.random(); - let engagementURL = "http://example.com"; - - // We need to call |gContentAPI.observe| at least once to set a valid |notificationListener| - // in UITour-lib.js, otherwise no message will get propagated. - gContentAPI.observe(() => {}); - - let receivedExpectedPromise = promiseWaitExpectedNotifications( - ["Heartbeat:NotificationOffered", "Heartbeat:NotificationClosed", "Heartbeat:TelemetrySent"]); - - // Show the Heartbeat notification and wait for it to be displayed. - let shownPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationOffered"); - gContentAPI.showHeartbeat("How would you rate Firefox?", "Thank you!", flowId, engagementURL); - - // Validate the returned timestamp. - let data = yield shownPromise; - validateTimestamp('Heartbeat:Offered', data.timestamp); - - // Close the heartbeat notification. - let closedPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationClosed"); - let pingSentPromise = promiseWaitHeartbeatNotification("Heartbeat:TelemetrySent"); - cleanUpNotification(flowId); - - data = yield closedPromise; - validateTimestamp('Heartbeat:NotificationClosed', data.timestamp); - - data = yield pingSentPromise; - info("'Heartbeat:TelemetrySent' notification received"); - checkTelemetry(data, flowId, ["offeredTS", "closedTS"]); - - // This rejects whenever an unexpected notification is received. - yield receivedExpectedPromise; -}) - -/** - * Check that the heartbeat UI correctly takes optional icon URL. - */ -add_UITour_task(function* test_heartbeat_take_optional_icon_URL() { - let flowId = "ui-ratefirefox-" + Math.random(); - let engagementURL = "http://example.com"; - let iconURL = "chrome://branding/content/icon48.png"; - - // We need to call |gContentAPI.observe| at least once to set a valid |notificationListener| - // in UITour-lib.js, otherwise no message will get propagated. - gContentAPI.observe(() => {}); - - let receivedExpectedPromise = promiseWaitExpectedNotifications( - ["Heartbeat:NotificationOffered", "Heartbeat:NotificationClosed", "Heartbeat:TelemetrySent"]); - - // Show the Heartbeat notification and wait for it to be displayed. - let shownPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationOffered"); - gContentAPI.showHeartbeat("How would you rate Firefox?", "Thank you!", flowId, engagementURL, null, null, { - iconURL: iconURL - }); - - // Validate the returned timestamp. - let data = yield shownPromise; - validateTimestamp('Heartbeat:Offered', data.timestamp); - - // Check the icon URL - let notification = getHeartbeatNotification(flowId); - is(notification.image, iconURL, "The optional icon URL is not taken correctly"); - - // Close the heartbeat notification. - let closedPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationClosed"); - let pingSentPromise = promiseWaitHeartbeatNotification("Heartbeat:TelemetrySent"); - cleanUpNotification(flowId); - - data = yield closedPromise; - validateTimestamp('Heartbeat:NotificationClosed', data.timestamp); - - data = yield pingSentPromise; - info("'Heartbeat:TelemetrySent' notification received"); - checkTelemetry(data, flowId, ["offeredTS", "closedTS"]); - - // This rejects whenever an unexpected notification is received. - yield receivedExpectedPromise; -}) - -/** - * Test that the heartbeat UI correctly works with null engagement URL. - */ -add_UITour_task(function* test_heartbeat_null_engagementURL() { - let flowId = "ui-ratefirefox-" + Math.random(); - let originalTabCount = gBrowser.tabs.length; - - // We need to call |gContentAPI.observe| at least once to set a valid |notificationListener| - // in UITour-lib.js, otherwise no message will get propagated. - gContentAPI.observe(() => {}); - - let receivedExpectedPromise = promiseWaitExpectedNotifications(["Heartbeat:NotificationOffered", - "Heartbeat:NotificationClosed", "Heartbeat:Voted", "Heartbeat:TelemetrySent"]); - - // Show the Heartbeat notification and wait for it to be displayed. - let shownPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationOffered"); - gContentAPI.showHeartbeat("How would you rate Firefox?", "Thank you!", flowId, null); - - // Validate the returned timestamp. - let data = yield shownPromise; - validateTimestamp('Heartbeat:Offered', data.timestamp); - - // Wait an the Voted, Closed and Telemetry Sent events. They are fired together, so - // wait for them here. - let closedPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationClosed"); - let votedPromise = promiseWaitHeartbeatNotification("Heartbeat:Voted"); - let pingSentPromise = promiseWaitHeartbeatNotification("Heartbeat:TelemetrySent"); - - // The UI was just shown. We can simulate a click on a rating element (i.e., "star"). - simulateVote(flowId, 2); - data = yield votedPromise; - validateTimestamp('Heartbeat:Voted', data.timestamp); - - // Validate the closing timestamp. - data = yield closedPromise; - validateTimestamp('Heartbeat:NotificationClosed', data.timestamp); - is(gBrowser.tabs.length, originalTabCount, "No engagement tab should be opened."); - - // Validate the data we send out. - data = yield pingSentPromise; - info("'Heartbeat:TelemetrySent' notification received."); - checkTelemetry(data, flowId, ["offeredTS", "votedTS", "closedTS", "score"]); - is(data.score, 2, "Checking Telemetry payload.score"); - - // This rejects whenever an unexpected notification is received. - yield receivedExpectedPromise; -}) - -/** - * Test that the heartbeat UI correctly works with an invalid, but non null, engagement URL. - */ -add_UITour_task(function* test_heartbeat_invalid_engagement_URL() { - let flowId = "ui-ratefirefox-" + Math.random(); - let originalTabCount = gBrowser.tabs.length; - let invalidEngagementURL = "invalidEngagement"; - - // We need to call |gContentAPI.observe| at least once to set a valid |notificationListener| - // in UITour-lib.js, otherwise no message will get propagated. - gContentAPI.observe(() => {}); - - let receivedExpectedPromise = promiseWaitExpectedNotifications(["Heartbeat:NotificationOffered", - "Heartbeat:NotificationClosed", "Heartbeat:Voted", "Heartbeat:TelemetrySent"]); - - // Show the Heartbeat notification and wait for it to be displayed. - let shownPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationOffered"); - gContentAPI.showHeartbeat("How would you rate Firefox?", "Thank you!", flowId, invalidEngagementURL); - - // Validate the returned timestamp. - let data = yield shownPromise; - validateTimestamp('Heartbeat:Offered', data.timestamp); - - // Wait an the Voted, Closed and Telemetry Sent events. They are fired together, so - // wait for them here. - let closedPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationClosed"); - let votedPromise = promiseWaitHeartbeatNotification("Heartbeat:Voted"); - let pingSentPromise = promiseWaitHeartbeatNotification("Heartbeat:TelemetrySent"); - - // The UI was just shown. We can simulate a click on a rating element (i.e., "star"). - simulateVote(flowId, 2); - data = yield votedPromise; - validateTimestamp('Heartbeat:Voted', data.timestamp); - - // Validate the closing timestamp. - data = yield closedPromise; - validateTimestamp('Heartbeat:NotificationClosed', data.timestamp); - is(gBrowser.tabs.length, originalTabCount, "No engagement tab should be opened."); - - // Validate the data we send out. - data = yield pingSentPromise; - info("'Heartbeat:TelemetrySent' notification received."); - checkTelemetry(data, flowId, ["offeredTS", "votedTS", "closedTS", "score"]); - is(data.score, 2, "Checking Telemetry payload.score"); - - // This rejects whenever an unexpected notification is received. - yield receivedExpectedPromise; -}) - -/** - * Test that the score is correctly reported. - */ -add_UITour_task(function* test_heartbeat_stars_vote() { - const expectedScore = 4; - let originalTabCount = gBrowser.tabs.length; - let flowId = "ui-ratefirefox-" + Math.random(); - - // We need to call |gContentAPI.observe| at least once to set a valid |notificationListener| - // in UITour-lib.js, otherwise no message will get propagated. - gContentAPI.observe(() => {}); - - let receivedExpectedPromise = promiseWaitExpectedNotifications(["Heartbeat:NotificationOffered", - "Heartbeat:NotificationClosed", "Heartbeat:Voted", "Heartbeat:TelemetrySent"]); - - // Show the Heartbeat notification and wait for it to be displayed. - let shownPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationOffered"); - gContentAPI.showHeartbeat("How would you rate Firefox?", "Thank you!", flowId, null); - - // Validate the returned timestamp. - let data = yield shownPromise; - validateTimestamp('Heartbeat:Offered', data.timestamp); - - // Wait an the Voted, Closed and Telemetry Sent events. They are fired together, so - // wait for them here. - let closedPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationClosed"); - let votedPromise = promiseWaitHeartbeatNotification("Heartbeat:Voted"); - let pingSentPromise = promiseWaitHeartbeatNotification("Heartbeat:TelemetrySent"); - - // The UI was just shown. We can simulate a click on a rating element (i.e., "star"). - simulateVote(flowId, expectedScore); - data = yield votedPromise; - validateTimestamp('Heartbeat:Voted', data.timestamp); - is(data.score, expectedScore, "Should report a score of " + expectedScore); - - // Validate the closing timestamp and vote. - data = yield closedPromise; - validateTimestamp('Heartbeat:NotificationClosed', data.timestamp); - is(gBrowser.tabs.length, originalTabCount, "No engagement tab should be opened."); - - // Validate the data we send out. - data = yield pingSentPromise; - info("'Heartbeat:TelemetrySent' notification received."); - checkTelemetry(data, flowId, ["offeredTS", "votedTS", "closedTS", "score"]); - is(data.score, expectedScore, "Checking Telemetry payload.score"); - - // This rejects whenever an unexpected notification is received. - yield receivedExpectedPromise; -}) - -/** - * Test that the engagement page is correctly opened when voting. - */ -add_UITour_task(function* test_heartbeat_engagement_tab() { - let engagementURL = "http://example.com"; - let flowId = "ui-ratefirefox-" + Math.random(); - let originalTabCount = gBrowser.tabs.length; - const expectedTabCount = originalTabCount + 1; - - // We need to call |gContentAPI.observe| at least once to set a valid |notificationListener| - // in UITour-lib.js, otherwise no message will get propagated. - gContentAPI.observe(() => {}); - - let receivedExpectedPromise = promiseWaitExpectedNotifications(["Heartbeat:NotificationOffered", - "Heartbeat:NotificationClosed", "Heartbeat:Voted", "Heartbeat:TelemetrySent"]); - - // Show the Heartbeat notification and wait for it to be displayed. - let shownPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationOffered"); - gContentAPI.showHeartbeat("How would you rate Firefox?", "Thank you!", flowId, engagementURL); - - // Validate the returned timestamp. - let data = yield shownPromise; - validateTimestamp('Heartbeat:Offered', data.timestamp); - - // Wait an the Voted, Closed and Telemetry Sent events. They are fired together, so - // wait for them here. - let closedPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationClosed"); - let votedPromise = promiseWaitHeartbeatNotification("Heartbeat:Voted"); - let pingSentPromise = promiseWaitHeartbeatNotification("Heartbeat:TelemetrySent"); - - // The UI was just shown. We can simulate a click on a rating element (i.e., "star"). - simulateVote(flowId, 1); - data = yield votedPromise; - validateTimestamp('Heartbeat:Voted', data.timestamp); - - // Validate the closing timestamp, vote and make sure the engagement page was opened. - data = yield closedPromise; - validateTimestamp('Heartbeat:NotificationClosed', data.timestamp); - is(gBrowser.tabs.length, expectedTabCount, "Engagement URL should open in a new tab."); - gBrowser.removeCurrentTab(); - - // Validate the data we send out. - data = yield pingSentPromise; - info("'Heartbeat:TelemetrySent' notification received."); - checkTelemetry(data, flowId, ["offeredTS", "votedTS", "closedTS", "score"]); - is(data.score, 1, "Checking Telemetry payload.score"); - - // This rejects whenever an unexpected notification is received. - yield receivedExpectedPromise; -}) - -/** - * Test that the engagement button opens the engagement URL. - */ -add_UITour_task(function* test_heartbeat_engagement_button() { - let engagementURL = "http://example.com"; - let flowId = "ui-engagewithfirefox-" + Math.random(); - let originalTabCount = gBrowser.tabs.length; - const expectedTabCount = originalTabCount + 1; - - // We need to call |gContentAPI.observe| at least once to set a valid |notificationListener| - // in UITour-lib.js, otherwise no message will get propagated. - gContentAPI.observe(() => {}); - - let receivedExpectedPromise = promiseWaitExpectedNotifications(["Heartbeat:NotificationOffered", - "Heartbeat:NotificationClosed", "Heartbeat:Engaged", "Heartbeat:TelemetrySent"]); - - // Show the Heartbeat notification and wait for it to be displayed. - let shownPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationOffered"); - gContentAPI.showHeartbeat("Do you want to engage with us?", "Thank you!", flowId, engagementURL, null, null, { - engagementButtonLabel: "Engage Me", - }); - - let data = yield shownPromise; - validateTimestamp('Heartbeat:Offered', data.timestamp); - - // Wait an the Engaged, Closed and Telemetry Sent events. They are fired together, so - // wait for them here. - let closedPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationClosed"); - let engagedPromise = promiseWaitHeartbeatNotification("Heartbeat:Engaged"); - let pingSentPromise = promiseWaitHeartbeatNotification("Heartbeat:TelemetrySent"); - - // Simulate user engagement. - let notification = getHeartbeatNotification(flowId); - is(notification.querySelectorAll(".star-x").length, 0, "No stars should be present"); - // The UI was just shown. We can simulate a click on the engagement button. - let engagementButton = notification.querySelector(".notification-button"); - is(engagementButton.label, "Engage Me", "Check engagement button text"); - engagementButton.doCommand(); - - data = yield engagedPromise; - validateTimestamp('Heartbeat:Engaged', data.timestamp); - - // Validate the closing timestamp, vote and make sure the engagement page was opened. - data = yield closedPromise; - validateTimestamp('Heartbeat:NotificationClosed', data.timestamp); - is(gBrowser.tabs.length, expectedTabCount, "Engagement URL should open in a new tab."); - gBrowser.removeCurrentTab(); - - // Validate the data we send out. - data = yield pingSentPromise; - info("'Heartbeat:TelemetrySent' notification received."); - checkTelemetry(data, flowId, ["offeredTS", "engagedTS", "closedTS"]); - - // This rejects whenever an unexpected notification is received. - yield receivedExpectedPromise; -}) - -/** - * Test that the learn more link is displayed and that the page is correctly opened when - * clicking on it. - */ -add_UITour_task(function* test_heartbeat_learnmore() { - let dummyURL = "http://example.com"; - let flowId = "ui-ratefirefox-" + Math.random(); - let originalTabCount = gBrowser.tabs.length; - const expectedTabCount = originalTabCount + 1; - - // We need to call |gContentAPI.observe| at least once to set a valid |notificationListener| - // in UITour-lib.js, otherwise no message will get propagated. - gContentAPI.observe(() => {}); - - let receivedExpectedPromise = promiseWaitExpectedNotifications(["Heartbeat:NotificationOffered", - "Heartbeat:NotificationClosed", "Heartbeat:LearnMore", "Heartbeat:TelemetrySent"]); - - // Show the Heartbeat notification and wait for it to be displayed. - let shownPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationOffered"); - gContentAPI.showHeartbeat("How would you rate Firefox?", "Thank you!", flowId, dummyURL, - "What is this?", dummyURL); - - let data = yield shownPromise; - validateTimestamp('Heartbeat:Offered', data.timestamp); - - // Wait an the LearnMore, Closed and Telemetry Sent events. They are fired together, so - // wait for them here. - let closedPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationClosed"); - let learnMorePromise = promiseWaitHeartbeatNotification("Heartbeat:LearnMore"); - let pingSentPromise = promiseWaitHeartbeatNotification("Heartbeat:TelemetrySent"); - - // The UI was just shown. Simulate a click on the learn more link. - clickLearnMore(flowId); - - data = yield learnMorePromise; - validateTimestamp('Heartbeat:LearnMore', data.timestamp); - cleanUpNotification(flowId); - - // The notification was closed. - data = yield closedPromise; - validateTimestamp('Heartbeat:NotificationClosed', data.timestamp); - is(gBrowser.tabs.length, expectedTabCount, "Learn more URL should open in a new tab."); - gBrowser.removeCurrentTab(); - - // Validate the data we send out. - data = yield pingSentPromise; - info("'Heartbeat:TelemetrySent' notification received."); - checkTelemetry(data, flowId, ["offeredTS", "learnMoreTS", "closedTS"]); - - // This rejects whenever an unexpected notification is received. - yield receivedExpectedPromise; -}) - -add_UITour_task(function* test_invalidEngagementButtonLabel() { - let engagementURL = "http://example.com"; - let flowId = "invalidEngagementButtonLabel-" + Math.random(); - - let eventPromise = promisePageEvent(); - - gContentAPI.showHeartbeat("Do you want to engage with us?", "Thank you!", flowId, engagementURL, - null, null, { - engagementButtonLabel: 42, - }); - - yield eventPromise; - ok(!isTourBrowser(gBrowser.selectedBrowser), - "Invalid engagementButtonLabel should prevent init"); - -}) - -add_UITour_task(function* test_privateWindowsOnly_noneOpen() { - let engagementURL = "http://example.com"; - let flowId = "privateWindowsOnly_noneOpen-" + Math.random(); - - let eventPromise = promisePageEvent(); - - gContentAPI.showHeartbeat("Do you want to engage with us?", "Thank you!", flowId, engagementURL, - null, null, { - engagementButtonLabel: "Yes!", - privateWindowsOnly: true, - }); - - yield eventPromise; - ok(!isTourBrowser(gBrowser.selectedBrowser), - "If there are no private windows opened, tour init should be prevented"); -}) - -add_UITour_task(function* test_privateWindowsOnly_notMostRecent() { - let engagementURL = "http://example.com"; - let flowId = "notMostRecent-" + Math.random(); - - let privateWin = yield BrowserTestUtils.openNewBrowserWindow({ private: true }); - let mostRecentWin = yield BrowserTestUtils.openNewBrowserWindow(); - - let eventPromise = promisePageEvent(); - - gContentAPI.showHeartbeat("Do you want to engage with us?", "Thank you!", flowId, engagementURL, - null, null, { - engagementButtonLabel: "Yes!", - privateWindowsOnly: true, - }); - - yield eventPromise; - is(getHeartbeatNotification(flowId, window), null, - "Heartbeat shouldn't appear in the default window"); - is(!!getHeartbeatNotification(flowId, privateWin), true, - "Heartbeat should appear in the most recent private window"); - is(getHeartbeatNotification(flowId, mostRecentWin), null, - "Heartbeat shouldn't appear in the most recent non-private window"); - - yield BrowserTestUtils.closeWindow(mostRecentWin); - yield BrowserTestUtils.closeWindow(privateWin); -}) - -add_UITour_task(function* test_privateWindowsOnly() { - let engagementURL = "http://example.com"; - let learnMoreURL = "http://example.org/learnmore/"; - let flowId = "ui-privateWindowsOnly-" + Math.random(); - - let privateWin = yield BrowserTestUtils.openNewBrowserWindow({ private: true }); - - yield new Promise((resolve) => { - gContentAPI.observe(function(aEventName, aData) { - info(aEventName + " notification received: " + JSON.stringify(aData, null, 2)); - ok(false, "No heartbeat notifications should arrive for privateWindowsOnly"); - }, resolve); - }); - - gContentAPI.showHeartbeat("Do you want to engage with us?", "Thank you!", flowId, engagementURL, - "Learn More", learnMoreURL, { - engagementButtonLabel: "Yes!", - privateWindowsOnly: true, - }); - - yield promisePageEvent(); - - ok(isTourBrowser(gBrowser.selectedBrowser), "UITour should have been init for the browser"); - - let notification = getHeartbeatNotification(flowId, privateWin); - - is(notification.querySelectorAll(".star-x").length, 0, "No stars should be present"); - - info("Test the learn more link."); - let learnMoreLink = notification.querySelector(".text-link"); - is(learnMoreLink.value, "Learn More", "Check learn more label"); - let learnMoreTabPromise = BrowserTestUtils.waitForNewTab(privateWin.gBrowser, null); - learnMoreLink.click(); - let learnMoreTab = yield learnMoreTabPromise; - is(learnMoreTab.linkedBrowser.currentURI.host, "example.org", "Check learn more site opened"); - ok(PrivateBrowsingUtils.isBrowserPrivate(learnMoreTab.linkedBrowser), "Ensure the learn more tab is private"); - yield BrowserTestUtils.removeTab(learnMoreTab); - - info("Test the engagement button's new tab."); - let engagementButton = notification.querySelector(".notification-button"); - is(engagementButton.label, "Yes!", "Check engagement button text"); - let engagementTabPromise = BrowserTestUtils.waitForNewTab(privateWin.gBrowser, null); - engagementButton.doCommand(); - let engagementTab = yield engagementTabPromise; - is(engagementTab.linkedBrowser.currentURI.host, "example.com", "Check enagement site opened"); - ok(PrivateBrowsingUtils.isBrowserPrivate(engagementTab.linkedBrowser), "Ensure the engagement tab is private"); - yield BrowserTestUtils.removeTab(engagementTab); - - yield BrowserTestUtils.closeWindow(privateWin); -}) - -/** - * Test that the survey closes itself after a while and submits Telemetry - */ -add_UITour_task(function* test_telemetry_surveyExpired() { - let flowId = "survey-expired-" + Math.random(); - let engagementURL = "http://example.com"; - let surveyDuration = 1; // 1 second (pref is in seconds) - Services.prefs.setIntPref("browser.uitour.surveyDuration", surveyDuration); - - // We need to call |gContentAPI.observe| at least once to set a valid |notificationListener| - // in UITour-lib.js, otherwise no message will get propagated. - gContentAPI.observe(() => {}); - - let receivedExpectedPromise = promiseWaitExpectedNotifications(["Heartbeat:NotificationOffered", - "Heartbeat:NotificationClosed", "Heartbeat:SurveyExpired", "Heartbeat:TelemetrySent"]); - - // Show the Heartbeat notification and wait for it to be displayed. - let shownPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationOffered"); - gContentAPI.showHeartbeat("How would you rate Firefox?", "Thank you!", flowId, engagementURL); - - let expiredPromise = promiseWaitHeartbeatNotification("Heartbeat:SurveyExpired"); - let closedPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationClosed"); - let pingPromise = promiseWaitHeartbeatNotification("Heartbeat:TelemetrySent"); - - yield Promise.all([shownPromise, expiredPromise, closedPromise]); - // Validate the ping data. - let data = yield pingPromise; - checkTelemetry(data, flowId, ["offeredTS", "expiredTS", "closedTS"]); - - Services.prefs.clearUserPref("browser.uitour.surveyDuration"); - - // This rejects whenever an unexpected notification is received. - yield receivedExpectedPromise; -}) - -/** - * Check that certain whitelisted experiment parameters get reflected in the - * Telemetry ping - */ -add_UITour_task(function* test_telemetry_params() { - let flowId = "telemetry-params-" + Math.random(); - let engagementURL = "http://example.com"; - let extraParams = { - "surveyId": "foo", - "surveyVersion": 1.5, - "testing": true, - "notWhitelisted": 123, - }; - let expectedFields = ["surveyId", "surveyVersion", "testing"]; - - // We need to call |gContentAPI.observe| at least once to set a valid |notificationListener| - // in UITour-lib.js, otherwise no message will get propagated. - gContentAPI.observe(() => {}); - - let receivedExpectedPromise = promiseWaitExpectedNotifications( - ["Heartbeat:NotificationOffered", "Heartbeat:NotificationClosed", "Heartbeat:TelemetrySent"]); - - // Show the Heartbeat notification and wait for it to be displayed. - let shownPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationOffered"); - gContentAPI.showHeartbeat("How would you rate Firefox?", "Thank you!", - flowId, engagementURL, null, null, extraParams); - yield shownPromise; - - let closedPromise = promiseWaitHeartbeatNotification("Heartbeat:NotificationClosed"); - let pingPromise = promiseWaitHeartbeatNotification("Heartbeat:TelemetrySent"); - cleanUpNotification(flowId); - - // The notification was closed. - let data = yield closedPromise; - validateTimestamp('Heartbeat:NotificationClosed', data.timestamp); - - // Validate the data we send out. - data = yield pingPromise; - info("'Heartbeat:TelemetrySent' notification received."); - checkTelemetry(data, flowId, ["offeredTS", "closedTS"].concat(expectedFields)); - for (let param of expectedFields) { - is(data[param], extraParams[param], - "Whitelisted experiment configs should be copied into Telemetry pings"); - } - - // This rejects whenever an unexpected notification is received. - yield receivedExpectedPromise; -}) diff --git a/browser/components/uitour/test/browser_UITour_modalDialog.js b/browser/components/uitour/test/browser_UITour_modalDialog.js deleted file mode 100644 index 1890739c4..000000000 --- a/browser/components/uitour/test/browser_UITour_modalDialog.js +++ /dev/null @@ -1,104 +0,0 @@ -"use strict"; - -var gTestTab; -var gContentAPI; -var gContentWindow; -var handleDialog; - -// Modified from toolkit/components/passwordmgr/test/prompt_common.js -var didDialog; - -var timer; // keep in outer scope so it's not GC'd before firing -function startCallbackTimer() { - didDialog = false; - - // Delay before the callback twiddles the prompt. - const dialogDelay = 10; - - // Use a timer to invoke a callback to twiddle the authentication dialog - timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - timer.init(observer, dialogDelay, Ci.nsITimer.TYPE_ONE_SHOT); -} - - -var observer = SpecialPowers.wrapCallbackObject({ - QueryInterface : function (iid) { - const interfaces = [Ci.nsIObserver, - Ci.nsISupports, Ci.nsISupportsWeakReference]; - - if (!interfaces.some( function(v) { return iid.equals(v) } )) - throw SpecialPowers.Components.results.NS_ERROR_NO_INTERFACE; - return this; - }, - - observe : function (subject, topic, data) { - var doc = getDialogDoc(); - if (doc) - handleDialog(doc); - else - startCallbackTimer(); // try again in a bit - } -}); - -function getDialogDoc() { - // Find the <browser> which contains notifyWindow, by looking - // through all the open windows and all the <browsers> in each. - var wm = Cc["@mozilla.org/appshell/window-mediator;1"]. - getService(Ci.nsIWindowMediator); - // var enumerator = wm.getEnumerator("navigator:browser"); - var enumerator = wm.getXULWindowEnumerator(null); - - while (enumerator.hasMoreElements()) { - var win = enumerator.getNext(); - var windowDocShell = win.QueryInterface(Ci.nsIXULWindow).docShell; - - var containedDocShells = windowDocShell.getDocShellEnumerator( - Ci.nsIDocShellTreeItem.typeChrome, - Ci.nsIDocShell.ENUMERATE_FORWARDS); - while (containedDocShells.hasMoreElements()) { - // Get the corresponding document for this docshell - var childDocShell = containedDocShells.getNext(); - // We don't want it if it's not done loading. - if (childDocShell.busyFlags != Ci.nsIDocShell.BUSY_FLAGS_NONE) - continue; - var childDoc = childDocShell.QueryInterface(Ci.nsIDocShell) - .contentViewer - .DOMDocument; - - // ok(true, "Got window: " + childDoc.location.href); - if (childDoc.location.href == "chrome://global/content/commonDialog.xul") - return childDoc; - } - } - - return null; -} - -function test() { - UITourTest(); -} - - -var tests = [ - taskify(function* test_modal_dialog_while_opening_tooltip() { - let panelShown; - let popup; - - handleDialog = (doc) => { - popup = document.getElementById("UITourTooltip"); - gContentAPI.showInfo("appMenu", "test title", "test text"); - doc.defaultView.setTimeout(function() { - is(popup.state, "closed", "Popup shouldn't be shown while dialog is up"); - panelShown = promisePanelElementShown(window, popup); - let dialog = doc.getElementById("commonDialog"); - dialog.acceptDialog(); - }, 1000); - }; - startCallbackTimer(); - executeSoon(() => alert("test")); - yield waitForConditionPromise(() => panelShown, "Timed out waiting for panel promise to be assigned", 100); - yield panelShown; - - yield hideInfoPromise(); - }) -]; diff --git a/browser/components/uitour/test/browser_UITour_observe.js b/browser/components/uitour/test/browser_UITour_observe.js deleted file mode 100644 index b4b435659..000000000 --- a/browser/components/uitour/test/browser_UITour_observe.js +++ /dev/null @@ -1,85 +0,0 @@ -"use strict"; - -var gTestTab; -var gContentAPI; -var gContentWindow; - -function test() { - requestLongerTimeout(2); - UITourTest(); -} - -var tests = [ - function test_no_params(done) { - function listener(event, params) { - is(event, "test-event-1", "Correct event name"); - is(params, null, "No param object"); - gContentAPI.observe(null); - done(); - } - - gContentAPI.observe(listener, () => { - UITour.notify("test-event-1"); - }); - }, - function test_param_string(done) { - function listener(event, params) { - is(event, "test-event-2", "Correct event name"); - is(params, "a param", "Correct param string"); - gContentAPI.observe(null); - done(); - } - - gContentAPI.observe(listener, () => { - UITour.notify("test-event-2", "a param"); - }); - }, - function test_param_object(done) { - function listener(event, params) { - is(event, "test-event-3", "Correct event name"); - is(JSON.stringify(params), JSON.stringify({key: "something"}), "Correct param object"); - gContentAPI.observe(null); - done(); - } - - gContentAPI.observe(listener, () => { - UITour.notify("test-event-3", {key: "something"}); - }); - }, - function test_background_tab(done) { - function listener(event, params) { - is(event, "test-event-background-1", "Correct event name"); - is(params, null, "No param object"); - gContentAPI.observe(null); - gBrowser.removeCurrentTab(); - done(); - } - - gContentAPI.observe(listener, () => { - gBrowser.selectedTab = gBrowser.addTab("about:blank"); - isnot(gBrowser.selectedTab, gTestTab, "Make sure the selected tab changed"); - - UITour.notify("test-event-background-1"); - }); - }, - // Make sure the tab isn't torn down when switching back to the tour one. - function test_background_then_foreground_tab(done) { - let blankTab = null; - function listener(event, params) { - is(event, "test-event-4", "Correct event name"); - is(params, null, "No param object"); - gContentAPI.observe(null); - gBrowser.removeTab(blankTab); - done(); - } - - gContentAPI.observe(listener, () => { - blankTab = gBrowser.selectedTab = gBrowser.addTab("about:blank"); - isnot(gBrowser.selectedTab, gTestTab, "Make sure the selected tab changed"); - gBrowser.selectedTab = gTestTab; - is(gBrowser.selectedTab, gTestTab, "Switch back to the test tab"); - - UITour.notify("test-event-4"); - }); - }, -]; diff --git a/browser/components/uitour/test/browser_UITour_panel_close_annotation.js b/browser/components/uitour/test/browser_UITour_panel_close_annotation.js deleted file mode 100644 index cff446573..000000000 --- a/browser/components/uitour/test/browser_UITour_panel_close_annotation.js +++ /dev/null @@ -1,153 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -/** - * Tests that annotations disappear when their target is hidden. - */ - -"use strict"; - -var gTestTab; -var gContentAPI; -var gContentWindow; -var highlight = document.getElementById("UITourHighlight"); -var tooltip = document.getElementById("UITourTooltip"); - -function test() { - registerCleanupFunction(() => { - // Close the find bar in case it's open in the remaining tab - gBrowser.getFindBar(gBrowser.selectedTab).close(); - }); - UITourTest(); -} - -var tests = [ - function test_highlight_move_outside_panel(done) { - gContentAPI.showInfo("urlbar", "test title", "test text"); - gContentAPI.showHighlight("customize"); - waitForElementToBeVisible(highlight, function checkPanelIsOpen() { - isnot(PanelUI.panel.state, "closed", "Panel should have opened"); - - // Move the highlight outside which should close the app menu. - gContentAPI.showHighlight("appMenu"); - waitForPopupAtAnchor(highlight.parentElement, document.getElementById("PanelUI-button"), () => { - isnot(PanelUI.panel.state, "open", - "Panel should have closed after the highlight moved elsewhere."); - ok(tooltip.state == "showing" || tooltip.state == "open", "The info panel should have remained open"); - done(); - }, "Highlight should move to the appMenu button and still be visible"); - }, "Highlight should be shown after showHighlight() for fixed panel items"); - }, - - function test_highlight_panel_hideMenu(done) { - gContentAPI.showHighlight("customize"); - gContentAPI.showInfo("search", "test title", "test text"); - waitForElementToBeVisible(highlight, function checkPanelIsOpen() { - isnot(PanelUI.panel.state, "closed", "Panel should have opened"); - - // Close the app menu and make sure the highlight also disappeared. - gContentAPI.hideMenu("appMenu"); - waitForElementToBeHidden(highlight, function checkPanelIsClosed() { - isnot(PanelUI.panel.state, "open", - "Panel still should have closed"); - ok(tooltip.state == "showing" || tooltip.state == "open", "The info panel should have remained open"); - done(); - }, "Highlight should have disappeared when panel closed"); - }, "Highlight should be shown after showHighlight() for fixed panel items"); - }, - - function test_highlight_panel_click_find(done) { - gContentAPI.showHighlight("help"); - gContentAPI.showInfo("searchIcon", "test title", "test text"); - waitForElementToBeVisible(highlight, function checkPanelIsOpen() { - isnot(PanelUI.panel.state, "closed", "Panel should have opened"); - - // Click the find button which should close the panel. - let findButton = document.getElementById("find-button"); - EventUtils.synthesizeMouseAtCenter(findButton, {}); - waitForElementToBeHidden(highlight, function checkPanelIsClosed() { - isnot(PanelUI.panel.state, "open", - "Panel should have closed when the find bar opened"); - ok(tooltip.state == "showing" || tooltip.state == "open", "The info panel should have remained open"); - done(); - }, "Highlight should have disappeared when panel closed"); - }, "Highlight should be shown after showHighlight() for fixed panel items"); - }, - - function test_highlight_info_panel_click_find(done) { - gContentAPI.showHighlight("help"); - gContentAPI.showInfo("customize", "customize me!", "awesome!"); - waitForElementToBeVisible(highlight, function checkPanelIsOpen() { - isnot(PanelUI.panel.state, "closed", "Panel should have opened"); - - // Click the find button which should close the panel. - let findButton = document.getElementById("find-button"); - EventUtils.synthesizeMouseAtCenter(findButton, {}); - waitForElementToBeHidden(highlight, function checkPanelIsClosed() { - isnot(PanelUI.panel.state, "open", - "Panel should have closed when the find bar opened"); - waitForElementToBeHidden(tooltip, function checkTooltipIsClosed() { - isnot(tooltip.state, "open", "The info panel should have closed too"); - done(); - }, "Tooltip should hide with the menu"); - }, "Highlight should have disappeared when panel closed"); - }, "Highlight should be shown after showHighlight() for fixed panel items"); - }, - - function test_highlight_panel_open_subview(done) { - gContentAPI.showHighlight("customize"); - gContentAPI.showInfo("backForward", "test title", "test text"); - waitForElementToBeVisible(highlight, function checkPanelIsOpen() { - isnot(PanelUI.panel.state, "closed", "Panel should have opened"); - - // Click the help button which should open the subview in the panel menu. - let helpButton = document.getElementById("PanelUI-help"); - EventUtils.synthesizeMouseAtCenter(helpButton, {}); - waitForElementToBeHidden(highlight, function highlightHidden() { - is(PanelUI.panel.state, "open", - "Panel should have stayed open when the subview opened"); - ok(tooltip.state == "showing" || tooltip.state == "open", "The info panel should have remained open"); - PanelUI.hide(); - done(); - }, "Highlight should have disappeared when the subview opened"); - }, "Highlight should be shown after showHighlight() for fixed panel items"); - }, - - function test_info_panel_open_subview(done) { - gContentAPI.showHighlight("urlbar"); - gContentAPI.showInfo("customize", "customize me!", "Open a subview"); - waitForElementToBeVisible(tooltip, function checkPanelIsOpen() { - isnot(PanelUI.panel.state, "closed", "Panel should have opened"); - - // Click the help button which should open the subview in the panel menu. - let helpButton = document.getElementById("PanelUI-help"); - EventUtils.synthesizeMouseAtCenter(helpButton, {}); - waitForElementToBeHidden(tooltip, function tooltipHidden() { - is(PanelUI.panel.state, "open", - "Panel should have stayed open when the subview opened"); - is(highlight.parentElement.state, "open", "The highlight should have remained open"); - PanelUI.hide(); - done(); - }, "Tooltip should have disappeared when the subview opened"); - }, "Highlight should be shown after showHighlight() for fixed panel items"); - }, - - function test_info_move_outside_panel(done) { - gContentAPI.showInfo("addons", "test title", "test text"); - gContentAPI.showHighlight("urlbar"); - let addonsButton = document.getElementById("add-ons-button"); - waitForPopupAtAnchor(tooltip, addonsButton, function checkPanelIsOpen() { - isnot(PanelUI.panel.state, "closed", "Panel should have opened"); - - // Move the info panel outside which should close the app menu. - gContentAPI.showInfo("appMenu", "Cool menu button", "It's three lines"); - waitForPopupAtAnchor(tooltip, document.getElementById("PanelUI-button"), () => { - isnot(PanelUI.panel.state, "open", - "Menu should have closed after the highlight moved elsewhere."); - is(highlight.parentElement.state, "open", "The highlight should have remained visible"); - done(); - }, "Tooltip should move to the appMenu button and still be visible"); - }, "Tooltip should be shown after showInfo() for a panel item"); - }, - -]; diff --git a/browser/components/uitour/test/browser_UITour_pocket.js b/browser/components/uitour/test/browser_UITour_pocket.js deleted file mode 100644 index 29548a475..000000000 --- a/browser/components/uitour/test/browser_UITour_pocket.js +++ /dev/null @@ -1,82 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -var gTestTab; -var gContentAPI; -var gContentWindow; -var button; - -function test() { - UITourTest(); -} - -var tests = [ - taskify(function* test_menu_show_navbar() { - is(button.open, false, "Menu should initially be closed"); - gContentAPI.showMenu("pocket"); - - // The panel gets created dynamically. - let widgetPanel = null; - yield waitForConditionPromise(() => { - widgetPanel = document.getElementById("customizationui-widget-panel"); - return widgetPanel && widgetPanel.state == "open"; - }, "Menu should be visible after showMenu()"); - - ok(button.open, "Button should know its view is open"); - ok(!widgetPanel.hasAttribute("noautohide"), "@noautohide shouldn't be on the pocket panel"); - ok(button.hasAttribute("open"), "Pocket button should know that the menu is open"); - - widgetPanel.hidePopup(); - checkPanelIsHidden(widgetPanel); - }), - taskify(function* test_menu_show_appMenu() { - CustomizableUI.addWidgetToArea("pocket-button", CustomizableUI.AREA_PANEL); - - is(PanelUI.multiView.hasAttribute("panelopen"), false, "Multiview should initially be closed"); - gContentAPI.showMenu("pocket"); - - yield waitForConditionPromise(() => { - return PanelUI.panel.state == "open"; - }, "Menu should be visible after showMenu()"); - - ok(!PanelUI.panel.hasAttribute("noautohide"), "@noautohide shouldn't be on the pocket panel"); - ok(PanelUI.multiView.showingSubView, "Subview should be open"); - ok(PanelUI.multiView.hasAttribute("panelopen"), "Multiview should know it's open"); - - PanelUI.showMainView(); - PanelUI.panel.hidePopup(); - checkPanelIsHidden(PanelUI.panel); - }), -]; - -// End tests - -function checkPanelIsHidden(aPanel) { - if (aPanel.parentElement) { - is_hidden(aPanel); - } else { - ok(!aPanel.parentElement, "Widget panel should have been removed"); - } - is(button.hasAttribute("open"), false, "Pocket button should know that the panel is closed"); -} - -if (Services.prefs.getBoolPref("extensions.pocket.enabled")) { - let placement = CustomizableUI.getPlacementOfWidget("pocket-button"); - - // Add the button to the nav-bar by default. - if (!placement || placement.area != CustomizableUI.AREA_NAVBAR) { - CustomizableUI.addWidgetToArea("pocket-button", CustomizableUI.AREA_NAVBAR); - } - registerCleanupFunction(() => { - CustomizableUI.reset(); - }); - - let widgetGroupWrapper = CustomizableUI.getWidget("pocket-button"); - button = widgetGroupWrapper.forWindow(window).node; - ok(button, "Got button node"); -} else { - todo(false, "Pocket is disabled so skip its UITour tests"); - tests = []; -} diff --git a/browser/components/uitour/test/browser_UITour_registerPageID.js b/browser/components/uitour/test/browser_UITour_registerPageID.js deleted file mode 100644 index 369abb1ed..000000000 --- a/browser/components/uitour/test/browser_UITour_registerPageID.js +++ /dev/null @@ -1,108 +0,0 @@ -"use strict"; - -var gTestTab; -var gContentAPI; -var gContentWindow; - -Components.utils.import("resource://gre/modules/UITelemetry.jsm"); -Components.utils.import("resource:///modules/BrowserUITelemetry.jsm"); - -add_task(function* setup_telemetry() { - UITelemetry._enabled = true; - - registerCleanupFunction(function() { - Services.prefs.clearUserPref("browser.uitour.seenPageIDs"); - resetSeenPageIDsLazyGetter(); - UITelemetry._enabled = undefined; - BrowserUITelemetry.setBucket(null); - delete window.UITelemetry; - delete window.BrowserUITelemetry; - }); -}); - -add_task(setup_UITourTest); - -function resetSeenPageIDsLazyGetter() { - delete UITour.seenPageIDs; - // This should be kept in sync with how UITour.init() sets this. - Object.defineProperty(UITour, "seenPageIDs", { - get: UITour.restoreSeenPageIDs.bind(UITour), - configurable: true, - }); -} - -function checkExpectedSeenPageIDs(expected) { - is(UITour.seenPageIDs.size, expected.length, "Should be " + expected.length + " total seen page IDs"); - - for (let id of expected) - ok(UITour.seenPageIDs.has(id), "Should have seen '" + id + "' page ID"); - - let prefData = Services.prefs.getCharPref("browser.uitour.seenPageIDs"); - prefData = new Map(JSON.parse(prefData)); - - is(prefData.size, expected.length, "Should be " + expected.length + " total seen page IDs persisted"); - - for (let id of expected) - ok(prefData.has(id), "Should have seen '" + id + "' page ID persisted"); -} - - -add_UITour_task(function test_seenPageIDs_restore() { - info("Setting up seenPageIDs to be restored from pref"); - let data = JSON.stringify([ - ["savedID1", { lastSeen: Date.now() }], - ["savedID2", { lastSeen: Date.now() }], - // 9 weeks ago, should auto expire. - ["savedID3", { lastSeen: Date.now() - 9 * 7 * 24 * 60 * 60 * 1000 }], - ]); - Services.prefs.setCharPref("browser.uitour.seenPageIDs", - data); - - resetSeenPageIDsLazyGetter(); - checkExpectedSeenPageIDs(["savedID1", "savedID2"]); -}); - -add_UITour_task(function* test_seenPageIDs_set_1() { - yield gContentAPI.registerPageID("testpage1"); - - yield waitForConditionPromise(() => UITour.seenPageIDs.size == 3, "Waiting for page to be registered."); - - checkExpectedSeenPageIDs(["savedID1", "savedID2", "testpage1"]); - - const PREFIX = BrowserUITelemetry.BUCKET_PREFIX; - const SEP = BrowserUITelemetry.BUCKET_SEPARATOR; - - let bucket = PREFIX + "UITour" + SEP + "testpage1"; - is(BrowserUITelemetry.currentBucket, bucket, "Bucket should have correct name"); - - gBrowser.selectedTab = gBrowser.addTab("about:blank"); - bucket = PREFIX + "UITour" + SEP + "testpage1" + SEP + "inactive" + SEP + "1m"; - is(BrowserUITelemetry.currentBucket, bucket, - "After switching tabs, bucket should be expiring"); - - gBrowser.removeTab(gBrowser.selectedTab); - gBrowser.selectedTab = gTestTab; - BrowserUITelemetry.setBucket(null); -}); - -add_UITour_task(function* test_seenPageIDs_set_2() { - yield gContentAPI.registerPageID("testpage2"); - - yield waitForConditionPromise(() => UITour.seenPageIDs.size == 4, "Waiting for page to be registered."); - - checkExpectedSeenPageIDs(["savedID1", "savedID2", "testpage1", "testpage2"]); - - const PREFIX = BrowserUITelemetry.BUCKET_PREFIX; - const SEP = BrowserUITelemetry.BUCKET_SEPARATOR; - - let bucket = PREFIX + "UITour" + SEP + "testpage2"; - is(BrowserUITelemetry.currentBucket, bucket, "Bucket should have correct name"); - - gBrowser.removeTab(gTestTab); - gTestTab = null; - bucket = PREFIX + "UITour" + SEP + "testpage2" + SEP + "closed" + SEP + "1m"; - is(BrowserUITelemetry.currentBucket, bucket, - "After closing tab, bucket should be expiring"); - - BrowserUITelemetry.setBucket(null); -}); diff --git a/browser/components/uitour/test/browser_UITour_resetProfile.js b/browser/components/uitour/test/browser_UITour_resetProfile.js deleted file mode 100644 index c91d0a4f2..000000000 --- a/browser/components/uitour/test/browser_UITour_resetProfile.js +++ /dev/null @@ -1,48 +0,0 @@ -"use strict"; - -var gTestTab; -var gContentAPI; -var gContentWindow; - -add_task(setup_UITourTest); - -// Test that a reset profile dialog appears when "resetFirefox" event is triggered -add_UITour_task(function* test_resetFirefox() { - let canReset = yield getConfigurationPromise("canReset"); - ok(!canReset, "Shouldn't be able to reset from mochitest's temporary profile."); - let dialogPromise = new Promise((resolve) => { - let winWatcher = Cc["@mozilla.org/embedcomp/window-watcher;1"]. - getService(Ci.nsIWindowWatcher); - winWatcher.registerNotification(function onOpen(subj, topic, data) { - if (topic == "domwindowopened" && subj instanceof Ci.nsIDOMWindow) { - subj.addEventListener("load", function onLoad() { - subj.removeEventListener("load", onLoad); - if (subj.document.documentURI == - "chrome://global/content/resetProfile.xul") { - winWatcher.unregisterNotification(onOpen); - ok(true, "Observed search manager window open"); - is(subj.opener, window, - "Reset Firefox event opened a reset profile window."); - subj.close(); - resolve(); - } - }); - } - }); - }); - - // make reset possible. - let profileService = Cc["@mozilla.org/toolkit/profile-service;1"]. - getService(Ci.nsIToolkitProfileService); - let currentProfileDir = Services.dirsvc.get("ProfD", Ci.nsIFile); - let profileName = "mochitest-test-profile-temp-" + Date.now(); - let tempProfile = profileService.createProfile(currentProfileDir, profileName); - canReset = yield getConfigurationPromise("canReset"); - ok(canReset, "Should be able to reset from mochitest's temporary profile once it's in the profile manager."); - yield gContentAPI.resetFirefox(); - yield dialogPromise; - tempProfile.remove(false); - canReset = yield getConfigurationPromise("canReset"); - ok(!canReset, "Shouldn't be able to reset from mochitest's temporary profile once removed from the profile manager."); -}); - diff --git a/browser/components/uitour/test/browser_UITour_showNewTab.js b/browser/components/uitour/test/browser_UITour_showNewTab.js deleted file mode 100644 index 2deb08148..000000000 --- a/browser/components/uitour/test/browser_UITour_showNewTab.js +++ /dev/null @@ -1,17 +0,0 @@ -"use strict"; - -var gTestTab; -var gContentAPI; -var gContentWindow; - -add_task(setup_UITourTest); - -// Test that we can switch to about:newtab -add_UITour_task(function* test_aboutNewTab() { - let newTabLoaded = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser, false, "about:newtab"); - info("Showing about:newtab"); - yield gContentAPI.showNewTab(); - info("Waiting for about:newtab to load"); - yield newTabLoaded; - is(gBrowser.selectedBrowser.currentURI.spec, "about:newtab", "Loaded about:newtab"); -}); diff --git a/browser/components/uitour/test/browser_UITour_sync.js b/browser/components/uitour/test/browser_UITour_sync.js deleted file mode 100644 index 14ac0c1f6..000000000 --- a/browser/components/uitour/test/browser_UITour_sync.js +++ /dev/null @@ -1,105 +0,0 @@ -"use strict"; - -var gTestTab; -var gContentAPI; -var gContentWindow; - -registerCleanupFunction(function() { - Services.prefs.clearUserPref("services.sync.username"); -}); - -add_task(setup_UITourTest); - -add_UITour_task(function* test_checkSyncSetup_disabled() { - let result = yield getConfigurationPromise("sync"); - is(result.setup, false, "Sync shouldn't be setup by default"); -}); - -add_UITour_task(function* test_checkSyncSetup_enabled() { - Services.prefs.setCharPref("services.sync.username", "uitour@tests.mozilla.org"); - let result = yield getConfigurationPromise("sync"); - is(result.setup, true, "Sync should be setup"); -}); - -add_UITour_task(function* test_checkSyncCounts() { - Services.prefs.setIntPref("services.sync.clients.devices.desktop", 4); - Services.prefs.setIntPref("services.sync.clients.devices.mobile", 5); - Services.prefs.setIntPref("services.sync.numClients", 9); - let result = yield getConfigurationPromise("sync"); - is(result.mobileDevices, 5, "mobileDevices should be set"); - is(result.desktopDevices, 4, "desktopDevices should be set"); - is(result.totalDevices, 9, "totalDevices should be set"); - - Services.prefs.clearUserPref("services.sync.clients.devices.desktop"); - result = yield getConfigurationPromise("sync"); - is(result.mobileDevices, 5, "mobileDevices should be set"); - is(result.desktopDevices, 0, "desktopDevices should be 0"); - is(result.totalDevices, 9, "totalDevices should be set"); - - Services.prefs.clearUserPref("services.sync.clients.devices.mobile"); - result = yield getConfigurationPromise("sync"); - is(result.mobileDevices, 0, "mobileDevices should be 0"); - is(result.desktopDevices, 0, "desktopDevices should be 0"); - is(result.totalDevices, 9, "totalDevices should be set"); - - Services.prefs.clearUserPref("services.sync.numClients"); - result = yield getConfigurationPromise("sync"); - is(result.mobileDevices, 0, "mobileDevices should be 0"); - is(result.desktopDevices, 0, "desktopDevices should be 0"); - is(result.totalDevices, 0, "totalDevices should be 0"); -}); - -// The showFirefoxAccounts API is sync related, so we test that here too... -add_UITour_task(function* test_firefoxAccountsNoParams() { - yield gContentAPI.showFirefoxAccounts(); - yield BrowserTestUtils.browserLoaded(gTestTab.linkedBrowser, false, - "about:accounts?action=signup&entrypoint=uitour"); -}); - -add_UITour_task(function* test_firefoxAccountsValidParams() { - yield gContentAPI.showFirefoxAccounts({ utm_foo: "foo", utm_bar: "bar" }); - yield BrowserTestUtils.browserLoaded(gTestTab.linkedBrowser, false, - "about:accounts?action=signup&entrypoint=uitour&utm_foo=foo&utm_bar=bar"); -}); - -add_UITour_task(function* test_firefoxAccountsNonAlphaValue() { - // All characters in the value are allowed, but they must be automatically escaped. - // (we throw a unicode character in there too - it's not auto-utf8 encoded, - // but that's ok, so long as it is escaped correctly.) - let value = "foo& /=?:\\\xa9"; - // encodeURIComponent encodes spaces to %20 but we want "+" - let expected = encodeURIComponent(value).replace(/%20/g, "+"); - yield gContentAPI.showFirefoxAccounts({ utm_foo: value }); - yield BrowserTestUtils.browserLoaded(gTestTab.linkedBrowser, false, - "about:accounts?action=signup&entrypoint=uitour&utm_foo=" + expected); -}); - -// A helper to check the request was ignored due to invalid params. -function* checkAboutAccountsNotLoaded() { - try { - yield waitForConditionPromise(() => { - return gBrowser.selectedBrowser.currentURI.spec.startsWith("about:accounts"); - }, "Check if about:accounts opened"); - ok(false, "No about:accounts tab should have opened"); - } catch (ex) { - ok(true, "No about:accounts tab opened"); - } -} - -add_UITour_task(function* test_firefoxAccountsNonObject() { - // non-string should be rejected. - yield gContentAPI.showFirefoxAccounts(99); - yield checkAboutAccountsNotLoaded(); -}); - -add_UITour_task(function* test_firefoxAccountsNonUtmPrefix() { - // Any non "utm_" name should should be rejected. - yield gContentAPI.showFirefoxAccounts({ utm_foo: "foo", bar: "bar" }); - yield checkAboutAccountsNotLoaded(); -}); - -add_UITour_task(function* test_firefoxAccountsNonAlphaName() { - // Any "utm_" name which includes non-alpha chars should be rejected. - yield gContentAPI.showFirefoxAccounts({ utm_foo: "foo", "utm_bar=": "bar" }); - yield checkAboutAccountsNotLoaded(); -}); diff --git a/browser/components/uitour/test/browser_UITour_toggleReaderMode.js b/browser/components/uitour/test/browser_UITour_toggleReaderMode.js deleted file mode 100644 index 58313e74b..000000000 --- a/browser/components/uitour/test/browser_UITour_toggleReaderMode.js +++ /dev/null @@ -1,16 +0,0 @@ -"use strict"; - -var gTestTab; -var gContentAPI; -var gContentWindow; - -add_task(setup_UITourTest); - -add_UITour_task(function*() { - ok(!gBrowser.selectedBrowser.currentURI.spec.startsWith("about:reader"), - "Should not be in reader mode at start of test."); - yield gContentAPI.toggleReaderMode(); - yield waitForConditionPromise(() => gBrowser.selectedBrowser.currentURI.spec.startsWith("about:reader")); - ok(gBrowser.selectedBrowser.currentURI.spec.startsWith("about:reader"), - "Should be in reader mode now."); -}); diff --git a/browser/components/uitour/test/browser_backgroundTab.js b/browser/components/uitour/test/browser_backgroundTab.js deleted file mode 100644 index c4117c698..000000000 --- a/browser/components/uitour/test/browser_backgroundTab.js +++ /dev/null @@ -1,46 +0,0 @@ -"use strict"; - -var gTestTab; -var gContentAPI; -var gContentWindow; - -requestLongerTimeout(2); -add_task(setup_UITourTest); - -add_UITour_task(function* test_bg_getConfiguration() { - info("getConfiguration is on the allowed list so should work"); - yield* loadForegroundTab(); - let data = yield getConfigurationPromise("availableTargets"); - ok(data, "Got data from getConfiguration"); - yield BrowserTestUtils.removeTab(gBrowser.selectedTab); -}); - -add_UITour_task(function* test_bg_showInfo() { - info("showInfo isn't on the allowed action list so should be denied"); - yield* loadForegroundTab(); - - yield showInfoPromise("appMenu", "Hello from the background", "Surprise!").then( - () => ok(false, "panel shouldn't have shown from a background tab"), - () => ok(true, "panel wasn't shown from a background tab")); - - yield BrowserTestUtils.removeTab(gBrowser.selectedTab); -}); - - -function* loadForegroundTab() { - // Spawn a content task that resolves once we're sure the visibilityState was - // changed. This state is what the tests in this file rely on. - let promise = ContentTask.spawn(gBrowser.selectedTab.linkedBrowser, null, function* () { - return new Promise(resolve => { - let document = content.document; - document.addEventListener("visibilitychange", function onStateChange() { - Assert.equal(document.visibilityState, "hidden", "UITour page should be hidden now."); - document.removeEventListener("visibilitychange", onStateChange); - resolve(); - }); - }); - }); - yield BrowserTestUtils.openNewForegroundTab(gBrowser); - yield promise; - isnot(gBrowser.selectedTab, gTestTab, "Make sure tour tab isn't selected"); -} diff --git a/browser/components/uitour/test/browser_closeTab.js b/browser/components/uitour/test/browser_closeTab.js deleted file mode 100644 index 2b998347a..000000000 --- a/browser/components/uitour/test/browser_closeTab.js +++ /dev/null @@ -1,18 +0,0 @@ -"use strict"; - -var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -var gTestTab; -var gContentAPI; -var gContentWindow; - -add_task(setup_UITourTest); - -add_UITour_task(function* test_closeTab() { - // Setting gTestTab to null indicates that the tab has already been closed, - // and if this does not happen the test run will fail. - let closePromise = BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "TabClose"); - yield gContentAPI.closeTab(); - yield closePromise; - gTestTab = null; -}); diff --git a/browser/components/uitour/test/browser_fxa.js b/browser/components/uitour/test/browser_fxa.js deleted file mode 100644 index 36ac45a62..000000000 --- a/browser/components/uitour/test/browser_fxa.js +++ /dev/null @@ -1,68 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts", - "resource://gre/modules/FxAccounts.jsm"); - -var gTestTab; -var gContentAPI; -var gContentWindow; - -function test() { - UITourTest(); -} - -registerCleanupFunction(function*() { - yield signOut(); - gFxAccounts.updateAppMenuItem(); -}); - -var tests = [ - taskify(function* test_highlight_accountStatus_loggedOut() { - let userData = yield fxAccounts.getSignedInUser(); - is(userData, null, "Not logged in initially"); - yield showMenuPromise("appMenu"); - yield showHighlightPromise("accountStatus"); - let highlight = document.getElementById("UITourHighlightContainer"); - is(highlight.getAttribute("targetName"), "accountStatus", "Correct highlight target"); - }), - - taskify(function* test_highlight_accountStatus_loggedIn() { - yield setSignedInUser(); - let userData = yield fxAccounts.getSignedInUser(); - isnot(userData, null, "Logged in now"); - gFxAccounts.updateAppMenuItem(); // Causes a leak - yield showMenuPromise("appMenu"); - yield showHighlightPromise("accountStatus"); - let highlight = document.getElementById("UITourHighlightContainer"); - is(highlight.popupBoxObject.anchorNode.id, "PanelUI-fxa-avatar", "Anchored on avatar"); - is(highlight.getAttribute("targetName"), "accountStatus", "Correct highlight target"); - }), -]; - -// Helpers copied from browser_aboutAccounts.js -// watch out - these will fire observers which if you aren't careful, may -// interfere with the tests. -function setSignedInUser(data) { - if (!data) { - data = { - email: "foo@example.com", - uid: "1234@lcip.org", - assertion: "foobar", - sessionToken: "dead", - kA: "beef", - kB: "cafe", - verified: true - }; - } - return fxAccounts.setSignedInUser(data); -} - -function signOut() { - // we always want a "localOnly" signout here... - return fxAccounts.signOut(true); -} diff --git a/browser/components/uitour/test/browser_no_tabs.js b/browser/components/uitour/test/browser_no_tabs.js deleted file mode 100644 index 62048b156..000000000 --- a/browser/components/uitour/test/browser_no_tabs.js +++ /dev/null @@ -1,102 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -var HiddenFrame = Cu.import("resource:///modules/HiddenFrame.jsm", {}).HiddenFrame; - -const HTML_NS = "http://www.w3.org/1999/xhtml"; -const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; - -/** - * Create a frame in the |hiddenDOMWindow| to host a |browser|, then load the URL in the - * latter. - * - * @param aURL - * The URL to open in the browser. - **/ -function createHiddenBrowser(aURL) { - let frame = new HiddenFrame(); - return new Promise(resolve => - frame.get().then(aFrame => { - let doc = aFrame.document; - let browser = doc.createElementNS(XUL_NS, "browser"); - browser.setAttribute("type", "content"); - browser.setAttribute("disableglobalhistory", "true"); - browser.setAttribute("src", aURL); - - doc.documentElement.appendChild(browser); - resolve({frame: frame, browser: browser}); - })); -} - -/** - * Remove the browser and the HiddenFrame. - * - * @param aFrame - * The HiddenFrame to dismiss. - * @param aBrowser - * The browser to dismiss. - */ -function destroyHiddenBrowser(aFrame, aBrowser) { - // Dispose of the hidden browser. - aBrowser.remove(); - - // Take care of the frame holding our invisible browser. - aFrame.destroy(); -} - -/** - * Test that UITour works when called when no tabs are available (e.g., when using windowless - * browsers). - */ -add_task(function* test_windowless_UITour() { - // Get the URL for the test page. - let pageURL = getRootDirectory(gTestPath) + "uitour.html"; - - // Allow the URL to use the UITour. - info("Adding UITour permission to the test page."); - let pageURI = Services.io.newURI(pageURL, null, null); - Services.perms.add(pageURI, "uitour", Services.perms.ALLOW_ACTION); - - // UITour's ping will resolve this promise. - let deferredPing = Promise.defer(); - - // Create a windowless browser and test that UITour works in it. - let browserPromise = createHiddenBrowser(pageURL); - browserPromise.then(frameInfo => { - isnot(frameInfo.browser, null, "The browser must exist and not be null."); - - // Load UITour frame script. - frameInfo.browser.messageManager.loadFrameScript( - "chrome://browser/content/content-UITour.js", false); - - // When the page loads, try to use UITour API. - frameInfo.browser.addEventListener("load", function loadListener() { - info("The test page was correctly loaded."); - - frameInfo.browser.removeEventListener("load", loadListener, true); - - // Get a reference to the UITour API. - info("Testing access to the UITour API."); - let contentWindow = Cu.waiveXrays(frameInfo.browser.contentDocument.defaultView); - isnot(contentWindow, null, "The content window must exist and not be null."); - - let uitourAPI = contentWindow.Mozilla.UITour; - - // Test the UITour API with a ping. - uitourAPI.ping(function() { - info("Ping response received from the UITour API."); - - // Make sure to clean up. - destroyHiddenBrowser(frameInfo.frame, frameInfo.browser); - - // Resolve our promise. - deferredPing.resolve(); - }); - }, true); - }); - - // Wait for the UITour ping to complete. - yield deferredPing.promise; -}); diff --git a/browser/components/uitour/test/browser_openPreferences.js b/browser/components/uitour/test/browser_openPreferences.js deleted file mode 100644 index c41865120..000000000 --- a/browser/components/uitour/test/browser_openPreferences.js +++ /dev/null @@ -1,36 +0,0 @@ -"use strict"; - -var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -var gTestTab; -var gContentAPI; -var gContentWindow; - -add_task(setup_UITourTest); - -add_UITour_task(function* test_openPreferences() { - let promiseTabOpened = BrowserTestUtils.waitForNewTab(gBrowser, "about:preferences"); - yield gContentAPI.openPreferences(); - let tab = yield promiseTabOpened; - yield BrowserTestUtils.removeTab(tab); -}); - -add_UITour_task(function* test_openInvalidPreferences() { - yield gContentAPI.openPreferences(999); - - try { - yield waitForConditionPromise(() => { - return gBrowser.selectedBrowser.currentURI.spec.startsWith("about:preferences"); - }, "Check if about:preferences opened"); - ok(false, "No about:preferences tab should have opened"); - } catch (ex) { - ok(true, "No about:preferences tab opened: " + ex); - } -}); - -add_UITour_task(function* test_openPrivacyPreferences() { - let promiseTabOpened = BrowserTestUtils.waitForNewTab(gBrowser, "about:preferences#privacy"); - yield gContentAPI.openPreferences("privacy"); - let tab = yield promiseTabOpened; - yield BrowserTestUtils.removeTab(tab); -}); diff --git a/browser/components/uitour/test/browser_openSearchPanel.js b/browser/components/uitour/test/browser_openSearchPanel.js deleted file mode 100644 index 5faa9db02..000000000 --- a/browser/components/uitour/test/browser_openSearchPanel.js +++ /dev/null @@ -1,33 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -var gTestTab; -var gContentAPI; -var gContentWindow; - -function test() { - UITourTest(); -} - -var tests = [ - function test_openSearchPanel(done) { - let searchbar = document.getElementById("searchbar"); - - // If suggestions are enabled, the panel will attempt to use the network to connect - // to the suggestions provider, causing the test suite to fail. - Services.prefs.setBoolPref("browser.search.suggest.enabled", false); - registerCleanupFunction(() => { - Services.prefs.clearUserPref("browser.search.suggest.enabled"); - }); - - ok(!searchbar.textbox.open, "Popup starts as closed"); - gContentAPI.openSearchPanel(() => { - ok(searchbar.textbox.open, "Popup was opened"); - searchbar.textbox.closePopup(); - ok(!searchbar.textbox.open, "Popup was closed"); - done(); - }); - }, -]; diff --git a/browser/components/uitour/test/browser_showMenu_controlCenter.js b/browser/components/uitour/test/browser_showMenu_controlCenter.js deleted file mode 100644 index 0faa5f862..000000000 --- a/browser/components/uitour/test/browser_showMenu_controlCenter.js +++ /dev/null @@ -1,44 +0,0 @@ -"use strict"; - -var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; -const CONTROL_CENTER_PANEL = gIdentityHandler._identityPopup; -const CONTROL_CENTER_MENU_NAME = "controlCenter"; - -var gTestTab; -var gContentAPI; -var gContentWindow; - -add_task(setup_UITourTest); - -add_UITour_task(function* test_showMenu() { - is_element_hidden(CONTROL_CENTER_PANEL, "Panel should initially be hidden"); - yield showMenuPromise(CONTROL_CENTER_MENU_NAME); - is_element_visible(CONTROL_CENTER_PANEL, "Panel should be visible after showMenu"); - - yield gURLBar.focus(); - is_element_visible(CONTROL_CENTER_PANEL, "Panel should remain visible after focus outside"); - - yield showMenuPromise(CONTROL_CENTER_MENU_NAME); - is_element_visible(CONTROL_CENTER_PANEL, - "Panel should remain visible and callback called after a 2nd showMenu"); - - yield BrowserTestUtils.withNewTab({ - gBrowser, - url: "about:blank" - }, function*() { - ok(true, "Tab opened"); - }); - - is_element_hidden(CONTROL_CENTER_PANEL, "Panel should hide upon tab switch"); -}); - -add_UITour_task(function* test_hideMenu() { - is_element_hidden(CONTROL_CENTER_PANEL, "Panel should initially be hidden"); - yield showMenuPromise(CONTROL_CENTER_MENU_NAME); - is_element_visible(CONTROL_CENTER_PANEL, "Panel should be visible after showMenu"); - let hidePromise = promisePanelElementHidden(window, CONTROL_CENTER_PANEL); - yield gContentAPI.hideMenu(CONTROL_CENTER_MENU_NAME); - yield hidePromise; - - is_element_hidden(CONTROL_CENTER_PANEL, "Panel should hide after hideMenu"); -}); diff --git a/browser/components/uitour/test/browser_trackingProtection.js b/browser/components/uitour/test/browser_trackingProtection.js deleted file mode 100644 index 32a9920ec..000000000 --- a/browser/components/uitour/test/browser_trackingProtection.js +++ /dev/null @@ -1,90 +0,0 @@ -"use strict"; - -var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; -const PREF_INTRO_COUNT = "privacy.trackingprotection.introCount"; -const PREF_TP_ENABLED = "privacy.trackingprotection.enabled"; -const BENIGN_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/benignPage.html"; -const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/general/trackingPage.html"; -const TOOLTIP_PANEL = document.getElementById("UITourTooltip"); -const TOOLTIP_ANCHOR = document.getElementById("tracking-protection-icon"); - -var {UrlClassifierTestUtils} = Cu.import("resource://testing-common/UrlClassifierTestUtils.jsm", {}); - -registerCleanupFunction(function() { - UrlClassifierTestUtils.cleanupTestTrackers(); - Services.prefs.clearUserPref(PREF_TP_ENABLED); - Services.prefs.clearUserPref(PREF_INTRO_COUNT); -}); - -function allowOneIntro() { - Services.prefs.setIntPref(PREF_INTRO_COUNT, TrackingProtection.MAX_INTROS - 1); -} - -add_task(function* setup_test() { - Services.prefs.setBoolPref(PREF_TP_ENABLED, true); - yield UrlClassifierTestUtils.addTestTrackers(); -}); - -add_task(function* test_benignPage() { - info("Load a test page not containing tracking elements"); - allowOneIntro(); - yield BrowserTestUtils.withNewTab({gBrowser, url: BENIGN_PAGE}, function*() { - yield waitForConditionPromise(() => { - return is_visible(TOOLTIP_PANEL); - }, "Info panel shouldn't appear on a benign page"). - then(() => ok(false, "Info panel shouldn't appear"), - () => { - ok(true, "Info panel didn't appear on a benign page"); - }); - - }); -}); - -add_task(function* test_trackingPages() { - info("Load a test page containing tracking elements"); - allowOneIntro(); - yield BrowserTestUtils.withNewTab({gBrowser, url: TRACKING_PAGE}, function*() { - yield new Promise((resolve, reject) => { - waitForPopupAtAnchor(TOOLTIP_PANEL, TOOLTIP_ANCHOR, resolve, - "Intro panel should appear"); - }); - - is(Services.prefs.getIntPref(PREF_INTRO_COUNT), TrackingProtection.MAX_INTROS, "Check intro count increased"); - - let step2URL = Services.urlFormatter.formatURLPref("privacy.trackingprotection.introURL") + - "?step=2&newtab=true"; - let buttons = document.getElementById("UITourTooltipButtons"); - - info("Click the step text and nothing should happen"); - let tabCount = gBrowser.tabs.length; - yield EventUtils.synthesizeMouseAtCenter(buttons.children[0], {}); - is(gBrowser.tabs.length, tabCount, "Same number of tabs should be open"); - - info("Resetting count to test that viewing the tour prevents future panels"); - allowOneIntro(); - - let panelHiddenPromise = promisePanelElementHidden(window, TOOLTIP_PANEL); - let tabPromise = BrowserTestUtils.waitForNewTab(gBrowser, step2URL); - info("Clicking the main button"); - EventUtils.synthesizeMouseAtCenter(buttons.children[1], {}); - let tab = yield tabPromise; - is(Services.prefs.getIntPref(PREF_INTRO_COUNT), TrackingProtection.MAX_INTROS, - "Check intro count is at the max after opening step 2"); - is(gBrowser.tabs.length, tabCount + 1, "Tour step 2 tab opened"); - yield panelHiddenPromise; - ok(true, "Panel hid when the button was clicked"); - yield BrowserTestUtils.removeTab(tab); - }); - - info("Open another tracking page and make sure we don't show the panel again"); - yield BrowserTestUtils.withNewTab({gBrowser, url: TRACKING_PAGE}, function*() { - yield waitForConditionPromise(() => { - return is_visible(TOOLTIP_PANEL); - }, "Info panel shouldn't appear more than MAX_INTROS"). - then(() => ok(false, "Info panel shouldn't appear again"), - () => { - ok(true, "Info panel didn't appear more than MAX_INTROS on tracking pages"); - }); - - }); -}); diff --git a/browser/components/uitour/test/browser_trackingProtection_tour.js b/browser/components/uitour/test/browser_trackingProtection_tour.js deleted file mode 100644 index 0ee0e1686..000000000 --- a/browser/components/uitour/test/browser_trackingProtection_tour.js +++ /dev/null @@ -1,77 +0,0 @@ -"use strict"; - -var gTestTab; -var gContentAPI; -var gContentWindow; - -const { UrlClassifierTestUtils } = Cu.import("resource://testing-common/UrlClassifierTestUtils.jsm", {}); - -const TP_ENABLED_PREF = "privacy.trackingprotection.enabled"; - -add_task(setup_UITourTest); - -add_task(function* test_setup() { - Services.prefs.setBoolPref("privacy.trackingprotection.enabled", true); - yield UrlClassifierTestUtils.addTestTrackers(); - - registerCleanupFunction(function() { - UrlClassifierTestUtils.cleanupTestTrackers(); - Services.prefs.clearUserPref("privacy.trackingprotection.enabled"); - }); -}); - -add_UITour_task(function* test_unblock_target() { - yield* checkToggleTarget("controlCenter-trackingUnblock"); -}); - -add_UITour_task(function* setup_block_target() { - // Preparation for test_block_target. These are separate since the reload - // interferes with UITour as it does a teardown. All we really care about - // is the permission manager entry but UITour tests shouldn't rely on that - // implementation detail. - TrackingProtection.disableForCurrentPage(); -}); - -add_UITour_task(function* test_block_target() { - yield* checkToggleTarget("controlCenter-trackingBlock"); - TrackingProtection.enableForCurrentPage(); -}); - - -function* checkToggleTarget(targetID) { - let popup = document.getElementById("UITourTooltip"); - - yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function () { - let doc = content.document; - let iframe = doc.createElement("iframe"); - iframe.setAttribute("id", "tracking-element"); - iframe.setAttribute("src", "https://tracking.example.com/"); - doc.body.insertBefore(iframe, doc.body.firstChild); - }); - - let testTargetAvailability = function* (expectedAvailable) { - let data = yield getConfigurationPromise("availableTargets"); - let available = (data.targets.indexOf(targetID) != -1); - is(available, expectedAvailable, "Target has expected availability."); - }; - yield testTargetAvailability(false); - yield showMenuPromise("controlCenter"); - yield testTargetAvailability(true); - - yield showInfoPromise(targetID, "This is " + targetID, - "My arrow should be on the side"); - is(popup.popupBoxObject.alignmentPosition, "end_before", - "Check " + targetID + " position"); - - let hideMenuPromise = - promisePanelElementHidden(window, gIdentityHandler._identityPopup); - yield gContentAPI.hideMenu("controlCenter"); - yield hideMenuPromise; - - ok(!is_visible(popup), "The tooltip should now be hidden."); - yield testTargetAvailability(false); - - yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function () { - content.document.getElementById("tracking-element").remove(); - }); -} diff --git a/browser/components/uitour/test/head.js b/browser/components/uitour/test/head.js deleted file mode 100644 index 2b5b994ae..000000000 --- a/browser/components/uitour/test/head.js +++ /dev/null @@ -1,449 +0,0 @@ -"use strict"; - -Cu.import("resource://gre/modules/Promise.jsm"); -Cu.import("resource://gre/modules/Task.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "UITour", - "resource:///modules/UITour.jsm"); - - -const SINGLE_TRY_TIMEOUT = 100; -const NUMBER_OF_TRIES = 30; - -function waitForConditionPromise(condition, timeoutMsg, tryCount=NUMBER_OF_TRIES) { - let defer = Promise.defer(); - let tries = 0; - function checkCondition() { - if (tries >= tryCount) { - defer.reject(timeoutMsg); - } - var conditionPassed; - try { - conditionPassed = condition(); - } catch (e) { - return defer.reject(e); - } - if (conditionPassed) { - return defer.resolve(); - } - tries++; - setTimeout(checkCondition, SINGLE_TRY_TIMEOUT); - return undefined; - } - setTimeout(checkCondition, SINGLE_TRY_TIMEOUT); - return defer.promise; -} - -function waitForCondition(condition, nextTest, errorMsg) { - waitForConditionPromise(condition, errorMsg).then(nextTest, (reason) => { - ok(false, reason + (reason.stack ? "\n" + reason.stack : "")); - }); -} - -/** - * Wrapper to partially transition tests to Task. Use `add_UITour_task` instead for new tests. - */ -function taskify(fun) { - return (done) => { - // Output the inner function name otherwise no name will be output. - info("\t" + fun.name); - return Task.spawn(fun).then(done, (reason) => { - ok(false, reason); - done(); - }); - }; -} - -function is_hidden(element) { - var style = element.ownerGlobal.getComputedStyle(element); - if (style.display == "none") - return true; - if (style.visibility != "visible") - return true; - if (style.display == "-moz-popup") - return ["hiding", "closed"].indexOf(element.state) != -1; - - // Hiding a parent element will hide all its children - if (element.parentNode != element.ownerDocument) - return is_hidden(element.parentNode); - - return false; -} - -function is_visible(element) { - var style = element.ownerGlobal.getComputedStyle(element); - if (style.display == "none") - return false; - if (style.visibility != "visible") - return false; - if (style.display == "-moz-popup" && element.state != "open") - return false; - - // Hiding a parent element will hide all its children - if (element.parentNode != element.ownerDocument) - return is_visible(element.parentNode); - - return true; -} - -function is_element_visible(element, msg) { - isnot(element, null, "Element should not be null, when checking visibility"); - ok(is_visible(element), msg); -} - -function waitForElementToBeVisible(element, nextTest, msg) { - waitForCondition(() => is_visible(element), - () => { - ok(true, msg); - nextTest(); - }, - "Timeout waiting for visibility: " + msg); -} - -function waitForElementToBeHidden(element, nextTest, msg) { - waitForCondition(() => is_hidden(element), - () => { - ok(true, msg); - nextTest(); - }, - "Timeout waiting for invisibility: " + msg); -} - -function elementVisiblePromise(element, msg) { - return waitForConditionPromise(() => is_visible(element), "Timeout waiting for visibility: " + msg); -} - -function elementHiddenPromise(element, msg) { - return waitForConditionPromise(() => is_hidden(element), "Timeout waiting for invisibility: " + msg); -} - -function waitForPopupAtAnchor(popup, anchorNode, nextTest, msg) { - waitForCondition(() => is_visible(popup) && popup.popupBoxObject.anchorNode == anchorNode, - () => { - ok(true, msg); - is_element_visible(popup, "Popup should be visible"); - nextTest(); - }, - "Timeout waiting for popup at anchor: " + msg); -} - -function getConfigurationPromise(configName) { - return ContentTask.spawn(gTestTab.linkedBrowser, configName, configName => { - return new Promise((resolve) => { - let contentWin = Components.utils.waiveXrays(content); - contentWin.Mozilla.UITour.getConfiguration(configName, resolve); - }); - }); -} - -function hideInfoPromise(...args) { - let popup = document.getElementById("UITourTooltip"); - gContentAPI.hideInfo.apply(gContentAPI, args); - return promisePanelElementHidden(window, popup); -} - -/** - * `buttons` and `options` require functions from the content scope so we take a - * function name to call to generate the buttons/options instead of the - * buttons/options themselves. This makes the signature differ from the content one. - */ -function showInfoPromise(target, title, text, icon, buttonsFunctionName, optionsFunctionName) { - let popup = document.getElementById("UITourTooltip"); - let shownPromise = promisePanelElementShown(window, popup); - return ContentTask.spawn(gTestTab.linkedBrowser, [...arguments], args => { - let contentWin = Components.utils.waiveXrays(content); - let [target, title, text, icon, buttonsFunctionName, optionsFunctionName] = args; - let buttons = buttonsFunctionName ? contentWin[buttonsFunctionName]() : null; - let options = optionsFunctionName ? contentWin[optionsFunctionName]() : null; - contentWin.Mozilla.UITour.showInfo(target, title, text, icon, buttons, options); - }).then(() => shownPromise); -} - -function showHighlightPromise(...args) { - let popup = document.getElementById("UITourHighlightContainer"); - gContentAPI.showHighlight.apply(gContentAPI, args); - return promisePanelElementShown(window, popup); -} - -function showMenuPromise(name) { - return ContentTask.spawn(gTestTab.linkedBrowser, name, name => { - return new Promise((resolve) => { - let contentWin = Components.utils.waiveXrays(content); - contentWin.Mozilla.UITour.showMenu(name, resolve); - }); - }); -} - -function waitForCallbackResultPromise() { - return ContentTask.spawn(gTestTab.linkedBrowser, null, function*() { - let contentWin = Components.utils.waiveXrays(content); - yield ContentTaskUtils.waitForCondition(() => { - return contentWin.callbackResult; - }, "callback should be called"); - return { - data: contentWin.callbackData, - result: contentWin.callbackResult, - }; - }); -} - -function promisePanelShown(win) { - let panelEl = win.PanelUI.panel; - return promisePanelElementShown(win, panelEl); -} - -function promisePanelElementEvent(win, aPanel, aEvent) { - return new Promise((resolve, reject) => { - let timeoutId = win.setTimeout(() => { - aPanel.removeEventListener(aEvent, onPanelEvent); - reject(aEvent + " event did not happen within 5 seconds."); - }, 5000); - - function onPanelEvent(e) { - aPanel.removeEventListener(aEvent, onPanelEvent); - win.clearTimeout(timeoutId); - // Wait one tick to let UITour.jsm process the event as well. - executeSoon(resolve); - } - - aPanel.addEventListener(aEvent, onPanelEvent); - }); -} - -function promisePanelElementShown(win, aPanel) { - return promisePanelElementEvent(win, aPanel, "popupshown"); -} - -function promisePanelElementHidden(win, aPanel) { - return promisePanelElementEvent(win, aPanel, "popuphidden"); -} - -function is_element_hidden(element, msg) { - isnot(element, null, "Element should not be null, when checking visibility"); - ok(is_hidden(element), msg); -} - -function isTourBrowser(aBrowser) { - let chromeWindow = aBrowser.ownerGlobal; - return UITour.tourBrowsersByWindow.has(chromeWindow) && - UITour.tourBrowsersByWindow.get(chromeWindow).has(aBrowser); -} - -function promisePageEvent() { - return new Promise((resolve) => { - Services.mm.addMessageListener("UITour:onPageEvent", function onPageEvent(aMessage) { - Services.mm.removeMessageListener("UITour:onPageEvent", onPageEvent); - SimpleTest.executeSoon(resolve); - }); - }); -} - -function loadUITourTestPage(callback, host = "https://example.org/") { - if (gTestTab) - gBrowser.removeTab(gTestTab); - - let url = getRootDirectory(gTestPath) + "uitour.html"; - url = url.replace("chrome://mochitests/content/", host); - - gTestTab = gBrowser.addTab(url); - gBrowser.selectedTab = gTestTab; - - gTestTab.linkedBrowser.addEventListener("load", function onLoad() { - gTestTab.linkedBrowser.removeEventListener("load", onLoad, true); - - if (gMultiProcessBrowser) { - // When e10s is enabled, make gContentAPI and gContentWindow proxies which has every property - // return a function which calls the method of the same name on - // contentWin.Mozilla.UITour/contentWin in a ContentTask. - let contentWinHandler = { - get(target, prop, receiver) { - return (...args) => { - let taskArgs = { - methodName: prop, - args, - }; - return ContentTask.spawn(gTestTab.linkedBrowser, taskArgs, args => { - let contentWin = Components.utils.waiveXrays(content); - return contentWin[args.methodName].apply(contentWin, args.args); - }); - }; - }, - }; - gContentWindow = new Proxy({}, contentWinHandler); - - let UITourHandler = { - get(target, prop, receiver) { - return (...args) => { - let browser = gTestTab.linkedBrowser; - const proxyFunctionName = "UITourHandler:proxiedfunction-"; - // We need to proxy any callback functions using messages: - let callbackMap = new Map(); - let fnIndices = []; - args = args.map((arg, index) => { - // Replace function arguments with "", and add them to the list of - // forwarded functions. We'll construct a function on the content-side - // that forwards all its arguments to a message, and we'll listen for - // those messages on our side and call the corresponding function with - // the arguments we got from the content side. - if (typeof arg == "function") { - callbackMap.set(index, arg); - fnIndices.push(index); - let handler = function(msg) { - // Please note that this handler assumes that the callback is used only once. - // That means that a single gContentAPI.observer() call can't be used to observe - // multiple events. - browser.messageManager.removeMessageListener(proxyFunctionName + index, handler); - callbackMap.get(index).apply(null, msg.data); - }; - browser.messageManager.addMessageListener(proxyFunctionName + index, handler); - return ""; - } - return arg; - }); - let taskArgs = { - methodName: prop, - args, - fnIndices, - }; - return ContentTask.spawn(browser, taskArgs, function*(args) { - let contentWin = Components.utils.waiveXrays(content); - let callbacksCalled = 0; - let resolveCallbackPromise; - let allCallbacksCalledPromise = new Promise(resolve => resolveCallbackPromise = resolve); - let argumentsWithFunctions = args.args.map((arg, index) => { - if (arg === "" && args.fnIndices.includes(index)) { - return function() { - callbacksCalled++; - sendAsyncMessage("UITourHandler:proxiedfunction-" + index, Array.from(arguments)); - if (callbacksCalled >= args.fnIndices.length) { - resolveCallbackPromise(); - } - }; - } - return arg; - }); - let rv = contentWin.Mozilla.UITour[args.methodName].apply(contentWin.Mozilla.UITour, - argumentsWithFunctions); - if (args.fnIndices.length) { - yield allCallbacksCalledPromise; - } - return rv; - }); - }; - }, - }; - gContentAPI = new Proxy({}, UITourHandler); - } else { - gContentWindow = Components.utils.waiveXrays(gTestTab.linkedBrowser.contentDocument.defaultView); - gContentAPI = gContentWindow.Mozilla.UITour; - } - - waitForFocus(callback, gTestTab.linkedBrowser); - }, true); -} - -// Wrapper for UITourTest to be used by add_task tests. -function* setup_UITourTest() { - return UITourTest(true); -} - -// Use `add_task(setup_UITourTest);` instead as we will fold this into `setup_UITourTest` once all tests are using `add_UITour_task`. -function UITourTest(usingAddTask = false) { - Services.prefs.setBoolPref("browser.uitour.enabled", true); - let testHttpsUri = Services.io.newURI("https://example.org", null, null); - let testHttpUri = Services.io.newURI("http://example.org", null, null); - Services.perms.add(testHttpsUri, "uitour", Services.perms.ALLOW_ACTION); - Services.perms.add(testHttpUri, "uitour", Services.perms.ALLOW_ACTION); - - // If a test file is using add_task, we don't need to have a test function or - // call `waitForExplicitFinish`. - if (!usingAddTask) { - waitForExplicitFinish(); - } - - registerCleanupFunction(function() { - delete window.gContentWindow; - delete window.gContentAPI; - if (gTestTab) - gBrowser.removeTab(gTestTab); - delete window.gTestTab; - Services.prefs.clearUserPref("browser.uitour.enabled"); - Services.perms.remove(testHttpsUri, "uitour"); - Services.perms.remove(testHttpUri, "uitour"); - }); - - // When using tasks, the harness will call the next added task for us. - if (!usingAddTask) { - nextTest(); - } -} - -function done(usingAddTask = false) { - info("== Done test, doing shared checks before teardown =="); - return new Promise((resolve) => { - executeSoon(() => { - if (gTestTab) - gBrowser.removeTab(gTestTab); - gTestTab = null; - - let highlight = document.getElementById("UITourHighlightContainer"); - is_element_hidden(highlight, "Highlight should be closed/hidden after UITour tab is closed"); - - let tooltip = document.getElementById("UITourTooltip"); - is_element_hidden(tooltip, "Tooltip should be closed/hidden after UITour tab is closed"); - - ok(!PanelUI.panel.hasAttribute("noautohide"), "@noautohide on the menu panel should have been cleaned up"); - ok(!PanelUI.panel.hasAttribute("panelopen"), "The panel shouldn't have @panelopen"); - isnot(PanelUI.panel.state, "open", "The panel shouldn't be open"); - is(document.getElementById("PanelUI-menu-button").hasAttribute("open"), false, "Menu button should know that the menu is closed"); - - info("Done shared checks"); - if (usingAddTask) { - executeSoon(resolve); - } else { - executeSoon(nextTest); - } - }); - }); -} - -function nextTest() { - if (tests.length == 0) { - info("finished tests in this file"); - finish(); - return; - } - let test = tests.shift(); - info("Starting " + test.name); - waitForFocus(function() { - loadUITourTestPage(function() { - test(done); - }); - }); -} - -/** - * All new tests that need the help of `loadUITourTestPage` should use this - * wrapper around their test's generator function to reduce boilerplate. - */ -function add_UITour_task(func) { - let genFun = function*() { - yield new Promise((resolve) => { - waitForFocus(function() { - loadUITourTestPage(function() { - let funcPromise = Task.spawn(func) - .then(() => done(true), - (reason) => { - ok(false, reason); - return done(true); - }); - resolve(funcPromise); - }); - }); - }); - }; - Object.defineProperty(genFun, "name", { - configurable: true, - value: func.name, - }); - add_task(genFun); -} diff --git a/browser/components/uitour/test/image.png b/browser/components/uitour/test/image.png Binary files differdeleted file mode 100644 index 597c7fd2c..000000000 --- a/browser/components/uitour/test/image.png +++ /dev/null diff --git a/browser/components/uitour/test/uitour.html b/browser/components/uitour/test/uitour.html deleted file mode 100644 index 6c42ac7f8..000000000 --- a/browser/components/uitour/test/uitour.html +++ /dev/null @@ -1,42 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <meta charset="utf-8" /> - <title>UITour test</title> - <script type="application/javascript" src="UITour-lib.js"> - </script> - <script type="application/javascript"> - var callbackResult, callbackData; - function makeCallback(name) { - return (function(data) { - callbackResult = name; - callbackData = data; - }); - } - - // Defined in content to avoid weird issues when crossing between chrome/content. - function makeButtons() { - return [ - {label: "Regular text", style: "text"}, - {label: "Link", callback: makeCallback("link"), style: "link"}, - {label: "Button 1", callback: makeCallback("button1")}, - {label: "Button 2", callback: makeCallback("button2"), icon: "image.png", - style: "primary"} - ]; - } - - function makeInfoOptions() { - return { - closeButtonCallback: makeCallback("closeButton"), - targetCallback: makeCallback("target"), - }; - } - </script> - </head> - <body> - <h1>UITour tests</h1> - <p>Because Firefox is...</p> - <p>Never gonna let you down</p> - <p>Never gonna give you up</p> - </body> -</html> |