diff --git a/tests/contact-page.spec.js b/tests/contact-page.spec.js new file mode 100644 index 0000000..cb015d9 --- /dev/null +++ b/tests/contact-page.spec.js @@ -0,0 +1,105 @@ +import { expect, test } from "@playwright/test"; +const AxeBuilder = require("@axe-core/playwright").default; + +const contactUrl = + process.env.TEST_CONTACT_URL || + "http://community-works-collaborative.test/contact/"; + +test.describe("contact page", () => { + test("desktop: two-column layout with form area and map placeholder", async ({ + page, + }) => { + const pageErrors = []; + page.on("pageerror", (err) => pageErrors.push(err.message)); + + await page.setViewportSize({ width: 1280, height: 900 }); + await page.goto(contactUrl); + + // No hero on the contact page. + expect(await page.locator(".page-hero").count()).toBe(0); + + // Block renders. + const block = page.locator(".contact-info").first(); + await expect(block).toBeVisible(); + + // Left column has heading, items, and form area. + const heading = page.locator(".contact-info__heading").first(); + await expect(heading).toBeVisible(); + await expect(heading).toHaveText(/contact/i); + + const items = page.locator(".contact-info__item"); + const itemsCount = await items.count(); + expect(itemsCount).toBeGreaterThanOrEqual(1); + + const formArea = page.locator(".contact-info__form").first(); + await expect(formArea).toBeAttached(); + + // Right column has the Leaflet placeholder. + const map = page.locator(".contact-info__map").first(); + await expect(map).toBeAttached(); + await expect(map).toHaveId("contact-map"); + + // No JS errors. + expect(pageErrors).toEqual([]); + }); + + test("mobile 402: single column, map drops below form, no horizontal overflow", async ({ + page, + }) => { + const pageErrors = []; + page.on("pageerror", (err) => pageErrors.push(err.message)); + + await page.setViewportSize({ width: 402, height: 874 }); + await page.goto(contactUrl); + + const details = page.locator(".contact-info__details").first(); + const map = page.locator(".contact-info__map").first(); + + await expect(details).toBeVisible(); + await expect(map).toBeAttached(); + + const detailsBox = await details.boundingBox(); + const mapBox = await map.boundingBox(); + + expect(detailsBox).not.toBeNull(); + expect(mapBox).not.toBeNull(); + expect(mapBox.x).toBeGreaterThanOrEqual(detailsBox.x - 1); + expect(mapBox.x + mapBox.width).toBeLessThanOrEqual(402 + 3); + + expect(pageErrors).toEqual([]); + }); + + test("mobile 320: nothing clips horizontally", async ({ page }) => { + await page.setViewportSize({ width: 320, height: 800 }); + await page.goto(contactUrl); + + const block = page.locator(".contact-info").first(); + await expect(block).toBeVisible(); + + const blockBox = await block.boundingBox(); + expect(blockBox.x + blockBox.width).toBeLessThanOrEqual(320 + 3); + }); + + test("axe: no violations", async ({ page }, testInfo) => { + await page.setViewportSize({ width: 1280, height: 900 }); + await page.goto(contactUrl); + + const results = await new AxeBuilder({ page }) + .withTags([ + "wcag2a", + "wcag2aa", + "wcag21a", + "wcag21aa", + "wcag22a", + "wcag22aa", + ]) + .analyze(); + + await testInfo.attach("accessibility-scan-results", { + body: JSON.stringify(results, null, 2), + contentType: "application/json", + }); + + expect(results.violations).toEqual([]); + }); +});