From 0e5d13ff014af4ee3b7b9d6a4d0e2a6e550cdc7c Mon Sep 17 00:00:00 2001 From: mirivlad Date: Fri, 5 Jun 2026 07:47:07 +0800 Subject: [PATCH] fix: ignore global hotkeys in editable fields --- frontend/src/App.svelte | 1 + scripts/check-gui-render.mjs | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/frontend/src/App.svelte b/frontend/src/App.svelte index 51e3541..0ac27d9 100644 --- a/frontend/src/App.svelte +++ b/frontend/src/App.svelte @@ -1980,6 +1980,7 @@ function onKeyActivate(fn) { return (e) => { + if (isEditableTarget(e.target)) return if (e.key === 'Enter' || e.key === ' ') { e.preventDefault() fn() diff --git a/scripts/check-gui-render.mjs b/scripts/check-gui-render.mjs index 01c36a1..cb8087c 100755 --- a/scripts/check-gui-render.mjs +++ b/scripts/check-gui-render.mjs @@ -208,6 +208,15 @@ async function runReadyScenario(cdp, url) { await clickText(cdp, '.tab', 'Действия') await assertText(cdp, 'Deploy smoke', 'actions: action card visible') + await clickText(cdp, '.actions-tab .btn', 'Добавить действие') + await waitForSelector(cdp, '.modal input[type="text"]') + await dispatchKeydown(cdp, '.modal input[type="text"]', ' ') + await assertEval(cdp, `!!document.querySelector('.modal input[type="text"]')`, 'actions: space in title input keeps modal open') + await setInputValue(cdp, '.modal input[type="text"]', 'GUI smoke action with spaces') + await setInputValue(cdp, '.modal input[placeholder="https://example.com"]', 'https://example.test/action') + await clickText(cdp, '.modal-actions .btn', 'Создать') + await waitForGone(cdp, '.modal-overlay') + await assertText(cdp, 'GUI smoke action with spaces', 'actions: action with spaces saved') await clickText(cdp, '.tab', 'Журнал') await assertText(cdp, 'Manual smoke entry', 'worklog: entry visible') @@ -368,6 +377,21 @@ async function setInputValue(cdp, selector, value) { await sleep(100) } +async function dispatchKeydown(cdp, selector, key) { + const ok = await evalValue(cdp, ` + (() => { + const el = document.querySelector(${JSON.stringify(selector)}); + if (!el) return false; + el.focus(); + const event = new KeyboardEvent('keydown', { key: ${JSON.stringify(key)}, bubbles: true, cancelable: true }); + el.dispatchEvent(event); + return true; + })() + `) + if (!ok) throw new Error(`Keydown target not found: ${selector}`) + await sleep(100) +} + async function setClipboardText(cdp, value) { await cdp.send('Runtime.evaluate', { expression: `window.__VERSTAK_GUI_SMOKE_CLIPBOARD__ = ${JSON.stringify(value)}`,