diff --git a/frontend/src/components/MessageItem.test.tsx b/frontend/src/components/MessageItem.test.tsx index 036d685..c5a36d7 100644 --- a/frontend/src/components/MessageItem.test.tsx +++ b/frontend/src/components/MessageItem.test.tsx @@ -59,6 +59,24 @@ describe("MessageItem component (Story 178 AC3)", () => { expect(screen.getByText("Read(src/main.rs)")).toBeInTheDocument(); }); + it("user messages use pre-wrap whitespace to preserve newlines (Story 195)", () => { + const { container } = render( + , + ); + + // The bubble div wrapping user text must have white-space: pre-wrap + // so newlines are rendered as visual line breaks + const divs = Array.from(container.querySelectorAll("div")); + const bubble = divs.find( + (div) => + div.style.whiteSpace === "pre-wrap" && + div.textContent?.includes("First line"), + ); + expect(bubble).toBeDefined(); + }); + it("is wrapped in React.memo (has displayName or $$typeof memo)", () => { // React.memo wraps the component — verify the export is memoized // by checking that the component has a memo wrapper diff --git a/frontend/src/components/MessageItem.tsx b/frontend/src/components/MessageItem.tsx index 686cd92..8846cad 100644 --- a/frontend/src/components/MessageItem.tsx +++ b/frontend/src/components/MessageItem.tsx @@ -53,7 +53,8 @@ function MessageItemInner({ msg }: MessageItemProps) { fontFamily: msg.role === "tool" ? "monospace" : "inherit", fontSize: msg.role === "tool" ? "0.85em" : "1em", fontWeight: "500", - whiteSpace: msg.role === "tool" ? "pre-wrap" : "normal", + whiteSpace: + msg.role === "tool" || msg.role === "user" ? "pre-wrap" : "normal", lineHeight: "1.6", }} >