99 lines
6.6 KiB
JavaScript
99 lines
6.6 KiB
JavaScript
// Rôle : vérifie les modales d'échange texte, les erreurs et la persistance des imports réels.
|
|
import { expect, test } from "@playwright/test";
|
|
import { Buffer } from "node:buffer";
|
|
|
|
async function setup(page) {
|
|
await page.goto("/#/toolboxes");
|
|
await page.getByText("Importer une toolbox", { exact: true }).locator('input[type="file"]').setInputFiles({
|
|
name: "exchange.json", mimeType: "application/json",
|
|
buffer: Buffer.from(JSON.stringify({
|
|
toolbox: { id: "exchange", name: "Text exchange", modules: [
|
|
{ id: "table", type: "table", title: "Tableau" },
|
|
{ id: "calc", type: "calculator", title: "Calculateur" },
|
|
] },
|
|
modules: { table: { rows: 2, columns: 2, cells: {} }, calc: { entries: [{ id: "original", label: "Original", value: 7, formula: "7" }] } },
|
|
})),
|
|
});
|
|
await page.getByRole("link", { name: "Ouvrir Text exchange", exact: true }).first().click();
|
|
}
|
|
|
|
test("table text import/export preserves formulas and labels, copies read-only text and resets cancelled drafts", async ({ page, context }) => {
|
|
await context.grantPermissions(["clipboard-read", "clipboard-write"]);
|
|
await setup(page);
|
|
const table = page.locator('[data-module-type="table"]');
|
|
const importButton = table.getByRole("button", { name: "Importer TSV", exact: true });
|
|
await expect(importButton).toBeHidden();
|
|
await table.getByRole("button", { name: "Afficher l'import/export de Tableau", exact: true }).click();
|
|
await expect(table.getByRole("button", { name: "Exporter TSV", exact: true })).toBeDisabled();
|
|
const originalOverflow = await page.locator("body").evaluate((body) => body.style.overflow);
|
|
await importButton.click();
|
|
const dialog = page.getByRole("dialog", { name: "Importer un tableau TSV", exact: true });
|
|
await expect(dialog.getByRole("textbox")).toBeFocused();
|
|
await expect(page.locator("body")).toHaveCSS("overflow", "hidden");
|
|
await dialog.getByRole("textbox").fill("cancelled");
|
|
await dialog.getByRole("button", { name: "Annuler", exact: true }).click();
|
|
await expect.poll(() => page.locator("body").evaluate((body) => body.style.overflow)).toBe(originalOverflow);
|
|
await importButton.click();
|
|
await expect(dialog.getByRole("textbox")).toHaveValue("");
|
|
await dialog.getByRole("button", { name: "Importer le TSV", exact: true }).click();
|
|
await expect(dialog.getByRole("alert")).toContainText("Le texte à importer est vide.");
|
|
await expect(dialog.getByRole("textbox")).toHaveAttribute("aria-invalid", "true");
|
|
const text = "@size: 2x2\n@columns: Quantity\tTotal\n@rows: Ore\tBars\n@tsv\n3\t=A1*2\n5\t=A2*2";
|
|
await dialog.getByRole("textbox").fill(text);
|
|
await expect(dialog.getByRole("alert")).toHaveCount(0);
|
|
await expect(dialog.getByRole("textbox")).toHaveAttribute("aria-invalid", "false");
|
|
await dialog.getByRole("button", { name: "Importer le TSV", exact: true }).click();
|
|
await expect(dialog).toBeHidden();
|
|
await expect(table.getByRole("textbox", { name: "Cellule B2", exact: true })).toHaveValue("10");
|
|
await page.reload();
|
|
await expect(table.getByRole("textbox", { name: "Intitulé de colonne A", exact: true })).toHaveValue("Quantity");
|
|
await expect(table.getByRole("textbox", { name: "Intitulé de ligne 1", exact: true })).toHaveValue("Ore");
|
|
await expect(table.getByRole("textbox", { name: "Cellule B1", exact: true })).toHaveValue("6");
|
|
await table.getByRole("button", { name: "Afficher l'import/export de Tableau", exact: true }).click();
|
|
await table.getByRole("button", { name: "Exporter TSV", exact: true }).click();
|
|
const exported = page.getByRole("dialog", { name: "Exporter un tableau TSV", exact: true });
|
|
await expect(exported.getByRole("textbox")).toHaveAttribute("readonly", "");
|
|
await expect(exported.getByRole("textbox")).toHaveValue(text);
|
|
await exported.getByRole("button", { name: "Copier le TSV", exact: true }).click();
|
|
await expect.poll(() => page.evaluate(() => globalThis.navigator.clipboard.readText())).toBe(text);
|
|
await expect(exported).toBeVisible();
|
|
await exported.getByRole("textbox").press("Escape");
|
|
await expect(exported).toBeHidden();
|
|
await expect.poll(() => page.locator("body").evaluate((body) => body.style.overflow)).toBe(originalOverflow);
|
|
await table.getByRole("button", { name: "Masquer l'import/export de Tableau", exact: true }).click();
|
|
await expect(importButton).toBeHidden();
|
|
});
|
|
|
|
test("invalid calculator imports preserve existing results and a corrected import replaces them with a persistent hierarchy", async ({ page }) => {
|
|
await setup(page);
|
|
const calc = page.locator('[data-module-type="calculator"]');
|
|
await calc.getByRole("button", { name: "Afficher l'import/export de Calculateur", exact: true }).click();
|
|
const openImport = calc.getByRole("button", { name: "Importer du texte", exact: true });
|
|
await openImport.click();
|
|
const dialog = page.getByRole("dialog", { name: "Importer des résultats", exact: true });
|
|
await dialog.getByRole("textbox").fill("invalid");
|
|
await dialog.getByRole("button", { name: "Importer le texte", exact: true }).click();
|
|
await expect(dialog.getByRole("alert")).toContainText("ligne calculateur invalide");
|
|
await expect(calc.locator(".calculator-entry em")).toHaveText(["Original"]);
|
|
await dialog.getByRole("button", { name: "Fermer", exact: true }).click();
|
|
await page.reload();
|
|
await expect(calc.locator(".calculator-entry em")).toHaveText(["Original"]);
|
|
await calc.getByRole("button", { name: "Afficher l'import/export de Calculateur", exact: true }).click();
|
|
await openImport.click();
|
|
await expect(dialog.getByRole("textbox")).toHaveValue("");
|
|
await expect(dialog.getByRole("alert")).toHaveCount(0);
|
|
const text = "@scrollResults: true\nOre: 10 | formula=10\n Bars: 20 | formula=base*2";
|
|
await dialog.getByRole("textbox").fill(text);
|
|
await dialog.getByRole("button", { name: "Importer le texte", exact: true }).click();
|
|
await expect(dialog).toBeHidden();
|
|
await expect(calc.locator(".calculator-entry em")).toHaveText(["Ore", "Bars"]);
|
|
await page.reload();
|
|
await expect(calc.locator(".calculator-entry em")).toHaveText(["Ore", "Bars"]);
|
|
await expect(calc.getByRole("button", { name: "Liste scrollable", exact: true })).toHaveAttribute("aria-pressed", "true");
|
|
await calc.getByRole("button", { name: "Afficher l'import/export de Calculateur", exact: true }).click();
|
|
await calc.getByRole("button", { name: "Exporter en format texte", exact: true }).click();
|
|
const exported = page.getByRole("dialog", { name: "Exporter des résultats", exact: true });
|
|
await expect(exported.getByRole("textbox")).toHaveValue(text);
|
|
await page.locator(".text-import-modal-root .confirm-backdrop").click({ position: { x: 10, y: 10 } });
|
|
await expect(exported).toBeHidden();
|
|
});
|