import { expect, test } from "@playwright/test"; /** * En-têtes de sécurité émis par le dev server Vite via `cspPlugin` (middleware). * Vérifie qu'au moins un GET racine et qu'une URL recette partagent les en-têtes durcis. */ test.describe("En-têtes de sécurité (dev server)", () => { test("/ renvoie CSP + en-têtes de sécurité", async ({ request }) => { const res = await request.get("/", { headers: { Accept: "text/html,*/*" } }); expect(res.status()).toBe(200); const headers = res.headers(); expect(headers["content-security-policy"]).toBeDefined(); expect(headers["content-security-policy"]).toContain("default-src 'self'"); expect(headers["content-security-policy"]).toContain("frame-ancestors 'none'"); expect(headers["x-content-type-options"]).toBe("nosniff"); expect(headers["x-frame-options"]).toBe("DENY"); expect(headers["referrer-policy"]).toBe("strict-origin-when-cross-origin"); expect(headers["permissions-policy"]).toContain("camera=()"); }); test("/r/:base/:variant renvoie les mêmes en-têtes", async ({ request }) => { const res = await request.get("/r/base%3Aonigiri/variant%3Aonigiri-kimchi-mozza", { headers: { Accept: "text/html,*/*" } }); expect(res.status()).toBe(200); const headers = res.headers(); expect(headers["content-security-policy"]).toBeDefined(); expect(headers["content-security-policy"]).toContain("frame-ancestors 'none'"); expect(headers["x-frame-options"]).toBe("DENY"); }); test("la meta CSP est présente dans le HTML initial", async ({ page }) => { await page.goto("/"); const cspContent = await page .locator('meta[http-equiv="Content-Security-Policy"]') .getAttribute("content"); expect(cspContent).toBeTruthy(); expect(cspContent!).toContain("default-src 'self'"); expect(cspContent!).toContain("frame-ancestors 'none'"); expect(cspContent!).toContain("object-src 'none'"); }); test("la meta CSP est présente sur une page recette", async ({ page }) => { await page.goto("/r/base%3Aonigiri/variant%3Aonigiri-kimchi-mozza"); const cspContent = await page .locator('meta[http-equiv="Content-Security-Policy"]') .getAttribute("content"); expect(cspContent).toBeTruthy(); expect(cspContent!).toContain("frame-ancestors 'none'"); }); });