// Rôle : vérifie la prise en main, son carrousel et son intégration à la home et à la page À propos. import { test, expect } from "@playwright/test"; import { readFile } from "node:fs/promises"; import { URL } from "node:url"; const site = JSON.parse(await readFile("website/public/data/site.json", "utf8")); const content = site.home.onboarding; async function setup(page, route = "/") { await page.clock.install({ time: new Date("2026-09-12T12:00:00Z") }); await page.clock.pauseAt(new Date("2026-09-12T12:01:00Z")); await page.goto(route); const section = page.getByRole("region", { name: content.title, exact: true }); await expect(section).toBeVisible(); return section; } async function expectSlide(section, index) { const slide = content.slides[index]; await expect(section.getByRole("button", { name: `${content.slideButtonLabel} ${index + 1}`, exact: true })).toHaveAttribute("aria-pressed", "true"); const image = section.getByRole("img", { name: slide.alt, exact: true }); await expect(image).toHaveAttribute("src", slide.src); await expect.poll(() => image.evaluate((element) => element.naturalWidth)).toBeGreaterThan(0); await expect(section.getByText(slide.title, { exact: true })).toBeVisible(); } test("onboarding cycles, pauses on hover and focus, and allows manual selection", async ({ page }) => { const section = await setup(page); await expectSlide(section, 0); await page.clock.runFor(4500); await expectSlide(section, 1); await section.getByRole("img", { name: content.slides[1].alt, exact: true }).hover(); await page.clock.runFor(9000); await expectSlide(section, 1); await page.mouse.move(0, 0); await page.clock.runFor(4500); await expectSlide(section, 2); const first = section.getByRole("button", { name: `${content.slideButtonLabel} 1`, exact: true }); await first.focus(); await page.clock.runFor(9000); await expectSlide(section, 2); await first.press("Enter"); await expectSlide(section, 0); await section.getByRole("button", { name: content.primaryAction, exact: true }).focus(); await page.clock.runFor(4500); await expectSlide(section, 1); await page.clock.runFor(4500 * (content.slides.length - 1)); await expectSlide(section, 0); }); test("reduced motion keeps previews still but manual selection remains available", async ({ page }) => { await page.emulateMedia({ reducedMotion: "reduce" }); const section = await setup(page); await page.clock.runFor(18000); await expectSlide(section, 0); await section.getByRole("button", { name: `${content.slideButtonLabel} 3`, exact: true }).click(); await expectSlide(section, 2); await page.mouse.move(0, 0); await section.getByRole("button", { name: content.primaryAction, exact: true }).focus(); await page.clock.runFor(18000); await expectSlide(section, 2); }); test("home onboarding creates the initial tools and starts the tutorial", async ({ page }) => { await page.goto("/"); await page.getByRole("button", { name: content.primaryAction, exact: true }).click(); const dialog = page.getByRole("dialog"); await dialog.getByRole("textbox", { name: "Nom", exact: true }).fill("Prise en main"); await dialog.getByRole("button", { name: "Créer", exact: true }).click(); await expect(page).toHaveURL(/#\/toolbox\//); await expect(page.locator('[data-module-type="memos"]')).toBeVisible(); await expect(page.locator('[data-module-type="links"]')).toBeVisible(); await expect(page.locator(".toolbox-tutorial-count")).toHaveText(/^1\//); await page.goto("/#/"); await expect(page.getByRole("region", { name: content.title, exact: true })).toBeVisible(); await page.reload(); await expect(page.getByRole("region", { name: content.title, exact: true })).toBeVisible(); }); test("about reuses onboarding without creation and exposes tool examples and destinations", async ({ page }) => { await page.goto("/#/about"); await expect(page.getByRole("heading", { name: site.about.title, exact: true })).toBeVisible(); const section = page.getByRole("region", { name: content.title, exact: true }); await expect(section).toBeVisible(); await expect(section.getByRole("button", { name: content.primaryAction, exact: true })).toHaveCount(0); for (const group of site.about.toolGroups) { await expect(page.getByRole("list", { name: `Exemples pour ${group.title}`, exact: true }).getByRole("listitem")).toHaveText(group.examples); } for (const card of content.cards) { await section.getByRole("link").filter({ hasText: card.title }).click(); await expect.poll(() => new URL(page.url()).hash).toBe(card.href); await page.goBack(); await expect(section).toBeVisible(); } await page.getByRole("link", { name: site.about.toolsLibraryLink, exact: true }).click(); await expect(page).toHaveURL(/#\/library$/); });