// Rôle : vérifie le chargement, la navigation par ancres et le nettoyage des défilements de la librairie. /* global window, document */ import { test, expect } from "@playwright/test"; import { LIBRARY_CATEGORY_DEFINITIONS } from "../website/src/features/toolboxes/toolboxModuleRegistry.js"; test("loads every library tool through the shared component registry", async ({ page }) => { const errors = []; page.on("pageerror", (error) => errors.push(error.message)); page.on("console", (message) => { if (message.type() === "error") errors.push(message.text()); }); await page.goto("/#/library"); for (const category of LIBRARY_CATEGORY_DEFINITIONS) { await page.locator(`.library-doc-nav-group > a[href="#/library#library-category-${category.key}"]`).click(); for (const type of category.types) { const tools = page.locator(`[data-module-type="${type}"] .module-content`); await expect(tools.first()).toBeVisible(); for (const tool of await tools.all()) { await expect(tool.getByText("Chargement de l'outil...")).toHaveCount(0); await expect(tool.locator(":scope > *").first()).toBeVisible(); } } } expect(errors).toEqual([]); }); test("library follows deep links, same-page hashes and browser history", async ({ page }) => { const errors = []; page.on("pageerror", (error) => errors.push(error.message)); await page.goto("/#/library#library-tool-m6"); await expect(page.locator('[data-module-type="combos"]')).toBeVisible(); await expect(page.locator("#library-category-buildsCommands")).toBeVisible(); await page.evaluate(() => { window.location.hash = "/library#library-tool-m8"; }); await expect(page.locator('[data-module-type="table"]')).toBeVisible(); await expect(page.locator("#library-category-calculationData")).toBeVisible(); await page.goBack(); await expect(page.locator('[data-module-type="combos"]')).toBeVisible(); await page.evaluate(() => { window.location.hash = "/library#%E0%A4%A"; }); await expect(page.locator("#library-category-notesTracking")).toBeVisible(); expect(errors).toEqual([]); }); test("library cancels obsolete scroll retries on selection and unmount", async ({ page }) => { await page.goto("/#/library"); await expect(page.locator('[data-module-type="notepad"]')).toBeVisible(); await page.clock.install({ time: new Date("2026-09-11T12:00:00Z") }); await page.clock.pauseAt(new Date("2026-09-11T12:00:01Z")); await page.evaluate(() => { window.libraryScrolls = []; window.scrollTo = (options) => window.libraryScrolls.push(options); }); const nav = page.locator(".library-doc-nav"); await nav.locator('a[href="#/library#library-tool-m0"]').dispatchEvent("click"); await page.clock.runFor(40); expect(await page.evaluate(() => window.libraryScrolls.length)).toBeGreaterThan(0); await nav.locator('a[href="#/library#library-tool-m1"]').dispatchEvent("click"); await page.evaluate(() => { window.libraryScrolls = []; }); await page.clock.runFor(700); const scrolls = await page.evaluate(() => window.libraryScrolls); expect(scrolls).toHaveLength(4); expect(scrolls.map((scroll) => scroll.behavior)).toEqual(["smooth", "auto", "auto", "auto"]); await nav.locator('a[href="#/library#library-tool-m2"]').dispatchEvent("click"); await page.clock.runFor(40); await page.evaluate(() => { window.location.hash = "/"; }); await expect(page.locator(".library-page")).toHaveCount(0); // Garder une cible homonyme permet de détecter un ancien timer après démontage. await page.evaluate(() => { const target = document.createElement("div"); target.id = "library-tool-m2"; document.body.append(target); window.libraryScrolls = []; }); await page.clock.runFor(700); expect(await page.evaluate(() => window.libraryScrolls)).toEqual([]); });