diff --git a/cypress/components/menu/menu.cy.tsx b/cypress/components/menu/menu.cy.tsx
deleted file mode 100644
index a0ee77f55d..0000000000
--- a/cypress/components/menu/menu.cy.tsx
+++ /dev/null
@@ -1,2024 +0,0 @@
-import React from "react";
-import {
- Menu,
- MenuProps,
- MenuItem,
- MenuWithChildren,
- MenuDivider,
- MenuDividerProps,
- MenuSegmentTitle,
- MenuFullscreenProps,
- ScrollableBlockProps,
-} from "../../../src/components/menu";
-import Box from "../../../src/components/box";
-import {
- submenuBlock,
- innerMenu,
- submenu,
- scrollBlock,
- lastSubmenuElement,
- menuDivider,
- segmentTitle,
- menuComponent,
- submenuItem,
- fullscreenMenu,
- fullScreenMenuWrapper,
- menu,
- menuItem,
- fullScreenMenuItem,
- searchDefaultInput,
- searchCrossIcon,
- searchButton,
-} from "../../locators/menu";
-import { getComponent, closeIconButton, icon } from "../../locators";
-import {
- keyCode,
- positionOfElement,
- pressTABKey,
- continuePressingTABKey,
-} from "../../support/helper";
-import { CHARACTERS } from "../../support/component-helper/constants";
-import {
- checkGoldenOutline,
- assertCssValueIsApproximately,
-} from "../../support/component-helper/common-steps";
-import CypressMountWithProviders from "../../support/component-helper/cypress-mount";
-import {
- MenuComponent,
- MenuComponentScrollable,
- MenuComponentSearch,
- MenuWithChildrenUpdating,
- MenuComponentFullScreen,
- MenuFullScreenBackgroundScrollTest,
- MenuFullScreenWithFalsyValues,
- MenuFullScreenKeysTest,
- MenuComponentItems,
- MenuFullScreenWithSearchButton,
- MenuComponentScrollableParent,
- MenuComponentWithIcon,
- MenuComponentButtonIcon,
- MenuSegmentTitleComponent,
- MenuItems,
- ClosedMenuFullScreenWithButtons,
- MenuDividerComponent,
- InGlobalHeaderStory,
-} from "../../../src/components/menu/menu-test.stories";
-import { NavigationBarWithSubmenuAndChangingHeight } from "../../../src/components/navigation-bar/navigation-bar-test.stories";
-
-const span = "span";
-const div = "div";
-
-context("Testing Menu component", () => {
- describe("check props for Menu component", () => {
- it("should verify scroll block within a submenu is scrollable", () => {
- CypressMountWithProviders();
-
- submenu().eq(positionOfElement("first")).trigger("mouseover");
- scrollBlock().scrollTo("bottom");
- lastSubmenuElement("li").should("be.visible");
- });
-
- it("should verify a submenu can be navigated using keyboard tabbing after an item was clicked", () => {
- CypressMountWithProviders();
-
- submenu().eq(positionOfElement("first")).trigger("mouseover");
- innerMenu(positionOfElement("third"), span).click({ multiple: true });
- cy.focused().tab();
- cy.focused().should("contain", "Item Submenu Three");
- cy.focused().parent().should("have.css", "box-shadow", "none");
- cy.focused().tab();
- cy.focused().should("contain", "Item Submenu Four");
- cy.focused().parent().should("have.css", "box-shadow", "none");
- });
-
- it("should verify a submenu can be navigated using keyboard down arrow after an item was clicked", () => {
- CypressMountWithProviders();
-
- submenu().eq(positionOfElement("first")).trigger("mouseover");
- innerMenu(positionOfElement("third"), span).click({ multiple: true });
- cy.focused().trigger("keydown", keyCode("downarrow"));
- cy.focused().should("contain", "Item Submenu Three");
- cy.focused().trigger("keydown", keyCode("downarrow"));
- cy.focused().should("contain", "Item Submenu Four");
- });
-
- it("should verify a submenu can be navigated using keyboard shift + tabbing after an item was clicked", () => {
- CypressMountWithProviders();
-
- submenu().eq(positionOfElement("first")).trigger("mouseover");
- innerMenu(positionOfElement("fifth"), span).click({ multiple: true });
- cy.focused().tab({ shift: true });
- cy.focused().should("contain", "Item Submenu Two");
- cy.focused().tab({ shift: true });
- cy.focused().should("contain", "Item Submenu One");
- });
-
- it("should verify a submenu can be navigated using keyboard up arrow after an item was clicked", () => {
- CypressMountWithProviders();
-
- submenu().eq(positionOfElement("first")).trigger("mouseover");
- innerMenu(positionOfElement("fifth"), span).click({ multiple: true });
- cy.focused().trigger("keydown", keyCode("uparrow"));
- cy.focused().should("contain", "Item Submenu Two");
- cy.focused().trigger("keydown", keyCode("uparrow"));
- cy.focused().should("contain", "Item Submenu One");
- });
-
- it("should verify a the first submenu item is focused using keyboard tabbing after the parent item was clicked", () => {
- CypressMountWithProviders();
-
- submenu().eq(positionOfElement("first")).click();
- cy.focused().tab();
- cy.focused().should("contain", "Item Submenu One");
- });
-
- it("should verify a the first submenu item is focused using keyboard down arrow after the parent item was clicked", () => {
- CypressMountWithProviders();
-
- submenu().eq(positionOfElement("first")).click();
- cy.focused().trigger("keydown", keyCode("downarrow"));
- cy.focused().should("contain", "Item Submenu One");
- });
-
- it("should verify number and type of elements in submenu", () => {
- const position = ["second", "third", "fifth", "sixth"] as const;
-
- CypressMountWithProviders();
-
- submenu().eq(positionOfElement("first")).trigger("mouseover");
- submenuBlock().children().should("have.length", 5);
- for (let i = 0; i < position.length; i++) {
- innerMenu(positionOfElement(position[i]), span).should(
- "have.attr",
- "data-component",
- "link"
- );
- }
- innerMenu(positionOfElement("fourth"), div).should(
- "have.attr",
- "data-component",
- "menu-divider"
- );
- });
-
- it.each([
- ["white", "rgb(230, 235, 237)", "first"],
- ["light", "rgb(255, 255, 255)", "third"],
- ["dark", "rgb(0, 25, 38)", "fifth"],
- ["black", "rgb(38, 38, 38)", "seventh"],
- ] as [string, string, "first" | "third" | "fifth" | "seventh"][])(
- "should verify submenu background color is %s",
- (colorName, color, menuNumber) => {
- CypressMountWithProviders();
-
- submenu().eq(positionOfElement(menuNumber)).trigger("mouseover");
- innerMenu(positionOfElement("second"), span).should(
- "have.css",
- "background-color",
- color
- );
- }
- );
-
- it.each([
- ["white", "rgb(255, 255, 255)", "first"],
- ["light", "rgb(230, 235, 237)", "fifth"],
- ["dark", "rgb(0, 50, 76)", "ninth"],
- ["black", "rgb(0, 0, 0)", "thirteenth"],
- ] as [string, string, "first" | "fifth" | "ninth" | "thirteenth"][])(
- "should verify Menu background color is %s",
- (colorName, color, menuNumber) => {
- CypressMountWithProviders();
- menuItem()
- .eq(positionOfElement(menuNumber))
- .children()
- .should("have.css", "background-color", color);
- }
- );
-
- it.each([
- ["white", "rgba(0, 0, 0, 0.9)"],
- ["light", "rgba(0, 0, 0, 0.9)"],
- ["dark", "rgb(255, 255, 255)"],
- ["black", "rgb(255, 255, 255)"],
- ] as [MenuProps["menuType"], string][])(
- "should verify icons have the correct color when menuType is %s",
- (menuType, color) => {
- CypressMountWithProviders(
-
- );
- pressTABKey(1);
- icon().should("have.css", "color", color);
- }
- );
-
- it.each([
- ["default", 1],
- ["large", 4],
- ] as [MenuDividerProps["size"], number][])(
- "should verify Menu Divider size is %s",
- (size, height) => {
- CypressMountWithProviders();
-
- submenu().eq(positionOfElement("first")).trigger("mouseover");
- menuDivider().then(($el) => {
- assertCssValueIsApproximately($el, "height", height);
- });
- }
- );
-
- it("should verify Menu Segment Title is visible within a submenu", () => {
- CypressMountWithProviders();
-
- submenu().eq(positionOfElement("second")).trigger("mouseover");
- segmentTitle()
- .should("have.text", "segment title")
- .and("be.visible")
- .and("have.css", "color", "rgba(0, 0, 0, 0.65)");
- });
-
- it("should verify default menu clickToOpen element does not open on hover", () => {
- CypressMountWithProviders();
-
- menuComponent(positionOfElement("fourth")).trigger("mouseover", {
- force: true,
- });
- submenuItem(positionOfElement("fourth"))
- .should("have.length", 0)
- .and("not.exist");
- });
-
- it("should verify default menu clickToOpen element opens on click", () => {
- CypressMountWithProviders();
-
- menuComponent(positionOfElement("sixth")).click();
- submenuItem(positionOfElement("sixth")).should("have.length", 2);
- innerMenu(positionOfElement("second"), span)
- .should("have.attr", "data-component", "link")
- .and("be.visible");
- innerMenu(positionOfElement("third"), span)
- .should("have.attr", "data-component", "link")
- .and("be.visible");
- });
-
- it.each(["Enter", "Space", "downarrow", "uparrow"] as (
- | "Enter"
- | "Space"
- | "downarrow"
- | "uparrow"
- )[])(
- "should verify default menu clickToOpen element opens using %s key",
- (key) => {
- CypressMountWithProviders();
- menuComponent(positionOfElement("sixth")).trigger(
- "keydown",
- keyCode(key)
- );
- submenuItem(positionOfElement("sixth")).should("have.length", 2);
- innerMenu(positionOfElement("second"), span)
- .should("have.attr", "data-component", "link")
- .and("be.visible");
- innerMenu(positionOfElement("third"), span)
- .should("have.attr", "data-component", "link")
- .and("be.visible");
- }
- );
-
- it.each([
- ["downarrow", 0],
- ["uparrow", 2],
- ] as ["downarrow" | "uparrow", number][])(
- "should verify the Search component is focusable by using the %s key",
- (key, tabs) => {
- CypressMountWithProviders();
-
- pressTABKey(1);
-
- cy.focused().trigger("keydown", keyCode("Enter"));
- pressTABKey(tabs);
- cy.focused().trigger("keydown", keyCode(key));
- searchDefaultInput().should("have.focus");
- }
- );
-
- it("should verify the Search component close icon is focusable when using keyboard to navigate down the list of items", () => {
- CypressMountWithProviders();
-
- pressTABKey(1);
- cy.focused().trigger("keydown", keyCode("Enter"));
- cy.focused().trigger("keydown", keyCode("downarrow"));
- searchDefaultInput().clear().type("FooBar");
- searchDefaultInput().tab();
- searchCrossIcon().parent().should("have.focus");
- });
-
- it("should verify the Search component close icon is centred when focused", () => {
- CypressMountWithProviders();
- const bottomLess = 201;
- const topLess = 181;
- const leftLess = 134;
- // additionVal is to compensate for the outline.
- const additionVal = 2;
-
- pressTABKey(1);
- cy.focused().trigger("keydown", keyCode("Enter"));
-
- cy.focused().trigger("keydown", keyCode("downarrow"));
-
- searchDefaultInput().clear().type("FooBar");
-
- searchDefaultInput().tab();
- searchCrossIcon().parent().should("have.focus");
-
- const bounding = (element: JQuery) => {
- return element[0].getBoundingClientRect();
- };
-
- searchCrossIcon()
- .then(($el) => bounding($el))
- .as("position");
-
- cy.get("@position")
- .its("bottom")
- .should("be.lessThan", bottomLess + additionVal);
- cy.get("@position").its("bottom").should("be.greaterThan", bottomLess);
- cy.get("@position")
- .its("top")
- .should("be.lessThan", topLess + additionVal);
- cy.get("@position").its("top").should("be.greaterThan", topLess);
- cy.get("@position")
- .its("left")
- .should("be.lessThan", leftLess + additionVal);
- cy.get("@position").its("left").should("be.greaterThan", leftLess);
- });
-
- it("should verify the Search component close icon is focusable when using keyboard to navigate up the list of items", () => {
- CypressMountWithProviders();
- pressTABKey(1);
- cy.focused().trigger("keydown", keyCode("Enter"));
- searchDefaultInput().clear().type("FooBar");
- cy.focused().trigger("keydown", keyCode("End"));
- cy.focused().tab({ shift: true });
- cy.focused().tab({ shift: true });
- searchCrossIcon().parent().should("have.focus");
- cy.focused().tab({ shift: true });
- searchDefaultInput().should("have.focus");
- });
-
- it("should verify that the Search component is focusable by using the downarrow key when rendered as the parent of a scrollable submenu", () => {
- CypressMountWithProviders();
-
- pressTABKey(3);
- cy.focused().trigger("keydown", keyCode("Enter"));
- cy.focused().trigger("keydown", keyCode("downarrow"));
- searchDefaultInput().should("have.focus");
- });
-
- it("should verify scroll Menu search has an alternate background color", () => {
- CypressMountWithProviders();
- submenu().eq(positionOfElement("third")).trigger("mouseover");
- menuItem()
- .eq(4)
- .children()
- .should("have.css", "background-color", "rgb(0, 50, 76)");
- });
-
- it("should not close submenu when enter is pressed on search component", () => {
- CypressMountWithProviders();
-
- pressTABKey(1);
- cy.focused().trigger("keydown", keyCode("Enter"));
- cy.focused().trigger("keydown", keyCode("downarrow"));
- searchDefaultInput().clear().type("FooBar");
- cy.focused().tab();
- cy.focused().trigger("keydown", keyCode("Enter"));
- submenuBlock().should("be.visible");
- });
-
- it("should verify if there is a Menu Item with a very long label inside a submenu, check that the width of the whole submenu is determined by this submenu item", () => {
- CypressMountWithProviders(
-
-
-
- );
-
- submenu().eq(positionOfElement("first")).trigger("mouseover");
- innerMenu(positionOfElement("second"), span).as("submenuBlock");
- cy.get("@submenuBlock").its("0").should("have.css", "width").as("width");
- cy.get("@width")
- .then(($el) => parseInt($el.toString()))
- .should("be.within", 385, 395);
- });
-
- it("should verify if there is a Menu Item with a submenu that has a very long label, check the width of the whole submenu is determined by this parent item", () => {
- CypressMountWithProviders(
-
-
-
- );
-
- submenu().eq(positionOfElement("first")).trigger("mouseover");
- submenu().eq(positionOfElement("first")).as("submenuBlock");
- cy.get("@submenuBlock").its("0").should("have.css", "width").as("width");
- cy.get("@width")
- .then(($el) => parseInt($el.toString()))
- .should("be.within", 490, 499);
- });
-
- it.each([
- ["float", 0.3, 409],
- ["float", 0.6, 819],
- ["float", 1.0, 1366],
- ["number", 350, 350],
- ["number", 900, 900],
- ["number", 1350, 1350],
- ["string", "450px", 450],
- ["string", "675px", 675],
- ["string", "1200px", 1200],
- ])(
- "should verify Menu width is set by width prop when passed as %s",
- (type, width, pixels) => {
- CypressMountWithProviders();
-
- menu().then(($el) => {
- assertCssValueIsApproximately($el, "width", pixels);
- });
- }
- );
-
- it.each([
- ["number", 15, 15],
- ["number", 27, 27],
- ["number", 41, 41],
- ["string", "10px", 10],
- ["string", "30px", 30],
- ["string", "50px", 50],
- ])(
- "should verify Menu height is set by height prop when passed as %s",
- (type, propValue, pixels) => {
- CypressMountWithProviders();
-
- menu().then(($el) => {
- assertCssValueIsApproximately($el, "height", pixels);
- });
- }
- );
-
- it.each([
- ["number", 810, 350, 810],
- ["number", 810, 1350, 1350],
- ["string", "700px", "300px", 700],
- ["string", "700px", "1200px", 1200],
- ] as [string, string | number, string | number, number][])(
- "should verify Menu minimum width is set by minWidth prop when passed as %s",
- (type, minWidth, width, pixels) => {
- CypressMountWithProviders(
-
- );
- menu().then(($el) => {
- assertCssValueIsApproximately($el, "width", pixels);
- });
- }
- );
-
- it.each([
- ["number", 810, 350, 350],
- ["number", 810, 1350, 810],
- ["string", "700px", "300px", 300],
- ["string", "700px", "1200px", 700],
- ] as [string, string | number, string | number, number][])(
- "should verify Menu maximum width is set by minWidth prop when passed as %s",
- (type, maxWidth, width, pixels) => {
- CypressMountWithProviders(
-
- );
- menu().then(($el) => {
- assertCssValueIsApproximately($el, "width", pixels);
- });
- }
- );
-
- it.each([
- ["number", 30, 20, 30],
- ["number", 30, 40, 40],
- ["string", "35px", "25px", 35],
- ["string", "35px", "40px", 40],
- ] as [string, string | number, string | number, number][])(
- "should verify Menu minimum height is set by minWidth prop when passed as %s",
- (type, minHeight, height, pixels) => {
- CypressMountWithProviders(
-
- );
-
- menu().then(($el) => {
- assertCssValueIsApproximately($el, "height", pixels);
- });
- }
- );
-
- it.each([
- ["number", 30, 20, 20],
- ["number", 30, 40, 30],
- ["string", "35px", "25px", 25],
- ["string", "35px", "40px", 35],
- ] as [string, string | number, string | number, number][])(
- "should verify Menu maximum height is set by minWidth prop when passed as %s",
- (type, maxHeight, height, pixels) => {
- CypressMountWithProviders(
-
- );
-
- menu().then(($el) => {
- assertCssValueIsApproximately($el, "height", pixels);
- });
- }
- );
-
- it.each(["block", "inline-block", "flex", "contents", "list-item", "none"])(
- "should verify Menu display is %s",
- (display) => {
- CypressMountWithProviders();
-
- menu()
- .should("have.attr", "display", display)
- .and("have.css", "display", display);
- }
- );
-
- it.each([
- "baseline",
- "bottom",
- "middle",
- "sub",
- "super",
- "text-bottom",
- "text-top",
- "top",
- ])("should verify Menu verticalAlign is %s", (alignment) => {
- CypressMountWithProviders();
-
- menu().should("have.css", "vertical-align", alignment);
- });
-
- it.each(["auto", "clip", "hidden", "scroll", "visible"])(
- "should verify Menu overflow is %s",
- (overflow) => {
- CypressMountWithProviders();
-
- menu()
- .should("have.attr", "overflow", overflow)
- .and("have.css", "overflow", overflow);
- }
- );
-
- it.each([
- "auto",
- "clip",
- "hidden",
- "scroll",
- "visible",
- ] as MenuProps["overflowX"][])(
- "should verify Menu overflowX is %s",
- (overflow) => {
- CypressMountWithProviders();
-
- menu().should("have.css", "overflow-x", overflow);
- }
- );
-
- it.each([
- "auto",
- "clip",
- "hidden",
- "scroll",
- "visible",
- ] as MenuProps["overflowY"][])(
- "should verify Menu overflowY is %s",
- (overflow) => {
- CypressMountWithProviders();
-
- menu().should("have.css", "overflow-y", overflow);
- }
- );
-
- it.each([
- "normal",
- "stretch",
- "baseline",
- "center",
- "flex-start",
- "flex-end",
- ])("should verify Menu alignItems is %s", (alignment) => {
- CypressMountWithProviders();
-
- menu().should("have.css", "align-items", alignment);
- });
-
- it.each([
- "normal",
- "baseline",
- "center",
- "flex-start",
- "flex-end",
- "space-between",
- "space-around",
- "stretch",
- ])("should verify Menu alignContent is %s", (alignment) => {
- CypressMountWithProviders();
-
- menu().should("have.css", "align-content", alignment);
- });
-
- it.each([
- "left",
- "center",
- "right",
- "flex-start",
- "flex-end",
- "normal",
- "stretch",
- ])("should verify Menu justifyItems is %s", (justified) => {
- CypressMountWithProviders();
-
- menu().should("have.css", "justify-items", justified);
- });
-
- it.each([
- "left",
- "center",
- "right",
- "flex-start",
- "flex-end",
- "normal",
- "space-between",
- "space-around",
- "stretch",
- ])("should verify Menu justifyContent is %s", (justified) => {
- CypressMountWithProviders();
-
- menu().should("have.css", "justify-content", justified);
- });
-
- it.each(["nowrap", "wrap", "wrap-reverse"] as MenuProps["flexWrap"][])(
- "should verify Menu flex wrap is %s",
- (wrap) => {
- CypressMountWithProviders();
-
- menu().should("have.css", "flex-wrap", wrap);
- }
- );
-
- it.each([
- "column",
- "column-reverse",
- "row",
- "row-reverse",
- ] as MenuProps["flexDirection"][])(
- "should verify Menu flex direction is %s",
- (direction) => {
- CypressMountWithProviders();
-
- menu().should("have.css", "flex-direction", direction);
- }
- );
-
- it.each(["auto", "content", "fit-content", "max-content", "min-content"])(
- "should verify Menu flex is %s",
- (flex) => {
- CypressMountWithProviders();
-
- menu().should("have.css", "flex-basis", flex);
- }
- );
-
- it.each([
- [10, "10"],
- [50, "50"],
- [100, "100"],
- ])("should verify Menu flex grow is %s", (value, growText) => {
- CypressMountWithProviders();
-
- menu().should("have.css", "flex-grow", growText);
- });
-
- it.each([
- [10, "10"],
- [50, "50"],
- [100, "100"],
- ])("should verify Menu flex shrink is %s", (value, shrinkText) => {
- CypressMountWithProviders(
-
- );
-
- menu().should("have.css", "flex-shrink", shrinkText);
- });
-
- it.each(["auto", "content", "fit-content", "max-content", "min-content"])(
- "should verify Menu flex basis is %s",
- (basis) => {
- CypressMountWithProviders();
-
- menu().should("have.css", "flex-basis", basis);
- }
- );
-
- it.each([
- "auto",
- "baseline",
- "left",
- "normal",
- "right",
- "stretch",
- "center",
- "flex-start",
- "flex-end",
- ])("should verify Menu justifySelf is %s", (justify) => {
- CypressMountWithProviders();
-
- menu().should("have.css", "justify-self", justify);
- });
-
- it.each([
- "auto",
- "baseline",
- "normal",
- "stretch",
- "center",
- "flex-start",
- "flex-end",
- ])("should verify Menu alignSelf is %s", (align) => {
- CypressMountWithProviders();
-
- menu().should("have.css", "align-self", align);
- });
-
- it.each([
- [10, "10"],
- [50, "50"],
- [100, "100"],
- ])("should verify Menu order is %s", (value, orderText) => {
- CypressMountWithProviders();
-
- menu().should("have.css", "order", orderText);
- });
-
- it("should verify Menu Items className is customisable", () => {
- CypressMountWithProviders(
-
- );
- menuItem().eq(0).should("have.attr", "class").as("item");
- cy.get("@item").should("contain", CHARACTERS.STANDARD);
- });
-
- it.each([
- ["selected", true, "rgb(230, 235, 237)"],
- ["not selected", false, "rgb(255, 255, 255)"],
- ])("should verify first Menu Item is %s", (state, boolVal, color) => {
- CypressMountWithProviders();
-
- submenu().eq(0).children().should("have.css", "background-color", color);
- });
-
- it.each([
- CHARACTERS.STANDARD,
- CHARACTERS.DIACRITICS,
- CHARACTERS.SPECIALCHARACTERS,
- ])("should verify Menu Item text is %s", (text) => {
- CypressMountWithProviders();
-
- menuItem().eq(0).should("have.text", text);
- });
-
- it("should verify Menu Item target is %s", () => {
- CypressMountWithProviders(
-
- );
- menuItem()
- .eq(0)
- .children()
- .children()
- .children()
- .should("have.attr", "target", CHARACTERS.STANDARD);
- });
-
- it.each([
- [true, 32],
- [false, 16],
- ])(
- "should verify dropdown arrow is displayed on Menu Item",
- (boolVal, padding) => {
- CypressMountWithProviders(
-
- );
-
- submenu()
- .eq(0)
- .children()
- .children()
- .should("have.css", "padding-right", `${padding}px`);
- }
- );
-
- it.each([
- ["default", "rgb(255, 255, 255)"],
- ["alternate", "rgb(217, 224, 228)"],
- ] as [MenuWithChildren["variant"], string][])(
- "should verify Menu Item has %s variant",
- (variant, color) => {
- CypressMountWithProviders();
-
- submenu()
- .eq(0)
- .children()
- .should("have.css", "background-color", color);
- }
- );
-
- it("should verify Menu Item ariaLabel is set to cypress_data", () => {
- CypressMountWithProviders(
-
- );
-
- submenu()
- .eq(0)
- .children()
- .children()
- .should("have.attr", "aria-label", CHARACTERS.STANDARD);
- });
-
- it.each([
- ["default", 1, 16, 121],
- ["large", 4, 0, 153],
- ] as [MenuDividerProps["size"], number, number, number][])(
- "should verify that a Menu size is %s",
- (size, height, margin, width) => {
- CypressMountWithProviders(
-
-
-
- );
-
- submenu().eq(positionOfElement("first")).trigger("mouseover");
- menuDivider().then(($el) => {
- assertCssValueIsApproximately($el, "height", height);
- assertCssValueIsApproximately($el, "margin-left", margin);
- assertCssValueIsApproximately($el, "width", width);
- });
- }
- );
-
- it.each([
- [100, 100],
- [200, 200],
- ["150px", 150],
- ["250px", 250],
- ] as [ScrollableBlockProps["height"], number][])(
- "should verify Menu scroll block height prop can be entered as a number or string",
- (height, pixels) => {
- CypressMountWithProviders();
-
- submenu().eq(positionOfElement("first")).trigger("mouseover");
- scrollBlock().then(($el) => {
- assertCssValueIsApproximately($el, "height", pixels);
- });
- }
- );
-
- it.each([
- ["default", "rgb(230, 235, 237)"],
- ["alternate", "rgb(217, 224, 228)"],
- ] as [ScrollableBlockProps["variant"], string][])(
- "should verify Menu scroll block has %s background color using variant prop",
- (variant, color) => {
- CypressMountWithProviders(
-
- );
-
- submenu().eq(positionOfElement("first")).trigger("mouseover");
- scrollBlock()
- .children()
- .children()
- .should("have.css", "background-color", color);
- }
- );
-
- it.each([
- ["default", "rgba(0, 0, 0, 0)"],
- ["alternate", "rgb(217, 224, 228)"],
- ] as [ScrollableBlockProps["variant"], string][])(
- "should verify that a Menu Segment Title has a variant background color",
- (variant, color) => {
- CypressMountWithProviders(
-
-
-
- );
- submenu().eq(positionOfElement("first")).trigger("mouseover");
- segmentTitle().should("have.css", "background-color", color);
- }
- );
-
- it("should verify that inner Menu without link is NOT available with tabbing in Fullscreen Menu", () => {
- CypressMountWithProviders();
-
- cy.viewport(1200, 800);
- menuItem().eq(positionOfElement("first")).click();
- continuePressingTABKey(8);
- menuItem().should("not.be.focused");
- });
-
- it("should verify Menu Item href prop", () => {
- CypressMountWithProviders(
-
- );
-
- submenu()
- .eq(0)
- .children()
- .children()
- .should("have.attr", "href", CHARACTERS.STANDARD);
- });
-
- it.each([["noopener"], ["noreferrer"], ["opener"]])(
- "should verify Menu Item with rel prop set to %s",
- (rel) => {
- CypressMountWithProviders();
-
- submenu().eq(0).children().children().should("have.attr", "rel", rel);
- }
- );
-
- it("should verify Scrollable Block parent prop", () => {
- CypressMountWithProviders(
- Parent} />
- );
-
- submenu().eq(positionOfElement("first")).trigger("mouseover");
- scrollBlock()
- .eq(0)
- .parent()
- .children()
- .eq(0)
- .should("have.text", "Parent");
- });
-
- it.each([
- ["default", "rgb(230, 235, 237)"],
- ["alternate", "rgb(217, 224, 228)"],
- ] as [ScrollableBlockProps["parentVariant"], string][])(
- "should verify Scrollable Block parent variant prop",
- (variant, color) => {
- CypressMountWithProviders(
- Parent}
- parentVariant={variant}
- />
- );
-
- submenu().eq(positionOfElement("first")).trigger("mouseover");
- scrollBlock()
- .eq(0)
- .parent()
- .children()
- .eq(0)
- .children()
- .should("have.css", "background-color", color);
- }
- );
- });
-
- describe("check props for Menu Fullscreen component", () => {
- beforeEach(() => {
- cy.viewport(1200, 800);
- CypressMountWithProviders();
- menuItem().eq(positionOfElement("first")).click();
- });
-
- it("should verify that the Menu Fullscreen is rendered properly", () => {
- fullscreenMenu(positionOfElement("first"))
- .find("span")
- .should("have.attr", "data-element", "close")
- .and("be.visible");
- fullscreenMenu(positionOfElement("second"))
- .find("ul")
- .should("have.attr", "data-component", "menu")
- .should("be.visible");
- fullscreenMenu(positionOfElement("second"))
- .find("ul > li")
- .should("have.length", 15);
- });
-
- it("should verify that the Menu Fullscreen is closed when close icon is clicked", () => {
- closeIconButton().eq(0).click();
-
- fullscreenMenu(positionOfElement("first")).should("not.be.visible");
- fullscreenMenu(positionOfElement("second")).should("not.be.visible");
- menu().should("be.visible");
- });
-
- it("should verify that close icon is focused in Menu Fullscreen, focusRedesignOptOut false", () => {
- fullScreenMenuWrapper().tab();
- closeIconButton()
- .should(
- "have.css",
- "box-shadow",
- "rgb(255, 188, 25) 0px 0px 0px 3px, rgba(0, 0, 0, 0.9) 0px 0px 0px 6px"
- )
- .and("have.css", "outline", "rgba(0, 0, 0, 0) solid 3px");
- closeIconButton().tab();
- cy.focused()
- .should(
- "have.css",
- "box-shadow",
- "rgba(0, 0, 0, 0.9) 0px 0px 0px 3px inset, rgb(255, 188, 25) 0px 0px 0px 6px inset"
- )
- .and("have.css", "outline", "rgba(0, 0, 0, 0) solid 3px");
- });
-
- it("should verify that close icon is focused in Menu Fullscreen, focusRedesignOptOut true", () => {
- cy.viewport(1200, 800);
- CypressMountWithProviders(
- ,
- undefined,
- undefined,
- {
- focusRedesignOptOut: true,
- }
- );
- menuItem().eq(positionOfElement("first")).click();
-
- fullScreenMenuWrapper().tab();
- closeIconButton().then(($el) => {
- checkGoldenOutline($el);
- });
-
- closeIconButton().tab();
- cy.focused().should(
- "have.css",
- "box-shadow",
- "rgb(255, 188, 25) 0px 0px 0px 3px inset"
- );
- });
-
- it("should verify that inner Menu is available with tabbing and styles are correct", () => {
- cy.viewport(1200, 800);
- CypressMountWithProviders();
- menuItem().eq(positionOfElement("first")).click();
-
- fullScreenMenuWrapper().tab();
- for (let i = 0; i < 4; i++) {
- cy.focused().tab();
- }
- fullScreenMenuItem(positionOfElement("fourth"))
- .find("ul > li")
- .eq(1)
- .children()
- .children()
- .should("have.css", "box-shadow")
- .and("contain", "rgb(255, 188, 25)");
- fullScreenMenuItem(positionOfElement("fourth"))
- .find("ul > li")
- .eq(1)
- .children()
- .children()
- .should("have.css", "background-color")
- .and("contain", "rgb(0, 126, 69)");
- fullScreenMenuItem(positionOfElement("fourth"))
- .find("ul > li")
- .eq(1)
- .children()
- .children()
- .should("have.css", "color")
- .and("contain", "rgb(255, 255, 255)");
- fullScreenMenuItem(positionOfElement("fourth"))
- .find("ul > li")
- .eq(1)
- .children()
- .children()
- .should("be.focused");
- });
-
- it("should verify that inner Menu is available with shift-tabbing and styles are correct", () => {
- cy.viewport(1200, 800);
- CypressMountWithProviders();
- menuItem().eq(positionOfElement("first")).click();
-
- fullScreenMenuWrapper().tab();
- for (let i = 0; i < 5; i++) {
- cy.focused().tab();
- }
- cy.focused().tab({ shift: true });
- fullScreenMenuItem(positionOfElement("fourth"))
- .find("ul > li")
- .eq(1)
- .children()
- .children()
- .should("have.css", "box-shadow")
- .and("contain", "rgb(255, 188, 25)");
- fullScreenMenuItem(positionOfElement("fourth"))
- .find("ul > li")
- .eq(1)
- .children()
- .children()
- .should("have.css", "background-color")
- .and("contain", "rgb(0, 126, 69)");
- fullScreenMenuItem(positionOfElement("fourth"))
- .find("ul > li")
- .eq(1)
- .children()
- .children()
- .should("have.css", "color")
- .and("contain", "rgb(255, 255, 255)");
- fullScreenMenuItem(positionOfElement("fourth"))
- .find("ul > li")
- .eq(1)
- .children()
- .children()
- .should("be.focused");
- });
-
- it("should verify that inner Menu without link is NOT available with tabbing in Fullscreen Menu", () => {
- continuePressingTABKey(8);
- menuItem().should("not.be.focused");
- });
-
- it.each([
- ["open", true, "be.visible"],
- ["closed", false, "not.be.visible"],
- ])(
- "should verify that Menu Fullscreen is %s when isOpen prop is %s",
- (value, boolVal, state) => {
- CypressMountWithProviders();
-
- getComponent("menu-fullscreen").should(state);
- }
- );
-
- it("should verify that Menu Fullscreen has no effect on the tab order when isOpen prop is false", () => {
- CypressMountWithProviders();
-
- cy.tab();
- cy.get("#button-1").should("be.focused");
- cy.tab();
- cy.get("#button-2").should("be.focused");
- });
-
- it.each([
- ["left", -1200, 1200],
- ["right", 1200, -1200],
- ] as [MenuFullscreenProps["startPosition"], number, number][])(
- "should verify that Menu Fullscreen start position is %s",
- (side, left, right) => {
- CypressMountWithProviders(
-
- );
- getComponent("menu-fullscreen").should("have.css", "left", `${left}px`);
- getComponent("menu-fullscreen").should(
- "have.css",
- "right",
- `${right}px`
- );
- }
- );
-
- it("should focus the next menu item on tab press when the current item has a Search input with searchButton but no value", () => {
- CypressMountWithProviders(
-
- );
-
- menuItem().first().find("a").focus();
- cy.tab();
- searchDefaultInput().should("have.focus");
- cy.tab();
- menuItem().last().find("a").should("have.focus");
- });
-
- it("should focus the search icon and button on tab press when the current item has a Search input with searchButton and has a value, focusRedesignOptOut flag not set", () => {
- CypressMountWithProviders(
-
- );
-
- menuItem().first().find("a").focus();
- cy.tab();
- searchDefaultInput().should("have.focus");
- cy.tab();
- searchCrossIcon().parent().should("have.focus");
- cy.tab();
- searchButton().should("have.focus");
- searchButton().should(
- "have.css",
- "box-shadow",
- "rgb(255, 188, 25) 0px 0px 0px 3px, rgba(0, 0, 0, 0.9) 0px 0px 0px 6px"
- );
- cy.tab();
- menuItem().last().find("a").should("have.focus");
- });
-
- it("should focus the search icon and button on tab press when the current item has a Search input with searchButton and has a value, focusRedesignOptOut flag set", () => {
- CypressMountWithProviders(
- ,
- undefined,
- undefined,
- { focusRedesignOptOut: true }
- );
-
- menuItem().first().find("a").focus();
- cy.tab();
- searchDefaultInput().should("have.focus");
- cy.tab();
- searchCrossIcon().parent().should("have.focus");
- cy.tab();
- searchButton().should("have.focus");
- searchButton().then(($el) => {
- checkGoldenOutline($el);
- });
- cy.tab();
- menuItem().last().find("a").should("have.focus");
- });
- });
-
- describe("check events for Menu component", () => {
- it("should call onClick callback when a click event is triggered", () => {
- const callback: MenuWithChildren["onClick"] = cy.stub().as("onClick");
- CypressMountWithProviders();
- menuComponent(positionOfElement("second")).click();
- cy.get("@onClick").should("have.been.calledOnce");
- });
-
- it("should call onSubmenuOpen callback when mouseover event is triggered", () => {
- const callback: MenuWithChildren["onSubmenuOpen"] = cy
- .stub()
- .as("onSubmenuOpen");
- CypressMountWithProviders(
-
- );
-
- submenu().eq(positionOfElement("first")).trigger("mouseover");
- cy.get("@onSubmenuOpen").should("have.been.calledOnce");
- });
-
- it("should call onSubmenuOpen callback when a click event is triggered", () => {
- const callback: MenuWithChildren["onSubmenuOpen"] = cy
- .stub()
- .as("onSubmenuOpen");
- CypressMountWithProviders(
-
- );
- menuComponent(positionOfElement("second")).click();
- cy.get("@onSubmenuOpen").should("have.been.calledOnce");
- });
-
- it.each(["Space", "Enter", "downarrow", "uparrow"] as (
- | "Space"
- | "Enter"
- | "downarrow"
- | "uparrow"
- )[])(
- "should call onSubmenuOpen callback when a %s keyboard event is triggered",
- (key) => {
- const callback: MenuWithChildren["onSubmenuOpen"] = cy
- .stub()
- .as("onSubmenuOpen");
- CypressMountWithProviders(
-
- );
- menuComponent(positionOfElement("second")).trigger(
- "keydown",
- keyCode(key)
- );
- cy.get("@onSubmenuOpen").should("have.been.calledOnce");
- }
- );
-
- it("should call onSubmenuClose callback when menu is closed", () => {
- const callback: MenuWithChildren["onSubmenuOpen"] = cy
- .stub()
- .as("onSubmenuOpen");
- CypressMountWithProviders(
-
- );
- submenu().eq(positionOfElement("first")).trigger("mouseover");
- submenu().eq(positionOfElement("second")).trigger("mouseover");
-
- cy.get("@onSubmenuOpen").should("have.been.calledOnce");
- });
-
- it("should call onClose callback when Menu Fullscreen is closed", () => {
- const callback: MenuFullscreenProps["onClose"] = cy.stub().as("onClose");
- CypressMountWithProviders();
- cy.viewport(1200, 800);
- menuItem().eq(positionOfElement("first")).click();
- closeIconButton().eq(0).click();
- cy.get("@onClose").should("have.been.calledOnce");
- });
-
- it("should have correct keyboard navigation order when children of submenu update", () => {
- CypressMountWithProviders();
- submenu().eq(positionOfElement("first")).trigger("mouseover");
- submenuBlock().children().should("have.length", 4);
-
- pressTABKey(1);
- cy.focused().trigger("keydown", keyCode("downarrow"));
- cy.focused().should("contain", "Apple");
- cy.focused().trigger("keydown", keyCode("downarrow"));
- cy.focused().should("contain", "Banana");
- cy.focused().trigger("keydown", keyCode("downarrow"));
- cy.focused().should("contain", "Carrot");
- cy.focused().trigger("keydown", keyCode("downarrow"));
- cy.focused().should("contain", "Broccoli");
-
- cy.focused().trigger("keydown", keyCode("uparrow"));
- cy.focused().should("contain", "Carrot");
- cy.focused().trigger("keydown", keyCode("uparrow"));
- cy.focused().should("contain", "Banana");
- cy.focused().trigger("keydown", keyCode("uparrow"));
- cy.focused().should("contain", "Apple");
- });
- });
-
- describe("Accessibility tests for Menu component", () => {
- it("should pass accessibility tests for Menu default", () => {
- CypressMountWithProviders();
-
- cy.checkAccessibility();
- });
-
- it("should pass accessibility tests for Menu expanded", () => {
- CypressMountWithProviders();
-
- submenu().eq(positionOfElement("first")).trigger("mouseover");
-
- cy.checkAccessibility();
- });
-
- it.each(["default", "large"] as MenuDividerProps["size"][])(
- "should pass accessibility tests for Menu when divider size is %s",
- (divider) => {
- CypressMountWithProviders();
-
- submenu().eq(positionOfElement("first")).trigger("mouseover");
-
- cy.checkAccessibility();
- }
- );
-
- it("should pass accessibility tests for Menu when search component is focused", () => {
- CypressMountWithProviders();
-
- pressTABKey(1);
- cy.focused().trigger("keydown", keyCode("Enter"));
- pressTABKey(0);
- cy.focused().trigger("keydown", keyCode("downarrow"));
-
- cy.checkAccessibility();
- });
-
- it("should pass accessibility tests for Menu when a submenu has a long label", () => {
- CypressMountWithProviders(
-
-
-
- );
-
- submenu().eq(positionOfElement("first")).trigger("mouseover");
-
- cy.checkAccessibility();
- });
-
- it("should pass accessibility tests for Menu when a menu item has a long label", () => {
- CypressMountWithProviders(
-
-
-
- );
-
- submenu().eq(positionOfElement("first")).trigger("mouseover");
-
- cy.checkAccessibility();
- });
-
- it.each(["450px", "675px", "1200px"])(
- "should pass accessibility tests for Menu when width is %s",
- (width) => {
- CypressMountWithProviders();
-
- cy.checkAccessibility();
- }
- );
-
- it.each(["10px", "30px", "50px"])(
- "should pass accessibility tests for Menu when height is s",
- (propValue) => {
- CypressMountWithProviders();
-
- cy.checkAccessibility();
- }
- );
-
- it.each(["default", "large"] as MenuDividerProps["size"][])(
- "should pass accessibility tests for Menu when size is %spx",
- (size) => {
- CypressMountWithProviders();
-
- cy.checkAccessibility();
- }
- );
-
- it.each(["block", "inline-block", "flex", "contents", "list-item", "none"])(
- "should pass accessibility tests for Menu when display is %s",
- (display) => {
- CypressMountWithProviders();
-
- cy.checkAccessibility();
- }
- );
-
- it.each([
- "baseline",
- "bottom",
- "middle",
- "sub",
- "super",
- "text-bottom",
- "text-top",
- "top",
- ])(
- "should pass accessibility tests for Menu when alignItems is %s",
- (alignment) => {
- CypressMountWithProviders();
-
- cy.checkAccessibility();
- }
- );
-
- it.each(["auto", "clip", "hidden", "scroll", "visible"])(
- "should pass accessibility tests for Menu when overflow is %s",
- (overflow) => {
- CypressMountWithProviders();
-
- cy.checkAccessibility();
- }
- );
-
- it.each([
- "auto",
- "clip",
- "hidden",
- "scroll",
- "visible",
- ] as MenuProps["overflowX"][])(
- "should pass accessibility tests for Menu when overflowX is %s",
- (overflow) => {
- CypressMountWithProviders();
-
- cy.checkAccessibility();
- }
- );
-
- it.each([
- "auto",
- "clip",
- "hidden",
- "scroll",
- "visible",
- ] as MenuProps["overflowY"][])(
- "should pass accessibility tests for Menu when overflowY is %s",
- (overflow) => {
- CypressMountWithProviders();
-
- cy.checkAccessibility();
- }
- );
-
- it.each([
- "normal",
- "stretch",
- "baseline",
- "center",
- "flex-start",
- "flex-end",
- ])(
- "should pass accessibility tests for Menu when alignItems is %s",
- (alignment) => {
- CypressMountWithProviders();
-
- cy.checkAccessibility();
- }
- );
-
- it.each([
- "normal",
- "baseline",
- "center",
- "flex-start",
- "flex-end",
- "space-between",
- "space-around",
- "stretch",
- ])(
- "should pass accessibility tests for Menu when alignContent is %s",
- (alignment) => {
- CypressMountWithProviders();
-
- cy.checkAccessibility();
- }
- );
-
- it.each([
- "left",
- "center",
- "right",
- "flex-start",
- "flex-end",
- "normal",
- "stretch",
- ])(
- "should pass accessibility tests for Menu when justifyItems is %s",
- (justified) => {
- CypressMountWithProviders();
-
- cy.checkAccessibility();
- }
- );
-
- it.each([
- "left",
- "center",
- "right",
- "flex-start",
- "flex-end",
- "normal",
- "space-between",
- "space-around",
- "stretch",
- ])(
- "should pass accessibility tests for Menu when justifyContent is %s",
- (justified) => {
- CypressMountWithProviders();
-
- cy.checkAccessibility();
- }
- );
-
- it.each(["nowrap", "wrap", "wrap-reverse"] as MenuProps["flexWrap"][])(
- "should pass accessibility tests for Menu when flexWrap is %s",
- (wrap) => {
- CypressMountWithProviders();
-
- cy.checkAccessibility();
- }
- );
-
- it.each([
- "column",
- "column-reverse",
- "row",
- "row-reverse",
- ] as MenuProps["flexDirection"][])(
- "should pass accessibility tests for Menu when flexDirection is %s",
- (direction) => {
- CypressMountWithProviders();
-
- cy.checkAccessibility();
- }
- );
-
- it.each(["auto", "content", "fit-content", "max-content", "min-content"])(
- "should pass accessibility tests for Menu when flex is %s",
- (flex) => {
- CypressMountWithProviders();
-
- cy.checkAccessibility();
- }
- );
-
- it.each([10, 50, 100])(
- "should pass accessibility tests for Menu when flexGrow is %s",
- (value) => {
- CypressMountWithProviders(
-
- );
-
- cy.checkAccessibility();
- }
- );
-
- it.each([10, 50, 100])(
- "should pass accessibility tests for Menu when flexShrink is %s",
- (value) => {
- CypressMountWithProviders(
-
- );
-
- cy.checkAccessibility();
- }
- );
-
- it.each(["auto", "content", "fit-content", "max-content", "min-content"])(
- "should pass accessibility tests for Menu when flexBasis is %s",
- (basis) => {
- CypressMountWithProviders();
-
- cy.checkAccessibility();
- }
- );
-
- it.each([
- "auto",
- "baseline",
- "left",
- "normal",
- "right",
- "stretch",
- "center",
- "flex-start",
- "flex-end",
- ])(
- "should pass accessibility tests for Menu when justifySelf is %s",
- (justify) => {
- CypressMountWithProviders();
-
- cy.checkAccessibility();
- }
- );
-
- it.each([
- "auto",
- "baseline",
- "normal",
- "stretch",
- "center",
- "flex-start",
- "flex-end",
- ])(
- "should pass accessibility tests for Menu when alignSelf is %s",
- (align) => {
- CypressMountWithProviders();
-
- cy.checkAccessibility();
- }
- );
-
- it.each([
- CHARACTERS.STANDARD,
- CHARACTERS.DIACRITICS,
- CHARACTERS.SPECIALCHARACTERS,
- ])(
- "should pass accessibility tests for Menu when item text is %s",
- (text) => {
- CypressMountWithProviders();
-
- cy.checkAccessibility();
- }
- );
-
- it.each(["default", "alternate"] as ScrollableBlockProps["variant"][])(
- "should pass accessibility tests for Menu when scroll block has a variant background color",
- (variant) => {
- CypressMountWithProviders(
-
- );
-
- submenu().eq(positionOfElement("first")).trigger("mouseover");
- cy.checkAccessibility();
- }
- );
-
- it.each(["default", "alternate"] as ScrollableBlockProps["variant"][])(
- "should pass accessibility tests for Menu when Segment Title has a variant background color",
- (variant) => {
- CypressMountWithProviders(
-
- );
-
- submenu().eq(positionOfElement("first")).trigger("mouseover");
- cy.checkAccessibility();
- }
- );
-
- it("should pass accessibility tests for Menu with parent item", () => {
- CypressMountWithProviders();
-
- submenu().eq(positionOfElement("first")).trigger("mouseover");
- cy.checkAccessibility();
- });
-
- it("should pass accessibility tests for Menu with button icon", () => {
- CypressMountWithProviders();
-
- submenu().eq(positionOfElement("first")).trigger("mouseover");
- cy.checkAccessibility();
- });
-
- // Test skipped because of issue FE-5731
- it.skip("should pass accessibility tests for Menu with icon", () => {
- CypressMountWithProviders();
-
- cy.checkAccessibility();
- });
- });
-
- describe("Accessibility tests for Menu Fullscreen component", () => {
- beforeEach(() => {
- cy.viewport(1200, 800);
- CypressMountWithProviders();
- menuItem().eq(positionOfElement("first")).click();
- });
-
- it("should pass accessibility tests for Menu Fullscreen", () => {
- cy.checkAccessibility();
- });
-
- it("should pass accessibility tests for Menu Fullscreen when close icon is clicked", () => {
- closeIconButton().eq(0).click();
- cy.checkAccessibility();
- });
-
- it("should pass accessibility tests for Menu Fullscreen when menu item is highlighted", () => {
- pressTABKey(5);
- cy.checkAccessibility();
- });
-
- it.each(["left", "right"] as MenuFullscreenProps["startPosition"][])(
- "should pass accessibility tests for Menu Fullscreen when start position is %s",
- (side) => {
- CypressMountWithProviders(
-
- );
- cy.checkAccessibility();
- }
- );
- });
-
- describe("when focused", () => {
- it("menu items should have the expected focus styling, focusRedesignOptOut true", () => {
- cy.viewport(1200, 800);
- CypressMountWithProviders(, undefined, undefined, {
- focusRedesignOptOut: true,
- });
-
- menuItem()
- .first()
- .find("a")
- .focus()
- .should(
- "have.css",
- "box-shadow",
- "rgb(255, 188, 25) 0px 0px 0px 3px inset"
- );
-
- menuItem()
- .last()
- .find("button")
- .focus()
- .should(
- "have.css",
- "box-shadow",
- "rgb(255, 188, 25) 0px 0px 0px 3px inset"
- );
-
- menuItem().last().find("button").click();
-
- submenu()
- .last()
- .find("button")
- .first()
- .focus()
- .should(
- "have.css",
- "box-shadow",
- "rgb(255, 188, 25) 0px 0px 0px 3px inset"
- );
-
- submenu()
- .last()
- .find("a")
- .first()
- .focus()
- .should(
- "have.css",
- "box-shadow",
- "rgb(255, 188, 25) 0px 0px 0px 3px inset"
- );
- });
-
- it("menu items should have the expected focus styling, focusRedesignOptOut false", () => {
- cy.viewport(1200, 800);
- CypressMountWithProviders();
-
- menuItem()
- .first()
- .find("a")
- .focus()
- .should(
- "have.css",
- "box-shadow",
- "rgba(0, 0, 0, 0.9) 0px 0px 0px 3px inset, rgb(255, 188, 25) 0px 0px 0px 6px inset"
- )
- .and("have.css", "outline", "rgba(0, 0, 0, 0) solid 3px");
-
- menuItem()
- .last()
- .find("button")
- .focus()
- .should(
- "have.css",
- "box-shadow",
- "rgba(0, 0, 0, 0.9) 0px 0px 0px 3px inset, rgb(255, 188, 25) 0px 0px 0px 6px inset"
- )
- .and("have.css", "outline", "rgba(0, 0, 0, 0) solid 3px");
-
- menuItem().last().find("button").click();
-
- submenu()
- .last()
- .find("button")
- .first()
- .focus()
- .should(
- "have.css",
- "box-shadow",
- "rgba(0, 0, 0, 0.9) 0px 0px 0px 3px inset, rgb(255, 188, 25) 0px 0px 0px 6px inset"
- )
- .and("have.css", "outline", "rgba(0, 0, 0, 0) solid 3px");
-
- submenu()
- .last()
- .find("a")
- .first()
- .focus()
- .should(
- "have.css",
- "box-shadow",
- "rgba(0, 0, 0, 0.9) 0px 0px 0px 3px inset, rgb(255, 188, 25) 0px 0px 0px 6px inset"
- )
- .and("have.css", "outline", "rgba(0, 0, 0, 0) solid 3px");
- });
- });
-
- describe("rounded corners", () => {
- it("has the expected border radius styling on the Submenu", () => {
- CypressMountWithProviders();
-
- submenu().eq(positionOfElement("first")).trigger("mouseover");
- submenuBlock().should("have.css", "border-radius", "0px 0px 8px 8px");
- submenu()
- .find("a")
- .last()
- .should("have.css", "border-radius", "0px 0px 8px 8px");
- });
-
- it("has the expected border radius styling on the Submenu Scrollable Block", () => {
- CypressMountWithProviders();
-
- submenu().eq(positionOfElement("first")).trigger("mouseover");
- scrollBlock().should("have.css", "border-radius", "0px 0px 0px 8px");
- scrollBlock()
- .find("a")
- .last()
- .should("have.css", "border-radius", "0px 0px 0px 8px");
- });
- });
-
- describe("edge case tests for MenuFullScreen", () => {
- it("tabbing forward through the menu and back to the start should not make the background scroll to the bottom", () => {
- CypressMountWithProviders();
-
- continuePressingTABKey(4);
-
- closeIconButton().should("be.focused");
-
- cy.checkNotInViewport("#bottom-box");
- });
-
- it("tabbing backward through the menu and back to the start should not make the background scroll to the bottom", () => {
- CypressMountWithProviders();
-
- continuePressingTABKey(3, true);
-
- closeIconButton().should("be.focused");
-
- cy.checkNotInViewport("#bottom-box");
- });
-
- it("should not render a MenuDivider when falsy values are rendered", () => {
- CypressMountWithProviders();
-
- menuDivider().should("not.exist");
- });
-
- it("should maintain the state of child items when a new item is added", () => {
- cy.clock();
- CypressMountWithProviders();
-
- cy.tick(5000);
- fullScreenMenuItem(5).should("contain.text", "count 2");
- });
- });
-
- describe("when inside a Navigation Bar", () => {
- it("all the content of a long submenu can be accessed with the keyboard while remaining visible", () => {
- CypressMountWithProviders();
-
- cy.viewport(1000, 500);
-
- menuComponent(1).trigger("keydown", keyCode("downarrow"));
- submenuItem(1).should("have.length", 20);
-
- for (let i = 0; i < 20; i++) {
- cy.focused().trigger("keydown", keyCode("downarrow"));
- }
-
- cy.focused().should("contain", "Foo 20");
- cy.checkInViewport(
- '[data-component="submenu-wrapper"] ul > li:nth-child(20)'
- );
- });
-
- it("all the content of a long submenu can be accessed with the keyboard while remaining visible if the navbar height changes", () => {
- CypressMountWithProviders();
-
- cy.viewport(1000, 500);
-
- menuComponent(1).trigger("keydown", keyCode("downarrow"));
- submenuItem(1).should("have.length", 21);
-
- // navigate to "change height" item and press it
- for (let i = 0; i < 3; i++) {
- cy.focused().trigger("keydown", keyCode("downarrow"));
- }
- cy.focused().trigger("keydown", keyCode("Enter"));
-
- // reopen menu and scroll to bottom with keyboard
- cy.wait(100);
- menuComponent(1).trigger("keydown", keyCode("downarrow"));
-
- for (let i = 0; i < 21; i++) {
- cy.focused().trigger("keydown", keyCode("downarrow"));
- }
-
- cy.checkInViewport(
- '[data-component="submenu-wrapper"] ul > li:nth-child(21)'
- );
- });
- });
-});
diff --git a/cypress/locators/menu/index.js b/cypress/locators/menu/index.js
deleted file mode 100644
index ac8fb1cf03..0000000000
--- a/cypress/locators/menu/index.js
+++ /dev/null
@@ -1,50 +0,0 @@
-import { DLS_ROOT } from "../locators";
-import {
- SUBMENU,
- SCROLL_BLOCK,
- MENU_DIVIDER,
- SEGMENT_TITLE,
- MENU,
- FULLSCREEN_MENU,
- MENU_ITEM,
- SEARCH_COMPONENT,
- CROSS_ICON,
-} from "./locators";
-
-import { BUTTON_DATA_COMPONENT_PREVIEW } from "../button/locators";
-
-// component preview locators
-export const submenu = () => cy.get(SUBMENU);
-export const submenuBlock = () => cy.get(SUBMENU).find("ul");
-export const innerMenu = (index, htmlProp) =>
- submenuBlock().find(`li:nth-child(${index})`).find(htmlProp);
-export const scrollBlock = () => cy.get(SUBMENU).find(SCROLL_BLOCK);
-export const lastSubmenuElement = (htmlProp) =>
- submenuBlock().find(htmlProp).last();
-export const menuDivider = () => cy.get(MENU_DIVIDER);
-export const segmentTitle = () => cy.get(SEGMENT_TITLE);
-export const segmentTitleItem = (index) =>
- segmentTitle()
- .parent()
- .find("ul")
- .find(`li:nth-child(${index})`)
- .find("span");
-export const menuComponent = (index) =>
- cy.get(MENU).first().find(`li:nth-child(${index})`);
-export const submenuItem = (index) =>
- menuComponent(index).find(SUBMENU).find("ul > li");
-export const menuCanvas = () => cy.get(DLS_ROOT);
-export const fullScreenMenuWrapper = () => cy.get(FULLSCREEN_MENU);
-export const fullscreenMenu = (index) =>
- cy.get(FULLSCREEN_MENU).find("div").eq(index);
-export const fullScreenMenuItem = (index) =>
- cy.get(`${FULLSCREEN_MENU} ${MENU}`).find(`li:nth-child(${index})`);
-export const menu = () => cy.get(MENU);
-export const menuItem = () => cy.get(MENU_ITEM);
-
-// component preview locators for Search
-export const searchDefault = () => cy.get(SEARCH_COMPONENT);
-export const searchDefaultInput = () => searchDefault().find("input");
-export const searchCrossIcon = () => searchDefault().find(CROSS_ICON);
-export const searchButton = () =>
- searchDefault().find(BUTTON_DATA_COMPONENT_PREVIEW);
diff --git a/playwright/components/menu/index.ts b/playwright/components/menu/index.ts
new file mode 100644
index 0000000000..0eafa17a9a
--- /dev/null
+++ b/playwright/components/menu/index.ts
@@ -0,0 +1,36 @@
+import type { Page } from "@playwright/test";
+import { DLS_ROOT } from "../locators";
+import {
+ SUBMENU,
+ SCROLL_BLOCK,
+ MENU_DIVIDER,
+ SEGMENT_TITLE,
+ MENU,
+ FULLSCREEN_MENU,
+ MENU_ITEM,
+} from "./locators";
+
+// component preview locators
+export const submenu = (page: Page) => page.locator(SUBMENU);
+export const submenuBlock = (page: Page) => page.locator(SUBMENU).locator("ul");
+export const innerMenu = (page: Page, index: number, htmlProp: string) =>
+ submenuBlock(page).locator(`li:nth-child(${index})`).locator(htmlProp);
+export const scrollBlock = (page: Page) =>
+ page.locator(SUBMENU).locator(SCROLL_BLOCK);
+export const lastSubmenuElement = (page: Page, htmlProp: string) =>
+ submenuBlock(page).locator(htmlProp).last();
+export const menuDivider = (page: Page) => page.locator(MENU_DIVIDER);
+export const segmentTitle = (page: Page) => page.locator(SEGMENT_TITLE);
+export const menuComponent = (page: Page, index: number) =>
+ page.locator(MENU).first().locator(`li:nth-child(${index})`);
+export const submenuItem = (page: Page, index: number) =>
+ menuComponent(page, index).locator(SUBMENU).locator("ul > li");
+export const menuCanvas = (page: Page) => page.locator(DLS_ROOT);
+export const fullScreenMenuWrapper = (page: Page) =>
+ page.locator(FULLSCREEN_MENU);
+export const fullscreenMenu = (page: Page, index: number) =>
+ page.locator(FULLSCREEN_MENU).locator("div").nth(index);
+export const fullScreenMenuItem = (page: Page, index: number) =>
+ page.locator(`${FULLSCREEN_MENU} ${MENU}`).locator(`li:nth-child(${index})`);
+export const menu = (page: Page) => page.locator(MENU);
+export const menuItem = (page: Page) => page.locator(MENU_ITEM);
diff --git a/cypress/locators/menu/locators.js b/playwright/components/menu/locators.ts
similarity index 75%
rename from cypress/locators/menu/locators.js
rename to playwright/components/menu/locators.ts
index be87757d5f..7894eddbd0 100644
--- a/cypress/locators/menu/locators.js
+++ b/playwright/components/menu/locators.ts
@@ -6,7 +6,3 @@ export const SEGMENT_TITLE = '[data-component="menu-segment-title"]';
export const MENU = '[data-component="menu"]';
export const FULLSCREEN_MENU = '[data-component="menu-fullscreen"]';
export const MENU_ITEM = '[data-component="menu-item"]';
-
-export const SEARCH_COMPONENT = '[data-component="search"]';
-export const CROSS_ICON = '[data-element="cross"]';
-export const SEARCH_ICON = "search";
diff --git a/src/components/menu/component.test-pw.tsx b/src/components/menu/component.test-pw.tsx
new file mode 100644
index 0000000000..63d3999cff
--- /dev/null
+++ b/src/components/menu/component.test-pw.tsx
@@ -0,0 +1,586 @@
+import React, { useState } from "react";
+import {
+ Menu,
+ MenuDivider,
+ MenuSegmentTitle,
+ MenuTitleProps,
+ ScrollableBlock,
+ MenuItem,
+ MenuWithChildren,
+ MenuFullscreen,
+ MenuFullscreenProps,
+ MenuProps,
+ MenuDividerProps,
+ ScrollableBlockProps,
+} from ".";
+import { MenuType } from "./menu.context";
+import Search from "../search";
+import GlobalHeader from "../global-header";
+import Box from "../box/box.component";
+import Typography from "../typography/typography.component";
+import useMediaQuery from "../../hooks/useMediaQuery";
+
+const menuTypes: MenuType[] = ["white", "light", "dark", "black"];
+
+export const MenuComponent = (props: Partial & MenuDividerProps) => {
+ return (
+
+ {menuTypes.map((menuType) => (
+
+
+ {menuType}
+
+
+
+ ))}
+
+ );
+};
+
+export const MenuComponentScrollable = (
+ props: Partial
+) => {
+ return (
+
+ {menuTypes.map((menuType) => (
+
+
+ {menuType}
+
+
+
+ ))}
+
+ );
+};
+
+export const MenuComponentSearch = () => {
+ return (
+
+ {menuTypes.map((menuType) => (
+
+
+ {menuType}
+
+
+
+ ))}
+
+ );
+};
+
+export const MenuWithChildrenUpdating = () => {
+ const [show, setShow] = React.useState(false);
+ return (
+ {}}
+ onFocus={() => {}}
+ onBlur={() => {}}
+ onMouseOver={() => setTimeout(() => setShow(true), 500)}
+ >
+
+
+ );
+};
+
+export const MenuComponentFullScreen = (
+ props: Partial
+) => {
+ const [menuOpen, setMenuOpen] = useState({
+ light: false,
+ dark: false,
+ white: false,
+ black: false,
+ });
+ const fullscreenViewBreakPoint = useMediaQuery("(max-width: 1200px)");
+ const responsiveMenuItems = (
+ startPosition: "left" | "right",
+ menu: MenuType
+ ) => {
+ if (fullscreenViewBreakPoint) {
+ return [
+ ,
+ setMenuOpen((state) => ({ ...state, [menu]: false }))}
+ {...props}
+ >
+
+
+ Menu Item Three
+ Menu Item Four
+
+ Submenu Item One
+ Submenu Item Two
+
+ Menu Item Six
+ ,
+ ];
+ }
+ return [
+
+ Menu Item One
+ ,
+
+ Submenu Item One
+ Submenu Item Two
+ ,
+
+ Menu Item Three
+ ,
+
+ Menu Item Four
+ ,
+
+ Submenu Item One
+ Submenu Item Two
+ ,
+
+ Menu Item Six
+ ,
+ ];
+ };
+ return (
+
+ {menuTypes.map((menuType) => (
+
+
+ {menuType}
+
+
+
+ ))}
+
+ );
+};
+
+export const MenuFullScreenBackgroundScrollTest = () => {
+ return (
+
+
+ I should not be scrolled into view
+
+ {}}>
+ Menu Item One
+ Menu Item Two
+
+
+ );
+};
+
+export const MenuComponentItems = (
+ props: MenuWithChildren & MenuDividerProps
+) => {
+ return (
+
+
+
+
+ );
+};
+
+export const MenuItems = (props: MenuWithChildren) => {
+ return (
+
+ {menuTypes.map((menuType) => (
+
+
+ {menuType}
+
+
+
+ ))}
+
+ );
+};
+
+export const MenuFullScreenWithSearchButton = ({
+ searchValue,
+}: {
+ searchValue?: string;
+}) => (
+ {}}>
+ Menu Item before Search
+
+
+
+
+ Menu Item after Search
+
+
+);
+
+export const MenuComponentScrollableParent = (
+ props: Partial
+) => {
+ const items = ["apple", "banana", "carrot", "grapefruit", "melon", "orange"];
+ const [itemSearch, setItemSearch] = React.useState(items);
+ const [searchString, setSearchString] = React.useState("");
+
+ const handleTextChange = (e: { target: { value: any } }) => {
+ const searchStr = e.target.value;
+ setSearchString(searchStr);
+ let found;
+
+ if (searchStr.length > 0) {
+ found = items.filter((item) => item.includes(searchStr));
+ } else {
+ found = items;
+ }
+
+ setItemSearch(found);
+ };
+
+ return (
+
+
+
+ );
+};
+
+export const MenuComponentWithIcon = () => {
+ return (
+
+ {menuTypes.map((menuType) => (
+
+
+ {menuType}
+
+
+
+ ))}
+
+ );
+};
+
+export const MenuComponentButtonIcon = () => {
+ return (
+
+
+
+ );
+};
+
+export const MenuSegmentTitleComponent = (props: Partial) => {
+ return (
+
+ {menuTypes.map((menuType) => (
+
+
+ {menuType}
+
+
+
+ ))}
+
+ );
+};
+
+export const ClosedMenuFullScreenWithButtons = () => {
+ return (
+ <>
+
+ {}}>
+ Menu Item One
+ Menu Item Two
+
+
+ >
+ );
+};
+
+export const MenuDividerComponent = (props: MenuDividerProps) => {
+ return (
+
+ {menuTypes.map((menuType) => (
+
+
+ {menuType}
+
+
+
+ ))}
+
+ );
+};
+
+export const InGlobalHeaderStory = () => {
+ return (
+
+
+
+ );
+};
+
+export const SubMenuWithVeryLongLabel = () => {
+ return (
+
+
+
+ );
+};
diff --git a/src/components/menu/menu-test.stories.tsx b/src/components/menu/menu-test.stories.tsx
index 2df950a16e..3f3ec786ec 100644
--- a/src/components/menu/menu-test.stories.tsx
+++ b/src/components/menu/menu-test.stories.tsx
@@ -1,28 +1,10 @@
import React, { useState, useEffect } from "react";
import { action } from "@storybook/addon-actions";
-import {
- Menu,
- MenuDivider,
- MenuSegmentTitle,
- MenuTitleProps,
- ScrollableBlock,
- MenuItem,
- MenuWithChildren,
- MenuFullscreen,
- MenuFullscreenProps,
- MenuProps,
- MenuDividerProps,
- ScrollableBlockProps,
-} from ".";
+import { Menu, MenuItem, MenuFullscreen, MenuFullscreenProps } from ".";
import { MenuType } from "./menu.context";
import Search from "../search";
import NavigationBar, { NavigationBarProps } from "../navigation-bar";
import GlobalHeader from "../global-header";
-import Box from "../box/box.component";
-import Typography from "../typography/typography.component";
-import useMediaQuery from "../../../src/hooks/useMediaQuery";
-
-const menuTypes: MenuType[] = ["white", "light", "dark", "black"];
export default {
title: "Menu/Test",
@@ -232,538 +214,6 @@ InNavigationBarStory.story = {
},
};
-export const MenuComponent = (props: Partial & MenuDividerProps) => {
- return (
-
- {menuTypes.map((menuType) => (
-
-
- {menuType}
-
-
-
- ))}
-
- );
-};
-
-export const MenuComponentScrollable = (
- props: Partial
-) => {
- return (
-
- {menuTypes.map((menuType) => (
-
-
- {menuType}
-
-
-
- ))}
-
- );
-};
-
-export const MenuComponentSearch = () => {
- return (
-
- {menuTypes.map((menuType) => (
-
-
- {menuType}
-
-
-
- ))}
-
- );
-};
-
-export const MenuWithChildrenUpdating = () => {
- const [show, setShow] = React.useState(false);
- return (
- {}}
- onFocus={() => {}}
- onBlur={() => {}}
- onMouseOver={() => setTimeout(() => setShow(true), 500)}
- >
-
-
- );
-};
-
-export const MenuComponentFullScreen = (
- props: Partial
-) => {
- const [menuOpen, setMenuOpen] = useState({
- light: false,
- dark: false,
- white: false,
- black: false,
- });
- const fullscreenViewBreakPoint = useMediaQuery("(max-width: 1200px)");
- const responsiveMenuItems = (
- startPosition: "left" | "right",
- menu: MenuType
- ) => {
- if (fullscreenViewBreakPoint) {
- return [
- setMenuOpen((state) => ({ ...state, [menu]: true }))}
- >
- Menu
- ,
- setMenuOpen((state) => ({ ...state, [menu]: false }))}
- {...props}
- >
- Menu Item One
- {}} submenu="Menu Item Two">
- Submenu Item One
- Submenu Item Two
-
- Menu Item Three
- Menu Item Four
-
- Submenu Item One
- Submenu Item Two
-
- Menu Item Six
- ,
- ];
- }
- return [
-
- Menu Item One
- ,
-
- Submenu Item One
- Submenu Item Two
- ,
-
- Menu Item Three
- ,
-
- Menu Item Four
- ,
-
- Submenu Item One
- Submenu Item Two
- ,
-
- Menu Item Six
- ,
- ];
- };
- return (
-
- {menuTypes.map((menuType) => (
-
-
- {menuType}
-
-
-
- ))}
-
- );
-};
-
-export const MenuFullScreenBackgroundScrollTest = () => {
- return (
-
-
- I should not be scrolled into view
-
- {}}>
- Menu Item One
- Menu Item Two
-
-
- );
-};
-
-export const MenuComponentItems = (
- props: MenuWithChildren & MenuDividerProps
-) => {
- return (
-
-
-
-
- );
-};
-
-export const MenuFullScreenWithFalsyValues = ({
- ...props
-}: Partial) => {
- const showMenuItem = false;
- return (
- {}} {...props}>
- Submenu Item One
- {false && Product Item One}
- {showMenuItem ? Product Item Two : null}
-
- );
-};
-
-export const MenuItems = (props: MenuWithChildren) => {
- return (
-
- {menuTypes.map((menuType) => (
-
-
- {menuType}
-
-
-
- ))}
-
- );
-};
-
-export const MenuFullScreenWithSearchButton = ({
- searchValue,
-}: {
- searchValue?: string;
-}) => (
- {}}>
- Menu Item before Search
-
-
-
-
- Menu Item after Search
-
-
-);
-
-export const MenuComponentScrollableParent = () => {
- const items = ["apple", "banana", "carrot", "grapefruit", "melon", "orange"];
- const [itemSearch, setItemSearch] = React.useState(items);
- const [searchString, setSearchString] = React.useState("");
-
- const handleTextChange = (e: { target: { value: string } }) => {
- const searchStr = e.target.value;
- setSearchString(searchStr);
- let found;
-
- if (searchStr.length > 0) {
- found = items.filter((item) => item.includes(searchStr));
- } else {
- found = items;
- }
-
- setItemSearch(found);
- };
-
- return (
-
-
-
- );
-};
-
-export const MenuComponentWithIcon = () => {
- return (
-
- {menuTypes.map((menuType) => (
-
-
- {menuType}
-
-
-
- ))}
-
- );
-};
-
-export const MenuComponentButtonIcon = () => {
- return (
-
-
-
- );
-};
-
-export const MenuSegmentTitleComponent = (props: Partial) => {
- return (
-
- {menuTypes.map((menuType) => (
-
-
- {menuType}
-
-
-
- ))}
-
- );
-};
-
-export const ClosedMenuFullScreenWithButtons = () => {
- return (
- <>
-
- {}}>
- Menu Item One
- Menu Item Two
-
-
- >
- );
-};
-
-export const MenuDividerComponent = (props: MenuDividerProps) => {
- return (
-
- {menuTypes.map((menuType) => (
-
-
- {menuType}
-
-
-
- ))}
-
- );
-};
-
const UpdatingSubmenu = () => {
const [counter, setCounter] = useState(0);
useEffect(() => {
diff --git a/src/components/menu/menu.pw.tsx b/src/components/menu/menu.pw.tsx
new file mode 100644
index 0000000000..d190b54aef
--- /dev/null
+++ b/src/components/menu/menu.pw.tsx
@@ -0,0 +1,2439 @@
+/* eslint-disable no-await-in-loop */
+import React from "react";
+import { test, expect } from "@playwright/experimental-ct-react17";
+import {
+ Menu,
+ MenuProps,
+ MenuItem,
+ MenuWithChildren,
+ MenuDivider,
+ MenuDividerProps,
+ MenuSegmentTitle,
+ MenuFullscreenProps,
+ ScrollableBlockProps,
+} from ".";
+import Box from "../box";
+import {
+ submenuBlock,
+ innerMenu,
+ submenu,
+ scrollBlock,
+ lastSubmenuElement,
+ menuDivider,
+ segmentTitle,
+ menuComponent,
+ submenuItem,
+ fullscreenMenu,
+ menu,
+ menuItem,
+} from "../../../playwright/components/menu/index";
+import {
+ searchDefaultInput,
+ searchCrossIcon,
+ searchButton,
+} from "../../../playwright/components/search/index";
+import {
+ getComponent,
+ closeIconButton,
+ icon,
+} from "../../../playwright/components/index";
+import {
+ continuePressingTAB,
+ continuePressingSHIFTTAB,
+ checkGoldenOutline,
+ assertCssValueIsApproximately,
+ checkAccessibility,
+ waitForAnimationEnd,
+} from "../../../playwright/support/helper";
+import { CHARACTERS } from "../../../playwright/support/constants";
+import {
+ MenuComponent,
+ MenuComponentScrollable,
+ MenuComponentSearch,
+ MenuWithChildrenUpdating,
+ MenuComponentFullScreen,
+ MenuFullScreenBackgroundScrollTest,
+ MenuComponentItems,
+ MenuFullScreenWithSearchButton,
+ MenuComponentScrollableParent,
+ MenuComponentWithIcon,
+ MenuComponentButtonIcon,
+ MenuSegmentTitleComponent,
+ MenuItems,
+ ClosedMenuFullScreenWithButtons,
+ MenuDividerComponent,
+ InGlobalHeaderStory,
+ SubMenuWithVeryLongLabel,
+} from "./component.test-pw";
+import { NavigationBarWithSubmenuAndChangingHeight } from "../navigation-bar/navigation-bar-test.stories";
+import { HooksConfig } from "../../../playwright";
+
+const span = "span";
+const div = "div";
+
+test.describe("Prop tests for Menu component", () => {
+ test(`should verify scroll block within a submenu is scrollable`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const subMenu = submenu(page).first();
+ await subMenu.hover();
+ const lastElement = lastSubmenuElement(page, "li");
+ await lastElement.scrollIntoViewIfNeeded();
+ await expect(lastElement).toBeInViewport();
+ });
+
+ test(`should verify a submenu can be navigated using keyboard tabbing after an item was clicked`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const subMenu = submenu(page).first();
+ await subMenu.hover();
+ const menuItemThree = innerMenu(page, 4, span)
+ .filter({ hasText: "Item Submenu Three" })
+ .first();
+ await menuItemThree.click();
+ await expect(menuItemThree).toHaveText("Item Submenu Three");
+ await expect(menuItemThree).toHaveCSS("box-shadow", "none");
+ await page.keyboard.press("Tab");
+ const menuItemFour = innerMenu(page, 5, span)
+ .filter({ hasText: "Item Submenu Four" })
+ .first();
+ await expect(menuItemFour).toHaveText("Item Submenu Four");
+ await expect(menuItemFour).toHaveCSS("box-shadow", "none");
+ });
+
+ test(`should verify a submenu can be navigated using keyboard down arrow after an item was clicked`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const subMenu = submenu(page).first();
+ await subMenu.hover();
+ const menuItemThree = innerMenu(page, 2, span).first();
+ await menuItemThree.click();
+ await page.keyboard.press("ArrowDown");
+ const focusedElement1 = page.locator("*:focus");
+ await expect(focusedElement1).toContainText("Item Submenu Three");
+ await page.keyboard.press("ArrowDown");
+ const focusedElement2 = page.locator("*:focus");
+ await expect(focusedElement2).toContainText("Item Submenu Four");
+ });
+
+ test(`should verify a submenu can be navigated using keyboard shift + tabbing after an item was clicked`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const subMenu = submenu(page).first();
+ await subMenu.hover();
+ const menuItemThree = innerMenu(page, 4, span).first();
+ await menuItemThree.click();
+ await page.keyboard.press("Shift+Tab");
+ const focusedElement1 = page.locator("*:focus");
+ await expect(focusedElement1).toContainText("Item Submenu Two");
+ await page.keyboard.press("Shift+Tab");
+ const focusedElement2 = page.locator("*:focus");
+ await expect(focusedElement2).toContainText("Item Submenu One");
+ });
+
+ test(`should verify a submenu can be navigated using keyboard up arrow after an item was clicked`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const subMenu = submenu(page).first();
+ await subMenu.hover();
+ const menuItemThree = innerMenu(page, 4, span).first();
+ await menuItemThree.click();
+ await page.keyboard.press("ArrowUp");
+ const focusedElement1 = page.locator("*:focus");
+ await expect(focusedElement1).toContainText("Item Submenu Two");
+ await page.keyboard.press("ArrowUp");
+ const focusedElement2 = page.locator("*:focus");
+ await expect(focusedElement2).toContainText("Item Submenu One");
+ });
+
+ test(`should verify the first submenu item is focused using keyboard tabbing after the parent item was clicked`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const subMenu = submenu(page).first();
+ await subMenu.click();
+ await page.keyboard.press("Tab");
+ const focusedElement = page.locator("*:focus");
+ await expect(focusedElement).toContainText("Item Submenu One");
+ });
+
+ test(`should verify the first submenu item is focused using keyboard down arrow after the parent item was clicked`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const subMenu = submenu(page).first();
+ await subMenu.click();
+ await page.keyboard.press("ArrowDown");
+ const focusedElement = page.locator("*:focus");
+ await expect(focusedElement).toContainText("Item Submenu One");
+ });
+
+ test(`should verify number and type of elements in submenu`, async ({
+ mount,
+ page,
+ }) => {
+ const position = [1, 2, 4, 5] as const;
+ await mount();
+
+ const subMenu = submenu(page).first();
+ await subMenu.hover();
+ const subMenuBlock = submenuBlock(page).first().locator("li");
+ await expect(subMenuBlock).toHaveCount(5);
+ for (let i = 0; i < position.length; i++) {
+ await expect(innerMenu(page, position[i], span).first()).toHaveAttribute(
+ "data-component",
+ "link"
+ );
+ }
+ const menuItemDivider = innerMenu(page, 3, div).first();
+ await expect(menuItemDivider).toHaveAttribute(
+ "data-component",
+ "menu-divider"
+ );
+ });
+
+ ([
+ ["white", "rgb(230, 235, 237)", 0],
+ ["light", "rgb(255, 255, 255)", 2],
+ ["dark", "rgb(0, 25, 38)", 4],
+ ["black", "rgb(38, 38, 38)", 6],
+ ] as [string, string, number][]).forEach(([colorName, color, menuNumber]) => {
+ test(`should verify the ${menuNumber}th submenu background color is ${colorName}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const subMenu = submenu(page).nth(menuNumber);
+ await subMenu.hover();
+ const menuItemThree = innerMenu(page, 2, span).first();
+ await expect(menuItemThree).toHaveCSS("background-color", color);
+ });
+ });
+
+ ([
+ ["white", "rgb(255, 255, 255)", 0],
+ ["light", "rgb(230, 235, 237)", 4],
+ ["dark", "rgb(0, 50, 76)", 8],
+ ["black", "rgb(0, 0, 0)", 12],
+ ] as [string, string, number][]).forEach(([colorName, color, menuNumber]) => {
+ test(`should verify the ${menuNumber}th menu background color is ${colorName}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const item = menuItem(page).nth(menuNumber).locator("span").first();
+ await expect(item).toHaveCSS("background-color", color);
+ });
+ });
+
+ ([
+ ["white", "rgba(0, 0, 0, 0.9)"],
+ ["light", "rgba(0, 0, 0, 0.9)"],
+ ["dark", "rgb(255, 255, 255)"],
+ ["black", "rgb(255, 255, 255)"],
+ ] as [MenuProps["menuType"], string][]).forEach(([menuType, color]) => {
+ test(`should verify icon color is ${color} when menuType prop is ${menuType}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount(
+
+ );
+
+ await page.keyboard.press("Tab");
+ await expect(icon(page)).toHaveCSS("color", color);
+ });
+ });
+
+ ([
+ ["default", 1],
+ ["large", 4],
+ ] as [MenuDividerProps["size"], number][]).forEach(([size, height]) => {
+ test(`should verify Menu Divider has the proper height when the size is ${size}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const subMenu = submenu(page).first();
+ await subMenu.hover();
+ const divider = menuDivider(page).first();
+ await assertCssValueIsApproximately(divider, "height", height);
+ });
+ });
+
+ test(`should verify a segment title is visible within a submenu`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const subMenu = submenu(page).nth(1);
+ await subMenu.hover();
+ const menuSegmentTitle = segmentTitle(page).first();
+ await expect(menuSegmentTitle).toHaveText("segment title");
+ await expect(menuSegmentTitle).toBeVisible();
+ await expect(menuSegmentTitle).toHaveCSS("color", "rgba(0, 0, 0, 0.65)");
+ });
+
+ test(`should verify menu does not open on hover when clickToOpen prop is true`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const fourthMenu = menuComponent(page, 3);
+ await fourthMenu.hover();
+ const subItem = submenuItem(page, 3);
+ await expect(subItem).toHaveCount(0);
+ });
+
+ test(`should verify menu opens on click when clickToOpen prop is true`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const sixthMenu = menuComponent(page, 5);
+ await sixthMenu.click();
+ const subMenuBlock = submenuBlock(page).first().locator("li");
+ await expect(subMenuBlock).toHaveCount(2);
+ await expect(innerMenu(page, 1, span).first()).toHaveAttribute(
+ "data-component",
+ "link"
+ );
+ await expect(innerMenu(page, 2, span).first()).toHaveAttribute(
+ "data-component",
+ "link"
+ );
+ });
+
+ ["Enter", "Space", "ArrowDown", "ArrowUp"].forEach((key) => {
+ test(`should verify menu opens using ${key} key when clickToOpen prop is true`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const sixthMenu = menuComponent(page, 5);
+ await sixthMenu.click();
+ await page.keyboard.press("Escape");
+ await page.keyboard.press(key);
+ const subMenuBlock = submenuBlock(page).first().locator("li");
+ await expect(subMenuBlock).toHaveCount(2);
+ await expect(innerMenu(page, 1, span).first()).toHaveAttribute(
+ "data-component",
+ "link"
+ );
+ await expect(innerMenu(page, 2, span).first()).toHaveAttribute(
+ "data-component",
+ "link"
+ );
+ });
+ });
+
+ ([
+ ["ArrowDown", 0],
+ ["ArrowUp", 2],
+ ] as [string, number][]).forEach(([key, tabs]) => {
+ test(`should verify the Search component is focusable by pressing the ${key} key`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await page.keyboard.press("Tab");
+ await page.keyboard.press("Enter");
+ await continuePressingTAB(page, tabs);
+ await page.keyboard.press(key);
+ await expect(searchDefaultInput(page)).toBeFocused();
+ });
+ });
+
+ test(`should verify the Search component close icon is focusable when using keyboard to navigate down the list of items`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await page.keyboard.press("Tab");
+ await page.keyboard.press("Enter");
+ await page.keyboard.press("ArrowDown");
+ await searchDefaultInput(page).fill("FooBar");
+ await page.keyboard.press("Tab");
+ const cross = searchCrossIcon(page).locator("..");
+ await expect(cross).toBeFocused();
+ });
+
+ test(`should verify the Search component close icon is centred when focused`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+ const bottomLess = 210;
+ const topLess = 174;
+ const leftLess = 124;
+ // additionVal is to compensate for the outline.
+ const additionVal = 2;
+
+ await page.keyboard.press("Tab");
+ await page.keyboard.press("Enter");
+ await page.keyboard.press("ArrowDown");
+ await searchDefaultInput(page).fill("FooBar");
+ await page.keyboard.press("Tab");
+ const cross = searchCrossIcon(page).locator("..");
+ await expect(cross).toBeFocused();
+
+ const boundBottom = await cross.evaluate((element) => {
+ return element.getBoundingClientRect().bottom;
+ });
+ expect(boundBottom).toBeLessThan(bottomLess + additionVal);
+ expect(boundBottom).toBeGreaterThan(bottomLess);
+
+ const boundTop = await cross.evaluate((element) => {
+ return element.getBoundingClientRect().top;
+ });
+ expect(boundTop).toBeLessThan(topLess + additionVal);
+ expect(boundTop).toBeGreaterThan(topLess);
+
+ const boundLeft = await cross.evaluate((element) => {
+ return element.getBoundingClientRect().left;
+ });
+ expect(boundLeft).toBeLessThan(leftLess + additionVal);
+ expect(boundLeft).toBeGreaterThan(leftLess);
+ });
+
+ test(`should verify the Search component close icon is focusable when using keyboard to navigate up the list of items`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await page.keyboard.press("Tab");
+ await page.keyboard.press("Enter");
+ await page.keyboard.press("ArrowDown");
+ await searchDefaultInput(page).fill("FooBar");
+ await page.keyboard.press("End");
+ await continuePressingSHIFTTAB(page, 2);
+ await page.waitForTimeout(2000);
+ const cross = searchCrossIcon(page).locator("..");
+ await expect(cross).toBeFocused();
+ await page.keyboard.press("Shift+Tab");
+ await expect(searchDefaultInput(page)).toBeFocused();
+ });
+
+ test(`should verify that the Search component is focusable by using the downarrow key when rendered as the parent of a scrollable submenu`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await continuePressingSHIFTTAB(page, 3);
+ await page.keyboard.press("Enter");
+ await page.keyboard.press("ArrowDown");
+ await expect(searchDefaultInput(page)).toBeFocused();
+ });
+
+ test(`should verify scroll Menu search has an alternate background color`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const subMenu = submenu(page).nth(2);
+ await subMenu.hover();
+ const item = menuItem(page).nth(4).locator("span").first();
+ await expect(item).toHaveCSS("background-color", "rgb(0, 50, 76)");
+ });
+
+ test(`should verify submenu is not closed when Enter key is pressed on search component`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await page.keyboard.press("Tab");
+ await page.keyboard.press("Enter");
+ await page.keyboard.press("ArrowDown");
+ await searchDefaultInput(page).fill("FooBar");
+ await page.keyboard.press("Tab");
+ await page.keyboard.press("Enter");
+ const subMenuBlock = submenuBlock(page).first().locator("li").first();
+ await expect(subMenuBlock).toBeVisible();
+ });
+
+ test(`should render with a menu item that has a very long label and verify the width of the whole submenu is determined by this item`, async ({
+ mount,
+ page,
+ }) => {
+ await mount(
+
+
+
+ );
+
+ const subMenu = submenu(page).first();
+ await subMenu.hover();
+ const subMenuBlock = innerMenu(page, 2, span).first();
+ const cssWidth = await subMenuBlock.evaluate((el) =>
+ window.getComputedStyle(el).getPropertyValue("width")
+ );
+ expect(parseInt(cssWidth)).toBeLessThanOrEqual(395);
+ expect(parseInt(cssWidth)).toBeGreaterThanOrEqual(385);
+ });
+
+ test(`should render with a submenu that has a very long label and verify the width of the whole submenu is determined by this item`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const subMenu = submenu(page).first();
+ await subMenu.hover();
+ const subMenuBlock = innerMenu(page, 2, span).first();
+ const cssWidth = await subMenuBlock.evaluate((el) =>
+ window.getComputedStyle(el).getPropertyValue("width")
+ );
+ expect(parseInt(cssWidth)).toBeLessThanOrEqual(500);
+ expect(parseInt(cssWidth)).toBeGreaterThanOrEqual(490);
+ });
+
+ ([
+ ["float", 0.3, 409],
+ ["float", 0.6, 819],
+ ["float", 1.0, 1366],
+ ["number", 350, 350],
+ ["number", 900, 900],
+ ["number", 1350, 1350],
+ ["string", "450px", 450],
+ ["string", "675px", 675],
+ ["string", "1200px", 1200],
+ ] as [string, number | string, number][]).forEach(([type, width, pixels]) => {
+ test(`should render with width set to ${pixels}px when prop is passed as a ${type}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const thisMenu = menu(page).first();
+ await assertCssValueIsApproximately(thisMenu, "width", pixels);
+ });
+ });
+
+ ([
+ ["number", 15, 15],
+ ["number", 27, 27],
+ ["number", 41, 41],
+ ["string", "10px", 10],
+ ["string", "30px", 30],
+ ["string", "50px", 50],
+ ] as [string, number | string, number][]).forEach(
+ ([type, propValue, pixels]) => {
+ test(`should render with height set to ${pixels}px when prop is passed as a ${type}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const thisMenu = menu(page).first();
+ await assertCssValueIsApproximately(thisMenu, "height", pixels);
+ });
+ }
+ );
+
+ ([
+ ["number", 810, 350, 810],
+ ["number", 810, 1350, 1350],
+ ["string", "700px", "300px", 700],
+ ["string", "700px", "1200px", 1200],
+ ] as [string, string | number, string | number, number][]).forEach(
+ ([type, minWidth, width, pixels]) => {
+ test(`should render with minimum width of ${pixels}px when minWidth prop is passed as a ${type}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const thisMenu = menu(page).first();
+ await assertCssValueIsApproximately(thisMenu, "width", pixels);
+ });
+ }
+ );
+
+ ([
+ ["number", 810, 350, 350],
+ ["number", 810, 1350, 810],
+ ["string", "700px", "300px", 300],
+ ["string", "700px", "1200px", 700],
+ ] as [string, string | number, string | number, number][]).forEach(
+ ([type, maxWidth, width, pixels]) => {
+ test(`should render with maximum width of ${pixels}px when maxWidth prop is passed as a ${type}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const thisMenu = menu(page).first();
+ await assertCssValueIsApproximately(thisMenu, "width", pixels);
+ });
+ }
+ );
+
+ ([
+ ["number", 30, 20, 30],
+ ["number", 30, 40, 40],
+ ["string", "35px", "25px", 35],
+ ["string", "35px", "40px", 40],
+ ] as [string, string | number, string | number, number][]).forEach(
+ ([type, minHeight, height, pixels]) => {
+ test(`should render with minimum height of ${pixels}px when minHeight prop is passed as a ${type}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const thisMenu = menu(page).first();
+ await assertCssValueIsApproximately(thisMenu, "height", pixels);
+ });
+ }
+ );
+
+ ([
+ ["number", 30, 20, 20],
+ ["number", 30, 40, 30],
+ ["string", "35px", "25px", 25],
+ ["string", "35px", "40px", 35],
+ ] as [string, string | number, string | number, number][]).forEach(
+ ([type, maxHeight, height, pixels]) => {
+ test(`should render with maximum height of ${pixels}px when maxHeight prop is passed as a ${type}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const thisMenu = menu(page).first();
+ await assertCssValueIsApproximately(thisMenu, "height", pixels);
+ });
+ }
+ );
+
+ ["block", "inline-block", "flex", "contents", "list-item", "none"].forEach(
+ (display) => {
+ test(`should render with display as ${display}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const thisMenu = menu(page).first();
+ await expect(thisMenu).toHaveAttribute("display", display);
+ await expect(thisMenu).toHaveCSS("display", display);
+ });
+ }
+ );
+
+ [
+ "baseline",
+ "bottom",
+ "middle",
+ "sub",
+ "super",
+ "text-bottom",
+ "text-top",
+ "top",
+ ].forEach((alignment) => {
+ test(`should render with verticalAlign as ${alignment}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const thisMenu = menu(page).first();
+ await expect(thisMenu).toHaveCSS("vertical-align", alignment);
+ });
+ });
+
+ ["auto", "clip", "hidden", "scroll", "visible"].forEach((overflow) => {
+ test(`should render with overflow as ${overflow}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const thisMenu = menu(page).first();
+ await expect(thisMenu).toHaveAttribute("overflow", overflow);
+ await expect(thisMenu).toHaveCSS("overflow", overflow);
+ });
+ });
+
+ ([
+ "auto",
+ "clip",
+ "hidden",
+ "scroll",
+ "visible",
+ ] as MenuProps["overflowX"][]).forEach((overflow) => {
+ test(`should render with overflowX as ${overflow}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const thisMenu = menu(page).first();
+ await expect(thisMenu).toHaveCSS("overflow-x", overflow as string);
+ });
+ });
+
+ ([
+ "auto",
+ "clip",
+ "hidden",
+ "scroll",
+ "visible",
+ ] as MenuProps["overflowY"][]).forEach((overflow) => {
+ test(`should render with overflowY as ${overflow}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const thisMenu = menu(page).first();
+ await expect(thisMenu).toHaveCSS("overflow-y", overflow as string);
+ });
+ });
+
+ ["normal", "stretch", "baseline", "center", "flex-start", "flex-end"].forEach(
+ (alignment) => {
+ test(`should render with alignItems as ${alignment}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const thisMenu = menu(page).first();
+ await expect(thisMenu).toHaveCSS("align-items", alignment);
+ });
+ }
+ );
+
+ [
+ "normal",
+ "baseline",
+ "center",
+ "flex-start",
+ "flex-end",
+ "space-between",
+ "space-around",
+ "stretch",
+ ].forEach((alignment) => {
+ test(`should render with alignContent as ${alignment}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const thisMenu = menu(page).first();
+ await expect(thisMenu).toHaveCSS("align-content", alignment);
+ });
+ });
+
+ [
+ "left",
+ "center",
+ "right",
+ "flex-start",
+ "flex-end",
+ "normal",
+ "stretch",
+ ].forEach((justified) => {
+ test(`should render with justifyItems as ${justified}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const thisMenu = menu(page).first();
+ await expect(thisMenu).toHaveCSS("justify-items", justified);
+ });
+ });
+
+ [
+ "left",
+ "center",
+ "right",
+ "flex-start",
+ "flex-end",
+ "normal",
+ "space-between",
+ "space-around",
+ "stretch",
+ ].forEach((justified) => {
+ test(`should render with justifyContent as ${justified}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const thisMenu = menu(page).first();
+ await expect(thisMenu).toHaveCSS("justify-content", justified);
+ });
+ });
+
+ (["nowrap", "wrap", "wrap-reverse"] as MenuProps["flexWrap"][]).forEach(
+ (wrap) => {
+ test(`should render with flexWrap as ${wrap}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const thisMenu = menu(page).first();
+ await expect(thisMenu).toHaveCSS("flex-wrap", wrap as string);
+ });
+ }
+ );
+
+ ([
+ "column",
+ "column-reverse",
+ "row",
+ "row-reverse",
+ ] as MenuProps["flexDirection"][]).forEach((direction) => {
+ test(`should render with flexDirection as ${direction}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const thisMenu = menu(page).first();
+ await expect(thisMenu).toHaveCSS("flex-direction", direction as string);
+ });
+ });
+
+ ["auto", "content", "fit-content", "max-content", "min-content"].forEach(
+ (flex) => {
+ test(`should render with flex as ${flex}`, async ({ mount, page }) => {
+ await mount();
+
+ const thisMenu = menu(page).first();
+ await expect(thisMenu).toHaveCSS("flex-basis", flex);
+ });
+ }
+ );
+
+ ([
+ [10, "10"],
+ [50, "50"],
+ [100, "100"],
+ ] as [MenuProps["flexGrow"], string][]).forEach(([value, growText]) => {
+ test(`should render with flexGrow as ${value}`, async ({ mount, page }) => {
+ await mount();
+
+ const thisMenu = menu(page).first();
+ await expect(thisMenu).toHaveCSS("flex-grow", growText);
+ });
+ });
+
+ ([
+ [10, "10"],
+ [50, "50"],
+ [100, "100"],
+ ] as [MenuProps["flexShrink"], string][]).forEach(([value, shrinkText]) => {
+ test(`should render with flexShrink as ${value}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const thisMenu = menu(page).first();
+ await expect(thisMenu).toHaveCSS("flex-shrink", shrinkText);
+ });
+ });
+
+ ["auto", "content", "fit-content", "max-content", "min-content"].forEach(
+ (basis) => {
+ test(`should render with flexBasis as ${basis}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const thisMenu = menu(page).first();
+ await expect(thisMenu).toHaveCSS("flex-basis", basis);
+ });
+ }
+ );
+
+ [
+ "auto",
+ "baseline",
+ "left",
+ "normal",
+ "right",
+ "stretch",
+ "center",
+ "flex-start",
+ "flex-end",
+ ].forEach((justify) => {
+ test(`should render with justifySelf as ${justify}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const thisMenu = menu(page).first();
+ await expect(thisMenu).toHaveCSS("justify-self", justify);
+ });
+ });
+
+ [
+ "auto",
+ "baseline",
+ "normal",
+ "stretch",
+ "center",
+ "flex-start",
+ "flex-end",
+ ].forEach((align) => {
+ test(`should render with alignSelf as ${align}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const thisMenu = menu(page).first();
+ await expect(thisMenu).toHaveCSS("align-self", align);
+ });
+ });
+
+ ([
+ [10, "10"],
+ [50, "50"],
+ [100, "100"],
+ ] as [MenuProps["order"], string][]).forEach(([value, orderText]) => {
+ test(`should render with order as ${value}`, async ({ mount, page }) => {
+ await mount();
+
+ const thisMenu = menu(page).first();
+ await expect(thisMenu).toHaveCSS("order", orderText);
+ });
+ });
+
+ test(`should render with className as ${CHARACTERS.STANDARD}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const item = menuItem(page).nth(0);
+ const itemClass = await item.evaluate((element) =>
+ element.getAttribute("class")
+ );
+ expect(itemClass).toContain(CHARACTERS.STANDARD);
+ });
+
+ ([
+ ["selected", true, "rgb(230, 235, 237)"],
+ ["not selected", false, "rgb(255, 255, 255)"],
+ ] as [string, MenuWithChildren["selected"], string][]).forEach(
+ ([state, boolVal, color]) => {
+ test(`should render with first Menu Item ${state}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const subMenu = submenu(page).first().locator("span").first();
+ await expect(subMenu).toHaveCSS("background-color", color);
+ });
+ }
+ );
+
+ [
+ CHARACTERS.STANDARD,
+ CHARACTERS.DIACRITICS,
+ CHARACTERS.SPECIALCHARACTERS,
+ ].forEach((text) => {
+ test(`should render with submenu text set to ${text}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const item = menuItem(page).first();
+ await expect(item).toHaveText(text);
+ });
+ });
+
+ test(`should render with Item target ${CHARACTERS.STANDARD}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const item = menuItem(page).first().locator("button");
+ await expect(item).toHaveAttribute("target", CHARACTERS.STANDARD);
+ });
+
+ ([
+ [true, 32],
+ [false, 16],
+ ] as [MenuWithChildren["showDropdownArrow"], number][]).forEach(
+ ([boolVal, padding]) => {
+ test(`should render with padding of ${padding}px on menu item when showDropdownArrow prop is ${boolVal}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const subMenu = submenu(page).first().locator("button");
+ await expect(subMenu).toHaveCSS("padding-right", `${padding}px`);
+ });
+ }
+ );
+
+ ([
+ ["default", "rgb(255, 255, 255)"],
+ ["alternate", "rgb(217, 224, 228)"],
+ ] as [MenuWithChildren["variant"], string][]).forEach(([variant, color]) => {
+ test(`should render with ${variant} Menu Item variant`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const subMenu = submenu(page).first().locator("span").first();
+ await expect(subMenu).toHaveCSS("background-color", color);
+ });
+ });
+
+ test(`should render with Menu Item ariaLabel set to ${CHARACTERS.STANDARD}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const subMenu = submenu(page).first().locator("button");
+ await expect(subMenu).toHaveAttribute("aria-label", CHARACTERS.STANDARD);
+ });
+
+ ([
+ ["default", 1, 16, 121],
+ ["large", 4, 0, 153],
+ ] as [MenuDividerProps["size"], number, number, number][]).forEach(
+ ([size, height, margin, width]) => {
+ test(`should render with Menu size ${size}`, async ({ mount, page }) => {
+ await mount(
+
+
+
+ );
+
+ const subMenu = submenu(page).first();
+ await subMenu.hover();
+ const divider = menuDivider(page);
+ await assertCssValueIsApproximately(divider, "height", height);
+ await assertCssValueIsApproximately(divider, "margin-left", margin);
+ await assertCssValueIsApproximately(divider, "width", width);
+ });
+ }
+ );
+
+ ([
+ [100, 100],
+ [200, 200],
+ ["150px", 150],
+ ["250px", 250],
+ ] as [ScrollableBlockProps["height"], number][]).forEach(
+ ([height, pixels]) => {
+ test(`should render with scroll block height of ${pixels}px when height prop is passed as a number or string`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const subMenu = submenu(page).first();
+ await subMenu.hover();
+ const block = scrollBlock(page);
+ await assertCssValueIsApproximately(block, "height", pixels);
+ });
+ }
+ );
+
+ ([
+ ["default", "rgb(230, 235, 237)"],
+ ["alternate", "rgb(217, 224, 228)"],
+ ] as [ScrollableBlockProps["variant"], string][]).forEach(
+ ([variant, color]) => {
+ test(`should render Menu scroll block with ${variant} background color using variant prop`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const subMenu = submenu(page).first();
+ await subMenu.hover();
+ const block = scrollBlock(page).locator("span").first();
+ await expect(block).toHaveCSS("background-color", color);
+ });
+ }
+ );
+
+ ([
+ ["default", "rgba(0, 0, 0, 0)"],
+ ["alternate", "rgb(217, 224, 228)"],
+ ] as [ScrollableBlockProps["variant"], string][]).forEach(
+ ([variant, color]) => {
+ test(`should render segment title with ${variant} variant background color`, async ({
+ mount,
+ page,
+ }) => {
+ await mount(
+
+
+
+ );
+
+ const subMenu = submenu(page).first();
+ await subMenu.hover();
+ const title = segmentTitle(page);
+ await expect(title).toHaveCSS("background-color", color);
+ });
+ }
+ );
+
+ test(`should verify that inner Menu without link is NOT available with tabbing in Fullscreen Menu`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await page.setViewportSize({ width: 1200, height: 800 });
+ const item = menuItem(page).first();
+ await item.click();
+ const fullscreen = getComponent(page, "menu-fullscreen").first();
+ await waitForAnimationEnd(fullscreen);
+ await continuePressingTAB(page, 8);
+ await expect(item).not.toBeFocused();
+ });
+
+ test(`should render Menu Item with href prop set to ${CHARACTERS.STANDARD}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const subMenu = submenu(page).first().locator("a");
+ await expect(subMenu).toHaveAttribute("href", CHARACTERS.STANDARD);
+ });
+
+ ([["noopener"], ["noreferrer"], ["opener"]] as [
+ MenuWithChildren["rel"]
+ ][]).forEach(([rel]) => {
+ test(`should render Menu Item with rel prop set to ${rel}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const subMenu = submenu(page).first().locator("button");
+ await expect(subMenu).toHaveAttribute("rel", rel as string);
+ });
+ });
+
+ test(`should render Scrollable Block with parent`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const subMenu = submenu(page).first();
+ await subMenu.hover();
+ const scrollBlockParent = getComponent(page, "scrollable-block-parent");
+ await expect(scrollBlockParent).toHaveCount(1);
+ });
+
+ ([
+ ["default", "rgb(255, 255, 255)"],
+ ["alternate", "rgb(230, 235, 237)"],
+ ] as [ScrollableBlockProps["parentVariant"], string][]).forEach(
+ ([variant, color]) => {
+ test(`should render scrollable block with ${variant} variant background color`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const subMenu = submenu(page).first();
+ await subMenu.hover();
+ const parentBackground = getComponent(page, "scrollable-block-parent")
+ .locator("span")
+ .nth(0);
+ await expect(parentBackground).toHaveAttribute(
+ "data-component",
+ "link"
+ );
+ await expect(parentBackground).toHaveCSS("background-color", color);
+ });
+ }
+ );
+});
+
+test.describe("Prop tests for Menu Fullscreen component", () => {
+ test(`should render Menu Fullscreen`, async ({ mount, page }) => {
+ await page.setViewportSize({ width: 1200, height: 800 });
+ await mount();
+
+ const item = menuItem(page).first();
+ await item.click();
+ const fullscreen = getComponent(page, "menu-fullscreen").first();
+ await waitForAnimationEnd(fullscreen);
+ const fullScreenMenu1 = fullscreenMenu(page, 0).locator("span");
+ await expect(fullScreenMenu1).toHaveAttribute("data-element", "close");
+ await expect(fullScreenMenu1).toBeVisible();
+ const fullScreenMenu2 = fullscreenMenu(page, 1).locator("ul").first();
+ await expect(fullScreenMenu2).toHaveAttribute("data-component", "menu");
+ await expect(fullScreenMenu2).toBeVisible();
+ const fullScreenMenu3 = fullscreenMenu(page, 1).locator("li");
+ await expect(fullScreenMenu3).toHaveCount(15);
+ });
+
+ test(`should verify that the Menu Fullscreen is closed when close icon is clicked`, async ({
+ mount,
+ page,
+ }) => {
+ await page.setViewportSize({ width: 1200, height: 800 });
+ await mount();
+
+ const item = menuItem(page).first();
+ await item.click();
+ const fullscreen = getComponent(page, "menu-fullscreen").first();
+ await waitForAnimationEnd(fullscreen);
+ const closeIcon = closeIconButton(page).first();
+ await closeIcon.click();
+ const fullScreenMenu1 = fullscreenMenu(page, 0).locator("span");
+ await expect(fullScreenMenu1).not.toBeVisible();
+ const fullScreenMenu2 = fullscreenMenu(page, 1).locator("ul").first();
+ await expect(fullScreenMenu2).not.toBeVisible();
+ const thisMenu = menu(page).first();
+ await expect(thisMenu).toBeVisible();
+ });
+
+ test(`should verify that close icon is focused in Menu Fullscreen when focusRedesignOptOut is false`, async ({
+ mount,
+ page,
+ }) => {
+ await page.setViewportSize({ width: 1200, height: 800 });
+ await mount();
+
+ const item = menuItem(page).first();
+ await item.click();
+ const fullscreen = getComponent(page, "menu-fullscreen").first();
+ await waitForAnimationEnd(fullscreen);
+ await page.keyboard.press("Tab");
+ const closeIcon = closeIconButton(page).first();
+ await expect(closeIcon).toHaveCSS(
+ "box-shadow",
+ "rgb(255, 188, 25) 0px 0px 0px 3px, rgba(0, 0, 0, 0.9) 0px 0px 0px 6px"
+ );
+ await expect(closeIcon).toHaveCSS("outline", "rgba(0, 0, 0, 0) solid 3px");
+ const focusedElement = page.locator("*:focus");
+ await expect(focusedElement).toHaveCSS(
+ "box-shadow",
+ "rgb(255, 188, 25) 0px 0px 0px 3px, rgba(0, 0, 0, 0.9) 0px 0px 0px 6px"
+ );
+ await expect(focusedElement).toHaveCSS(
+ "outline",
+ "rgba(0, 0, 0, 0) solid 3px"
+ );
+ });
+
+ test(`should verify that close icon is focused in Menu Fullscreen when focusRedesignOptOut is true`, async ({
+ mount,
+ page,
+ }) => {
+ await page.setViewportSize({ width: 1200, height: 800 });
+ await mount(, {
+ hooksConfig: { focusRedesignOptOut: true },
+ });
+
+ const item = menuItem(page).first();
+ await item.click();
+ const fullscreen = getComponent(page, "menu-fullscreen").first();
+ await waitForAnimationEnd(fullscreen);
+ await page.keyboard.press("Tab");
+ const closeIcon = closeIconButton(page).first();
+ await checkGoldenOutline(closeIcon);
+ await page.keyboard.press("Tab");
+ const focusedElement = page.locator("*:focus");
+ await expect(focusedElement).toHaveCSS(
+ "box-shadow",
+ "rgb(255, 188, 25) 0px 0px 0px 3px inset"
+ );
+ });
+
+ test(`should verify that inner Menu is available with tabbing and styles are correct`, async ({
+ mount,
+ page,
+ }) => {
+ await page.setViewportSize({ width: 1200, height: 800 });
+ await mount();
+
+ const item = menuItem(page).first();
+ await item.click();
+ const fullscreen = getComponent(page, "menu-fullscreen").first();
+ await waitForAnimationEnd(fullscreen);
+ await continuePressingTAB(page, 4);
+ const fullMenuItem = fullscreenMenu(page, 3)
+ .locator("li")
+ .locator("a")
+ .first();
+
+ const fullMenuItemBoxShadow = await fullMenuItem.evaluate((element) => {
+ const style = window.getComputedStyle(element);
+ return style.getPropertyValue("box-shadow");
+ });
+ expect(fullMenuItemBoxShadow).toContain("rgb(255, 188, 25)");
+
+ const fullMenuItemBackgroundColor = await fullMenuItem.evaluate(
+ (element) => {
+ const style = window.getComputedStyle(element);
+ return style.getPropertyValue("background-color");
+ }
+ );
+ expect(fullMenuItemBackgroundColor).toContain("rgb(0, 126, 69)");
+
+ const fullMenuItemColor = await fullMenuItem.evaluate((element) => {
+ const style = window.getComputedStyle(element);
+ return style.getPropertyValue("color");
+ });
+ expect(fullMenuItemColor).toContain("rgb(255, 255, 255)");
+ await expect(fullMenuItem).toBeFocused();
+ });
+
+ test(`should verify that inner Menu is available with shift-tabbing and styles are correct`, async ({
+ mount,
+ page,
+ }) => {
+ await page.setViewportSize({ width: 1200, height: 800 });
+ await mount();
+
+ const item = menuItem(page).first();
+ await item.click();
+ const fullscreen = getComponent(page, "menu-fullscreen").first();
+ await waitForAnimationEnd(fullscreen);
+ await continuePressingTAB(page, 5);
+ await page.keyboard.press("Shift+Tab");
+ const fullMenuItem = fullscreenMenu(page, 3)
+ .locator("li")
+ .locator("a")
+ .first();
+
+ const fullMenuItemBoxShadow = await fullMenuItem.evaluate((element) => {
+ const style = window.getComputedStyle(element);
+ return style.getPropertyValue("box-shadow");
+ });
+ expect(fullMenuItemBoxShadow).toContain("rgb(255, 188, 25)");
+
+ const fullMenuItemBackgroundColor = await fullMenuItem.evaluate(
+ (element) => {
+ const style = window.getComputedStyle(element);
+ return style.getPropertyValue("background-color");
+ }
+ );
+ expect(fullMenuItemBackgroundColor).toContain("rgb(0, 126, 69)");
+
+ const fullMenuItemColor = await fullMenuItem.evaluate((element) => {
+ const style = window.getComputedStyle(element);
+ return style.getPropertyValue("color");
+ });
+ expect(fullMenuItemColor).toContain("rgb(255, 255, 255)");
+
+ await expect(fullMenuItem).toBeFocused();
+ });
+
+ test(`should verify that inner Menu without link is NOT available when tabbing in Fullscreen Menu`, async ({
+ mount,
+ page,
+ }) => {
+ await page.setViewportSize({ width: 1200, height: 800 });
+ await mount();
+
+ const item = menuItem(page).first();
+ await item.click();
+ const fullscreen = getComponent(page, "menu-fullscreen").first();
+ await waitForAnimationEnd(fullscreen);
+ await continuePressingTAB(page, 5);
+ await expect(item).not.toBeFocused();
+ });
+
+ ([
+ ["open", true],
+ ["closed", false],
+ ] as [string, MenuFullscreenProps["isOpen"]][]).forEach(
+ ([value, boolVal]) => {
+ test(`should render with Menu Fullscreen ${value} when isOpen prop is ${boolVal}`, async ({
+ mount,
+ page,
+ }) => {
+ await page.setViewportSize({ width: 1200, height: 800 });
+ await mount();
+
+ const fullScreenMenu = getComponent(page, "menu-fullscreen").nth(3);
+ if (boolVal) {
+ await expect(fullScreenMenu).toBeVisible();
+ } else {
+ await expect(fullScreenMenu).not.toBeVisible();
+ }
+ });
+ }
+ );
+
+ test(`should verify that Menu Fullscreen has no effect on the tab order when isOpen prop is false`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await page.keyboard.press("Tab");
+ const button1 = page.getByRole("button").nth(0);
+ await expect(button1).toBeFocused();
+ await page.keyboard.press("Tab");
+ const button2 = page.getByRole("button").nth(1);
+ await expect(button2).toBeFocused();
+ });
+
+ ([
+ ["left", -1200, 1200],
+ ["right", 1200, -1200],
+ ] as [MenuFullscreenProps["startPosition"], number, number][]).forEach(
+ ([side, left, right]) => {
+ test(`should render with Menu Fullscreen start position ${side}`, async ({
+ mount,
+ page,
+ }) => {
+ await page.setViewportSize({ width: 1200, height: 800 });
+ await mount();
+
+ const menuFullScreen = getComponent(page, "menu-fullscreen").first();
+ await expect(menuFullScreen).toHaveCSS("left", `${left}px`);
+ await expect(menuFullScreen).toHaveCSS("right", `${right}px`);
+ });
+ }
+ );
+
+ test(`should focus the next menu item on tab press when the current item has a Search input with searchButton but no value`, async ({
+ mount,
+ page,
+ }) => {
+ await page.setViewportSize({ width: 1200, height: 800 });
+ await mount();
+
+ const item1 = menuItem(page).first().locator("a");
+ await item1.focus();
+ await page.keyboard.press("Tab");
+ const searchInput = searchDefaultInput(page);
+ await expect(searchInput).toBeFocused();
+ await page.keyboard.press("Tab");
+ const item2 = menuItem(page).last().locator("a");
+ await expect(item2).toBeFocused();
+ });
+
+ test(`should focus the search icon and button on tab press when the current item has a Search input with searchButton and has a value, focusRedesignOptOut flag not set`, async ({
+ mount,
+ page,
+ }) => {
+ await page.setViewportSize({ width: 1200, height: 800 });
+ await mount();
+
+ const item1 = menuItem(page).first().locator("a");
+ await item1.focus();
+ await page.keyboard.press("Tab");
+ const searchInput = searchDefaultInput(page);
+ await expect(searchInput).toBeFocused();
+ await page.keyboard.press("Tab");
+ const crossIcon = searchCrossIcon(page).locator("..");
+ await expect(crossIcon).toBeFocused();
+ await page.keyboard.press("Tab");
+ const button = searchButton(page);
+ await expect(button).toBeFocused();
+ await expect(button).toHaveCSS(
+ "box-shadow",
+ "rgb(255, 188, 25) 0px 0px 0px 3px, rgba(0, 0, 0, 0.9) 0px 0px 0px 6px"
+ );
+ await page.keyboard.press("Tab");
+ const item2 = menuItem(page).last().locator("a");
+ await expect(item2).toBeFocused();
+ });
+
+ test(`should focus the search icon and button on tab press when the current item has a Search input with searchButton and has a value, focusRedesignOptOut flag set`, async ({
+ mount,
+ page,
+ }) => {
+ await mount(
+ ,
+ {
+ hooksConfig: { focusRedesignOptOut: true },
+ }
+ );
+
+ const item = menuItem(page).first().locator("a");
+ await item.focus();
+ await page.keyboard.press("Tab");
+ const searchInput = searchDefaultInput(page);
+ await expect(searchInput).toBeFocused();
+ await page.keyboard.press("Tab");
+ const crossIcon = searchCrossIcon(page).locator("..");
+ await expect(crossIcon).toBeFocused();
+ await page.keyboard.press("Tab");
+ const button = searchButton(page);
+ await expect(button).toBeFocused();
+ await checkGoldenOutline(button);
+ await page.keyboard.press("Tab");
+ const item2 = menuItem(page).last().locator("a");
+ await expect(item2).toBeFocused();
+ });
+});
+
+test.describe("Event tests for Menu component", () => {
+ test(`should call onClick callback when a click event is triggered`, async ({
+ mount,
+ page,
+ }) => {
+ let callbackCount = 0;
+ await mount(
+ {
+ callbackCount += 1;
+ }}
+ />
+ );
+
+ const menuComp = menuComponent(page, 1);
+ await menuComp.click();
+ expect(callbackCount).toBe(1);
+ });
+
+ test(`should call onSubmenuOpen callback when mouseover event is triggered`, async ({
+ mount,
+ page,
+ }) => {
+ let callbackCount = 0;
+ await mount(
+ {
+ callbackCount += 1;
+ }}
+ submenu="Menu Item One"
+ />
+ );
+
+ const subMenu = submenu(page).first();
+ await subMenu.hover();
+ expect(callbackCount).toBe(1);
+ });
+
+ test(`should call onSubmenuOpen callback when a click event is triggered`, async ({
+ mount,
+ page,
+ }) => {
+ let callbackCount = 0;
+ await mount(
+ {
+ callbackCount += 1;
+ }}
+ submenu="Menu Item One"
+ />
+ );
+
+ const menuComp = menuComponent(page, 1);
+ await menuComp.click();
+ expect(callbackCount).toBe(1);
+ });
+
+ ["Space", "Enter", "ArrowDown", "ArrowUp"].forEach((key) => {
+ test(`should call onSubmenuOpen callback when a ${key} keyboard event is triggered`, async ({
+ mount,
+ page,
+ }) => {
+ let callbackCount = 0;
+ await mount(
+ {
+ callbackCount += 1;
+ }}
+ submenu="Menu Item One"
+ />
+ );
+
+ await page.keyboard.press("Tab");
+ await page.keyboard.press(key);
+ expect(callbackCount).toBe(1);
+ });
+ });
+
+ test(`should call onSubmenuClose callback when menu is closed`, async ({
+ mount,
+ page,
+ }) => {
+ let callbackCount = 0;
+ await mount(
+ {
+ callbackCount += 1;
+ }}
+ submenu="Menu Item Three"
+ />
+ );
+
+ await page.keyboard.press("Tab");
+ await page.keyboard.press("ArrowDown");
+ expect(callbackCount).toBe(1);
+ });
+
+ test(`should call onClose callback when Menu Fullscreen is closed`, async ({
+ mount,
+ page,
+ }) => {
+ let callbackCount = 0;
+ await page.setViewportSize({ width: 1200, height: 800 });
+ await mount(
+ {
+ callbackCount += 1;
+ }}
+ />
+ );
+
+ const item = menuItem(page).first();
+ await item.click();
+ const fullscreen = getComponent(page, "menu-fullscreen").first();
+ await waitForAnimationEnd(fullscreen);
+ const closeIcon = closeIconButton(page).first();
+ await closeIcon.click();
+ expect(callbackCount).toBe(1);
+ });
+
+ test(`should have correct keyboard navigation order when children of submenu update`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const subMenu = submenu(page).first();
+ await subMenu.hover();
+ const subMenuBlock = submenuBlock(page).locator("li");
+ await expect(subMenuBlock).toHaveCount(4);
+ await page.keyboard.press("Tab");
+ await page.keyboard.press("ArrowDown");
+ const focusedElement1 = page.locator("*:focus");
+ await expect(focusedElement1).toHaveText("Apple");
+ await page.keyboard.press("ArrowDown");
+ const focusedElement2 = page.locator("*:focus");
+ await expect(focusedElement2).toHaveText("Banana");
+ await page.keyboard.press("ArrowDown");
+ const focusedElement3 = page.locator("*:focus");
+ await expect(focusedElement3).toHaveText("Carrot");
+ await page.keyboard.press("ArrowDown");
+ const focusedElement4 = page.locator("*:focus");
+ await expect(focusedElement4).toHaveText("Broccoli");
+ await page.keyboard.press("ArrowUp");
+ const focusedElement5 = page.locator("*:focus");
+ await expect(focusedElement5).toHaveText("Carrot");
+ await page.keyboard.press("ArrowUp");
+ const focusedElement6 = page.locator("*:focus");
+ await expect(focusedElement6).toHaveText("Banana");
+ await page.keyboard.press("ArrowUp");
+ const focusedElement7 = page.locator("*:focus");
+ await expect(focusedElement7).toHaveText("Apple");
+ });
+});
+
+test.describe("Accessibility tests for Menu component", () => {
+ test(`should pass accessibility tests for default Menu`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await checkAccessibility(page);
+ });
+
+ test(`should pass accessibility tests when expanded`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const subMenu = submenu(page).first();
+ await subMenu.hover();
+ await checkAccessibility(page);
+ });
+
+ (["default", "large"] as MenuDividerProps["size"][]).forEach((divider) => {
+ test(`should pass accessibility tests when divider size is ${divider}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const subMenu = submenu(page).first();
+ await subMenu.hover();
+ await checkAccessibility(page);
+ });
+ });
+
+ // Skipped because of FE-6287
+ test.skip(`should pass accessibility tests when search component is focused`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await page.keyboard.press("Tab");
+ await page.keyboard.press("Enter");
+ await page.keyboard.press("Tab");
+ const subMenu = getComponent(page, "submenu").first();
+ await waitForAnimationEnd(subMenu);
+ await checkAccessibility(page);
+ });
+
+ test(`should pass accessibility tests when a submenu has a long label`, async ({
+ mount,
+ page,
+ }) => {
+ await mount(
+
+
+
+ );
+
+ const subMenu = submenu(page).first();
+ await subMenu.hover();
+ await checkAccessibility(page);
+ });
+
+ test(`should pass accessibility tests when a menu item has a long label`, async ({
+ mount,
+ page,
+ }) => {
+ await mount(
+
+
+
+ );
+
+ const subMenu = submenu(page).first();
+ await subMenu.hover();
+ await checkAccessibility(page);
+ });
+
+ ["450px", "675px", "1200px"].forEach((width) => {
+ test(`should pass accessibility tests when width is ${width}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await checkAccessibility(page);
+ });
+ });
+
+ ["10px", "30px", "50px"].forEach((propValue) => {
+ test(`should pass accessibility tests when height is ${propValue}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await checkAccessibility(page);
+ });
+ });
+
+ (["default", "large"] as MenuDividerProps["size"][]).forEach((size) => {
+ test(`should pass accessibility tests when size is ${size}px`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await checkAccessibility(page);
+ });
+ });
+
+ ["block", "inline-block", "flex", "contents", "list-item", "none"].forEach(
+ (display) => {
+ test(`should pass accessibility tests when display is ${display}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await checkAccessibility(page);
+ });
+ }
+ );
+
+ [
+ "baseline",
+ "bottom",
+ "middle",
+ "sub",
+ "super",
+ "text-bottom",
+ "text-top",
+ "top",
+ ].forEach((alignment) => {
+ test(`should pass accessibility tests when alignItems is ${alignment}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await checkAccessibility(page);
+ });
+ });
+
+ ["auto", "clip", "hidden", "scroll", "visible"].forEach((overflow) => {
+ test(`should pass accessibility tests when overflow is ${overflow}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await checkAccessibility(page);
+ });
+ });
+
+ ([
+ "auto",
+ "clip",
+ "hidden",
+ "scroll",
+ "visible",
+ ] as MenuProps["overflowX"][]).forEach((overflow) => {
+ test(`should pass accessibility tests when overflowX is ${overflow}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await checkAccessibility(page);
+ });
+ });
+
+ ([
+ "auto",
+ "clip",
+ "hidden",
+ "scroll",
+ "visible",
+ ] as MenuProps["overflowY"][]).forEach((overflow) => {
+ test(`should pass accessibility tests when overflowY is ${overflow}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await checkAccessibility(page);
+ });
+ });
+
+ ["normal", "stretch", "baseline", "center", "flex-start", "flex-end"].forEach(
+ (alignment) => {
+ test(`should pass accessibility tests for when alignItems is ${alignment}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await checkAccessibility(page);
+ });
+ }
+ );
+
+ [
+ "normal",
+ "baseline",
+ "center",
+ "flex-start",
+ "flex-end",
+ "space-between",
+ "space-around",
+ "stretch",
+ ].forEach((alignment) => {
+ test(`should pass accessibility tests when alignContent is ${alignment}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await checkAccessibility(page);
+ });
+ });
+
+ [
+ "left",
+ "center",
+ "right",
+ "flex-start",
+ "flex-end",
+ "normal",
+ "stretch",
+ ].forEach((justified) => {
+ test(`should pass accessibility tests when justifyItems is ${justified}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await checkAccessibility(page);
+ });
+ });
+
+ [
+ "left",
+ "center",
+ "right",
+ "flex-start",
+ "flex-end",
+ "normal",
+ "space-between",
+ "space-around",
+ "stretch",
+ ].forEach((justified) => {
+ test(`should pass accessibility tests when justifyContent is ${justified}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await checkAccessibility(page);
+ });
+ });
+
+ (["nowrap", "wrap", "wrap-reverse"] as MenuProps["flexWrap"][]).forEach(
+ (wrap) => {
+ test(`should pass accessibility tests when flexWrap is ${wrap}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await checkAccessibility(page);
+ });
+ }
+ );
+
+ ([
+ "column",
+ "column-reverse",
+ "row",
+ "row-reverse",
+ ] as MenuProps["flexDirection"][]).forEach((direction) => {
+ test(`should pass accessibility tests when flexDirection is ${direction}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await checkAccessibility(page);
+ });
+ });
+
+ ["auto", "content", "fit-content", "max-content", "min-content"].forEach(
+ (flex) => {
+ test(`should pass accessibility tests when flex is ${flex}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await checkAccessibility(page);
+ });
+ }
+ );
+
+ [10, 50, 100].forEach((value) => {
+ test(`should pass accessibility tests when flexGrow is ${value}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await checkAccessibility(page);
+ });
+ });
+
+ [10, 50, 100].forEach((value) => {
+ test(`should pass accessibility tests when flexShrink is ${value}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await checkAccessibility(page);
+ });
+ });
+
+ ["auto", "content", "fit-content", "max-content", "min-content"].forEach(
+ (basis) => {
+ test(`should pass accessibility tests when flexBasis is ${basis}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await checkAccessibility(page);
+ });
+ }
+ );
+
+ [
+ "auto",
+ "baseline",
+ "left",
+ "normal",
+ "right",
+ "stretch",
+ "center",
+ "flex-start",
+ "flex-end",
+ ].forEach((justify) => {
+ test(`should pass accessibility tests when justifySelf is ${justify}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await checkAccessibility(page);
+ });
+ });
+
+ [
+ "auto",
+ "baseline",
+ "normal",
+ "stretch",
+ "center",
+ "flex-start",
+ "flex-end",
+ ].forEach((align) => {
+ test(`should pass accessibility tests when alignSelf is ${align}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await checkAccessibility(page);
+ });
+ });
+
+ [
+ CHARACTERS.STANDARD,
+ CHARACTERS.DIACRITICS,
+ CHARACTERS.SPECIALCHARACTERS,
+ ].forEach((text) => {
+ test(`should pass accessibility tests when item text is ${text}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await checkAccessibility(page);
+ });
+ });
+
+ (["default", "alternate"] as ScrollableBlockProps["variant"][]).forEach(
+ (variant) => {
+ test(`should pass accessibility tests when scroll block has ${variant} variant background color`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const subMenu = submenu(page).first();
+ await subMenu.hover();
+
+ await checkAccessibility(page);
+ });
+ }
+ );
+
+ (["default", "alternate"] as ScrollableBlockProps["variant"][]).forEach(
+ (variant) => {
+ test(`should pass accessibility tests when Segment Title has a ${variant} variant background color`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const subMenu = submenu(page).first();
+ await subMenu.hover();
+
+ await checkAccessibility(page);
+ });
+ }
+ );
+
+ test(`should pass accessibility tests for Menu with parent item`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const subMenu = submenu(page).first();
+ await subMenu.hover();
+ await checkAccessibility(page);
+ });
+
+ test(`should pass accessibility tests for Menu with button icon`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const subMenu = submenu(page).first();
+ await subMenu.hover();
+ await checkAccessibility(page);
+ });
+
+ // Test skipped because of issue FE-5731
+ test.skip(`should pass accessibility tests for Menu with icon`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await checkAccessibility(page);
+ });
+});
+
+test.describe("Accessibility tests for Menu Fullscreen component", () => {
+ test(`should pass accessibility tests for Menu Fullscreen`, async ({
+ mount,
+ page,
+ }) => {
+ await page.setViewportSize({ width: 1200, height: 800 });
+ await mount();
+
+ const item = menuItem(page).first();
+ await item.click();
+ const fullscreen = getComponent(page, "menu-fullscreen").first();
+ await waitForAnimationEnd(fullscreen);
+ await checkAccessibility(page);
+ });
+
+ test(`should pass accessibility tests when close icon is clicked`, async ({
+ mount,
+ page,
+ }) => {
+ await page.setViewportSize({ width: 1200, height: 800 });
+ await mount();
+
+ const item = menuItem(page).first();
+ await item.click();
+ await expect(
+ getComponent(page, "menu-fullscreen")
+ .first()
+ .locator("a")
+ .first()
+ .locator("span")
+ ).toHaveText("Menu Item One");
+ const closeIcon = closeIconButton(page).first();
+ await closeIcon.click();
+ await checkAccessibility(page);
+ });
+
+ test(`should pass accessibility tests when menu item is highlighted`, async ({
+ mount,
+ page,
+ }) => {
+ await page.setViewportSize({ width: 1200, height: 800 });
+ await mount();
+
+ const item = menuItem(page).first();
+ await item.click();
+ const fullscreen = getComponent(page, "menu-fullscreen").first();
+ await waitForAnimationEnd(fullscreen);
+ await continuePressingTAB(page, 5);
+ await checkAccessibility(page);
+ });
+
+ (["left", "right"] as MenuFullscreenProps["startPosition"][]).forEach(
+ (side) => {
+ test(`should pass accessibility tests when start position is ${side}`, async ({
+ mount,
+ page,
+ }) => {
+ await page.setViewportSize({ width: 1200, height: 800 });
+ await mount();
+
+ const item = menuItem(page).first();
+ await item.click();
+ const fullscreen = getComponent(page, "menu-fullscreen").first();
+ await waitForAnimationEnd(fullscreen);
+ await checkAccessibility(page);
+ });
+ }
+ );
+});
+
+test.describe(
+ "Styling, Scrolling & Navigation Bar Tests for Menu Component",
+ () => {
+ test(`should render menu items with the expected focus styling when focusRedesignOptOut is true`, async ({
+ mount,
+ page,
+ }) => {
+ await page.setViewportSize({ width: 1200, height: 800 });
+ await mount(, {
+ hooksConfig: { focusRedesignOptOut: true },
+ });
+
+ const item1 = menuItem(page).first().locator("a");
+ await item1.focus();
+ await expect(item1).toHaveCSS(
+ "box-shadow",
+ "rgb(255, 188, 25) 0px 0px 0px 3px inset"
+ );
+
+ const item2 = menuItem(page).last().locator("button");
+ await item2.focus();
+ await expect(item2).toHaveCSS(
+ "box-shadow",
+ "rgb(255, 188, 25) 0px 0px 0px 3px inset"
+ );
+ await item2.click();
+
+ const subMenu1 = submenu(page).last().locator("button").first();
+ await subMenu1.focus();
+ await expect(subMenu1).toHaveCSS(
+ "box-shadow",
+ "rgb(255, 188, 25) 0px 0px 0px 3px inset"
+ );
+
+ const subMenu2 = submenu(page).last().locator("a").first();
+ await subMenu2.focus();
+ await expect(subMenu2).toHaveCSS(
+ "box-shadow",
+ "rgb(255, 188, 25) 0px 0px 0px 3px inset"
+ );
+ });
+
+ test(`should render menu items with the expected focus styling when focusRedesignOptOut is false`, async ({
+ mount,
+ page,
+ }) => {
+ await page.setViewportSize({ width: 1200, height: 800 });
+ await mount();
+
+ const item1 = menuItem(page).first().locator("a");
+ await item1.focus();
+ await expect(item1).toHaveCSS(
+ "box-shadow",
+ "rgba(0, 0, 0, 0.9) 0px 0px 0px 3px inset, rgb(255, 188, 25) 0px 0px 0px 6px inset"
+ );
+ await expect(item1).toHaveCSS("outline", "rgba(0, 0, 0, 0) solid 3px");
+
+ const item2 = menuItem(page).last().locator("button");
+ await item2.focus();
+ await expect(item2).toHaveCSS(
+ "box-shadow",
+ "rgba(0, 0, 0, 0.9) 0px 0px 0px 3px inset, rgb(255, 188, 25) 0px 0px 0px 6px inset"
+ );
+ await expect(item2).toHaveCSS("outline", "rgba(0, 0, 0, 0) solid 3px");
+ await item2.click();
+
+ const subMenu1 = submenu(page).last().locator("button").first();
+ await subMenu1.focus();
+ await expect(subMenu1).toHaveCSS(
+ "box-shadow",
+ "rgba(0, 0, 0, 0.9) 0px 0px 0px 3px inset, rgb(255, 188, 25) 0px 0px 0px 6px inset"
+ );
+ await expect(subMenu1).toHaveCSS("outline", "rgba(0, 0, 0, 0) solid 3px");
+
+ const subMenu2 = submenu(page).last().locator("a").first();
+ await subMenu2.focus();
+ await expect(subMenu2).toHaveCSS(
+ "box-shadow",
+ "rgba(0, 0, 0, 0.9) 0px 0px 0px 3px inset, rgb(255, 188, 25) 0px 0px 0px 6px inset"
+ );
+ await expect(subMenu2).toHaveCSS("outline", "rgba(0, 0, 0, 0) solid 3px");
+ });
+
+ test(`should render with the expected border radius styling on the Submenu`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const subMenu = submenu(page).first();
+ await subMenu.hover();
+ const subMenuBlock = submenuBlock(page).first();
+ await expect(subMenuBlock).toHaveCSS("border-radius", "0px 0px 8px 8px");
+ const subMenu2 = submenu(page).locator("a").last();
+ await expect(subMenu2).toHaveCSS("border-radius", "0px 0px 8px 8px");
+ });
+
+ test(`should render with the expected border radius styling on the Submenu Scrollable Block`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ const subMenu = submenu(page).first();
+ await subMenu.hover();
+ const scrollableBlock = scrollBlock(page).first();
+ await expect(scrollableBlock).toHaveCSS(
+ "border-radius",
+ "0px 0px 0px 8px"
+ );
+ const scrollableItem = scrollBlock(page).locator("a").last();
+ await expect(scrollableItem).toHaveCSS(
+ "border-radius",
+ "0px 0px 0px 8px"
+ );
+ });
+
+ test(`should verify that tabbing forward through the menu and back to the start should not make the background scroll to the bottom`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await continuePressingTAB(page, 4);
+ const closeIcon = closeIconButton(page);
+ await expect(closeIcon).toBeFocused();
+ await expect(page.getByTestId("#bottom-box")).not.toBeInViewport();
+ });
+
+ test(`should verify that tabbing backward through the menu and back to the start should not make the background scroll to the bottom`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await continuePressingSHIFTTAB(page, 3);
+ const closeIcon = closeIconButton(page);
+ await expect(closeIcon).toBeFocused();
+ await expect(page.getByTestId("#bottom-box")).not.toBeInViewport();
+ });
+
+ test(`should render with all the content of a long submenu accessible with the keyboard while remaining visible`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await page.setViewportSize({ width: 1000, height: 500 });
+ await page.keyboard.press("Tab");
+ await page.keyboard.press("ArrowDown");
+ const subMenuItem = submenuItem(page, 1);
+ await expect(subMenuItem).toHaveCount(20);
+ for (let i = 0; i < 20; i++) {
+ await page.keyboard.press("ArrowDown");
+ }
+ const focusedElement = page.locator("*:focus");
+ await expect(focusedElement).toHaveText("Foo 20");
+ const subMenu = page.locator(
+ '[data-component="submenu-wrapper"] ul > li:nth-child(20)'
+ );
+ await expect(subMenu).toBeInViewport();
+ });
+
+ test(`should render with all the content of a long submenu accessible with the keyboard while remaining visible if the navbar height changes`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await page.setViewportSize({ width: 1000, height: 500 });
+ await page.keyboard.press("Tab");
+ await page.keyboard.press("ArrowDown");
+ const subMenuItem = submenuItem(page, 1);
+ await expect(subMenuItem).toHaveCount(21);
+ for (let i = 0; i < 3; i++) {
+ await page.keyboard.press("ArrowDown");
+ }
+ await page.keyboard.press("Enter");
+
+ await page.waitForTimeout(100);
+ await page.keyboard.press("Tab");
+ await page.keyboard.press("ArrowDown");
+ for (let i = 0; i < 21; i++) {
+ await page.keyboard.press("ArrowDown");
+ }
+ const subMenu = page.locator(
+ '[data-component="submenu-wrapper"] ul > li:nth-child(21)'
+ );
+ await expect(subMenu).toBeInViewport();
+ });
+ }
+);