Files
clawfort/e2e/tests/capabilities/accessibility/modal.spec.ts
2026-02-13 16:57:45 -05:00

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");
});
});