// Rôle : vérifie le contenu et la sélection du Bloc Note face aux changements de page et aux mises à jour externes. /* global window, document, NodeFilter */ import { test, expect } from "@playwright/test"; import { fileURLToPath, URL } from "node:url"; const probeUrl = `/@fs/${fileURLToPath(new URL("./fixtures/notepad-sync-probe.js", import.meta.url))}`; async function setup(page) { await page.goto("/"); await page.evaluate(async (url) => { const { mountNotepadSyncProbe } = await import(url); document.getElementById("app").style.display = "none"; const element = document.createElement("div"); element.id = "notepad-probe"; document.body.prepend(element); const button = document.createElement("button"); button.id = "outside-editor"; button.textContent = "Outside"; document.body.append(button); window.notepadProbe = mountNotepadSyncProbe(element); }, probeUrl); return page.locator("#notepad-probe .notepad-editor"); } test("focused page changes never save the old DOM into the new page or module", async ({ page }) => { const editor = await setup(page); await expect(editor).toHaveText("Alpha"); await editor.focus(); const content = await page.evaluate(() => { window.notepadProbe.select("b"); return document.querySelector("#notepad-probe .notepad-editor").innerHTML; }); expect(content).toBe("

Bravo

"); await editor.fill("Second edited"); const saved = await page.evaluate(() => window.notepadProbe.writes.at(-1)); expect(saved.data.pages.find((item) => item.id === "a").html).toBe("

Alpha

"); expect(saved.data.pages.find((item) => item.id === "b").text).toBe("Second edited"); await page.evaluate(() => window.notepadProbe.update({ moduleId: "other", data: { activePageId: "b", pages: [{ id: "b", title: "Other", html: "

Other module

" }] } })); await expect(editor).toHaveText("Other module"); await editor.fill("Other edited"); expect(await page.evaluate(() => window.notepadProbe.writes.at(-1).moduleId)).toBe("other"); await page.evaluate(() => window.notepadProbe.unmount()); }); test("local echoes preserve selection and external content synchronizes after blur", async ({ page }) => { const editor = await setup(page); await editor.fill("Local text"); await page.evaluate(() => { const node = document.createTreeWalker(document.querySelector("#notepad-probe .notepad-editor"), NodeFilter.SHOW_TEXT).nextNode(); const range = document.createRange(); range.setStart(node, 2); range.collapse(true); const selection = document.getSelection(); selection.removeAllRanges(); selection.addRange(range); window.notepadProbe.update({}); }); expect(await page.evaluate(() => document.getSelection().anchorOffset)).toBe(2); await expect(editor).toHaveText("Local text"); const writeCount = await page.evaluate(() => window.notepadProbe.writes.length); await page.evaluate(() => window.notepadProbe.patchPage("a", { html: "

External text

" })); await expect(editor).toHaveText("Local text"); expect(await page.evaluate(() => document.getSelection().anchorOffset)).toBe(2); await page.locator("#outside-editor").click(); await expect(editor).toHaveText("External text"); await expect(page.locator("#outside-editor")).toBeFocused(); expect(await page.evaluate(() => window.notepadProbe.writes.length)).toBe(writeCount); // L'horodatage reste celui de la sauvegarde locale ; il ne suffit pas à reconnaître un écho. await page.evaluate(() => window.notepadProbe.patchPage("a", { html: "

Another update

" })); await expect(editor).toHaveText("Another update"); await page.evaluate(() => window.notepadProbe.unmount()); });