diff --git a/cypress/components/accordion/accordion.cy.tsx b/cypress/components/accordion/accordion.cy.tsx deleted file mode 100644 index 473ff58ed7..0000000000 --- a/cypress/components/accordion/accordion.cy.tsx +++ /dev/null @@ -1,640 +0,0 @@ -import React from "react"; -import CypressMountWithProviders from "../../support/component-helper/cypress-mount"; -import { - accordion, - accordionIcon, - accordionTitleContainer, - accordionTitleContainerByPosition, - accordionContent, -} from "../../locators/accordion"; -import { - positionOfElement, - keyCode, - getRotationAngle, -} from "../../support/helper"; -import { getDataElementByValue } from "../../locators"; -import { - ACCORDION_ADD_CONTENT, - ACCORDION_REMOVE_CONTENT, -} from "../../locators/accordion/locators"; -import { - checkGoldenOutline, - assertCssValueIsApproximately, -} from "../../support/component-helper/common-steps"; -import { SIZE, CHARACTERS } from "../../support/component-helper/constants"; - -import { - AccordionComponent, - AccordionWithIcon, - AccordionGroupWithError, - AccordionGroupWithWarning, - AccordionGroupWithInfo, - AccordionGroupComponent, - DynamicContent, - AccordionDefault, - AccordionWithBoxAndDifferentPaddings, - AccordionOpeningButton, - AccordionGroupDefault, - AccordionGroupValidation, - AccordionWithDefinitionList, -} from "../../../src/components/accordion/accordion-test.stories"; - -const testData = [CHARACTERS.DIACRITICS, CHARACTERS.SPECIALCHARACTERS]; - -context("Testing Accordion component", () => { - describe("when focused", () => { - it("should have the expected styling when the focusRedesignOptOut is false", () => { - CypressMountWithProviders(); - accordionTitleContainer() - .focus() - .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"); - }); - - it("should have the expected styling when the focusRedesignOptOut is true", () => { - CypressMountWithProviders(, undefined, undefined, { - focusRedesignOptOut: true, - }); - accordionTitleContainer() - .focus() - .should("have.css", "outline", "rgb(255, 188, 25) solid 3px"); - }); - }); - - describe("should render Accordion component", () => { - it("should check AccordionRow is expanded using click", () => { - CypressMountWithProviders(); - - accordionTitleContainer().click(); - - accordionTitleContainer() - .should("have.attr", "aria-expanded", "true") - .and("be.visible"); - - accordionContent() - .should("have.attr", "data-element", "accordion-content") - .and("be.visible"); - }); - - it("should check AccordionRow is expanded using Enter key", () => { - CypressMountWithProviders(); - - accordionTitleContainer().trigger("keydown", keyCode("Enter")); - - accordionTitleContainer() - .should("have.attr", "aria-expanded", "true") - .and("be.visible"); - - accordionContent() - .should("have.attr", "data-element", "accordion-content") - .and("be.visible"); - }); - - it.each([["chevron_down"], ["dropdown"]])( - "should set iconType to %s when Accordion row is closed", - (iconType) => { - CypressMountWithProviders(); - - accordionIcon() - .should("have.attr", "type", iconType) - .and("be.visible") - .and("have.css", "transform") - .then((cssString) => - // eslint-disable-next-line jest/valid-expect - expect(getRotationAngle(cssString.toString())).to.equal(90) - ); - } - ); - - it.each([["chevron_down"], ["dropdown"]])( - "should set iconType to %s when Accordion row is open", - (iconType) => { - CypressMountWithProviders(); - - accordionTitleContainer().click(); - - accordionIcon() - .should("have.attr", "type", iconType) - .and("be.visible") - .and("have.css", "transform", "none"); - } - ); - - it.each(["left", "right"])( - "should set Accordion iconAlign to %s", - (iconAlign) => { - CypressMountWithProviders(); - - accordionTitleContainerByPosition(positionOfElement("first")) - .first() - .should("have.attr", "data-element", "accordion-headings-container") - .and("be.visible"); - accordionTitleContainerByPosition(positionOfElement("first")) - .last() - .should("have.attr", "data-component", "icon") - .and("be.visible"); - if (iconAlign === "right") { - // set by default - accordionTitleContainer() - .should("have.css", "justify-content", "space-between") - .and("not.have.css", "flex-direction", "row-reverse"); - accordionTitleContainerByPosition(positionOfElement("first")) - .first() - .should("have.css", "margin-right", "0px"); - } else { - accordionTitleContainer().should( - "have.css", - "flex-direction", - "row-reverse" - ); - accordionTitleContainerByPosition(positionOfElement("first")) - .last() - .should("have.css", "margin-right", "16px"); - } - } - ); - - it("should verify AccordionRow is expanded by clicking on validation icon", () => { - CypressMountWithProviders(); - - accordionIcon().eq(0).click(); - - accordionTitleContainer() - .should("have.attr", "aria-expanded", "true") - .and("be.visible"); - - accordionContent() - .should("have.attr", "data-element", "accordion-content") - .and("be.visible"); - }); - - it.each([[true], [false]])( - "should call onChange callback when a click event is triggered and expanded is set to %s", - (isExpanded) => { - const callback = cy.stub(); - - CypressMountWithProviders( - - ); - - accordionTitleContainer() - .click() - .then(() => { - // eslint-disable-next-line no-unused-expressions, jest/valid-expect - expect(callback).to.have.been.calledOnce; - }); - } - ); - - it.each(testData)( - "should render Accordion component with %s as a title", - (titleValue) => { - CypressMountWithProviders(); - - accordionTitleContainer().should("contain.text", titleValue); - } - ); - - it.each(testData)( - "should render Accordion component with %s as a subtitle", - (titleValue) => { - CypressMountWithProviders(); - - accordionTitleContainer().should("contain.text", titleValue); - } - ); - - it.each([ - [SIZE.SMALL, 24], - [SIZE.LARGE, 45], - ])( - "should render Accordion component with %s as a size and has height property set to %s", - (size, height) => { - CypressMountWithProviders(); - - accordionTitleContainer().then(($el) => { - assertCssValueIsApproximately($el, "height", height); - }); - } - ); - - it.each([ - ["solid", "rgb(204, 214, 219)"], - ["none", "rgba(0, 0, 0, 0.9)"], - ])( - "should render Accordion component with border type '%s'", - (border, colour) => { - CypressMountWithProviders(); - - accordion() - .should("have.css", "border-bottom-style", border) - .and("have.css", "border-bottom-color", colour); - } - ); - - it.each([["true"], ["false"]])( - "should check Accordion is expanded or not by default", - (state) => { - CypressMountWithProviders( - - ); - - accordionTitleContainer() - .should("have.attr", "aria-expanded", state) - .and("be.visible"); - } - ); - - it.each([ - ["true", "be.visible"], - ["false", "be.visible"], - ])("should check Accordion is expanded or not", (state, visibility) => { - CypressMountWithProviders(); - - accordionTitleContainer() - .should("have.attr", "aria-expanded", state) - .and(visibility); - }); - - it.each([ - ["white", "rgb(255, 255, 255)", "be.visible"], - ["transparent", "rgba(0, 0, 0, 0)", "be.visible"], - ])("should check Accordion scheme is %s", (scheme, colour) => { - CypressMountWithProviders(); - - accordion().should("have.css", "background-color", colour); - }); - - it.each(["700px", "900px", "1100px", "1300px"])( - "should check Accordion width is %s", - (widths) => { - CypressMountWithProviders(); - - accordion().then(($el) => { - assertCssValueIsApproximately($el, "width", parseInt(widths)); - }); - } - ); - - it("should verify Accordion has an error message in the tooltip", () => { - CypressMountWithProviders(); - - accordionIcon().eq(0).click(); - - accordionIcon() - .should("have.attr", "data-element", "error") - .and("have.attr", "type", "error"); - }); - - it("should verify AccordionRow has a warning message in the tooltip", () => { - CypressMountWithProviders(); - - accordionIcon().eq(0).click(); - - accordionIcon() - .should("have.attr", "data-element", "warning") - .and("have.attr", "type", "warning"); - }); - - it("should verify AccordionRow has an info message in the tooltip", () => { - CypressMountWithProviders(); - - accordionIcon().eq(0).click(); - - accordionIcon() - .should("have.attr", "data-element", "info") - .and("have.attr", "type", "info"); - }); - - it.each(["100px", "200px", "300px"])( - "should check accordion heading is a button with width %s", - (widths) => { - CypressMountWithProviders( - - ); - - accordionTitleContainer() - .should("have.css", "width") - .and("contain", widths); - } - ); - - it("should verify accordion title changes when accordion is opened", () => { - CypressMountWithProviders( - - ); - - accordionTitleContainer().should("contain.text", "Closed"); - - accordionIcon().eq(0).click(); - - accordionTitleContainer().should("contain.text", "Open"); - }); - }); - - describe("should render Accordion Grouped component", () => { - it("should move through all grouped accordions using ArrowDown key and check focus when focusRedesignOptOut is true", () => { - CypressMountWithProviders( - , - undefined, - undefined, - { - focusRedesignOptOut: true, - } - ); - - accordionTitleContainer().eq(0).focus(); - accordionTitleContainerByPosition(0) - .parent() - .then(($el) => { - checkGoldenOutline($el); - }) - .and("be.visible"); - - accordionTitleContainer().eq(0).trigger("keydown", keyCode("downarrow")); - accordionTitleContainerByPosition(1) - .parent() - .then(($el) => { - checkGoldenOutline($el); - }) - .and("be.visible"); - - accordionTitleContainer().eq(1).trigger("keydown", keyCode("downarrow")); - accordionTitleContainerByPosition(2) - .parent() - .then(($el) => { - checkGoldenOutline($el); - }) - .and("be.visible"); - }); - - it("should move through all grouped accordions using ArrowDown key and check focus when focusRedesignOptOut is false", () => { - CypressMountWithProviders(); - - accordionTitleContainer().eq(0).focus(); - accordionTitleContainerByPosition(0) - .parent() - .should( - "have.css", - "box-shadow", - "rgb(255, 188, 25) 0px 0px 0px 3px, rgba(0, 0, 0, 0.9) 0px 0px 0px 6px" - ) - .and("be.visible"); - - accordionTitleContainer().eq(0).trigger("keydown", keyCode("downarrow")); - accordionTitleContainerByPosition(1) - .parent() - .should( - "have.css", - "box-shadow", - "rgb(255, 188, 25) 0px 0px 0px 3px, rgba(0, 0, 0, 0.9) 0px 0px 0px 6px" - ) - .and("be.visible"); - - accordionTitleContainer().eq(1).trigger("keydown", keyCode("downarrow")); - accordionTitleContainerByPosition(2) - .parent() - .should( - "have.css", - "box-shadow", - "rgb(255, 188, 25) 0px 0px 0px 3px, rgba(0, 0, 0, 0.9) 0px 0px 0px 6px" - ) - .and("be.visible"); - }); - - it("should move to the last grouped accordion using End key and check it is focused when focusRedesignOptOut is true", () => { - CypressMountWithProviders( - , - undefined, - undefined, - { - focusRedesignOptOut: true, - } - ); - - accordionTitleContainer().eq(0).focus(); - - accordionTitleContainer().eq(0).trigger("keydown", keyCode("End")); - - accordionTitleContainerByPosition(2) - .parent() - .then(($el) => { - checkGoldenOutline($el); - }) - .and("be.visible"); - }); - - it("should move to the last grouped accordion using End key and check it is focused when focusRedesignOptOut is false", () => { - CypressMountWithProviders(); - - accordionTitleContainer().eq(0).focus(); - - accordionTitleContainer().eq(0).trigger("keydown", keyCode("End")); - - accordionTitleContainerByPosition(2) - .parent() - .should( - "have.css", - "box-shadow", - "rgb(255, 188, 25) 0px 0px 0px 3px, rgba(0, 0, 0, 0.9) 0px 0px 0px 6px" - ) - .and("be.visible"); - }); - - it("should move to the first grouped accordion using Home key and check it is focused when focusRedesignOptOut is true", () => { - CypressMountWithProviders( - , - undefined, - undefined, - { - focusRedesignOptOut: true, - } - ); - - accordionTitleContainer().eq(2).focus(); - - accordionTitleContainer().eq(2).trigger("keydown", keyCode("Home")); - - accordionTitleContainerByPosition(0) - .parent() - .then(($el) => { - checkGoldenOutline($el); - }) - .and("be.visible"); - }); - - it("should move to the first grouped accordion using Home key and check it is focused when focusRedesignOptOut is false", () => { - CypressMountWithProviders(); - - accordionTitleContainer().eq(2).focus(); - - accordionTitleContainer().eq(2).trigger("keydown", keyCode("Home")); - - accordionTitleContainerByPosition(0) - .parent() - .should( - "have.css", - "box-shadow", - "rgb(255, 188, 25) 0px 0px 0px 3px, rgba(0, 0, 0, 0.9) 0px 0px 0px 6px" - ) - .and("be.visible"); - }); - }); - - describe("should change content height when children change", () => { - it("should have proper height", () => { - CypressMountWithProviders(); - accordionContent().then(($el) => { - assertCssValueIsApproximately($el, "height", 49); - }); - getDataElementByValue(ACCORDION_ADD_CONTENT).click(); - accordionContent().then(($el) => { - assertCssValueIsApproximately($el, "height", 66); - }); - getDataElementByValue(ACCORDION_ADD_CONTENT).click(); - accordionContent().then(($el) => { - assertCssValueIsApproximately($el, "height", 83); - }); - getDataElementByValue(ACCORDION_REMOVE_CONTENT).click(); - accordionContent().then(($el) => { - assertCssValueIsApproximately($el, "height", 66); - }); - getDataElementByValue(ACCORDION_REMOVE_CONTENT).click(); - accordionContent().then(($el) => { - assertCssValueIsApproximately($el, "height", 49); - }); - }); - }); - - describe("Accessibility tests for Accordion", () => { - it("should pass accessibility tests for AccordionDefault", () => { - CypressMountWithProviders(); - - cy.checkAccessibility(); - }); - - it("should pass accessibility tests for AccordionDefault expanded", () => { - CypressMountWithProviders(); - - cy.checkAccessibility(); - }); - - it("should pass accessibility tests for Accordion with disableContentPadding", () => { - CypressMountWithProviders(); - - cy.checkAccessibility(); - }); - - it("should pass accessibility tests for Accordion transparent", () => { - CypressMountWithProviders(); - - cy.checkAccessibility(); - }); - - it("should pass accessibility tests for Accordion size small", () => { - CypressMountWithProviders(); - - cy.checkAccessibility(); - }); - - it("should pass accessibility tests for Accordion with subTitle", () => { - CypressMountWithProviders(); - - cy.checkAccessibility(); - }); - - it("should pass accessibility tests for Accordion with full borders", () => { - CypressMountWithProviders(); - - cy.checkAccessibility(); - }); - - it("should pass accessibility tests for Accordion with full borders expanded", () => { - CypressMountWithProviders(); - - cy.checkAccessibility(); - }); - - it("should pass accessibility tests for Accordion with left aligned icon", () => { - CypressMountWithProviders(); - - cy.checkAccessibility(); - }); - - it("should pass accessibility tests for Accordion with 500px width", () => { - CypressMountWithProviders(); - - cy.checkAccessibility(); - }); - - it.each([ - [0, 0], - [1, 1], - [2, 2], - [3, 3], - [4, 4], - [5, 5], - [6, 6], - ])( - "should pass accessibility tests for Accordion with margin set to %s and padding set to %s", - (margin, padding) => { - CypressMountWithProviders(); - - cy.checkAccessibility(); - } - ); - - it.each([[0], [1], [2], [3], [4], [5], [6]])( - "should pass accessibility tests for Accordion with title padding set to %s", - (padding) => { - CypressMountWithProviders( - - ); - - cy.checkAccessibility(); - } - ); - - it("should pass accessibility tests for Accordion with Box and different paddings", () => { - CypressMountWithProviders(); - - cy.checkAccessibility(); - }); - - it("should pass accessibility tests for Accordion with opening buttons", () => { - CypressMountWithProviders(); - - cy.checkAccessibility(); - }); - - it("should pass accessibility tests for AccordionGroup", () => { - CypressMountWithProviders(); - - cy.checkAccessibility(); - }); - - it("should pass accessibility tests for AccordionGroupValidation", () => { - CypressMountWithProviders(); - - cy.checkAccessibility(); - }); - - it("should pass accessibility tests for AccordionWithDefinitionList", () => { - CypressMountWithProviders(); - - cy.checkAccessibility(); - }); - }); -}); diff --git a/cypress/locators/accordion/index.js b/cypress/locators/accordion/index.js index 67149d16cc..c9a47a0007 100644 --- a/cypress/locators/accordion/index.js +++ b/cypress/locators/accordion/index.js @@ -1,22 +1,5 @@ -import { - ACCORDION_PREVIEW, - ACCORDION_TITLE_CONTAINER, - ACCORDION_ICON, - ACCORDION_CONTENT, -} from "./locators"; +import { ACCORDION_TITLE_CONTAINER } from "./locators"; // locators -export const accordionTitleContainer = () => - cy.get(ACCORDION_PREVIEW).find(ACCORDION_TITLE_CONTAINER); +// eslint-disable-next-line import/prefer-default-export export const accordionDefaultTitle = () => cy.get(ACCORDION_TITLE_CONTAINER); -export const accordionTitleContainerByPosition = (index) => - cy - .get(ACCORDION_PREVIEW) - .find(ACCORDION_TITLE_CONTAINER) - .eq(index) - .children(); -export const accordionIcon = () => - accordionTitleContainer().find(ACCORDION_ICON); -export const accordionContent = () => - cy.get(ACCORDION_PREVIEW).find(ACCORDION_CONTENT); -export const accordion = () => cy.get(ACCORDION_PREVIEW); diff --git a/cypress/locators/accordion/locators.js b/cypress/locators/accordion/locators.js index 8ce7257cec..35b1cb1436 100644 --- a/cypress/locators/accordion/locators.js +++ b/cypress/locators/accordion/locators.js @@ -1,8 +1,4 @@ // component preview locators -export const ACCORDION_PREVIEW = '[data-component="accordion"]'; +// eslint-disable-next-line import/prefer-default-export export const ACCORDION_TITLE_CONTAINER = '[data-element="accordion-title-container"]'; -export const ACCORDION_ICON = '[data-component="icon"]'; -export const ACCORDION_CONTENT = '[data-element="accordion-content"]'; -export const ACCORDION_ADD_CONTENT = "add-content"; -export const ACCORDION_REMOVE_CONTENT = "remove-content"; diff --git a/playwright/components/accordion/index.ts b/playwright/components/accordion/index.ts new file mode 100644 index 0000000000..301d42b33a --- /dev/null +++ b/playwright/components/accordion/index.ts @@ -0,0 +1,43 @@ +import type { Page } from "@playwright/test"; +import { + ACCORDION_PREVIEW, + ACCORDION_TITLE_CONTAINER, + ACCORDION_ICON, + ACCORDION_CONTENT, +} from "./locators"; + +// locators +const accordionTitleContainer = (page: Page) => { + return page.locator(ACCORDION_PREVIEW).locator(ACCORDION_TITLE_CONTAINER); +}; + +const accordionDefaultTitle = (page: Page) => { + return page.locator(ACCORDION_TITLE_CONTAINER); +}; + +const accordionTitleContainerByPosition = (page: Page, index: number) => { + return page + .locator(ACCORDION_PREVIEW) + .locator(`${ACCORDION_TITLE_CONTAINER}:nth-child(${index + 1}) > *`); +}; + +const accordionIcon = (page: Page) => { + return accordionTitleContainer(page).locator(ACCORDION_ICON); +}; + +const accordionContent = (page: Page) => { + return page.locator(ACCORDION_PREVIEW).locator(ACCORDION_CONTENT); +}; + +const accordion = (page: Page) => { + return page.locator(ACCORDION_PREVIEW); +}; + +export { + accordionTitleContainer, + accordionDefaultTitle, + accordionTitleContainerByPosition, + accordionIcon, + accordionContent, + accordion, +}; diff --git a/playwright/components/accordion/locators.ts b/playwright/components/accordion/locators.ts new file mode 100644 index 0000000000..8ce7257cec --- /dev/null +++ b/playwright/components/accordion/locators.ts @@ -0,0 +1,8 @@ +// component preview locators +export const ACCORDION_PREVIEW = '[data-component="accordion"]'; +export const ACCORDION_TITLE_CONTAINER = + '[data-element="accordion-title-container"]'; +export const ACCORDION_ICON = '[data-component="icon"]'; +export const ACCORDION_CONTENT = '[data-element="accordion-content"]'; +export const ACCORDION_ADD_CONTENT = "add-content"; +export const ACCORDION_REMOVE_CONTENT = "remove-content"; diff --git a/playwright/components/index.ts b/playwright/components/index.ts index 6e41f91018..06a3ffb2f7 100644 --- a/playwright/components/index.ts +++ b/playwright/components/index.ts @@ -1,8 +1,10 @@ import type { Page } from "@playwright/test"; import { ICON } from "./locators"; -const icon = (page: Page) => { +export const icon = (page: Page) => { return page.locator(ICON); }; -export default icon; +export const getDataElementByValue = (page: Page, element: string) => { + return page.locator(`[data-element="${element}"]`); +}; diff --git a/playwright/support/helper.ts b/playwright/support/helper.ts index 549dfed8b8..c3d6167c25 100644 --- a/playwright/support/helper.ts +++ b/playwright/support/helper.ts @@ -143,3 +143,48 @@ export const containsClass = async ( await expect(locatorFunc).toHaveClass(classNameRegEx); }; + +const positions = { + first: 0, + second: 1, + third: 2, + fourth: 3, + fifth: 4, + sixth: 5, + seventh: 6, + eighth: 7, + ninth: 8, + tenth: 9, + eleventh: 10, + thirteenth: 12, +}; + +export function positionOfElement(type: keyof typeof positions): number { + return positions[type]; +} + +/** + * Converts from a "matrix(a, b, c, d, e, f)" string output from a CSS transform: rotate + * to the actual rotation angle, while accounting for rounding errors in the calculation. + * Adapted from https://css-tricks.com/get-value-of-css-rotation-through-javascript/ */ +export function getRotationAngle(cssTransformString: string) { + const matrixValues = cssTransformString + .split("(")[1] + .split(")")[0] + .split(",") + .map(Number); + const [a, b] = matrixValues; + const angleInRadians = Math.atan2(b, a); + const angleInDegrees = angleInRadians * (180 / Math.PI); + return Math.round(angleInDegrees); +} + +export const assertCssValueIsApproximately = async ( + element: Locator, + cssProp: string, + value: number +) => { + const val = await getStyle(element, cssProp); + expect(parseInt(val)).toBeGreaterThanOrEqual(value - 2); + expect(parseInt(val)).toBeLessThanOrEqual(value + 2); +}; diff --git a/src/components/accordion/accordion.pw.tsx b/src/components/accordion/accordion.pw.tsx new file mode 100644 index 0000000000..10cdb8ffb9 --- /dev/null +++ b/src/components/accordion/accordion.pw.tsx @@ -0,0 +1,736 @@ +import React from "react"; +import { test, expect } from "@playwright/experimental-ct-react17"; +import { + accordion, + accordionIcon, + accordionTitleContainer, + accordionTitleContainerByPosition, + accordionContent, +} from "../../../playwright/components/accordion"; +import { + positionOfElement, + getRotationAngle, + checkGoldenOutline, + assertCssValueIsApproximately, + getStyle, + expectEventWasCalledOnce, + checkAccessibility, +} from "../../../playwright/support/helper"; +import { getDataElementByValue } from "../../../playwright/components"; +import { + ACCORDION_ADD_CONTENT, + ACCORDION_REMOVE_CONTENT, +} from "../../../playwright/components/accordion/locators"; +import { SIZE, CHARACTERS } from "../../../playwright/support/constants"; +import { HooksConfig } from "../../../playwright"; + +import { + AccordionComponent, + AccordionWithIcon, + AccordionGroupWithError, + AccordionGroupWithWarning, + AccordionGroupWithInfo, + AccordionGroupComponent, + DynamicContent, + AccordionDefault, + AccordionWithBoxAndDifferentPaddings, + AccordionOpeningButton, + AccordionGroupDefault, + AccordionGroupValidation, + AccordionWithDefinitionList, +} from "./components.test-pw"; + +const testData = [CHARACTERS.DIACRITICS, CHARACTERS.SPECIALCHARACTERS]; + +test.describe("when focused", () => { + test("should have the expected styling when the focusRedesignOptOut is false", async ({ + mount, + page, + }) => { + await mount(); + const elementLocator = accordionTitleContainer(page); + const element = await elementLocator; + await element.focus(); + await expect(elementLocator).toHaveCSS( + "box-shadow", + "rgb(255, 188, 25) 0px 0px 0px 3px, rgba(0, 0, 0, 0.9) 0px 0px 0px 6px" + ); + await expect(elementLocator).toHaveCSS( + "outline", + "rgba(0, 0, 0, 0) solid 3px" + ); + }); + + test("should have the expected styling when the focusRedesignOptOut is true", async ({ + mount, + page, + }) => { + await mount(, { + hooksConfig: { focusRedesignOptOut: true }, + }); + const elementLocator = accordionTitleContainer(page); + const element = await elementLocator; + await element.focus(); + await expect(elementLocator).toHaveCSS( + "outline", + "rgb(255, 188, 25) solid 3px" + ); + }); +}); + +test.describe("should render Accordion component", () => { + test("should check AccordionRow is expanded using click", async ({ + mount, + page, + }) => { + await mount(); + + await accordionTitleContainer(page).click(); + + await expect(accordionTitleContainer(page)).toHaveAttribute( + "aria-expanded", + "true" + ); + await expect(accordionTitleContainer(page)).toBeVisible(); + + await expect(accordionContent(page)).toHaveAttribute( + "data-element", + "accordion-content" + ); + await expect(accordionContent(page)).toBeVisible(); + }); + + test("should check AccordionRow is expanded using Enter key", async ({ + mount, + page, + }) => { + await mount(); + + await accordionTitleContainer(page).press("Enter"); + + await expect(accordionTitleContainer(page)).toHaveAttribute( + "aria-expanded", + "true" + ); + await expect(accordionTitleContainer(page)).toBeVisible(); + + await expect(accordionContent(page)).toHaveAttribute( + "data-element", + "accordion-content" + ); + await expect(accordionContent(page)).toBeVisible(); + }); + + (["chevron_down", "dropdown"] as const).forEach((iconType) => { + test(`should set iconType to ${iconType} when Accordion row is closed`, async ({ + page, + mount, + }) => { + await mount(); + + await expect(accordionIcon(page)).toHaveAttribute("type", iconType); + await expect(accordionIcon(page)).toBeVisible(); + const transformValue = await getStyle(accordionIcon(page), "transform"); + await expect(getRotationAngle(transformValue)).toBe(90); + }); + }); + + (["chevron_down", "dropdown"] as const).forEach((iconType) => { + test(`should set iconType to ${iconType} when Accordion row is open`, async ({ + page, + mount, + }) => { + await mount(); + + await accordionTitleContainer(page).click(); + + await expect(accordionIcon(page)).toHaveAttribute("type", iconType); + await expect(accordionIcon(page)).toBeVisible(); + await expect(accordionIcon(page)).toHaveCSS("transform", "none"); + }); + }); + + (["left", "right"] as const).forEach((iconAlign) => { + test(`should set Accordion iconAlign to ${iconAlign}`, async ({ + mount, + page, + }) => { + await mount(); + + const headingContainerLocator = accordionTitleContainerByPosition( + page, + positionOfElement("first") + ); + + await expect(headingContainerLocator.first()).toHaveAttribute( + "data-element", + "accordion-headings-container" + ); + await expect(headingContainerLocator.first()).toBeVisible(); + + if (iconAlign === "right") { + // set by default + await expect(accordionTitleContainer(page)).toHaveCSS( + "justify-content", + "space-between" + ); + await expect(accordionTitleContainer(page)).not.toHaveCSS( + "flex-direction", + "row-reverse" + ); + await expect(headingContainerLocator.first()).toHaveCSS( + "margin-right", + "0px" + ); + } else { + await expect(accordionTitleContainer(page)).toHaveCSS( + "flex-direction", + "row-reverse" + ); + await expect(headingContainerLocator.last()).toHaveCSS( + "margin-right", + "16px" + ); + } + }); + }); + + test("should verify AccordionRow is expanded by clicking on validation icon", async ({ + mount, + page, + }) => { + await mount(); + + await accordionIcon(page).nth(0).click(); + + await expect(accordionTitleContainer(page)).toHaveAttribute( + "aria-expanded", + "true" + ); + await expect(accordionTitleContainer(page)).toBeVisible(); + + await expect(accordionContent(page)).toHaveAttribute( + "data-element", + "accordion-content" + ); + await expect(accordionContent(page)).toBeVisible(); + }); + + [true, false].forEach((isExpanded) => { + test(`should call onChange callback when a click event is triggered and expanded is set to ${isExpanded}`, async ({ + mount, + page, + }) => { + const messages: string[] = []; + + await mount( + { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + messages.push(data); + }} + /> + ); + + await accordionTitleContainer(page).click(); + + await expectEventWasCalledOnce(messages, "onClick"); + }); + }); + + testData.forEach((titleValue) => { + test(`should render Accordion component with ${titleValue} as a title`, async ({ + mount, + page, + }) => { + await mount(); + + await expect(accordionTitleContainer(page)).toContainText(titleValue); + }); + }); + + testData.forEach((titleValue) => { + test(`should render Accordion component with ${titleValue} as a subtitle`, async ({ + mount, + page, + }) => { + await mount(); + + await expect(accordionTitleContainer(page)).toContainText(titleValue); + }); + }); + + ([ + [SIZE.SMALL, 24], + [SIZE.LARGE, 45], + ] as const).forEach(([size, height]) => { + test(`should render Accordion component with ${size} as a size and has height property set to ${height}`, async ({ + mount, + page, + }) => { + await mount(); + + const cssHeight = await getStyle(accordionTitleContainer(page), "height"); + await expect(parseInt(cssHeight)).toBeLessThanOrEqual(height + 1); + await expect(parseInt(cssHeight)).toBeGreaterThanOrEqual(height - 1); + }); + }); + + ([ + ["full", "solid", "rgb(204, 214, 219)"], + ["none", "none", "rgba(0, 0, 0, 0.9)"], + ] as const).forEach(([borderProp, borderStyle, colour]) => { + test(`should render Accordion component with border type '${borderProp}'`, async ({ + mount, + page, + }) => { + await mount(); + + await expect(accordion(page)).toHaveCSS( + "border-bottom-style", + borderStyle + ); + await expect(accordion(page)).toHaveCSS("border-bottom-color", colour); + }); + }); + + [true, false].forEach((state) => { + test(`should render Accordion component with default expanded state '${state}'`, async ({ + mount, + page, + }) => { + await mount(); + + await expect(accordionTitleContainer(page)).toHaveAttribute( + "aria-expanded", + String(state) + ); + await expect(accordionTitleContainer(page)).toBeVisible(); + }); + }); + + [true, false].forEach((state) => { + test(`should render Accordion component with expanded state '${state}'`, async ({ + mount, + page, + }) => { + await mount(); + + await expect(accordionTitleContainer(page)).toHaveAttribute( + "aria-expanded", + String(state) + ); + await expect(accordionTitleContainer(page)).toBeVisible(); + }); + }); + + ([ + ["white", "rgb(255, 255, 255)"], + ["transparent", "rgba(0, 0, 0, 0)"], + ] as const).forEach(([scheme, colour]) => { + test(`should check Accordion scheme is ${scheme}`, async ({ + mount, + page, + }) => { + await mount(); + + await expect(accordion(page)).toHaveCSS("background-color", colour); + }); + }); + + ["700px", "900px", "1100px", "1300px"].forEach((width) => { + test(`should check Accordion width is ${width}`, async ({ + mount, + page, + }) => { + await mount(); + + await assertCssValueIsApproximately( + accordion(page), + "width", + parseInt(width) + ); + }); + }); + + test("should verify Accordion has an error message in the tooltip", async ({ + mount, + page, + }) => { + await mount(); + + await accordionIcon(page).nth(0).click(); + + await expect(accordionIcon(page).nth(0)).toHaveAttribute( + "data-element", + "error" + ); + await expect(accordionIcon(page).nth(0)).toHaveAttribute("type", "error"); + }); + + test("should verify AccordionRow has a warning message in the tooltip", async ({ + mount, + page, + }) => { + await mount(); + + await accordionIcon(page).nth(0).click(); + + await expect(accordionIcon(page).nth(0)).toHaveAttribute( + "data-element", + "warning" + ); + await expect(accordionIcon(page).nth(0)).toHaveAttribute("type", "warning"); + }); + + test("should verify AccordionRow has an info message in the tooltip", async ({ + mount, + page, + }) => { + await mount(); + + await accordionIcon(page).nth(0).click(); + + await expect(accordionIcon(page).nth(0)).toHaveAttribute( + "data-element", + "info" + ); + await expect(accordionIcon(page).nth(0)).toHaveAttribute("type", "info"); + }); + + ["100px", "200px", "300px"].forEach((width) => { + test(`should check accordion heading is a button with width ${width}`, async ({ + mount, + page, + }) => { + await mount( + + ); + + const cssWidth = await getStyle(accordionTitleContainer(page), "width"); + await expect(cssWidth).toContain(width); + }); + }); + + test("should verify accordion title changes when accordion is opened", async ({ + mount, + page, + }) => { + await mount( + + ); + + await expect(accordionTitleContainer(page)).toContainText("Closed"); + + await accordionIcon(page).nth(0).click(); + + await expect(accordionTitleContainer(page)).toContainText("Open"); + }); +}); + +test.describe("should render Accordion Grouped component", () => { + test("should move through all grouped accordions using ArrowDown key and check focus when focusRedesignOptOut is true", async ({ + mount, + page, + }) => { + await mount(, { + hooksConfig: { focusRedesignOptOut: true }, + }); + + await accordionTitleContainer(page).nth(0).focus(); + await checkGoldenOutline(accordionTitleContainer(page).nth(0)); + await expect(accordionTitleContainer(page).nth(0)).toBeVisible(); + + await accordionTitleContainer(page).nth(0).press("ArrowDown"); + await checkGoldenOutline(accordionTitleContainer(page).nth(1)); + await expect(accordionTitleContainer(page).nth(1)).toBeVisible(); + + await accordionTitleContainer(page).nth(1).press("ArrowDown"); + await checkGoldenOutline(accordionTitleContainer(page).nth(2)); + await expect(accordionTitleContainer(page).nth(2)).toBeVisible(); + }); + + test("should move through all grouped accordions using ArrowDown key and check focus when focusRedesignOptOut is false", async ({ + mount, + page, + }) => { + await mount(); + + await accordionTitleContainer(page).nth(0).focus(); + await expect(accordionTitleContainer(page).nth(0)).toHaveCSS( + "box-shadow", + "rgb(255, 188, 25) 0px 0px 0px 3px, rgba(0, 0, 0, 0.9) 0px 0px 0px 6px" + ); + await expect(accordionTitleContainer(page).nth(0)).toBeVisible(); + + await accordionTitleContainer(page).nth(0).press("ArrowDown"); + await expect(accordionTitleContainer(page).nth(1)).toHaveCSS( + "box-shadow", + "rgb(255, 188, 25) 0px 0px 0px 3px, rgba(0, 0, 0, 0.9) 0px 0px 0px 6px" + ); + await expect(accordionTitleContainer(page).nth(1)).toBeVisible(); + + await accordionTitleContainer(page).nth(1).press("ArrowDown"); + await expect(accordionTitleContainer(page).nth(2)).toHaveCSS( + "box-shadow", + "rgb(255, 188, 25) 0px 0px 0px 3px, rgba(0, 0, 0, 0.9) 0px 0px 0px 6px" + ); + await expect(accordionTitleContainer(page).nth(2)).toBeVisible(); + }); + + test("should move to the last grouped accordion using End key and check it is focused when focusRedesignOptOut is true", async ({ + mount, + page, + }) => { + await mount(, { + hooksConfig: { focusRedesignOptOut: true }, + }); + + await accordionTitleContainer(page).nth(0).focus(); + + await accordionTitleContainer(page).nth(0).press("End"); + + await checkGoldenOutline(accordionTitleContainer(page).nth(2)); + await expect(accordionTitleContainer(page).nth(2)).toBeVisible(); + }); + + test("should move to the last grouped accordion using End key and check it is focused when focusRedesignOptOut is false", async ({ + mount, + page, + }) => { + await mount(); + + await accordionTitleContainer(page).nth(0).focus(); + + await accordionTitleContainer(page).nth(0).press("End"); + + await expect(accordionTitleContainer(page).nth(2)).toHaveCSS( + "box-shadow", + "rgb(255, 188, 25) 0px 0px 0px 3px, rgba(0, 0, 0, 0.9) 0px 0px 0px 6px" + ); + await expect(accordionTitleContainer(page).nth(2)).toBeVisible(); + }); + + test("should move to the first grouped accordion using Home key and check it is focused when focusRedesignOptOut is true", async ({ + mount, + page, + }) => { + await mount(, { + hooksConfig: { focusRedesignOptOut: true }, + }); + + await accordionTitleContainer(page).nth(2).focus(); + + await accordionTitleContainer(page).nth(2).press("Home"); + + await checkGoldenOutline(accordionTitleContainer(page).nth(0)); + await expect(accordionTitleContainer(page).nth(2)).toBeVisible(); + }); + + test("should move to the first grouped accordion using Home key and check it is focused when focusRedesignOptOut is false", async ({ + mount, + page, + }) => { + await mount(); + + await accordionTitleContainer(page).nth(2).focus(); + + await accordionTitleContainer(page).nth(2).press("Home"); + + await expect(accordionTitleContainer(page).nth(0)).toHaveCSS( + "box-shadow", + "rgb(255, 188, 25) 0px 0px 0px 3px, rgba(0, 0, 0, 0.9) 0px 0px 0px 6px" + ); + await expect(accordionTitleContainer(page).nth(0)).toBeVisible(); + }); +}); + +test.describe("should change content height when children change", () => { + test("should have proper height", async ({ mount, page }) => { + await mount(); + await assertCssValueIsApproximately(accordionContent(page), "height", 49); + await getDataElementByValue(page, ACCORDION_ADD_CONTENT).click(); + await assertCssValueIsApproximately(accordionContent(page), "height", 66); + await getDataElementByValue(page, ACCORDION_ADD_CONTENT).click(); + await assertCssValueIsApproximately(accordionContent(page), "height", 83); + await getDataElementByValue(page, ACCORDION_REMOVE_CONTENT).click(); + await assertCssValueIsApproximately(accordionContent(page), "height", 66); + await getDataElementByValue(page, ACCORDION_REMOVE_CONTENT).click(); + await assertCssValueIsApproximately(accordionContent(page), "height", 49); + }); +}); + +test.describe("Accessibility tests for Accordion", () => { + test("should pass accessibility tests for AccordionDefault", async ({ + mount, + page, + }) => { + await mount(); + + await checkAccessibility(page); + }); + + test("should pass accessibility tests for AccordionDefault expanded", async ({ + mount, + page, + }) => { + await mount(); + + await checkAccessibility(page); + }); + + test("should pass accessibility tests for Accordion with disableContentPadding", async ({ + mount, + page, + }) => { + await mount(); + + await checkAccessibility(page); + }); + + test("should pass accessibility tests for Accordion transparent", async ({ + mount, + page, + }) => { + await mount(); + + await checkAccessibility(page); + }); + + test("should pass accessibility tests for Accordion size small", async ({ + mount, + page, + }) => { + await mount(); + + await checkAccessibility(page); + }); + + test("should pass accessibility tests for Accordion with subTitle", async ({ + mount, + page, + }) => { + await mount(); + + await checkAccessibility(page); + }); + + test("should pass accessibility tests for Accordion with full borders", async ({ + mount, + page, + }) => { + await mount(); + + await checkAccessibility(page); + }); + + test("should pass accessibility tests for Accordion with full borders expanded", async ({ + mount, + page, + }) => { + await mount(); + + await checkAccessibility(page); + }); + + test("should pass accessibility tests for Accordion with left aligned icon", async ({ + mount, + page, + }) => { + await mount(); + + await checkAccessibility(page); + }); + + test("should pass accessibility tests for Accordion with 500px width", async ({ + mount, + page, + }) => { + await mount(); + + await checkAccessibility(page); + }); + + [ + [0, 0], + [1, 1], + [2, 2], + [3, 3], + [4, 4], + [5, 5], + [6, 6], + ].forEach(([margin, padding]) => { + test(`should pass accessibility tests for Accordion with margin set to ${margin} and padding set to ${padding}`, async ({ + mount, + page, + }) => { + await mount(); + + await checkAccessibility(page); + }); + }); + + [0, 1, 2, 3, 4, 5, 6].forEach((padding) => { + test(`should pass accessibility tests for Accordion with title padding set to ${padding}`, async ({ + mount, + page, + }) => { + await mount( + + ); + + await checkAccessibility(page); + }); + }); + + test("should pass accessibility tests for Accordion with Box and different paddings", async ({ + mount, + page, + }) => { + await mount(); + + await checkAccessibility(page); + }); + + test("should pass accessibility tests for Accordion with opening buttons", async ({ + mount, + page, + }) => { + await mount(); + + await checkAccessibility(page); + }); + + test("should pass accessibility tests for AccordionGroup", async ({ + mount, + page, + }) => { + await mount(); + + await checkAccessibility(page); + }); + + test("should pass accessibility tests for AccordionGroupValidation", async ({ + mount, + page, + }) => { + await mount(); + + await checkAccessibility(page); + }); + + test("should pass accessibility tests for AccordionWithDefinitionList", async ({ + mount, + page, + }) => { + await mount(); + + await checkAccessibility(page); + }); +}); diff --git a/src/components/accordion/components.test-pw.tsx b/src/components/accordion/components.test-pw.tsx new file mode 100644 index 0000000000..d7e53230c5 --- /dev/null +++ b/src/components/accordion/components.test-pw.tsx @@ -0,0 +1,574 @@ +import React from "react"; +import { Accordion, AccordionGroup, AccordionProps } from "."; +import Textbox from "../textbox"; +import Box from "../box"; +import Button from "../button/button.component"; +import { Checkbox } from "../checkbox"; +import { Dl, Dt, Dd } from "../definition-list"; +import Link from "../link/link.component"; + +export const Grouped = () => ( + + + + + + + + + + + + + +
Content
+
Content
+
Content
+
+
+
+); + +const errorVal = "error"; +const warningVal = "warning"; +const infoVal = "info"; + +interface ValidationObject { + one: string; + two: string; + three: string; +} + +type Validations = keyof ValidationObject; + +// stories for component testing +export const AccordionComponent = (props: Partial) => { + return ( + {}} + subTitle="Sub Title" + title="Title" + width="100%" + {...props} + > +
Content
+
Content
+
Content
+
+ ); +}; + +export const AccordionWithIcon = () => { + const [errors] = React.useState({ + one: errorVal, + }); + const [warnings] = React.useState({ + one: warningVal, + }); + + const [expanded, setExpanded] = React.useState({ + one: false, + }); + + return ( + + + setExpanded((previousState) => ({ + ...previousState, + one: !previousState.one, + })) + } + error={errors.one} + warning={warnings.one} + > + + + + ); +}; + +export const AccordionGroupWithError = () => { + const [errors] = React.useState({ + one: errorVal, + two: errorVal, + three: errorVal, + }); + + return ( +
+ + +
+ +
+
+
+
+ ); +}; + +export const AccordionGroupWithWarning = () => { + const [warnings] = React.useState({ + one: warningVal, + }); + + return ( +
+ + +
+ +
+
+
+
+ ); +}; + +export const AccordionGroupWithInfo = () => { + const [infos] = React.useState({ + one: infoVal, + }); + + return ( +
+ + +
+ +
+
+
+
+ ); +}; + +export const AccordionGroupComponent = () => { + return ( + + {}} width="100%"> + + + + + {}} width="100%"> + + + + + {}} width="100%"> +
Content
+
+
+ ); +}; + +export const DynamicContent = () => { + const [contentCount, setContentCount] = React.useState(3); + const modifyContentCount = (modifier: number) => { + if (modifier === 1) { + setContentCount(contentCount + 1); + } + if (modifier === -1 && contentCount > 0) { + setContentCount(contentCount - 1); + } + }; + return ( + <> + + + + {Array.from(Array(contentCount).keys()).map((value) => ( +
Content
+ ))} +
+ + ); +}; + +// stories from storybook to import +export const AccordionDefault = (props: Partial) => { + return ( + +
Content
+
Content
+
Content
+
+ ); +}; + +export const AccordionWithBoxAndDifferentPaddings = () => { + return ( + + + + + This is example content inside of the Box component with gray + background + +
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla in + ornare neque. Maecenas pellentesque et erat tincidunt mollis. Etiam + diam nisi, elementum efficitur ipsum et, imperdiet iaculis ligula. + Cras eget lorem aliquam lorem mollis fringilla a sit amet nisl. + Donec semper odio elit, tempus ultrices est molestie id. Ut sit amet + sollicitudin ipsum, eu tristique ligula. Praesent velit velit, + finibus ut odio sit amet, fringilla iaculis lacus. Aliquam facilisis + libero nec ipsum tincidunt imperdiet. Ut commodo mi ac odio blandit, + ac molestie ante dapibus. Ut molestie auctor turpis, quis ultrices + ante aliquet eu. Aenean et condimentum arcu, non malesuada elit. + Cras a magna vestibulum, semper tortor id, molestie eros. +
+
+
+ + + + This is example content inside of the Box component with gray + background + +
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla in + ornare neque. Maecenas pellentesque et erat tincidunt mollis. Etiam + diam nisi, elementum efficitur ipsum et, imperdiet iaculis ligula. + Cras eget lorem aliquam lorem mollis fringilla a sit amet nisl. + Donec semper odio elit, tempus ultrices est molestie id. Ut sit amet + sollicitudin ipsum, eu tristique ligula. Praesent velit velit, + finibus ut odio sit amet, fringilla iaculis lacus. Aliquam facilisis + libero nec ipsum tincidunt imperdiet. Ut commodo mi ac odio blandit, + ac molestie ante dapibus. Ut molestie auctor turpis, quis ultrices + ante aliquet eu. Aenean et condimentum arcu, non malesuada elit. + Cras a magna vestibulum, semper tortor id, molestie eros. +
+
+
+
+ ); +}; + +export const AccordionOpeningButton = () => { + return ( +
+ +
Content
+
Content
+
Content
+
+
+ +
Content
+
Content
+
Content
+
+
+ +
Content
+
Content
+
Content
+
+
+ +
Content
+
Content
+
Content
+
+
+ ); +}; + +export const AccordionGroupDefault = () => { + return ( + + + + + + + + + + + + + +
Content
+
Content
+
Content
+
+
+
+ ); +}; + +export const AccordionGroupValidation = () => { + const [errors, setErrors] = React.useState({ + one: errorVal, + two: errorVal, + three: errorVal, + }); + const [warnings, setWarnings] = React.useState({ + one: warningVal, + two: warningVal, + three: warningVal, + }); + const [infos, setInfos] = React.useState({ + one: infoVal, + two: infoVal, + three: infoVal, + }); + const [expanded, setExpanded] = React.useState({ + one: false, + two: false, + three: true, + }); + + const handleChange = ( + id: Validations, + type: ValidationObject, + setter: React.Dispatch>, + msg: string + ) => { + const update = type[id] ? undefined : msg; + setter((previous: ValidationObject) => ({ ...previous, [id]: update })); + }; + + return ( + + + + setExpanded((previousState) => ({ + ...previousState, + one: !previousState.one, + })) + } + error={errors.one} + warning={warnings.one} + info={infos.one} + > +
+ handleChange("one", errors, setErrors, "error")} + checked={!!errors.one} + /> + + handleChange("one", warnings, setWarnings, "warning") + } + /> + handleChange("one", infos, setInfos, "info")} + /> +
+
+ + setExpanded((previousState) => ({ + ...previousState, + two: !previousState.two, + })) + } + subTitle="Sub title" + error={errors.two} + warning={warnings.two} + info={infos.two} + > +
+ handleChange("two", errors, setErrors, "error")} + checked={!!errors.two} + /> + + handleChange("two", warnings, setWarnings, "warning") + } + /> + handleChange("two", infos, setInfos, "info")} + /> +
+
+ + setExpanded((previousState) => ({ + ...previousState, + three: !previousState.three, + })) + } + subTitle="This is a longer sub title" + error={errors.three} + warning={warnings.three} + info={infos.three} + > +
+ handleChange("three", errors, setErrors, "error")} + checked={!!errors.three} + /> + + handleChange("three", warnings, setWarnings, "warning") + } + /> + handleChange("three", infos, setInfos, "info")} + /> +
+
+
+
+ ); +}; + +export const AccordionWithDefinitionList = () => { + return ( + +
+
Drink
+
Coffee
+
Brew Method
+
Stove Top Moka Pot
+
Brand of Coffee
+
Magic Coffee Beans
+
Website
+
+ Magic Coffee Beans Website +
+
Email
+
+ magic@coffeebeans.com +
+
Main and Registered Address
+
Magic Coffee Beans,
+
In The Middle of Our Street,
+
Madness,
+
CO4 3VE
+
+ +
+
+
+ ); +}; diff --git a/src/components/button-bar/button-bar.pw.tsx b/src/components/button-bar/button-bar.pw.tsx index cb2202c53b..7af502c2d2 100644 --- a/src/components/button-bar/button-bar.pw.tsx +++ b/src/components/button-bar/button-bar.pw.tsx @@ -15,7 +15,7 @@ import { buttonDataComponent, buttonMinorComponent, } from "../../../playwright/components/button/index"; -import icon from "../../../playwright/components/index"; +import { icon } from "../../../playwright/components/index"; import { checkAccessibility, getStyle, diff --git a/src/components/detail/detail.pw.tsx b/src/components/detail/detail.pw.tsx index eeaa82a6f6..621e66d424 100644 --- a/src/components/detail/detail.pw.tsx +++ b/src/components/detail/detail.pw.tsx @@ -7,7 +7,7 @@ import { footnotePreview, } from "../../../playwright/components/detail/index"; -import icon from "../../../playwright/components/index"; +import { icon } from "../../../playwright/components/index"; import { CHARACTERS } from "../../../cypress/support/component-helper/constants"; import { checkAccessibility } from "../../../playwright/support/helper";