Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[POC]Integrate a11y scan into E2E tests #2096

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
575 changes: 304 additions & 271 deletions e2e/scripts/pageHelpers.js

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions e2e/scripts/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,22 @@ const generateUserCredentials = function () {
return user;
};

// https://playwright.dev/docs/accessibility-testing#using-snapshots-to-allow-specific-known-issues
function createViolationFingerprints(accessibilityScanResults) {
const violationFingerprints = accessibilityScanResults.violations.map(
(violation) => ({
rule: violation.id,
// These are CSS selectors which uniquely identify each element with
// a violation of the rule in question.
targets: violation.nodes.map((node) => node.target),
})
);

return JSON.stringify(violationFingerprints, null, 2);
}

module.exports = {
createViolationFingerprints,
isPrompt,
mkdirIfNotExists,
diffArrays,
Expand Down
79 changes: 66 additions & 13 deletions e2e/tests/desktop/guest-shopper.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,43 @@
const { test, expect } = require("@playwright/test");
const {
generateUserCredentials,
createViolationFingerprints,
} = require("../../scripts/utils.js");
const { addProductToCart, searchProduct, checkoutProduct } = require("../../scripts/pageHelpers.js")
const {
addProductToCart,
searchProduct,
checkoutProduct,
} = require("../../scripts/pageHelpers.js");
const config = require("../../config");
const AxeBuilder = require("@axe-core/playwright").default; // 1

const GUEST_USER_CREDENTIALS = generateUserCredentials();

test.describe("HomePage accessibility", () => {
test("should not have any automatically detectable accessibility issues except the known issues", async ({
page,
}) => {
await page.goto(config.RETAIL_APP_HOME);
// wait til product tiles are fully load before analyzing
await expect(
page.getByRole("link", { name: /Denim slim skirt/i })
).toBeVisible();
const accessibilityScanResults = await new AxeBuilder({
page,
}).analyze();

expect(
createViolationFingerprints(accessibilityScanResults)
).toMatchSnapshot("HomePage-a11y-snapshot");
});
});

/**
* Test that guest shoppers can add a product to cart and go through the entire checkout process,
* validating that shopper is able to get to the order summary section
*/
test("Guest shopper can checkout items as guest", async ({ page }) => {
await addProductToCart({page})
await addProductToCart({ page });

// cart
await page.getByLabel(/My cart/i).click();
Expand All @@ -27,7 +53,15 @@ test("Guest shopper can checkout items as guest", async ({ page }) => {
page.getByRole("link", { name: /Cotton Turtleneck Sweater/i })
).toBeVisible();

await checkoutProduct({page, userCredentials: GUEST_USER_CREDENTIALS });
const accessibilityScanResults = await new AxeBuilder({
page,
}).analyze();

expect(createViolationFingerprints(accessibilityScanResults)).toMatchSnapshot(
["Guest-cart-a11y-snapshots", "landing"]
);

await checkoutProduct({ page, userCredentials: GUEST_USER_CREDENTIALS });

await expect(
page.getByRole("heading", { name: /Order Summary/i })
Expand All @@ -42,7 +76,7 @@ test("Guest shopper can checkout items as guest", async ({ page }) => {
* Test that guest shoppers can use the product edit modal on cart page
*/
test("Guest shopper can edit product item in cart", async ({ page }) => {
await addProductToCart({page});
await addProductToCart({ page });

// cart
await page.getByLabel(/My cart/i).click();
Expand All @@ -65,26 +99,35 @@ test("Guest shopper can edit product item in cart", async ({ page }) => {
await page.waitForLoadState();

// Product edit modal should be open
await expect(page.getByTestId('product-view')).toBeVisible();
await expect(page.getByTestId("product-view")).toBeVisible();

await page.getByRole("radio", { name: "S", exact: true }).click();
await page.getByRole("radio", { name: "Meadow Violet", exact: true }).click();
await page.getByRole("button", { name: /Update/i }).click();

await page.waitForLoadState();
await expect(page.getByText(/Color: Meadow Violet/i)).toBeVisible();
await expect(page.getByText(/Size: S/i)).toBeVisible();
const accessibilityScanResults = await new AxeBuilder({
page,
}).analyze();

expect(createViolationFingerprints(accessibilityScanResults)).toMatchSnapshot(
["Guest-cart-a11y-snapshots", "editing-item"]
);
});

/**
* Test that guest shoppers can add product bundle to cart and successfully checkout
*/
test("Guest shopper can checkout product bundle", async ({ page }) => {
await searchProduct({page, query: 'bundle'});
await searchProduct({ page, query: "bundle" });

await page.getByRole("link", {
name: /Turquoise Jewelry Bundle/i,
}).click();
await page
.getByRole("link", {
name: /Turquoise Jewelry Bundle/i,
})
.click();

await page.waitForLoadState();

Expand All @@ -108,15 +151,23 @@ test("Guest shopper can checkout product bundle", async ({ page }) => {
// bundle child selections with all color gold
await expect(page.getByText(/Turquoise and Gold Bracelet/i)).toBeVisible();
await expect(page.getByText(/Turquoise and Gold Necklace/i)).toBeVisible();
await expect(page.getByText(/Turquoise and Gold Hoop Earring/i)).toBeVisible();
await expect(
page.getByText(/Turquoise and Gold Hoop Earring/i)
).toBeVisible();

const qtyText = page.locator('text="Qty: 1"');
const colorGoldText = page.locator('text="Color: Gold"');
await expect(colorGoldText).toHaveCount(3);
await expect(qtyText).toHaveCount(3);

await checkoutProduct({page, userCredentials: GUEST_USER_CREDENTIALS });
await checkoutProduct({ page, userCredentials: GUEST_USER_CREDENTIALS });
const accessibilityScanResults = await new AxeBuilder({
page,
}).analyze();

expect(createViolationFingerprints(accessibilityScanResults)).toMatchSnapshot(
["Checkout-a11y-snapshots", "bundle-checkout"]
);
await expect(
page.getByRole("heading", { name: /Order Summary/i })
).toBeVisible();
Expand All @@ -126,5 +177,7 @@ test("Guest shopper can checkout product bundle", async ({ page }) => {
).toBeVisible();
await expect(page.getByText(/Turquoise and Gold Bracelet/i)).toBeVisible();
await expect(page.getByText(/Turquoise and Gold Necklace/i)).toBeVisible();
await expect(page.getByText(/Turquoise and Gold Hoop Earring/i)).toBeVisible();
await expect(
page.getByText(/Turquoise and Gold Hoop Earring/i)
).toBeVisible();
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
[
{
"rule": "aria-allowed-attr",
"targets": [
[
"#popover-trigger-\\:r3g\\:"
]
]
},
{
"rule": "color-contrast",
"targets": [
[
".css-a4jxtg"
]
]
},
{
"rule": "listitem",
"targets": [
[
".css-427wse:nth-child(1)"
],
[
".css-427wse:nth-child(2)"
],
[
".css-427wse:nth-child(3)"
]
]
},
{
"rule": "region",
"targets": [
[
"#popover-trigger-\\:r3g\\: > .css-1igwmid.chakra-stack > .chakra-input__group.css-1y0e7gb[data-group=\"true\"] > .css-va76oz[autocomplete=\"off\"][type=\"search\"]"
]
]
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
[
{
"rule": "aria-allowed-attr",
"targets": [
[
"#popover-trigger-\\:r3g\\:"
]
]
},
{
"rule": "color-contrast",
"targets": [
[
".css-a4jxtg"
]
]
},
{
"rule": "listitem",
"targets": [
[
".css-427wse:nth-child(1)"
],
[
".css-427wse:nth-child(2)"
],
[
".css-427wse:nth-child(3)"
]
]
},
{
"rule": "region",
"targets": [
[
"#popover-trigger-\\:r3g\\: > .css-1igwmid.chakra-stack > .chakra-input__group.css-1y0e7gb[data-group=\"true\"] > .css-va76oz[autocomplete=\"off\"][type=\"search\"]"
]
]
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
[
{
"rule": "aria-prohibited-attr",
"targets": [
[
"div[aria-label=\"7.99\"]"
]
]
},
{
"rule": "listitem",
"targets": [
[
".css-427wse:nth-child(1)"
],
[
".css-427wse:nth-child(2)"
],
[
".css-427wse:nth-child(3)"
]
]
},
{
"rule": "page-has-heading-one",
"targets": [
[
"html"
]
]
},
{
"rule": "region",
"targets": [
[
".css-1k2aozt"
]
]
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[
{
"rule": "aria-allowed-attr",
"targets": [
[
"#popover-trigger-\\:Rd95aqeqlbpH1\\:"
]
]
},
{
"rule": "listitem",
"targets": [
[
".css-427wse:nth-child(1)"
],
[
".css-427wse:nth-child(2)"
],
[
".css-427wse:nth-child(3)"
]
]
},
{
"rule": "region",
"targets": [
[
"#popover-trigger-\\:Rd95aqeqlbpH1\\: > .css-1igwmid.chakra-stack > .chakra-input__group.css-1y0e7gb[data-group=\"true\"] > .css-va76oz[type=\"search\"][aria-label=\"Search for products...\"]"
]
]
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[
{
"rule": "aria-allowed-attr",
"targets": [
[
"#popover-trigger-\\:Rd95aqeqlbpH1\\:"
]
]
},
{
"rule": "listitem",
"targets": [
[
".css-427wse:nth-child(1)"
],
[
".css-427wse:nth-child(2)"
],
[
".css-427wse:nth-child(3)"
]
]
},
{
"rule": "region",
"targets": [
[
"#popover-trigger-\\:Rd95aqeqlbpH1\\: > .css-1igwmid.chakra-stack > .chakra-input__group.css-1y0e7gb[data-group=\"true\"] > .css-va76oz[type=\"search\"][aria-label=\"Search for products...\"]"
]
]
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[
{
"rule": "aria-allowed-attr",
"targets": [
[
"#popover-trigger-\\:Rd95aqeqlbpH1\\:"
]
]
},
{
"rule": "listitem",
"targets": [
[
".css-427wse:nth-child(1)"
],
[
".css-427wse:nth-child(2)"
],
[
".css-427wse:nth-child(3)"
]
]
},
{
"rule": "region",
"targets": [
[
"#popover-trigger-\\:Rd95aqeqlbpH1\\: > .css-1igwmid.chakra-stack > .chakra-input__group.css-1y0e7gb[data-group=\"true\"] > .css-va76oz[autocomplete=\"off\"][type=\"search\"]"
]
]
}
]
Loading
Loading