From f509f8746e6a8857148b027b18a505f863495554 Mon Sep 17 00:00:00 2001 From: Pierre MARTIN Date: Tue, 10 Nov 2026 21:04:08 +0100 Subject: [PATCH] =?UTF-8?q?Test=20navigateur=20des=20prompts=20:=20capture?= =?UTF-8?q?s=20sans=20bandeau=20r=C3=A9siduel,=20repli=20par=20s=C3=A9lect?= =?UTF-8?q?ion=20v=C3=A9rifi=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- tests/browser/prompts.mjs | 45 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/tests/browser/prompts.mjs b/tests/browser/prompts.mjs index fce87ac..cce6d0d 100644 --- a/tests/browser/prompts.mjs +++ b/tests/browser/prompts.mjs @@ -111,14 +111,22 @@ const idle = () => until("écran libre", () => !document.body.classList.contains * après la règle commune : rien d'interactif sous une barre d'action, pas * de bouton étiré. before() est rejoué avant chaque taille (le bandeau * « Prompt copié » ne dure que 2 s). */ -async function capture(name, before = async () => {}) { +async function capture(name, before = null) { if (!full) { return; } + // Le bandeau « Prompt copié » d'une copie précédente est parti (sauf + // pour sa propre capture, où before le fait réapparaître). + await until( + "bandeau parti", + () => document.getElementById("prompt-banner").hidden, + null, + 10_000, + ); for (const size of SIZES) { await page.setViewportSize(size); await sleep(300); - await before(); + await before?.(); const hidden = await hiddenUnderActionBar(page); check( hidden.length === 0, @@ -385,6 +393,39 @@ check(conceptText.includes("le concept « Videau » (en anglais : Cube)"), "prom check(/chances de gagner \d+ %/.test(conceptText), "prompt du concept : évaluation"); await capture("8-feuille-du-prompt-glossaire"); await copyPrompt("prompt du concept"); +if (full) { + // Le repli : navigator.clipboard refuse (comme hors contexte sûr) ; le + // texte est sélectionné dans la feuille et copié par le navigateur. + await until("bandeau parti", () => document.getElementById("prompt-banner").hidden); + await page.evaluate(async () => { + await navigator.clipboard.writeText(""); + navigator.clipboard.writeText = () => Promise.reject(new Error("refusé")); + }); + await page.click("#prompt-copy"); + await until( + "copie de repli", + () => + !document.getElementById("prompt-banner").hidden || + document.getElementById("prompt-status").textContent !== "", + null, + 10_000, + ); + const fallback = await page.evaluate(async () => ({ + selected: window.getSelection().toString(), + text: document.getElementById("prompt-text").textContent, + banner: !document.getElementById("prompt-banner").hidden, + clipboard: await navigator.clipboard.readText(), + })); + // Copié depuis une sélection, le texte perd ses espaces insécables + // (« 41 % ») : ce sont des espaces ordinaires dans le presse-papiers. + const plain = (text) => text.replace(/ /g, " ").trim(); + check(plain(fallback.selected) === plain(fallback.text), "repli : texte non sélectionné"); + check( + fallback.banner && plain(fallback.clipboard) === plain(fallback.text), + `repli : le navigateur n'a pas copié le texte sélectionné (bandeau ${fallback.banner}, presse-papiers ${fallback.clipboard.length} car. pour ${fallback.text.length})`, + ); + log("repli par sélection du texte : copié"); +} await closePrompt("#/glossaire/videau"); const csp = await page.evaluate(() => window.__csp);