From ae26e2026f8c438d36e6f6638907d5b7a1a0d0ca Mon Sep 17 00:00:00 2001 From: John McLear Date: Tue, 28 Apr 2026 18:39:25 +0100 Subject: [PATCH] test(playwright): use insertText so Firefox stops dropping keystrokes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit writeToPad has been calling page.keyboard.type, which fires one keydown/keyup per character against the contenteditable. Under WITH_PLUGINS load Firefox's input pipeline can't keep up with the per-event firing while plugin hooks are still warming, and randomly swallows characters from the tail of the string — pad ends up with e.g. "aligned tex" instead of "aligned text". The dropped character is irrecoverable: there is no event to retry against. Switch to page.keyboard.insertText, which dispatches a single input event per call. Etherpad's incorporateUserChanges loop reads the resulting DOM atomically, so the result is identical to what real typing produces — minus the per-key race. insertText does not translate \n into Enter (it concatenates "One\nTwo" into "OneTwo"), so split on newlines and press Enter between segments to preserve multi-line input that the existing callers (timeslider_line_numbers, page_up_down, etc.) rely on. Verified locally on Firefox + WITH_PLUGINS: - ep_align Alignment: 4/4 pass (previously 0/4 even after retries) - italic.spec: 2/2 pass - timeslider_line_numbers (multi-line): pass Chromium remains green. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/tests/frontend-new/helper/padHelper.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/tests/frontend-new/helper/padHelper.ts b/src/tests/frontend-new/helper/padHelper.ts index c1dcbecee3c..b2d49b61e72 100644 --- a/src/tests/frontend-new/helper/padHelper.ts +++ b/src/tests/frontend-new/helper/padHelper.ts @@ -142,7 +142,18 @@ export const clearPadContent = async (page: Page) => { export const writeToPad = async (page: Page, text: string) => { const body = await getPadBody(page); await body.click(); - await page.keyboard.type(text); + // Use insertText (single input event) instead of keyboard.type + // (one keydown/keyup per char). Firefox under WITH_PLUGINS load + // racily drops characters from per-key events; insertText delivers + // each chunk in one event, which Etherpad's incorporateUserChanges + // pipeline handles atomically. insertText does not translate \n + // into a real Enter keystroke, so split on newlines and press + // Enter between segments to preserve multi-line input. + const lines = text.split('\n'); + for (let i = 0; i < lines.length; i++) { + if (lines[i]) await page.keyboard.insertText(lines[i]); + if (i < lines.length - 1) await page.keyboard.press('Enter'); + } } export const clearAuthorship = async (page: Page) => {