import { expect, test } from "@playwright/test"; const expectedPages = [ "/", "/about-us/", "/contact/", "/services/", "/focus-areas/", "/insights/", "/market-intelligence-opportunity-analysis/", "/develop-and-deploy-catalytic-capital/", "/stakeholder-engagement-partnership-development/", "/sustainable-technology-incubation/", "/sustainable-business-model-innovation/", "/project-management-implementation/", "/impact-assessment-reporting/", "/policy-advocacy-development/", "/the-economics-of-pfas-remediation/", "/structuring-marine-conservation-finance/", "/sustainable-living-resource-utilization/", "/economic-development-for-island-and-coastal-communities/", ]; test.describe("page rendering", () => { for (const path of expectedPages) { test(`${path} renders meaningful HTML without horizontal overflow`, async ({ page }) => { const response = await page.goto(path); expect(response?.status(), path).toBeLessThan(400); await expect(page.locator("h1")).toBeVisible(); await expect(page.locator("main")).toContainText(/BlueCap|water|capital|aquatic|PFAS|marine/i); const overflow = await page.evaluate( () => document.documentElement.scrollWidth - document.documentElement.clientWidth, ); expect(overflow, `${path} has horizontal overflow`).toBeLessThanOrEqual(1); }); } }); test("all internal href links resolve", async ({ page, request, baseURL }) => { const found = new Set(); for (const path of expectedPages) { await page.goto(path); const links = await page.locator("a[href]").evaluateAll((anchors) => anchors.map((anchor) => (anchor as HTMLAnchorElement).href), ); for (const href of links) { if (href.startsWith("mailto:") || href.startsWith("tel:")) continue; const url = new URL(href); if (url.origin !== baseURL) continue; found.add(`${url.pathname}${url.search}`); } } for (const href of found) { const response = await request.get(href); expect(response.status(), href).toBeLessThan(400); } }); test("desktop navigation and CTA links are clickable", async ({ page }) => { await page.setViewportSize({ width: 1440, height: 900 }); await page.goto("/"); await page.getByRole("link", { name: "Explore services" }).click(); await expect(page).toHaveURL(/\/services\/$/); await expect(page.getByRole("heading", { name: /Advisory services/ })).toBeVisible(); await page.goto("/"); await page.getByRole("link", { name: "Request a consultation" }).first().click(); await expect(page).toHaveURL(/\/contact\/$/); await expect(page.getByRole("heading", { name: /Get in touch/ })).toBeVisible(); }); test("service and focus-area learn more links are wired to detail pages", async ({ page }) => { for (const path of ["/services/", "/focus-areas/"]) { await page.goto(path); const learnMoreLinks = page.getByRole("link", { name: "Learn more" }); const count = await learnMoreLinks.count(); expect(count, `${path} should expose Learn more links`).toBeGreaterThan(0); for (let index = 0; index < count; index += 1) { const href = await learnMoreLinks.nth(index).getAttribute("href"); expect(href, `${path} Learn more ${index + 1}`).toMatch(/^\/.+\/$/); const response = await page.request.get(href!); expect(response.status(), href ?? "").toBeLessThan(400); } } }); test("mobile menu opens and navigates", async ({ page }) => { await page.setViewportSize({ width: 390, height: 844 }); await page.goto("/"); await page.locator(".mobile-nav summary").click(); await expect(page.locator(".mobile-nav nav")).toBeVisible(); await page.locator(".mobile-nav").getByRole("link", { name: "Focus Areas" }).click(); await expect(page).toHaveURL(/\/focus-areas\/$/); await expect(page.getByRole("heading", { name: /Focused expertise/ })).toBeVisible(); }); test("contact form validates required, invalid, and valid paths", async ({ page }) => { await page.goto("/contact/"); const submit = page.getByRole("button", { name: "Submit" }); await submit.click(); const emptyValidation = await page.locator('input[name="name"]').evaluate((input) => { return (input as HTMLInputElement).validationMessage.length > 0; }); expect(emptyValidation).toBe(true); await expect(page).toHaveURL(/\/contact\/$/); await page.locator('input[name="name"]').fill("Test User"); await page.locator('input[name="email"]').fill("not-an-email"); await page.locator('textarea[name="message"]').fill("Too short"); await submit.click(); const invalidEmail = await page.locator('input[name="email"]').evaluate((input) => { return !(input as HTMLInputElement).validity.valid; }); expect(invalidEmail).toBe(true); await page.locator('input[name="email"]').fill("test@example.com"); await page.locator('textarea[name="message"]').fill("This is a valid test inquiry for BlueCap Strategies."); await page.locator("form").evaluate((form) => { form.setAttribute("data-endpoint", "/thank-you/"); form.setAttribute("action", "/thank-you/"); form.setAttribute("method", "get"); }); await submit.click(); await expect(page).toHaveURL(/\/thank-you\/(?:\?.*)?$/); await expect(page.getByRole("heading", { name: "Thank you" })).toBeVisible(); });