diff --git a/packages/main/cypress/specs/ColorPalettePopover.cy.tsx b/packages/main/cypress/specs/ColorPalettePopover.cy.tsx new file mode 100644 index 000000000000..4c68cbb3af18 --- /dev/null +++ b/packages/main/cypress/specs/ColorPalettePopover.cy.tsx @@ -0,0 +1,242 @@ +import Input from "../../src/Input.js"; +import Button from "../../src/Button.js"; +import ColorPaletteItem from "../../src/ColorPaletteItem.js"; +import ColorPalettePopover from "../../src/ColorPalettePopover.js"; + +function ColorPaletteSample() { + return ( + <> + + + + + + + + + + + + + + + + + ); +} + +describe("Color Palette Popover tests", () => { + it("Test if focusing first element works on initial open", () => { + cy.mount(); + + // use the command to open the color palette popover + cy.get("[ui5-color-palette-popover]") + .ui5ColorPalettePopoverOpen({ opener: "colorPaletteBtnTest" }); + + // get elements and assert focus + cy.get("#colorPalettePopoverTest") + .ui5GetColorPaletteInPopover() + .ui5GetColorPaletteDefaultButton() + .should("have.focus"); + + // close popover + cy.get("#colorPalettePopoverTest") + .ui5GetColorPaletteInPopover() + .ui5GetColorPaletteDefaultButton() + .realClick(); + }); + + it("Test if default color functionality works", () => { + cy.mount(); + const DEFAULT_COLOR = "green"; + + // open color palette popover + cy.get("[ui5-color-palette-popover]") + .ui5ColorPalettePopoverOpen({ opener: "colorPaletteBtnTest" }); + + // get color palette within popover + cy.get("#colorPalettePopoverTest") + .ui5GetColorPaletteInPopover() + .as("colorPalette"); + + // find and click default color button + cy.get("@colorPalette") + .ui5GetColorPaletteDefaultButton() + .realPress("Space"); // simulate space key press + + // "green" is selected as default color + cy.get("@colorPalette") + .invoke("prop", "selectedColor") + .should("equal", DEFAULT_COLOR); + }); + + it("Test if keyboard navigation on elements works correctly", () => { + const EXPECTED_COLOR = "pink"; + cy.mount(); + + // open color palette popover + cy.get("[ui5-color-palette-popover]") + .ui5ColorPalettePopoverOpen({ opener: "colorPaletteBtnTest" }); + + // get color palette within popover + cy.get("#colorPalettePopoverTest") + .ui5GetColorPaletteInPopover() + .as("colorPalette"); + + // get default button and perform keyboard navigation + cy.get("@colorPalette") + .ui5GetColorPaletteDefaultButton() + .realPress("ArrowDown"); + + // find first color palette item and press space + cy.get("@colorPalette") + .ui5GetColorPaletteFirstItem() + .realPress("Space"); + + // "pink" is selected + cy.get("@colorPalette") + .invoke("prop", "selectedColor") + .should("equal", EXPECTED_COLOR); + }); + + it("Test if keyboard navigation on elements works correctly", () => { + cy.mount(); + + // open color palette popover + cy.get("[ui5-color-palette-popover]") + .ui5ColorPalettePopoverOpen({ opener: "colorPaletteBtnTest" }); + + // get color palette within popover + cy.get("#colorPalettePopoverTest") + .ui5GetColorPaletteInPopover() + .as("colorPalette"); + + // get default button and perform keyboard navigation up + cy.get("@colorPalette") + .ui5GetColorPaletteDefaultButton() + .realPress("ArrowUp"); + + // more Colors button is focused + cy.get("@colorPalette") + .ui5GetColorPaletteMoreColorsButton() + .should("have.focus"); + + // close popover + cy.get("@colorPalette") + .ui5GetColorPaletteDefaultButton() + .realClick(); + }); + + it("Test 'close' event fired when popover closes", () => { + cy.mount( + <> + + + + + + + + + + + + + + + + + + + ); + + // listener to increment the counter on popover close + cy.get("#colorPalettePopoverTest6").ui5RegisterCloseCounter("#inpOpenChangeCounter"); + + // open popover and close it by clicking outside + cy.get("[ui5-color-palette-popover]").ui5ColorPalettePopoverOpen({ opener: "colorPaletteBtnTest6" }); + cy.get("#btnFocusOut").realClick(); + + // verify that the close event fired + cy.get("#inpOpenChangeCounter").should("have.attr", "value", "1"); + + // open the color palette popover again + cy.get("[ui5-color-palette-popover]").ui5ColorPalettePopoverOpen({ opener: "colorPaletteBtnTest6" }); + + // close the popover + cy.get("#colorPalettePopoverTest6").ui5ColorPalettePopoverClose(); + + cy.get("#inpOpenChangeCounter").should("have.attr", "value", "2"); + }); + + // the item is focused but the assertion fails + it.skip("After selecting an item, opening the popover again should focus the selected item", () => { + cy.mount(); + + // open the popover and select the first item using keyboard navigation + cy.get("[ui5-color-palette-popover]") + .ui5ColorPalettePopoverOpen({ opener: "colorPaletteBtnTest" }); + cy.get("#colorPalettePopoverTest") + .ui5GetColorPaletteInPopover() + .as("colorPalette"); + + // navigate from the default button to the first palette item + cy.get("@colorPalette") + .realPress("ArrowDown") + .realPress("Space"); + + // close the popover by clicking the opener button + cy.get("#colorPaletteBtnTest").realClick(); + + // re-open the popover + cy.get("[ui5-color-palette-popover]") + .ui5ColorPalettePopoverOpen({ opener: "colorPaletteBtnTest" }); + + // verify that the previously selected item is focused + cy.get("#colorPalettePopoverTest") + .ui5GetColorPaletteInPopover() + .ui5GetColorPaletteFirstItem() + .should("be.focused"); + }); + + it("Clicking default button and opening the popover again should focus the default button", () => { + cy.mount(); + + // open the popover + cy.get("[ui5-color-palette-popover]") + .ui5ColorPalettePopoverOpen({ opener: "colorPaletteBtnTest" }); + + // click on the default button inside the popover + cy.get("#colorPalettePopoverTest") + .ui5GetColorPaletteInPopover() + .ui5GetColorPaletteDefaultButton() + .realClick(); + + // close the popover by clicking the opener button + cy.get("#colorPaletteBtnTest").realClick(); + + // re-open the popover + cy.get("[ui5-color-palette-popover]") + .ui5ColorPalettePopoverOpen({ opener: "colorPaletteBtnTest" }); + + // assert that the default button is focused + cy.get("#colorPalettePopoverTest") + .ui5GetColorPaletteInPopover() + .ui5GetColorPaletteDefaultButton() + .should("have.focus"); + }); +}); diff --git a/packages/main/cypress/support/commands.ts b/packages/main/cypress/support/commands.ts index 95ab78647721..f1ff67f7a7e5 100644 --- a/packages/main/cypress/support/commands.ts +++ b/packages/main/cypress/support/commands.ts @@ -38,8 +38,9 @@ import { internals, isPhone } from "@ui5/webcomponents-base/dist/Device.js"; import "./commands/Menu.commands.js"; -import "./commands/ColorPicker.commands.js"; import "./commands/ColorPalette.commands.js"; +import "./commands/ColorPalettePopover.commands.js"; +import "./commands/ColorPicker.commands.js"; type SimulationDevices = "phone" @@ -56,6 +57,14 @@ declare global { ui5ColorPickerUpdateInput(name: string, value: string): Chainable ui5ColorPaletteCheckSelectedColor(colorPaletteItem: string, values: {r: string, g: string, b: string, a: string}): Chainable ui5ColorPaletteNavigateAndCheckSelectedColor(colorPalette: string, startIndex: number, key: string, expectedValue: string): Chainable + ui5ColorPalettePopoverOpened(): Chainable + ui5ColorPalettePopoverOpen(options?: { opener?: string }): Chainable + ui5GetColorPaletteInPopover(): Chainable + ui5GetColorPaletteDefaultButton(): Chainable + ui5GetColorPaletteFirstItem(): Chainable + ui5GetColorPaletteMoreColorsButton(): Chainable + ui5RegisterCloseCounter(inputSelector: string): Chainable + ui5ColorPalettePopoverClose(): Chainable } } } diff --git a/packages/main/cypress/support/commands/ColorPalettePopover.commands.ts b/packages/main/cypress/support/commands/ColorPalettePopover.commands.ts new file mode 100644 index 000000000000..af2efb14a093 --- /dev/null +++ b/packages/main/cypress/support/commands/ColorPalettePopover.commands.ts @@ -0,0 +1,84 @@ +Cypress.Commands.add("ui5ColorPalettePopoverOpen", { prevSubject: true }, (prevSubject, options) => { + cy.wrap(prevSubject) + .as("colorPalettePopover") + .then(popover => { + if (options?.opener) { + cy.wrap(popover) + .invoke("attr", "opener", options.opener); + } + + cy.wrap(popover) + .invoke("attr", "open", true); + }); + + cy.get("@colorPalettePopover") + .ui5ColorPalettePopoverOpened(); +}); + +Cypress.Commands.add("ui5ColorPalettePopoverOpened", { prevSubject: true }, subject => { + cy.wrap(subject) + .as("colorPalettePopover"); + + cy.get("@colorPalettePopover") + .should("have.attr", "open"); + + cy.get("@colorPalettePopover") + .shadow() + .find("[ui5-responsive-popover]") + .should(respPopover => { + expect(respPopover.is(":popover-open")).to.be.true; + expect(respPopover.width()).to.not.equal(0); + expect(respPopover.height()).to.not.equal(0); + }) + .and("have.attr", "open"); +}); + +Cypress.Commands.add("ui5GetColorPaletteInPopover", { prevSubject: true }, subject => { + cy.wrap(subject) + .shadow() + .find("[ui5-responsive-popover]") + .find("[ui5-color-palette]"); +}); + +Cypress.Commands.add("ui5GetColorPaletteDefaultButton", { prevSubject: true }, subject => { + cy.wrap(subject) + .shadow() + .find(".ui5-cp-default-color-button"); +}); + +Cypress.Commands.add("ui5GetColorPaletteFirstItem", { prevSubject: true }, subject => { + cy.wrap(subject) + .shadow() + .find("ui5-color-palette-item") + .first(); +}); + +Cypress.Commands.add("ui5GetColorPaletteMoreColorsButton", { prevSubject: true }, subject => { + cy.wrap(subject) + .shadow() + .find(".ui5-cp-more-colors"); +}); + +Cypress.Commands.add("ui5ColorPalettePopoverClose", { prevSubject: true }, subject => { + cy.wrap(subject).as("colorPalettePopover"); + + // close the popover + cy.get("@colorPalettePopover") + .realPress("Escape"); + + cy.get("@colorPalettePopover") + .should("not.have.attr", "open"); +}); + +Cypress.Commands.add("ui5RegisterCloseCounter", { prevSubject: true }, (subject, inputSelector: string) => { + cy.wrap(subject).then(element => { + const popoverElement = element[0]; + let openChangeCounter = 0; + + popoverElement.addEventListener("ui5-close", () => { + // increment the value of the input field, indicating that the event close was fired + openChangeCounter++; + Cypress.$(inputSelector).val(`${openChangeCounter}`); + }); + }); +});