michael@0: /* Any copyright is dedicated to the Public Domain. michael@0: * http://creativecommons.org/publicdomain/zero/1.0/ */ michael@0: michael@0: "use strict"; michael@0: michael@0: let gTestTab; michael@0: let gContentAPI; michael@0: let gContentWindow; michael@0: michael@0: Components.utils.import("resource:///modules/UITour.jsm"); michael@0: michael@0: function test() { michael@0: UITourTest(); michael@0: } michael@0: michael@0: let tests = [ michael@0: function test_untrusted_host(done) { michael@0: loadUITourTestPage(function() { michael@0: let bookmarksMenu = document.getElementById("bookmarks-menu-button"); michael@0: ise(bookmarksMenu.open, false, "Bookmark menu should initially be closed"); michael@0: michael@0: gContentAPI.showMenu("bookmarks"); michael@0: ise(bookmarksMenu.open, false, "Bookmark menu should not open on a untrusted host"); michael@0: michael@0: done(); michael@0: }, "http://mochi.test:8888/"); michael@0: }, michael@0: function test_unsecure_host(done) { michael@0: loadUITourTestPage(function() { michael@0: let bookmarksMenu = document.getElementById("bookmarks-menu-button"); michael@0: ise(bookmarksMenu.open, false, "Bookmark menu should initially be closed"); michael@0: michael@0: gContentAPI.showMenu("bookmarks"); michael@0: ise(bookmarksMenu.open, false, "Bookmark menu should not open on a unsecure host"); michael@0: michael@0: done(); michael@0: }, "http://example.com/"); michael@0: }, michael@0: function test_unsecure_host_override(done) { michael@0: Services.prefs.setBoolPref("browser.uitour.requireSecure", false); michael@0: loadUITourTestPage(function() { michael@0: let highlight = document.getElementById("UITourHighlight"); michael@0: is_element_hidden(highlight, "Highlight should initially be hidden"); michael@0: michael@0: gContentAPI.showHighlight("urlbar"); michael@0: waitForElementToBeVisible(highlight, done, "Highlight should be shown on a unsecure host when override pref is set"); michael@0: michael@0: Services.prefs.setBoolPref("browser.uitour.requireSecure", true); michael@0: }, "http://example.com/"); michael@0: }, michael@0: function test_disabled(done) { michael@0: Services.prefs.setBoolPref("browser.uitour.enabled", false); michael@0: michael@0: let bookmarksMenu = document.getElementById("bookmarks-menu-button"); michael@0: ise(bookmarksMenu.open, false, "Bookmark menu should initially be closed"); michael@0: michael@0: gContentAPI.showMenu("bookmarks"); michael@0: ise(bookmarksMenu.open, false, "Bookmark menu should not open when feature is disabled"); michael@0: michael@0: Services.prefs.setBoolPref("browser.uitour.enabled", true); michael@0: done(); michael@0: }, michael@0: function test_highlight(done) { michael@0: function test_highlight_2() { michael@0: let highlight = document.getElementById("UITourHighlight"); michael@0: gContentAPI.hideHighlight(); michael@0: is_element_hidden(highlight, "Highlight should be hidden after hideHighlight()"); michael@0: michael@0: gContentAPI.showHighlight("urlbar"); michael@0: waitForElementToBeVisible(highlight, test_highlight_3, "Highlight should be shown after showHighlight()"); michael@0: } michael@0: function test_highlight_3() { michael@0: let highlight = document.getElementById("UITourHighlight"); michael@0: gContentAPI.showHighlight("backForward"); michael@0: waitForElementToBeVisible(highlight, done, "Highlight should be shown after showHighlight()"); michael@0: } michael@0: michael@0: let highlight = document.getElementById("UITourHighlight"); michael@0: is_element_hidden(highlight, "Highlight should initially be hidden"); michael@0: michael@0: gContentAPI.showHighlight("urlbar"); michael@0: waitForElementToBeVisible(highlight, test_highlight_2, "Highlight should be shown after showHighlight()"); michael@0: }, michael@0: function test_highlight_circle(done) { michael@0: function check_highlight_size() { michael@0: let panel = highlight.parentElement; michael@0: let anchor = panel.anchorNode; michael@0: let anchorRect = anchor.getBoundingClientRect(); michael@0: info("addons target: width: " + anchorRect.width + " height: " + anchorRect.height); michael@0: let maxDimension = Math.round(Math.max(anchorRect.width, anchorRect.height)); michael@0: let highlightRect = highlight.getBoundingClientRect(); michael@0: info("highlight: width: " + highlightRect.width + " height: " + highlightRect.height); michael@0: is(Math.round(highlightRect.width), maxDimension, "The width of the highlight should be equal to the largest dimension of the target"); michael@0: is(Math.round(highlightRect.height), maxDimension, "The height of the highlight should be equal to the largest dimension of the target"); michael@0: is(Math.round(highlightRect.height), Math.round(highlightRect.width), "The height and width of the highlight should be the same to create a circle"); michael@0: is(highlight.style.borderRadius, "100%", "The border-radius should be 100% to create a circle"); michael@0: done(); michael@0: } michael@0: let highlight = document.getElementById("UITourHighlight"); michael@0: is_element_hidden(highlight, "Highlight should initially be hidden"); michael@0: michael@0: gContentAPI.showHighlight("addons"); michael@0: waitForElementToBeVisible(highlight, check_highlight_size, "Highlight should be shown after showHighlight()"); michael@0: }, michael@0: function test_highlight_customize_auto_open_close(done) { michael@0: let highlight = document.getElementById("UITourHighlight"); michael@0: gContentAPI.showHighlight("customize"); michael@0: waitForElementToBeVisible(highlight, function checkPanelIsOpen() { michael@0: isnot(PanelUI.panel.state, "closed", "Panel should have opened"); michael@0: michael@0: // Move the highlight outside which should close the app menu. michael@0: gContentAPI.showHighlight("appMenu"); michael@0: waitForElementToBeVisible(highlight, function checkPanelIsClosed() { michael@0: isnot(PanelUI.panel.state, "open", michael@0: "Panel should have closed after the highlight moved elsewhere."); michael@0: done(); michael@0: }, "Highlight should move to the appMenu button"); michael@0: }, "Highlight should be shown after showHighlight() for fixed panel items"); michael@0: }, michael@0: function test_highlight_customize_manual_open_close(done) { michael@0: let highlight = document.getElementById("UITourHighlight"); michael@0: // Manually open the app menu then show a highlight there. The menu should remain open. michael@0: let shownPromise = promisePanelShown(window); michael@0: gContentAPI.showMenu("appMenu"); michael@0: shownPromise.then(() => { michael@0: isnot(PanelUI.panel.state, "closed", "Panel should have opened"); michael@0: gContentAPI.showHighlight("customize"); michael@0: michael@0: waitForElementToBeVisible(highlight, function checkPanelIsStillOpen() { michael@0: isnot(PanelUI.panel.state, "closed", "Panel should still be open"); michael@0: michael@0: // Move the highlight outside which shouldn't close the app menu since it was manually opened. michael@0: gContentAPI.showHighlight("appMenu"); michael@0: waitForElementToBeVisible(highlight, function () { michael@0: isnot(PanelUI.panel.state, "closed", michael@0: "Panel should remain open since UITour didn't open it in the first place"); michael@0: gContentAPI.hideMenu("appMenu"); michael@0: done(); michael@0: }, "Highlight should move to the appMenu button"); michael@0: }, "Highlight should be shown after showHighlight() for fixed panel items"); michael@0: }).then(null, Components.utils.reportError); michael@0: }, michael@0: function test_highlight_effect(done) { michael@0: function waitForHighlightWithEffect(highlightEl, effect, next, error) { michael@0: return waitForCondition(() => highlightEl.getAttribute("active") == effect, michael@0: next, michael@0: error); michael@0: } michael@0: function checkDefaultEffect() { michael@0: is(highlight.getAttribute("active"), "none", "The default should be no effect"); michael@0: michael@0: gContentAPI.showHighlight("urlbar", "none"); michael@0: waitForHighlightWithEffect(highlight, "none", checkZoomEffect, "There should be no effect"); michael@0: } michael@0: function checkZoomEffect() { michael@0: gContentAPI.showHighlight("urlbar", "zoom"); michael@0: waitForHighlightWithEffect(highlight, "zoom", () => { michael@0: let style = window.getComputedStyle(highlight); michael@0: is(style.animationName, "uitour-zoom", "The animation-name should be uitour-zoom"); michael@0: checkSameEffectOnDifferentTarget(); michael@0: }, "There should be a zoom effect"); michael@0: } michael@0: function checkSameEffectOnDifferentTarget() { michael@0: gContentAPI.showHighlight("appMenu", "wobble"); michael@0: waitForHighlightWithEffect(highlight, "wobble", () => { michael@0: highlight.addEventListener("animationstart", function onAnimationStart(aEvent) { michael@0: highlight.removeEventListener("animationstart", onAnimationStart); michael@0: ok(true, "Animation occurred again even though the effect was the same"); michael@0: checkRandomEffect(); michael@0: }); michael@0: gContentAPI.showHighlight("backForward", "wobble"); michael@0: }, "There should be a wobble effect"); michael@0: } michael@0: function checkRandomEffect() { michael@0: function waitForActiveHighlight(highlightEl, next, error) { michael@0: return waitForCondition(() => highlightEl.hasAttribute("active"), michael@0: next, michael@0: error); michael@0: } michael@0: michael@0: gContentAPI.hideHighlight(); michael@0: gContentAPI.showHighlight("urlbar", "random"); michael@0: waitForActiveHighlight(highlight, () => { michael@0: ok(highlight.hasAttribute("active"), "The highlight should be active"); michael@0: isnot(highlight.getAttribute("active"), "none", "A random effect other than none should have been chosen"); michael@0: isnot(highlight.getAttribute("active"), "random", "The random effect shouldn't be 'random'"); michael@0: isnot(UITour.highlightEffects.indexOf(highlight.getAttribute("active")), -1, "Check that a supported effect was randomly chosen"); michael@0: done(); michael@0: }, "There should be an active highlight with a random effect"); michael@0: } michael@0: michael@0: let highlight = document.getElementById("UITourHighlight"); michael@0: is_element_hidden(highlight, "Highlight should initially be hidden"); michael@0: michael@0: gContentAPI.showHighlight("urlbar"); michael@0: waitForElementToBeVisible(highlight, checkDefaultEffect, "Highlight should be shown after showHighlight()"); michael@0: }, michael@0: function test_highlight_effect_unsupported(done) { michael@0: function checkUnsupportedEffect() { michael@0: is(highlight.getAttribute("active"), "none", "No effect should be used when an unsupported effect is requested"); michael@0: done(); michael@0: } michael@0: michael@0: let highlight = document.getElementById("UITourHighlight"); michael@0: is_element_hidden(highlight, "Highlight should initially be hidden"); michael@0: michael@0: gContentAPI.showHighlight("urlbar", "__UNSUPPORTED__"); michael@0: waitForElementToBeVisible(highlight, checkUnsupportedEffect, "Highlight should be shown after showHighlight()"); michael@0: }, michael@0: function test_info_1(done) { michael@0: let popup = document.getElementById("UITourTooltip"); michael@0: let title = document.getElementById("UITourTooltipTitle"); michael@0: let desc = document.getElementById("UITourTooltipDescription"); michael@0: let icon = document.getElementById("UITourTooltipIcon"); michael@0: let buttons = document.getElementById("UITourTooltipButtons"); michael@0: michael@0: popup.addEventListener("popupshown", function onPopupShown() { michael@0: popup.removeEventListener("popupshown", onPopupShown); michael@0: is(popup.popupBoxObject.anchorNode, document.getElementById("urlbar"), "Popup should be anchored to the urlbar"); michael@0: is(title.textContent, "test title", "Popup should have correct title"); michael@0: is(desc.textContent, "test text", "Popup should have correct description text"); michael@0: is(icon.src, "", "Popup should have no icon"); michael@0: is(buttons.hasChildNodes(), false, "Popup should have no buttons"); michael@0: michael@0: popup.addEventListener("popuphidden", function onPopupHidden() { michael@0: popup.removeEventListener("popuphidden", onPopupHidden); michael@0: michael@0: popup.addEventListener("popupshown", function onPopupShown() { michael@0: popup.removeEventListener("popupshown", onPopupShown); michael@0: done(); michael@0: }); michael@0: michael@0: gContentAPI.showInfo("urlbar", "test title", "test text"); michael@0: michael@0: }); michael@0: gContentAPI.hideInfo(); michael@0: }); michael@0: michael@0: gContentAPI.showInfo("urlbar", "test title", "test text"); michael@0: }, michael@0: function test_info_2(done) { michael@0: let popup = document.getElementById("UITourTooltip"); michael@0: let title = document.getElementById("UITourTooltipTitle"); michael@0: let desc = document.getElementById("UITourTooltipDescription"); michael@0: let icon = document.getElementById("UITourTooltipIcon"); michael@0: let buttons = document.getElementById("UITourTooltipButtons"); michael@0: michael@0: popup.addEventListener("popupshown", function onPopupShown() { michael@0: popup.removeEventListener("popupshown", onPopupShown); michael@0: is(popup.popupBoxObject.anchorNode, document.getElementById("urlbar"), "Popup should be anchored to the urlbar"); michael@0: is(title.textContent, "urlbar title", "Popup should have correct title"); michael@0: is(desc.textContent, "urlbar text", "Popup should have correct description text"); michael@0: is(icon.src, "", "Popup should have no icon"); michael@0: is(buttons.hasChildNodes(), false, "Popup should have no buttons"); michael@0: michael@0: gContentAPI.showInfo("search", "search title", "search text"); michael@0: executeSoon(function() { michael@0: is(popup.popupBoxObject.anchorNode, document.getElementById("searchbar"), "Popup should be anchored to the searchbar"); michael@0: is(title.textContent, "search title", "Popup should have correct title"); michael@0: is(desc.textContent, "search text", "Popup should have correct description text"); michael@0: michael@0: done(); michael@0: }); michael@0: }); michael@0: michael@0: gContentAPI.showInfo("urlbar", "urlbar title", "urlbar text"); michael@0: }, michael@0: michael@0: // Make sure this test is last in the file so the appMenu gets left open and done will confirm it got tore down. michael@0: function cleanupMenus(done) { michael@0: gContentAPI.showMenu("appMenu"); michael@0: done(); michael@0: }, michael@0: ];