diff --git a/frontend/console/e2e/cron.spec.ts b/frontend/console/e2e/cron.spec.ts index d408f11ed1..d86da68586 100644 --- a/frontend/console/e2e/cron.spec.ts +++ b/frontend/console/e2e/cron.spec.ts @@ -24,3 +24,46 @@ test('send cron request', async ({ page }) => { expect(responseJson).toEqual({}) }) + +test('submit cron form using ⌘+⏎ shortcut', async ({ page }) => { + await navigateToDecl(page, 'cron', 'thirtySeconds') + + await page.locator('input#request-path').focus() + + // The keypress is sometimes flakey in playwright, so try 3 times. Ideally we'd find a better way to do this. + for (let attempt = 0; attempt < 3; attempt++) { + try { + await page.keyboard.press('ControlOrMeta+Enter') + const responseEditor = page.locator('#response-editor .cm-content[role="textbox"]') + await expect(responseEditor).toBeVisible() + + const responseText = await responseEditor.textContent() + const responseJson = JSON.parse(responseText?.trim() || '{}') + + expect(responseJson).toEqual({}) + break + } catch (error) { + if (attempt === 2) throw error + } + } +}) + +test('submit cron form using ⌘+⏎ shortcut without focusing first', async ({ page }) => { + await navigateToDecl(page, 'cron', 'thirtySeconds') + + // The keypress is sometimes flakey in playwright, so try 3 times. Ideally we'd find a better way to do this. + for (let attempt = 0; attempt < 3; attempt++) { + try { + await page.keyboard.press('ControlOrMeta+Enter') + const responseEditor = page.locator('#response-editor .cm-content[role="textbox"]') + await expect(responseEditor).toBeVisible() + const responseText = await responseEditor.textContent() + const responseJson = JSON.parse(responseText?.trim() || '{}') + + expect(responseJson).toEqual({}) + break + } catch (error) { + if (attempt === 2) throw error + } + } +}) diff --git a/frontend/console/src/features/modules/decls/verb/VerbFormInput.tsx b/frontend/console/src/features/modules/decls/verb/VerbFormInput.tsx index 1432816467..2643c4810d 100644 --- a/frontend/console/src/features/modules/decls/verb/VerbFormInput.tsx +++ b/frontend/console/src/features/modules/decls/verb/VerbFormInput.tsx @@ -1,4 +1,5 @@ import { Copy01Icon } from 'hugeicons-react' +import { useEffect, useRef } from 'react' import { Button } from '../../../../components/Button' export const VerbFormInput = ({ @@ -18,13 +19,32 @@ export const VerbFormInput = ({ onSubmit: (path: string) => void handleCopyButton?: () => void }) => { + const formRef = useRef(null) + const handleSubmit: React.FormEventHandler = async (event) => { event.preventDefault() onSubmit(path) } + const shortcutText = `Send ${window.navigator.userAgent.includes('Mac') ? '⌘ + ⏎' : 'Ctrl + ⏎'}` + + useEffect(() => { + const handleKeydown = (event: KeyboardEvent) => { + if ((event.metaKey || event.ctrlKey) && event.key === 'Enter') { + event.preventDefault() + formRef.current?.dispatchEvent(new Event('submit', { cancelable: true, bubbles: true })) + } + } + + window.addEventListener('keydown', handleKeydown) + + return () => { + window.removeEventListener('keydown', handleKeydown) + } + }, [path, readOnly, onSubmit]) + return ( -
+
{requestType} @@ -38,7 +58,7 @@ export const VerbFormInput = ({ readOnly={readOnly} onChange={(event) => setPath(event.target.value)} /> -