spb/phi-conseil
Public
1import { test, expect } from "./fixtures";23const routes = ["/", "/services", "/a-propos", "/temoignages", "/nous-joindre", "/confidentialite"];45test.describe("navigation et liens", () => {6 test("toutes les pages répondent 200 avec un H1 unique", async ({ page }) => {7 for (const r of routes) {8 const res = await page.goto(r);9 expect(res?.status(), r).toBe(200);10 await expect(page.locator("h1")).toHaveCount(1);11 }12 });1314 test("aucun lien interne mort sur l'accueil", async ({ page, request }) => {15 await page.goto("/");16 const hrefs = await page17 .locator("a[href^='/']")18 .evaluateAll((as) =>19 Array.from(20 new Set(21 as22 .map((a) => (a as HTMLAnchorElement).getAttribute("href")!.split("#")[0])23 .filter(Boolean),24 ),25 ),26 );27 expect(hrefs.length).toBeGreaterThan(5);28 for (const h of hrefs) {29 const res = await request.get(h);30 expect(res.status(), h).toBeLessThan(400);31 }32 });3334 test("le lien actif est signalé par aria-current", async ({ page, isMobile }) => {35 test.skip(isMobile, "navigation desktop");36 await page.goto("/services");37 await expect(38 page39 .getByRole("navigation", { name: "Navigation principale" })40 .getByRole("link", { name: "Nos services" }),41 ).toHaveAttribute("aria-current", "page");42 });4344 test("les CTA mènent aux bonnes pages", async ({ page }) => {45 await page.goto("/");46 await page.getByRole("link", { name: /Découvrir nos services/ }).click();47 await expect(page).toHaveURL(/\/services$/);48 await page.goto("/");49 await page50 .getByRole("link", { name: /^Nous joindre/ })51 .last()52 .click();53 await expect(page).toHaveURL(/\/nous-joindre$/);54 });5556 test("sitemap, robots, manifest et icônes sont servis", async ({ request }) => {57 for (const p of [58 "/sitemap.xml",59 "/robots.txt",60 "/manifest.webmanifest",61 "/icon.svg",62 "/apple-icon.png",63 "/opengraph-image",64 ]) {65 const res = await request.get(p);66 expect(res.status(), p).toBe(200);67 }68 const icon = await request.get("/icon.svg");69 expect(await icon.text()).toContain('<path d="M ');70 });7172 test("en-têtes de sécurité présents", async ({ request }) => {73 const res = await request.get("/");74 const h = res.headers();75 expect(h["content-security-policy"]).toContain("frame-ancestors 'none'");76 expect(h["x-content-type-options"]).toBe("nosniff");77 expect(h["x-powered-by"]).toBeUndefined();78 });7980 test("page 404 personnalisée", async ({ page }) => {81 const res = await page.goto("/page-inexistante");82 expect(res?.status()).toBe(404);83 await expect(page.getByRole("heading", { level: 1 })).toContainText("n’existe pas");84 });85});86