summaryrefslogtreecommitdiffstats
path: root/browser/components/firefoxview/tests/browser/browser_feature_callout_position.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/firefoxview/tests/browser/browser_feature_callout_position.js')
-rw-r--r--browser/components/firefoxview/tests/browser/browser_feature_callout_position.js402
1 files changed, 402 insertions, 0 deletions
diff --git a/browser/components/firefoxview/tests/browser/browser_feature_callout_position.js b/browser/components/firefoxview/tests/browser/browser_feature_callout_position.js
new file mode 100644
index 0000000000..386fbbb91b
--- /dev/null
+++ b/browser/components/firefoxview/tests/browser/browser_feature_callout_position.js
@@ -0,0 +1,402 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+requestLongerTimeout(2);
+
+const featureTourPref = "browser.firefox-view.feature-tour";
+const defaultPrefValue = getPrefValueByScreen(1);
+
+add_task(
+ async function feature_callout_first_screen_positioned_below_element() {
+ const testMessage = getCalloutMessageById(
+ "FIREFOX_VIEW_FEATURE_TOUR_1_NO_CWS"
+ );
+ const sandbox = createSandboxWithCalloutTriggerStub(testMessage);
+
+ await BrowserTestUtils.withNewTab(
+ {
+ gBrowser,
+ url: "about:firefoxview",
+ },
+ async browser => {
+ const { document } = browser.contentWindow;
+ await waitForCalloutScreen(document, "FEATURE_CALLOUT_1");
+ let parentBottom = document
+ .querySelector("#tab-pickup-container")
+ .getBoundingClientRect().bottom;
+ let containerTop = document
+ .querySelector(calloutSelector)
+ .getBoundingClientRect().top;
+
+ Assert.lessOrEqual(
+ parentBottom,
+ containerTop + 5 + 1, // Add 5px for overlap and 1px for fuzziness to account for possible subpixel rounding
+ "Feature Callout is positioned below parent element with 5px overlap"
+ );
+ }
+ );
+ sandbox.restore();
+ }
+);
+
+add_task(
+ async function feature_callout_second_screen_positioned_left_of_element() {
+ const testMessage = getCalloutMessageById(
+ "FIREFOX_VIEW_FEATURE_TOUR_2_NO_CWS"
+ );
+ testMessage.message.content.screens[1].content.arrow_position = "end";
+ const sandbox = createSandboxWithCalloutTriggerStub(testMessage);
+
+ await BrowserTestUtils.withNewTab(
+ {
+ gBrowser,
+ url: "about:firefoxview",
+ },
+ async browser => {
+ const { document } = browser.contentWindow;
+ const parent = document.querySelector(
+ "#recently-closed-tabs-container"
+ );
+ parent.style.gridArea = "1/2";
+ await waitForCalloutScreen(document, "FEATURE_CALLOUT_2");
+ let parentLeft = parent.getBoundingClientRect().left;
+ let containerRight = document
+ .querySelector(calloutSelector)
+ .getBoundingClientRect().right;
+
+ Assert.greaterOrEqual(
+ parentLeft,
+ containerRight - 5 - 1, // Subtract 5px for overlap and 1px for fuzziness to account for possible subpixel rounding
+ "Feature Callout is positioned left of parent element with 5px overlap"
+ );
+ }
+ );
+ sandbox.restore();
+ }
+);
+
+add_task(
+ async function feature_callout_second_screen_positioned_above_element() {
+ const testMessage = getCalloutMessageById(
+ "FIREFOX_VIEW_FEATURE_TOUR_2_NO_CWS"
+ );
+ const sandbox = createSandboxWithCalloutTriggerStub(testMessage);
+
+ await BrowserTestUtils.withNewTab(
+ {
+ gBrowser,
+ url: "about:firefoxview",
+ },
+ async browser => {
+ const { document } = browser.contentWindow;
+ await waitForCalloutScreen(document, "FEATURE_CALLOUT_2");
+ let parentTop = document
+ .querySelector("#recently-closed-tabs-container")
+ .getBoundingClientRect().top;
+ let containerBottom = document
+ .querySelector(calloutSelector)
+ .getBoundingClientRect().bottom;
+
+ Assert.greaterOrEqual(
+ parentTop,
+ containerBottom - 5 - 1,
+ "Feature Callout is positioned above parent element with 5px overlap"
+ );
+ }
+ );
+ sandbox.restore();
+ }
+);
+
+add_task(
+ async function feature_callout_third_screen_position_respects_RTL_layouts() {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ // Set layout direction to right to left
+ ["intl.l10n.pseudo", "bidi"],
+ ],
+ });
+
+ const testMessage = getCalloutMessageById(
+ "FIREFOX_VIEW_FEATURE_TOUR_2_NO_CWS"
+ );
+ const sandbox = createSandboxWithCalloutTriggerStub(testMessage);
+
+ await BrowserTestUtils.withNewTab(
+ {
+ gBrowser,
+ url: "about:firefoxview",
+ },
+ async browser => {
+ const { document } = browser.contentWindow;
+ const parent = document.querySelector(
+ "#recently-closed-tabs-container"
+ );
+ parent.style.gridArea = "1/2";
+ await waitForCalloutScreen(document, "FEATURE_CALLOUT_2");
+ let parentRight = parent.getBoundingClientRect().right;
+ let containerLeft = document
+ .querySelector(calloutSelector)
+ .getBoundingClientRect().left;
+
+ Assert.lessOrEqual(
+ parentRight,
+ containerLeft + 5 + 1,
+ "Feature Callout is positioned right of parent element when callout is set to 'end' in RTL layouts"
+ );
+ }
+ );
+
+ await SpecialPowers.popPrefEnv();
+ sandbox.restore();
+ }
+);
+
+add_task(
+ async function feature_callout_is_repositioned_if_parent_container_is_toggled() {
+ const testMessage = getCalloutMessageById(
+ "FIREFOX_VIEW_FEATURE_TOUR_1_NO_CWS"
+ );
+ const sandbox = createSandboxWithCalloutTriggerStub(testMessage);
+
+ await BrowserTestUtils.withNewTab(
+ {
+ gBrowser,
+ url: "about:firefoxview",
+ },
+ async browser => {
+ const { document } = browser.contentWindow;
+ await waitForCalloutScreen(document, "FEATURE_CALLOUT_1");
+ const parentEl = document.querySelector("#tab-pickup-container");
+ const calloutStartingTopPosition =
+ document.querySelector(calloutSelector).style.top;
+
+ //container has been toggled/minimized
+ parentEl.removeAttribute("open", "");
+ await BrowserTestUtils.waitForMutationCondition(
+ document.querySelector(calloutSelector),
+ { attributes: true },
+ () =>
+ document.querySelector(calloutSelector).style.top !=
+ calloutStartingTopPosition
+ );
+ isnot(
+ document.querySelector(calloutSelector).style.top,
+ calloutStartingTopPosition,
+ "Feature Callout position is recalculated when parent element is toggled"
+ );
+ await closeCallout(document);
+ }
+ );
+ sandbox.restore();
+ }
+);
+
+// This test should be moved into a surface agnostic test suite with bug 1793656.
+add_task(async function feature_callout_top_end_positioning() {
+ const testMessage = getCalloutMessageById(
+ "FIREFOX_VIEW_FEATURE_TOUR_1_NO_CWS"
+ );
+ testMessage.message.content.screens[0].content.arrow_position = "top-end";
+ const sandbox = createSandboxWithCalloutTriggerStub(testMessage);
+
+ await BrowserTestUtils.withNewTab(
+ {
+ gBrowser,
+ url: "about:firefoxview",
+ },
+ async browser => {
+ const { document } = browser.contentWindow;
+ await waitForCalloutScreen(document, "FEATURE_CALLOUT_1");
+ let parent = document.querySelector("#tab-pickup-container");
+ let container = document.querySelector(calloutSelector);
+ let parentLeft = parent.getBoundingClientRect().left;
+ let containerLeft = container.getBoundingClientRect().left;
+
+ ok(
+ container.classList.contains("arrow-top-end"),
+ "Feature Callout container has the expected arrow-top-end class"
+ );
+ isfuzzy(
+ containerLeft - parent.clientWidth + container.offsetWidth,
+ parentLeft,
+ 1, // Display scaling can cause up to 1px difference in layout
+ "Feature Callout's right edge is approximately aligned with parent element's right edge"
+ );
+
+ await closeCallout(document);
+ }
+ );
+ sandbox.restore();
+});
+
+// This test should be moved into a surface agnostic test suite with bug 1793656.
+add_task(async function feature_callout_top_start_positioning() {
+ const testMessage = getCalloutMessageById(
+ "FIREFOX_VIEW_FEATURE_TOUR_1_NO_CWS"
+ );
+ testMessage.message.content.screens[0].content.arrow_position = "top-start";
+ const sandbox = createSandboxWithCalloutTriggerStub(testMessage);
+
+ await BrowserTestUtils.withNewTab(
+ {
+ gBrowser,
+ url: "about:firefoxview",
+ },
+ async browser => {
+ const { document } = browser.contentWindow;
+ await waitForCalloutScreen(document, "FEATURE_CALLOUT_1");
+ let parent = document.querySelector("#tab-pickup-container");
+ let container = document.querySelector(calloutSelector);
+ let parentLeft = parent.getBoundingClientRect().left;
+ let containerLeft = container.getBoundingClientRect().left;
+
+ ok(
+ container.classList.contains("arrow-top-start"),
+ "Feature Callout container has the expected arrow-top-start class"
+ );
+ isfuzzy(
+ containerLeft,
+ parentLeft,
+ 1, // Display scaling can cause up to 1px difference in layout
+ "Feature Callout's left edge is approximately aligned with parent element's left edge"
+ );
+
+ await closeCallout(document);
+ }
+ );
+ sandbox.restore();
+});
+
+// This test should be moved into a surface agnostic test suite with bug 1793656.
+add_task(
+ async function feature_callout_top_end_position_respects_RTL_layouts() {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ // Set layout direction to right to left
+ ["intl.l10n.pseudo", "bidi"],
+ ],
+ });
+
+ const testMessage = getCalloutMessageById(
+ "FIREFOX_VIEW_FEATURE_TOUR_1_NO_CWS"
+ );
+ testMessage.message.content.screens[0].content.arrow_position = "top-end";
+ const sandbox = createSandboxWithCalloutTriggerStub(testMessage);
+
+ await BrowserTestUtils.withNewTab(
+ {
+ gBrowser,
+ url: "about:firefoxview",
+ },
+ async browser => {
+ const { document } = browser.contentWindow;
+ await waitForCalloutScreen(document, "FEATURE_CALLOUT_1");
+ let parent = document.querySelector("#tab-pickup-container");
+ let container = document.querySelector(calloutSelector);
+ let parentLeft = parent.getBoundingClientRect().left;
+ let containerLeft = container.getBoundingClientRect().left;
+
+ ok(
+ container.classList.contains("arrow-top-start"),
+ "In RTL mode, the feature Callout container has the expected arrow-top-start class"
+ );
+ is(
+ containerLeft,
+ parentLeft,
+ "In RTL mode, the feature Callout's left edge is aligned with parent element's left edge"
+ );
+
+ await closeCallout(document);
+ }
+ );
+
+ await SpecialPowers.popPrefEnv();
+ sandbox.restore();
+ }
+);
+
+add_task(async function feature_callout_is_larger_than_its_parent() {
+ let testMessage = {
+ message: {
+ id: "FIREFOX_VIEW_FEATURE_TOUR_1_NO_CWS",
+ template: "feature_callout",
+ content: {
+ id: "FIREFOX_VIEW_FEATURE_TOUR",
+ transitions: false,
+ disableHistoryUpdates: true,
+ screens: [
+ {
+ id: "FEATURE_CALLOUT_1",
+ parent_selector: ".brand-icon",
+ content: {
+ position: "callout",
+ arrow_position: "end",
+ title: "callout-firefox-view-tab-pickup-title",
+ subtitle: {
+ string_id: "callout-firefox-view-tab-pickup-subtitle",
+ },
+ logo: {
+ imageURL: "chrome://browser/content/callout-tab-pickup.svg",
+ darkModeImageURL:
+ "chrome://browser/content/callout-tab-pickup-dark.svg",
+ height: "128px", // .brand-icon has a height of 32px
+ },
+ dismiss_button: {
+ action: {
+ navigate: true,
+ },
+ },
+ },
+ },
+ ],
+ },
+ },
+ };
+
+ const sandbox = createSandboxWithCalloutTriggerStub(testMessage);
+
+ await SpecialPowers.pushPrefEnv({
+ set: [[featureTourPref, getPrefValueByScreen(1)]],
+ });
+
+ await BrowserTestUtils.withNewTab(
+ {
+ gBrowser,
+ url: "about:firefoxview",
+ },
+ async browser => {
+ const { document } = browser.contentWindow;
+ await waitForCalloutScreen(document, "FEATURE_CALLOUT_1");
+ let parent = document.querySelector(".brand-icon");
+ let container = document.querySelector(calloutSelector);
+ let parentHeight = parent.offsetHeight;
+ let containerHeight = container.offsetHeight;
+
+ let parentPositionTop =
+ parent.getBoundingClientRect().top + window.scrollY;
+ let containerPositionTop =
+ container.getBoundingClientRect().top + window.scrollY;
+ Assert.greater(
+ containerHeight,
+ parentHeight,
+ "Feature Callout is height is larger than parent element when callout is configured at end of callout"
+ );
+ Assert.less(
+ containerPositionTop,
+ parentPositionTop,
+ "Feature Callout is positioned higher that parent element when callout is configured at end of callout"
+ );
+ isfuzzy(
+ containerHeight / 2 + containerPositionTop,
+ parentHeight / 2 + parentPositionTop,
+ 1, // Display scaling can cause up to 1px difference in layout
+ "Feature Callout is centered equally to parent element when callout is configured at end of callout"
+ );
+ await ASRouter.resetMessageState();
+ }
+ );
+ sandbox.restore();
+});