diff --git a/cypress/components/pill/pill.cy.tsx b/cypress/components/pill/pill.cy.tsx
deleted file mode 100644
index 0b8e90cb52..0000000000
--- a/cypress/components/pill/pill.cy.tsx
+++ /dev/null
@@ -1,392 +0,0 @@
-import React from "react";
-import Pill, { PillProps } from "../../../src/components/pill";
-import { PillComponent } from "../../../src/components/pill/pill-test.stories";
-import { pillPreview, pillCloseIcon } from "../../locators/pill/index";
-import CypressMountWithProviders from "../../support/component-helper/cypress-mount";
-import { checkOutlineCss } from "../../support/component-helper/common-steps";
-import { closeIconButton } from "../../locators/index";
-import { CHARACTERS } from "../../support/component-helper/constants";
-
-const specialCharacters = [CHARACTERS.DIACRITICS, CHARACTERS.SPECIALCHARACTERS];
-const testData = CHARACTERS.STANDARD;
-const warning = "rgb(242, 133, 51)";
-const neutral = "rgb(51, 91, 112)";
-const negative = "rgb(203, 55, 74)";
-const positive = "rgb(0, 138, 33)";
-const tag = "rgb(0, 126, 69)";
-const status = "rgb(51, 91, 112)";
-const transparent = "rgba(0, 0, 0, 0)";
-const colorsSemanticCaution500 = "rgb(239, 103, 0)";
-const blackOpacity65 = "rgba(0, 0, 0, 0.65)";
-const brilliantGreenShade20 = "rgb(0, 176, 0)";
-const red = "rgb(255, 0, 0)";
-const hexBlue = "#123456";
-const green = "rgb(0, 123, 10)";
-const small = "S";
-const medium = "M";
-const large = "L";
-const extraLarge = "XL";
-
-context("Testing Pill component", () => {
- describe("when focused", () => {
- it.each(["S", "M", "L", "XL"] as PillProps["size"][])(
- "should have the expected styling when size is %s and focusRedesignOptOut is false",
- (size) => {
- CypressMountWithProviders(
- {}}>
- Pill
-
- );
-
- pillCloseIcon()
- .focus()
- .then(() => {
- pillCloseIcon()
- .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.each(["S", "M", "L", "XL"] as PillProps["size"][])(
- "should have the expected styling when size is %s and focusRedesignOptOut is true",
- (size) => {
- CypressMountWithProviders(
- {}}>
- Pill
- ,
- undefined,
- undefined,
- {
- focusRedesignOptOut: true,
- }
- );
- pillCloseIcon()
- .focus()
- .then(() => {
- pillCloseIcon().should(
- "have.css",
- "box-shadow",
- "rgb(255, 188, 25) 0px 0px 0px 3px"
- );
- });
- }
- );
- });
-
- describe("should render Pill component with props", () => {
- it.each(specialCharacters)(
- "should render Pill using %s as label",
- (label) => {
- CypressMountWithProviders({label});
-
- pillPreview().should("have.text", label);
- }
- );
-
- it.each([
- ["warning", warning],
- ["neutral", neutral],
- ["negative", negative],
- ["positive", positive],
- ] as [PillProps["colorVariant"], string][])(
- "should render Pill component with colorVariant set to %s",
- (color, output) => {
- CypressMountWithProviders(
-
- Pill
-
- );
-
- pillPreview()
- .then((elem) => {
- checkOutlineCss(elem, 1, "border", "solid", output);
- })
- .should("have.css", "background-color", transparent);
- }
- );
-
- it("should render Pill component with data-element", () => {
- CypressMountWithProviders();
- pillPreview().should("have.attr", "data-element", testData);
- });
-
- it("should render Pill component with data-role", () => {
- CypressMountWithProviders();
- pillPreview().should("have.attr", "data-role", testData);
- });
-
- it.each([
- ["warning", warning],
- ["neutral", neutral],
- ["negative", negative],
- ["positive", positive],
- ] as [PillProps["colorVariant"], string][])(
- "should render Pill component with color fill to %s",
- (color, output) => {
- CypressMountWithProviders(
-
- Pill
-
- );
-
- pillPreview()
- .then((elem) => {
- checkOutlineCss(elem, 1, "border", "solid", output);
- })
- .should("have.css", "background-color", output);
- }
- );
-
- it.each([
- ["tag", tag],
- ["status", status],
- ] as [PillProps["pillRole"], string][])(
- "should render Pill component with pillRole set to %s",
- (role, output) => {
- CypressMountWithProviders(
- {role}
- );
- pillPreview().then((elem) => {
- checkOutlineCss(elem, 1, "border", "solid", output);
- });
- }
- );
-
- it.each([
- [
- "colorsSemanticCaution500",
- colorsSemanticCaution500,
- "rgb(239, 103, 0)",
- ],
- ["blackOpacity65", blackOpacity65, "rgba(0, 0, 0, 0.65)"],
- ["brilliantGreenShade20", brilliantGreenShade20, "rgb(0, 176, 0)"],
- ["red", red, "rgb(255, 0, 0)"],
- ["#123456", hexBlue, "rgb(18, 52, 86)"],
- [green, green, "rgb(0, 123, 10)"],
- ])(
- "should render Pill component with borderColor set to %s",
- (colourDescription, color, output) => {
- CypressMountWithProviders(
-
- Pill
-
- );
-
- pillPreview().then((elem) => {
- checkOutlineCss(elem, 1, "border", "solid", output);
- });
- }
- );
-
- it.each(["20px", "100px"])(
- "should render Pill component with maxWidth set to %s",
- (maxWidth) => {
- CypressMountWithProviders(
- Pill with a long label
- );
-
- pillPreview().should("have.css", "max-width", maxWidth);
- }
- );
-
- it.each([
- [small, "16px", "12px", "0px 8px"],
- [medium, "20px", "14px", "0px 8px"],
- [large, "24px", "14px", "0px 8px"],
- [extraLarge, "28px", "16px", "0px 12px"],
- ] as [PillProps["size"], string, string, string][])(
- "should render Pill component with size set to %s",
- (size, height, fontSize, padding) => {
- CypressMountWithProviders(Pill);
-
- pillPreview()
- .should("have.css", "min-height", height)
- .should("have.css", "line-height", height)
- .should("have.css", "font-size", fontSize)
- .should("have.css", "padding", padding);
- }
- );
-
- it.each([
- [true, "break-spaces"],
- [false, "nowrap"],
- ])(
- "should render Pill component with wrapText set to %s",
- (booleanState, cssValue) => {
- CypressMountWithProviders(
-
- Wrapped pill
-
- );
-
- pillPreview()
- .should("have.text", "Wrapped pill")
- .should("have.css", "white-space", cssValue);
- }
- );
-
- describe("should render Pill component and check events", () => {
- it("should call the delete action after the CloseIcon is clicked", () => {
- const callback: PillProps["onDelete"] = cy.stub().as("onDelete");
-
- CypressMountWithProviders();
-
- closeIconButton().click();
- cy.get("@onDelete").should("have.been.calledOnce");
- });
-
- it("should call the click action after the Pill is clicked", () => {
- const callback: PillProps["onClick"] = cy.stub().as("onClick");
-
- CypressMountWithProviders();
-
- pillPreview().click();
- cy.get("@onClick").should("have.been.calledOnce");
- });
- });
-
- describe("Accessibility tests for Pill component", () => {
- it.each(specialCharacters)(
- "should render Pill using %s as label for accessibility tests",
- (label) => {
- CypressMountWithProviders({label});
-
- cy.checkAccessibility();
- }
- );
-
- it.each([
- "warning",
- "neutral",
- "negative",
- "positive",
- ] as PillProps["colorVariant"][])(
- "should render Pill component with colorVariant set to %s for accessibility tests",
- (color) => {
- CypressMountWithProviders(
-
- Pill
-
- );
- cy.checkAccessibility();
- }
- );
-
- it("should render Pill component with data-element for accessibility tests", () => {
- CypressMountWithProviders();
- cy.checkAccessibility();
- });
-
- it("should render Pill component with data-role for accessibility tests", () => {
- CypressMountWithProviders();
- cy.checkAccessibility();
- });
-
- it.each([
- "warning",
- "neutral",
- "negative",
- "positive",
- ] as PillProps["colorVariant"][])(
- "should render Pill component with color fill to %s for accessibility tests",
- (color) => {
- CypressMountWithProviders(
-
- Pill
-
- );
- cy.checkAccessibility();
- }
- );
-
- it.each(["tag", "status"] as PillProps["pillRole"][])(
- "should render Pill component with pillRole set to %s for accessibility tests",
- (role) => {
- CypressMountWithProviders(
- {role}
- );
- cy.checkAccessibility();
- }
- );
-
- it.each(["20px", "100px"])(
- "should render Pill component with maxWidth set to %s for accessibility tests",
- (maxWidth) => {
- CypressMountWithProviders(
- Pill with a long label
- );
- cy.checkAccessibility();
- }
- );
-
- it.each([small, medium, large, extraLarge] as PillProps["size"][])(
- "should render Pill component with size set to %s for accessibility tests",
- (size) => {
- CypressMountWithProviders(Pill);
- cy.checkAccessibility();
- }
- );
-
- it.each([
- [true, "break-spaces"],
- [false, "nowrap"],
- ])(
- "should render Pill component with wrapText set to %s for accessibility tests",
- (booleanState) => {
- CypressMountWithProviders(
-
- Wrapped pill
-
- );
- cy.checkAccessibility();
- }
- );
-
- it.each([
- colorsSemanticCaution500,
- blackOpacity65,
- brilliantGreenShade20,
- red,
- hexBlue,
- green,
- ])(
- "should render Pill component with borderColor set to %s for accessibility tests",
- (color) => {
- CypressMountWithProviders(
-
- Pill
-
- );
- cy.checkAccessibility();
- }
- );
- });
- });
-
- it.each(["S", "M", "L", "XL"] as PillProps["size"][])(
- "should have the expected border radius styling when size is %s",
- (size) => {
- CypressMountWithProviders(
- {}}>
- Pill
-
- );
- pillPreview().should("have.css", "border-radius", "2px");
- pillCloseIcon().should("have.css", "border-radius", "0px");
- pillCloseIcon()
- .focus()
- .then(() => {
- pillCloseIcon().should(
- "have.css",
- "border-radius",
- "0px 2px 2px 0px"
- );
- });
- }
- );
-});
diff --git a/playwright/components/pill/index.ts b/playwright/components/pill/index.ts
index bebb06ef8b..ea7e5cec62 100644
--- a/playwright/components/pill/index.ts
+++ b/playwright/components/pill/index.ts
@@ -1,7 +1,6 @@
import { Page } from "playwright-core";
-import PILL_CLOSE_ICON from "./locators";
+import { PILL_PREVIEW, PILL_CLOSE_ICON } from "./locators";
// component preview locators
-const pillCloseIcon = (page: Page) => page.locator(PILL_CLOSE_ICON);
-
-export default pillCloseIcon;
+export const pillPreview = (page: Page) => page.locator(PILL_PREVIEW);
+export const pillCloseIcon = (page: Page) => page.locator(PILL_CLOSE_ICON);
diff --git a/playwright/components/pill/locators.ts b/playwright/components/pill/locators.ts
index 5c38b0af5b..df7ebdb5de 100644
--- a/playwright/components/pill/locators.ts
+++ b/playwright/components/pill/locators.ts
@@ -1,4 +1,3 @@
// component preview locators
-const PILL_CLOSE_ICON = '[data-element="close"]';
-
-export default PILL_CLOSE_ICON;
+export const PILL_PREVIEW = '[data-component="pill"]';
+export const PILL_CLOSE_ICON = '[data-element="close"]';
diff --git a/src/components/pill/components.test-pw.tsx b/src/components/pill/components.test-pw.tsx
new file mode 100644
index 0000000000..fe7ea958a5
--- /dev/null
+++ b/src/components/pill/components.test-pw.tsx
@@ -0,0 +1,8 @@
+import React from "react";
+import Pill, { PillProps } from ".";
+
+const PillComponent = ({ children = "noop", ...args }: Partial) => {
+ return {children};
+};
+
+export default PillComponent;
diff --git a/src/components/pill/pill.pw.tsx b/src/components/pill/pill.pw.tsx
new file mode 100644
index 0000000000..1939d2182a
--- /dev/null
+++ b/src/components/pill/pill.pw.tsx
@@ -0,0 +1,412 @@
+import React from "react";
+import { test, expect } from "@playwright/experimental-ct-react17";
+import PillComponent from "./components.test-pw";
+import Pill, { PillProps } from ".";
+import {
+ pillPreview,
+ pillCloseIcon,
+} from "../../../playwright/components/pill";
+import {
+ checkCSSOutline,
+ checkAccessibility,
+} from "../../../playwright/support/helper";
+import { CHARACTERS } from "../../../playwright/support/constants";
+
+const specialCharacters = [CHARACTERS.DIACRITICS, CHARACTERS.SPECIALCHARACTERS];
+const testData = CHARACTERS.STANDARD;
+const warning = "rgb(242, 133, 51)";
+const neutral = "rgb(51, 91, 112)";
+const negative = "rgb(203, 55, 74)";
+const positive = "rgb(0, 138, 33)";
+const tag = "rgb(0, 126, 69)";
+const status = "rgb(51, 91, 112)";
+const transparent = "rgba(0, 0, 0, 0)";
+const colorsSemanticCaution500 = "rgb(239, 103, 0)";
+const blackOpacity65 = "rgba(0, 0, 0, 0.65)";
+const brilliantGreenShade20 = "rgb(0, 176, 0)";
+const red = "rgb(255, 0, 0)";
+const hexBlue = "#123456";
+const green = "rgb(0, 123, 10)";
+const small = "S";
+const medium = "M";
+const large = "L";
+const extraLarge = "XL";
+
+test.describe("should render Pill component with props", () => {
+ specialCharacters.forEach((label) => {
+ test(`should render label prop as ${label}`, async ({ mount, page }) => {
+ await mount({label});
+
+ await expect(pillPreview(page)).toHaveText(label);
+ });
+ });
+
+ test(`should render data-element tag prop`, async ({ mount, page }) => {
+ await mount();
+
+ await expect(pillPreview(page)).toHaveAttribute("data-element", testData);
+ });
+
+ test(`should render data-role tag prop`, async ({ mount, page }) => {
+ await mount();
+
+ await expect(pillPreview(page)).toHaveAttribute("data-role", testData);
+ });
+
+ ([
+ ["warning", warning],
+ ["neutral", neutral],
+ ["negative", negative],
+ ["positive", positive],
+ ] as const).forEach(([color, output]) => {
+ test(`should render colorVariant prop as ${color}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await checkCSSOutline(
+ pillPreview(page),
+ "2px",
+ "border",
+ "solid",
+ output
+ );
+ await expect(pillPreview(page)).toHaveCSS(
+ "background-color",
+ transparent
+ );
+ });
+ });
+
+ ([
+ ["warning", warning],
+ ["neutral", neutral],
+ ["negative", negative],
+ ["positive", positive],
+ ] as const).forEach(([color, output]) => {
+ test(`should render colorVariant with color fill set as ${color}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount(
+
+ );
+
+ await checkCSSOutline(
+ pillPreview(page),
+ "2px",
+ "border",
+ "solid",
+ output
+ );
+ await expect(pillPreview(page)).toHaveCSS("background-color", output);
+ });
+ });
+
+ ([
+ ["tag", tag],
+ ["status", status],
+ ] as [PillProps["pillRole"], string][]).forEach(([role, output]) => {
+ test(`should render pillRole prop set as ${role}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount({role});
+
+ await checkCSSOutline(
+ pillPreview(page),
+ "2px",
+ "border",
+ "solid",
+ output
+ );
+ });
+ });
+
+ ([
+ [colorsSemanticCaution500, "rgb(239, 103, 0)"],
+ [blackOpacity65, "rgba(0, 0, 0, 0.65)"],
+ [brilliantGreenShade20, "rgb(0, 176, 0)"],
+ [red, "rgb(255, 0, 0)"],
+ [green, "rgb(0, 123, 10)"],
+ [hexBlue, "rgb(18, 52, 86)"],
+ ] as const).forEach(([color, output]) => {
+ test(`should render borderColor prop set as ${output}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount(
+
+ Pill
+
+ );
+
+ await checkCSSOutline(
+ pillPreview(page),
+ "2px",
+ "border",
+ "solid",
+ output
+ );
+ });
+ });
+
+ ["20px", "100px"].forEach((maxWidth) => {
+ test(`should render maxWidth prop set to ${maxWidth}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount(Pill with a long label);
+
+ const elementLocator = pillPreview(page);
+ await expect(elementLocator).toHaveCSS("max-width", maxWidth);
+ });
+ });
+
+ ([
+ [small, "16px", "12px", "0px 8px"],
+ [medium, "20px", "14px", "0px 8px"],
+ [large, "24px", "14px", "0px 8px"],
+ [extraLarge, "28px", "16px", "0px 12px"],
+ ] as const).forEach(([size, height, fontSize, padding]) => {
+ test(`should render size prop set as ${size}`, async ({ mount, page }) => {
+ await mount(Pill);
+
+ const elementLocator = pillPreview(page);
+ await expect(elementLocator).toHaveCSS("min-height", height);
+ await expect(elementLocator).toHaveCSS("line-height", height);
+ await expect(elementLocator).toHaveCSS("font-size", fontSize);
+ await expect(elementLocator).toHaveCSS("padding", padding);
+ });
+ });
+
+ ([
+ [true, "break-spaces"],
+ [false, "nowrap"],
+ ] as const).forEach(([booleanState, cssValue]) => {
+ test(`should render wrapText prop set as ${booleanState}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount(
+
+ Wrapped pill
+
+ );
+
+ const elementLocator = pillPreview(page);
+ await expect(elementLocator).toHaveText("Wrapped pill");
+ await expect(elementLocator).toHaveCSS("white-space", cssValue);
+ });
+ });
+});
+
+test.describe("should check focus outlines and border radius", () => {
+ ([small, medium, large, extraLarge] as PillProps["size"][]).forEach(
+ (size) => {
+ test(`should have the expected styling when size is ${size} and focusRedesignOptOut is false`, async ({
+ mount,
+ page,
+ }) => {
+ await mount(
+ {}}>
+ Pill
+
+ );
+
+ const elementLocator = pillCloseIcon(page);
+ await elementLocator.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"
+ );
+ });
+ }
+ );
+
+ ([small, medium, large, extraLarge] as PillProps["size"][]).forEach(
+ (size) => {
+ test(`should have the expected styling when size is ${size} and focusRedesignOptOut is true`, async ({
+ mount,
+ page,
+ }) => {
+ await mount(
+ {}}>
+ Pill
+ ,
+ {
+ hooksConfig: { focusRedesignOptOut: true },
+ }
+ );
+
+ const elementLocator = pillCloseIcon(page);
+ await elementLocator.focus();
+ await expect(elementLocator).toHaveCSS(
+ "box-shadow",
+ "rgb(255, 188, 25) 0px 0px 0px 3px"
+ );
+ });
+ }
+ );
+
+ ([small, medium, large, extraLarge] as PillProps["size"][]).forEach(
+ (size) => {
+ test(`should have the expected border radius styling when size is ${size}`, async ({
+ mount,
+ page,
+ }) => {
+ await mount(
+ {}}>
+ Pill
+
+ );
+
+ const pillPreviewLocator = pillPreview(page);
+ await expect(pillPreviewLocator).toHaveCSS("border-radius", "2px");
+
+ const elementLocator = pillCloseIcon(page);
+ await expect(elementLocator).toHaveCSS("border-radius", "0px");
+ await elementLocator.focus();
+ await expect(elementLocator).toHaveCSS(
+ "border-radius",
+ "0px 2px 2px 0px"
+ );
+ });
+ }
+ );
+});
+
+test.describe("should check for action events", () => {
+ test(`should call the delete action after the CloseIcon is clicked`, async ({
+ mount,
+ page,
+ }) => {
+ let callbackCount = 0;
+ await mount(
+ {
+ callbackCount += 1;
+ }}
+ />
+ );
+
+ const cross = pillCloseIcon(page);
+ await cross.click();
+ expect(callbackCount).toBe(1);
+ });
+
+ test(`should call the click action after the Pill is clicked`, async ({
+ mount,
+ page,
+ }) => {
+ let callbackCount = 0;
+ await mount(
+ {
+ callbackCount += 1;
+ }}
+ />
+ );
+
+ const cross = pillPreview(page);
+ await cross.click();
+ expect(callbackCount).toBe(1);
+ });
+});
+
+test.describe("should check for Accessibility tests", () => {
+ specialCharacters.forEach((label) => {
+ test(`should render label as ${label} for accessibility`, async ({
+ mount,
+ page,
+ }) => {
+ await mount({label});
+
+ await checkAccessibility(page);
+ });
+ });
+
+ (["warning", "neutral", "negative", "positive"] as const).forEach((color) => {
+ test(`should render colorVariant as ${color} for accessibility`, async ({
+ mount,
+ page,
+ }) => {
+ await mount();
+
+ await checkAccessibility(page);
+ });
+ });
+
+ (["tag", "status"] as const).forEach((role) => {
+ test(`should render pillRole prop set as ${role} for accessibility`, async ({
+ mount,
+ page,
+ }) => {
+ await mount({role});
+
+ await checkAccessibility(page);
+ });
+ });
+
+ (["warning", "neutral", "negative", "positive"] as const).forEach((color) => {
+ test(`should render colorVariant with fill color as ${color} for accessibility`, async ({
+ mount,
+ page,
+ }) => {
+ await mount(
+
+ );
+
+ await checkAccessibility(page);
+ });
+ });
+
+ ["20px", "100px"].forEach((maxWidth) => {
+ test(`should render maxWidth prop set as ${maxWidth} for accessibility`, async ({
+ mount,
+ page,
+ }) => {
+ await mount(Pill with a long label);
+
+ await checkAccessibility(page);
+ });
+ });
+
+ ([small, medium, large, extraLarge] as const).forEach((size) => {
+ test(`should render size prop set as ${size} for accessibility`, async ({
+ mount,
+ page,
+ }) => {
+ await mount(Pill);
+
+ await checkAccessibility(page);
+ });
+ });
+
+ ([
+ colorsSemanticCaution500,
+ blackOpacity65,
+ brilliantGreenShade20,
+ red,
+ hexBlue,
+ green,
+ ] as const).forEach((color) => {
+ test(`should render borderColor set as ${color} for accessibility`, async ({
+ mount,
+ page,
+ }) => {
+ await mount(
+
+ Pill
+
+ );
+
+ await checkAccessibility(page);
+ });
+ });
+});