sokko-g/e2e/toolbox-cover.spec.js
Shinuwa 0ac1a0974e
All checks were successful
Deploy Sokko G / deploy (push) Successful in 19s
Refocus responsive layouts on compact desktop use
2026-10-05 15:47:46 +02:00

124 lines
7.3 KiB
JavaScript

// Rôle : vérifie la persistance et le remplacement des images de toolbox.
import { expect, test } from "@playwright/test";
import { readFile } from "node:fs/promises";
import { Buffer } from "node:buffer";
import { fileURLToPath, URL } from "node:url";
const imagePath = fileURLToPath(new URL("../website/public/static/img/toolbox-icons/sword.png", import.meta.url));
const fixture = JSON.parse(await readFile(new URL("./fixtures/toolbox-export.json", import.meta.url), "utf8"));
const cover = `data:image/png;base64,${(await readFile(imagePath)).toString("base64")}`;
const { games } = JSON.parse(await readFile(new URL("../website/public/data/games.json", import.meta.url), "utf8"));
const gameCover = games.find((game) => game.id === "mhwilds").images.cardCover;
function picker(page) {
return page.getByRole("button", { name: "Changer l'image de la toolbox" });
}
async function importToolbox(page, name, scope = page.getByText("Importer une toolbox", { exact: true })) {
await scope.locator('input[type="file"][accept="application/json"]').setInputFiles({
name: "cover.json", mimeType: "application/json",
buffer: Buffer.from(JSON.stringify({ ...fixture, toolbox: { ...fixture.toolbox, name, customCover: cover } })),
});
}
async function uploadCover(page, file = imagePath) {
await picker(page).click();
const action = page.getByRole("button", { name: /Ajouter une image de card|Remplacer l'image de card/ });
await expect(action).toBeVisible();
const chooser = page.waitForEvent("filechooser");
await action.click();
await (await chooser).setFiles(file);
return page.getByRole("dialog", { name: "Image de card", exact: true });
}
async function exportToolbox(page, name) {
const download = page.waitForEvent("download");
await page.getByRole("button", { name: `Exporter ${name}`, exact: true }).click();
return JSON.parse(await readFile(await (await download).path(), "utf8"));
}
test("saves a cropped cover through reload and export/import, then returns to an icon", async ({ page }) => {
await page.goto("/#/toolboxes");
await page.getByRole("button", { name: "Nouvelle toolbox" }).click();
const creation = page.getByRole("dialog", { name: "Nouvelle toolbox" });
await creation.getByLabel("Nom").fill("Cover workflow");
await creation.getByRole("button", { name: "Créer" }).click();
await expect(picker(page).locator("img")).toHaveAttribute("src", /toolbox\.png$/);
await picker(page).click();
await page.getByRole("button", { name: "Utiliser l'icône sword", exact: true }).click();
const editor = await uploadCover(page);
await expect(editor.getByRole("button", { name: "Valider" })).toBeEnabled();
await editor.getByRole("button", { name: "Valider" }).click();
await expect(editor).toBeHidden();
const savedCover = await picker(page).locator("img").getAttribute("src");
expect(savedCover).toMatch(/^data:image\/(webp|jpeg);base64,/);
await expect.poll(() => picker(page).locator("img").evaluate((img) => [img.naturalWidth, img.naturalHeight])).toEqual([620, 248]);
await page.reload();
await expect(picker(page).locator("img")).toHaveAttribute("src", savedCover);
await page.goto("/#/toolboxes");
await expect(page.getByRole("link", { name: "Ouvrir Cover workflow", exact: true }).first().locator("img")).toHaveAttribute("src", savedCover);
const exported = await exportToolbox(page, "Cover workflow");
expect(exported.toolbox.customCover).toBe(savedCover);
expect(exported.toolbox.icon).toMatch(/sword\.png$/);
exported.toolbox.name = "Imported cover";
await page.getByText("Importer une toolbox", { exact: true }).locator('input[type="file"]').setInputFiles({
name: "export.json", mimeType: "application/json", buffer: Buffer.from(JSON.stringify(exported)),
});
await page.getByRole("link", { name: "Ouvrir Imported cover", exact: true }).first().click();
await expect(picker(page).locator("img")).toHaveAttribute("src", savedCover);
await picker(page).click();
await expect(page.getByRole("button", { name: "Remplacer l'image de card" })).toHaveAttribute("aria-pressed", "true");
await expect(page.getByRole("button", { name: "Utiliser l'icône sword", exact: true })).toHaveAttribute("aria-pressed", "false");
await page.getByRole("button", { name: "Utiliser l'icône sword", exact: true }).click();
await page.reload();
await expect(picker(page).locator("img")).toHaveAttribute("src", /sword\.png$/);
await page.goto("/#/toolboxes");
expect((await exportToolbox(page, "Imported cover")).toolbox.customCover || "").toBe("");
});
test("cancelled and unreadable replacements preserve the cover and allow selecting the same file again", async ({ page }) => {
await page.goto("/#/toolboxes");
await importToolbox(page, "Preserved cover");
await page.getByRole("link", { name: "Ouvrir Preserved cover", exact: true }).first().click();
let editor = await uploadCover(page);
await expect(editor.getByRole("button", { name: "Valider" })).toBeEnabled();
await editor.getByRole("button", { name: "Annuler" }).click();
await expect(picker(page).locator("img")).toHaveAttribute("src", cover);
editor = await uploadCover(page);
await expect(editor.getByRole("button", { name: "Valider" })).toBeEnabled();
await editor.getByRole("button", { name: "Fermer", exact: true }).click();
editor = await uploadCover(page, { name: "broken.png", mimeType: "image/png", buffer: Buffer.from("not an image") });
await expect(editor.getByText("Image illisible. Choisis un autre fichier.")).toBeVisible();
await expect(editor.getByRole("button", { name: "Valider" })).toBeDisabled();
await editor.getByRole("button", { name: "Annuler" }).click();
await page.reload();
await expect(picker(page).locator("img")).toHaveAttribute("src", cover);
});
test("game association takes precedence without discarding the custom cover", async ({ page }) => {
await page.goto("/#/games/mhwilds");
await page.getByRole("tab", { name: "Toolbox", exact: true }).click();
const drawer = page.locator("#toolbox-drawer .drawer-panel");
await importToolbox(page, "Linked cover", drawer);
await expect(drawer.getByRole("heading", { name: "Linked cover" })).toBeVisible();
await drawer.getByRole("button", { name: "Fermer", exact: true }).click();
await page.goto("/#/toolboxes");
const link = page.getByRole("link", { name: "Ouvrir Linked cover", exact: true }).first();
await expect(link.locator("img")).toHaveAttribute("src", gameCover);
await expect.poll(() => link.locator("img").evaluate((img) => img.naturalWidth)).toBeGreaterThan(0);
expect((await exportToolbox(page, "Linked cover")).toolbox.customCover).toBe(cover);
await link.click();
await expect(page.locator(".toolbox-game-icon img")).toHaveAttribute("src", gameCover);
await expect(picker(page)).toHaveCount(0);
await page.goto("/#/games/mhwilds");
await page.getByRole("tab", { name: "Toolbox", exact: true }).click();
await drawer.getByRole("button", { name: "Lier une toolbox", exact: true }).click();
const dialog = page.getByRole("dialog", { name: "Lier une toolbox", exact: true });
await dialog.getByLabel("Toolbox associée").selectOption("");
await dialog.getByRole("button", { name: "Valider" }).click();
await drawer.getByRole("button", { name: "Fermer", exact: true }).click();
await page.goto("/#/toolboxes");
await expect(link.locator("img")).toHaveAttribute("src", cover);
await link.click();
await expect(picker(page).locator("img")).toHaveAttribute("src", cover);
});