diff --git a/frontend/src/components/Chat.test.tsx b/frontend/src/components/Chat.test.tsx index 62ca5ba..d36ea54 100644 --- a/frontend/src/components/Chat.test.tsx +++ b/frontend/src/components/Chat.test.tsx @@ -1,4 +1,10 @@ -import { act, render, screen, waitFor } from "@testing-library/react"; +import { + act, + fireEvent, + render, + screen, + waitFor, +} from "@testing-library/react"; import { beforeEach, describe, expect, it, vi } from "vitest"; import { api } from "../api/client"; @@ -261,3 +267,46 @@ describe("Chat two-column layout", () => { }); }); }); + +describe("Chat input Shift+Enter behavior", () => { + beforeEach(() => { + capturedWsHandlers = null; + setupMocks(); + }); + + it("renders a textarea element for the chat input (AC3)", async () => { + render(); + const input = screen.getByPlaceholderText("Send a message..."); + expect(input.tagName.toLowerCase()).toBe("textarea"); + }); + + it("sends message on Enter key press without Shift (AC2)", async () => { + render(); + const input = screen.getByPlaceholderText("Send a message..."); + + await act(async () => { + fireEvent.change(input, { target: { value: "Hello" } }); + }); + await act(async () => { + fireEvent.keyDown(input, { key: "Enter", shiftKey: false }); + }); + + await waitFor(() => { + expect((input as HTMLTextAreaElement).value).toBe(""); + }); + }); + + it("does not send message on Shift+Enter (AC1)", async () => { + render(); + const input = screen.getByPlaceholderText("Send a message..."); + + await act(async () => { + fireEvent.change(input, { target: { value: "Hello" } }); + }); + await act(async () => { + fireEvent.keyDown(input, { key: "Enter", shiftKey: true }); + }); + + expect((input as HTMLTextAreaElement).value).toBe("Hello"); + }); +}); diff --git a/frontend/src/components/Chat.tsx b/frontend/src/components/Chat.tsx index 04c64f4..5d9a6a2 100644 --- a/frontend/src/components/Chat.tsx +++ b/frontend/src/components/Chat.tsx @@ -44,7 +44,7 @@ export function Chat({ projectPath, onCloseProject }: ChatProps) { const wsRef = useRef(null); const messagesEndRef = useRef(null); - const inputRef = useRef(null); + const inputRef = useRef(null); const scrollContainerRef = useRef(null); const shouldAutoScrollRef = useRef(true); const lastScrollTopRef = useRef(0); @@ -652,16 +652,18 @@ export function Chat({ projectPath, onCloseProject }: ChatProps) { alignItems: "center", }} > - setInput(e.target.value)} onKeyDown={(e) => { - if (e.key === "Enter") { + if (e.key === "Enter" && !e.shiftKey) { + e.preventDefault(); sendMessage(); } }} placeholder="Send a message..." + rows={1} style={{ flex: 1, padding: "14px 20px", @@ -673,6 +675,9 @@ export function Chat({ projectPath, onCloseProject }: ChatProps) { background: "#2f2f2f", color: "#ececec", boxShadow: "0 2px 6px rgba(0,0,0,0.02)", + resize: "none", + overflowY: "auto", + fontFamily: "inherit", }} />