Files
azionelab-v2/tests/functional/tests/portal.spec.ts
T
2026-06-25 22:57:43 +02:00

118 lines
4.5 KiB
TypeScript

import { expect, test } from "@playwright/test";
const sectionIds = [
"inizio",
"laboratorio",
"maestro",
"lezioni",
"spettacoli",
"galleria",
"contatti",
];
test("renders the complete seeded single page", async ({ page }) => {
await page.goto("/");
await expect(page).toHaveTitle(/Azione!Lab/);
await expect(page.getByRole("heading", { level: 1 })).toHaveText(
"Il teatro diventa presenza.",
);
await expect(page.getByText("Ernesto Estatico")).toBeVisible();
await expect(page.getByText(/Via dell'Epomeo 9999, Napoli/).first()).toBeVisible();
await expect(page.locator(".feature-card")).toHaveCount(3);
await expect(page.locator(".show-card")).toHaveCount(2);
await expect(page.locator(".gallery-item")).toHaveCount(4);
await expect(page.locator(".show-meta", { hasText: /^0$/ })).toHaveCount(0);
const positions = await page.evaluate((ids) => ids.map((id) => {
const element = document.getElementById(id);
if (!element) throw new Error(`Missing section #${id}`);
return element.getBoundingClientRect().top + window.scrollY;
}), sectionIds);
expect(positions).toEqual([...positions].sort((a, b) => a - b));
});
test("provides usable contact actions", async ({ page }) => {
await page.goto("/#contatti");
await expect(page.getByRole("link", { name: /Scrivi una mail/ })).toHaveAttribute(
"href",
"mailto:ciao@azionelab.org",
);
await expect(page.getByRole("link", { name: /Chiama/ })).toHaveAttribute(
"href",
"tel:+393331234567",
);
await expect(page.getByRole("link", { name: /WhatsApp/ })).toHaveAttribute(
"href",
"https://wa.me/393331234567",
);
});
test("supports mobile navigation without horizontal overflow", async ({ page }) => {
await page.setViewportSize({ width: 390, height: 844 });
await page.goto("/");
const menu = page.locator("details.mobile-menu");
await menu.locator("summary").click();
await expect(menu).toHaveAttribute("open", "");
await menu.getByRole("link", { name: "Le lezioni" }).click();
await expect(page).toHaveURL(/#lezioni$/);
const dimensions = await page.evaluate(() => ({
clientWidth: document.documentElement.clientWidth,
scrollWidth: document.documentElement.scrollWidth,
}));
expect(dimensions.scrollWidth).toBeLessThanOrEqual(dimensions.clientWidth + 1);
});
test("uses semantic landmarks, image alternatives and keyboard access", async ({ page }) => {
await page.goto("/");
await expect(page.getByRole("banner")).toHaveCount(1);
await expect(page.getByRole("main")).toHaveCount(1);
await expect(page.getByRole("contentinfo")).toHaveCount(1);
await expect(page.getByRole("heading", { level: 1 })).toHaveCount(1);
const alternatives = await page.locator("img").evaluateAll((images) =>
images.map((image) => image.getAttribute("alt")?.trim() ?? ""),
);
expect(alternatives.length).toBeGreaterThan(0);
expect(alternatives.every(Boolean)).toBe(true);
const images = page.locator("img");
for (let index = 0; index < await images.count(); index += 1) {
const image = images.nth(index);
await image.scrollIntoViewIfNeeded();
await expect
.poll(() => image.evaluate((element) => element.naturalWidth))
.toBeGreaterThan(0);
}
await page.keyboard.press("Tab");
await expect(page.getByRole("link", { name: "Vai al contenuto" })).toBeFocused();
});
test("protects the edge and exposes the WordPress admin", async ({ page, request, playwright }) => {
const response = await request.get("/");
expect(response.ok()).toBe(true);
expect(response.headers()["content-security-policy"]).toContain("object-src 'none'");
expect(response.headers()["x-content-type-options"]).toBe("nosniff");
expect(response.headers()["permissions-policy"]).toContain("camera=()");
expect((await request.get("/xmlrpc.php")).status()).toBe(403);
expect((await request.get("/.env")).status()).toBe(404);
expect((await request.get("/wp-config.php")).status()).toBe(404);
expect((await request.get("/wp-content/uploads/probe.php")).status()).toBe(403);
expect((await request.get("/wp-json/wp/v2/users")).status()).toBe(404);
await page.goto("/wp-admin/");
await expect(page).toHaveURL(/\/wp-login\.php/);
await expect(page.locator('input[name="log"]')).toBeVisible();
await expect(page.locator('input[name="pwd"]')).toBeVisible();
const invalidHost = await playwright.request.newContext({
baseURL: process.env.INVALID_HOST_URL ?? "http://proxy",
});
expect((await invalidHost.get("/")).status()).toBe(404);
await invalidHost.dispose();
});