diff --git a/app/src/features/human/MicCloudComposer.test.tsx b/app/src/features/human/MicCloudComposer.test.tsx index 77aad8561..68357510f 100644 --- a/app/src/features/human/MicCloudComposer.test.tsx +++ b/app/src/features/human/MicCloudComposer.test.tsx @@ -201,4 +201,91 @@ describe('MicCloudComposer', () => { fireEvent.click(screen.getByRole('button', { name: /start recording/i })); expect(onError).toHaveBeenCalledWith(expect.stringMatching(/not available/i)); }); + + // ── Spacebar shortcut (#1471) ──────────────────────────────────────────── + + it('spacebar starts recording when idle and stops + submits on second press', async () => { + transcribeCloudMock.mockResolvedValueOnce('voice via space'); + const onSubmit = vi.fn(); + render(); + + fireEvent.keyDown(window, { code: 'Space' }); + await waitFor(() => expect(getUserMediaMock).toHaveBeenCalled()); + await waitFor(() => + expect(screen.getByRole('button', { name: /stop recording and send/i })).toBeInTheDocument() + ); + + fireEvent.keyDown(window, { code: 'Space' }); + await waitFor(() => expect(onSubmit).toHaveBeenCalledWith('voice via space')); + }); + + it('spacebar ignores key repeat so holding the key does not flap the recorder', () => { + render(); + fireEvent.keyDown(window, { code: 'Space', repeat: true }); + expect(getUserMediaMock).not.toHaveBeenCalled(); + }); + + it('spacebar ignores modifier combinations so Shift-Space etc. stay free', () => { + render(); + fireEvent.keyDown(window, { code: 'Space', shiftKey: true }); + fireEvent.keyDown(window, { code: 'Space', ctrlKey: true }); + fireEvent.keyDown(window, { code: 'Space', metaKey: true }); + fireEvent.keyDown(window, { code: 'Space', altKey: true }); + expect(getUserMediaMock).not.toHaveBeenCalled(); + }); + + it('spacebar does not trigger when focus is inside a text input', () => { + render( + <> + + + + ); + const input = screen.getByTestId('text-field'); + input.focus(); + fireEvent.keyDown(input, { code: 'Space' }); + expect(getUserMediaMock).not.toHaveBeenCalled(); + }); + + it('spacebar does not trigger when focus is inside a textarea', () => { + render( + <> +