generated from bisco/codex-bootstrap
118 lines
4.5 KiB
TypeScript
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();
|
|
});
|