174 lines
5.0 KiB
TypeScript
174 lines
5.0 KiB
TypeScript
import { SELECTORS } from "../../fixtures/selectors";
|
|
import { expect, test } from "../../fixtures/test";
|
|
|
|
test.describe("Policy Modal Accessibility @smoke", () => {
|
|
test.beforeEach(async ({ gotoApp, waitForAppReady }) => {
|
|
await gotoApp();
|
|
await waitForAppReady();
|
|
});
|
|
|
|
test("terms modal opens and has correct ARIA attributes", async ({
|
|
page,
|
|
}) => {
|
|
// Click terms link
|
|
const termsLink = page.locator(SELECTORS.footer.termsLink);
|
|
await termsLink.click();
|
|
|
|
// Modal should be visible
|
|
const modal = page.locator(SELECTORS.policyModal.root);
|
|
await expect(modal).toBeVisible();
|
|
|
|
// Check ARIA attributes
|
|
await expect(modal).toHaveAttribute("role", "dialog");
|
|
await expect(modal).toHaveAttribute("aria-modal", "true");
|
|
|
|
// Check aria-label
|
|
const ariaLabel = await modal.getAttribute("aria-label");
|
|
expect(ariaLabel).toMatch(/Terms|Attribution/);
|
|
});
|
|
|
|
test("attribution modal opens and has correct ARIA attributes", async ({
|
|
page,
|
|
}) => {
|
|
// Click attribution link
|
|
const attributionLink = page.locator(SELECTORS.footer.attributionLink);
|
|
await attributionLink.click();
|
|
|
|
// Modal should be visible
|
|
const modal = page.locator(SELECTORS.policyModal.root);
|
|
await expect(modal).toBeVisible();
|
|
|
|
// Check ARIA attributes
|
|
await expect(modal).toHaveAttribute("role", "dialog");
|
|
await expect(modal).toHaveAttribute("aria-modal", "true");
|
|
});
|
|
|
|
test("policy modal closes with escape key @smoke", async ({ page }) => {
|
|
// Open terms modal
|
|
const termsLink = page.locator(SELECTORS.footer.termsLink);
|
|
await termsLink.click();
|
|
|
|
const modal = page.locator(SELECTORS.policyModal.root);
|
|
await expect(modal).toBeVisible();
|
|
|
|
// Press escape
|
|
await page.keyboard.press("Escape");
|
|
await page.waitForTimeout(500);
|
|
|
|
// Modal should be closed
|
|
await expect(modal).not.toBeVisible();
|
|
});
|
|
|
|
test("policy modal closes with close button", async ({ page }) => {
|
|
// Open terms modal
|
|
const termsLink = page.locator(SELECTORS.footer.termsLink);
|
|
await termsLink.click();
|
|
|
|
const modal = page.locator(SELECTORS.policyModal.root);
|
|
await expect(modal).toBeVisible();
|
|
|
|
// Click close button
|
|
const closeButton = modal.locator(SELECTORS.policyModal.closeButton);
|
|
await closeButton.click();
|
|
|
|
// Modal should be closed
|
|
await expect(modal).not.toBeVisible();
|
|
});
|
|
|
|
test("policy modal closes with backdrop click", async ({ page }) => {
|
|
// Open terms modal
|
|
const termsLink = page.locator(SELECTORS.footer.termsLink);
|
|
await termsLink.click();
|
|
|
|
const modal = page.locator(SELECTORS.policyModal.root);
|
|
await expect(modal).toBeVisible();
|
|
|
|
// Click backdrop
|
|
const backdrop = page.locator(".fixed.inset-0.bg-black\\/70").first();
|
|
await backdrop.click();
|
|
|
|
// Modal should be closed
|
|
await page.waitForTimeout(500);
|
|
await expect(modal).not.toBeVisible();
|
|
});
|
|
|
|
test("focus returns to trigger after closing policy modal @smoke", async ({
|
|
page,
|
|
}) => {
|
|
// Open terms modal
|
|
const termsLink = page.locator(SELECTORS.footer.termsLink);
|
|
await termsLink.click();
|
|
|
|
const modal = page.locator(SELECTORS.policyModal.root);
|
|
await expect(modal).toBeVisible();
|
|
|
|
// Close modal
|
|
await page.keyboard.press("Escape");
|
|
await page.waitForTimeout(500);
|
|
|
|
// Focus should return to terms link
|
|
await expect(termsLink).toBeFocused();
|
|
});
|
|
|
|
test("focus is contained within policy modal", async ({ page }) => {
|
|
// Open terms modal
|
|
const termsLink = page.locator(SELECTORS.footer.termsLink);
|
|
await termsLink.click();
|
|
|
|
const modal = page.locator(SELECTORS.policyModal.root);
|
|
await expect(modal).toBeVisible();
|
|
|
|
// Tab multiple times
|
|
for (let i = 0; i < 10; i++) {
|
|
await page.keyboard.press("Tab");
|
|
|
|
// Check focus is still in modal
|
|
const isInModal = await page.evaluate(() => {
|
|
const modal = document.querySelector('[role="dialog"]');
|
|
const active = document.activeElement;
|
|
return modal?.contains(active);
|
|
});
|
|
|
|
expect(isInModal).toBe(true);
|
|
}
|
|
});
|
|
|
|
test("policy modal content is readable", async ({ page }) => {
|
|
// Open terms modal
|
|
const termsLink = page.locator(SELECTORS.footer.termsLink);
|
|
await termsLink.click();
|
|
|
|
const modal = page.locator(SELECTORS.policyModal.root);
|
|
await expect(modal).toBeVisible();
|
|
|
|
// Check title is present
|
|
const title = modal.locator(SELECTORS.policyModal.termsTitle);
|
|
await expect(title).toBeVisible();
|
|
await expect(title).toContainText("Terms of Use");
|
|
|
|
// Check content is present
|
|
const content = modal.locator(".modal-body-text");
|
|
const paragraphs = await content.locator("p").count();
|
|
expect(paragraphs).toBeGreaterThan(0);
|
|
});
|
|
|
|
test("policy modal has correct heading structure", async ({ page }) => {
|
|
// Open terms modal
|
|
const termsLink = page.locator(SELECTORS.footer.termsLink);
|
|
await termsLink.click();
|
|
|
|
const modal = page.locator(SELECTORS.policyModal.root);
|
|
await expect(modal).toBeVisible();
|
|
|
|
// Should have h2 heading
|
|
const heading = modal.locator("h2");
|
|
await expect(heading).toBeVisible();
|
|
|
|
// Check heading level
|
|
const headingLevel = await heading.evaluate((el) =>
|
|
el.tagName.toLowerCase(),
|
|
);
|
|
expect(headingLevel).toBe("h2");
|
|
});
|
|
});
|