// Rôle : couvre les mutations persistantes des liens, compteurs et checklists. import { expect, test } from "@playwright/test"; import { Buffer } from "node:buffer"; async function setup(page, type, data) { await page.goto("/#/toolboxes"); await page.getByText("Importer une toolbox", { exact: true }).locator('input[type="file"]').setInputFiles({ name: "basic.json", mimeType: "application/json", buffer: Buffer.from(JSON.stringify({ toolbox: { id: "basic", name: "Basic workflows", modules: [{ id: "tool", type, title: "Tool" }] }, modules: { tool: data }, })), }); await page.getByRole("link", { name: "Ouvrir Basic workflows", exact: true }).first().click(); const tool = page.locator(`[data-module-type="${type}"]`); await tool.getByRole("button", { name: "Afficher l'ajout de Tool", exact: true }).click(); return tool; } test("links persist creation and copying; deleting a category preserves its links", async ({ page, context }) => { await context.grantPermissions(["clipboard-read", "clipboard-write"]); const tool = await setup(page, "links", { links: [] }); const form = tool.locator(".links-add-form"); await form.getByPlaceholder("Nom du lien", { exact: true }).fill("Guide"); await form.locator('input[type="url"]').fill("https://example.com/guide"); await form.getByPlaceholder("Catégorie", { exact: true }).fill("Reference"); await form.getByRole("button", { name: "Ajouter", exact: true }).click(); const link = tool.getByRole("link", { name: /Guide/ }); await expect(link).toHaveAttribute("href", "https://example.com/guide"); await expect(link).toHaveAttribute("target", "_blank"); await expect(link).toHaveAttribute("rel", /noreferrer/); await expect(form.locator('input[type="url"]')).toHaveValue(""); await tool.getByRole("button", { name: "Copier Guide", exact: true }).click(); await expect.poll(() => page.evaluate(() => globalThis.navigator.clipboard.readText())).toBe("https://example.com/guide"); await page.reload(); await expect(link).toHaveAttribute("href", "https://example.com/guide"); await tool.getByRole("button", { name: "Supprimer la catégorie Reference", exact: true }).click(); await expect(tool.getByRole("heading", { name: "Reference", exact: true })).toHaveCount(0); await page.reload(); await expect(link).toBeVisible(); await tool.getByRole("button", { name: "Supprimer Guide", exact: true }).click(); await page.reload(); await expect(link).toHaveCount(0); }); test("counters persist signed values and reset without affecting other counters", async ({ page }) => { const tool = await setup(page, "counters", { counters: [{ id: "other", label: "Other", value: 9 }] }); await tool.getByPlaceholder("Nom du compteur", { exact: true }).fill("Attempts"); await tool.locator(".counters-add-form").getByRole("button", { name: "Ajouter", exact: true }).click(); const item = tool.locator(".counter-item").filter({ has: page.getByRole("button", { name: "Supprimer Attempts", exact: true }) }); await tool.getByRole("button", { name: "Incrémenter Attempts", exact: true }).click(); await expect(item.locator("strong")).toHaveText("1"); await tool.getByRole("button", { name: "Décrémenter Attempts", exact: true }).click({ clickCount: 2 }); await expect(item.locator("strong")).toHaveText("-1"); await page.reload(); await expect(item.locator("strong")).toHaveText("-1"); await tool.getByRole("button", { name: "Réinitialiser Attempts", exact: true }).click(); await page.reload(); await expect(item.locator("strong")).toHaveText("0"); await tool.getByRole("button", { name: "Supprimer Attempts", exact: true }).click(); await page.reload(); await expect(tool.locator(".counter-item")).toHaveCount(1); await expect(tool.locator(".counter-value strong")).toHaveText("9"); await expect(tool.locator(".counter-value span")).toHaveText("Other"); }); test("checklist quantities are clamped and completed categories hide without losing data", async ({ page }) => { const tool = await setup(page, "checklist", { sections: [] }); await tool.getByPlaceholder("Catégorie", { exact: true }).fill("Craft"); await tool.getByPlaceholder("Nouvel item", { exact: true }).fill("Ore"); await tool.getByRole("spinbutton", { name: "Quantité cible", exact: true }).fill("3"); await tool.getByRole("button", { name: "Ajouter", exact: true }).click(); const quantity = tool.getByRole("spinbutton", { name: "Quantité actuelle Ore", exact: true }); await tool.getByRole("button", { name: "Ajouter une quantité", exact: true }).click(); await expect(quantity).toHaveValue("1"); await quantity.fill("99"); await expect(quantity).toHaveValue("3"); await tool.getByRole("radio", { name: "Cachée quand terminée", exact: true }).click(); await expect(quantity).toHaveCount(0); await page.reload(); await expect(tool.getByRole("radio", { name: "Cachée quand terminée", exact: true })).toHaveAttribute("aria-checked", "true"); await tool.getByRole("radio", { name: "Visible quand terminée", exact: true }).click(); await expect(quantity).toHaveValue("3"); await tool.getByRole("button", { name: "Retirer une quantité", exact: true }).click(); await page.reload(); await expect(quantity).toHaveValue("2"); await tool.getByRole("button", { name: "Supprimer Ore", exact: true }).click(); await page.reload(); await expect(quantity).toHaveCount(0); });