feat(FN-3037): add focus-visible styling to AgentLogViewer log action butto

Adds `focus-visible` styling to action buttons in the AgentLogViewer component, improving keyboard accessibility for interactive button elements.

Fusion-Task-Id: FN-3037
This commit is contained in:
Fusion
2026-04-30 19:16:41 -07:00
committed by gsxdsm
parent c553920b40
commit 135b0f0b16
13 changed files with 593 additions and 432 deletions

View File

@@ -1123,7 +1123,7 @@ describe("AgentLogViewer", () => {
const detail = container.querySelector(".agent-log-tool-detail");
expect(detail).toBeTruthy();
expect(detail!.textContent).toContain(longDetail);
expect(detail!.textContent!.length).toBeGreaterThan(5000); // " — " prefix adds a few chars
expect(detail!.textContent!.length).toBe(5000);
});
it("renders multiline text content without truncation", () => {
@@ -1168,6 +1168,16 @@ describe("AgentLogViewer", () => {
expect(detail).toBeTruthy();
expect(detail!.textContent).toContain(longDetail);
});
it("preserves raw whitespace in tool detail blocks", () => {
const detailText = "stdout:\n line one\n indented line two\n";
const entries = [makeEntry({ text: "Bash", type: "tool_result", detail: detailText })];
const { container } = render(<AgentLogViewer entries={entries} loading={false} />);
const detail = container.querySelector(".agent-log-tool-detail") as HTMLElement;
expect(detail).toBeTruthy();
expect(detail.tagName).toBe("PRE");
expect(detail.textContent).toBe(detailText);
});
});
describe("markdown rendering", () => {
@@ -1350,6 +1360,8 @@ describe("AgentLogViewer", () => {
const textSpans = container.querySelectorAll(".agent-log-text");
expect(textSpans).toHaveLength(1);
expect(textSpans[0].textContent).toContain("**bold** and *italic*");
const plainBlock = textSpans[0].querySelector(".agent-log-plain-block") as HTMLElement;
expect(plainBlock).toBeTruthy();
// Plain mode should remove markdown rendering/prose container
expect(textSpans[0].querySelector(".markdown-body")).toBeNull();
expect(textSpans[0].querySelector("strong")).toBeNull();
@@ -1407,6 +1419,18 @@ describe("AgentLogViewer", () => {
expect(strong!.textContent).toBe("bold");
});
it("preserves line breaks in plain text mode for thinking entries", () => {
const entries = [makeEntry({ text: "line1\nline2\nline3", type: "thinking", agent: "executor" })];
const { container } = render(<AgentLogViewer entries={entries} loading={false} />);
const toggle = container.querySelector("[data-testid='agent-log-mode-toggle']") as HTMLButtonElement;
fireEvent.click(toggle);
const plainThinking = container.querySelector(".agent-log-thinking .agent-log-plain-block") as HTMLElement;
expect(plainThinking).toBeTruthy();
expect(plainThinking.textContent).toContain("line1\nline2\nline3");
});
it("shows raw markdown syntax literally in plain text mode for text entries", () => {
const entries = [
makeEntry({ text: "## Heading\n\n- item 1\n- item 2\n\n`code` and **bold**" }),

View File

@@ -229,10 +229,10 @@ describe("TaskDetailModal", () => {
it("styles agent log viewer scroll container scrollbar rules", () => {
const css = loadAllAppCss();
expectBaseRule(css, ".detail-section--agent-log .agent-log-viewer-scroll", "scrollbar-color: var(--border) transparent;");
expectBaseRule(css, ".detail-section--agent-log .agent-log-viewer-scroll", "scrollbar-width: thin;");
expectBaseRule(css, ".detail-section--agent-log .agent-log-viewer-scroll::-webkit-scrollbar", "width: 6px;");
expectBaseRule(css, ".detail-section--agent-log .agent-log-viewer-scroll::-webkit-scrollbar-thumb", "background: var(--border);");
expectBaseRule(css, ".agent-log-viewer-scroll", "scrollbar-color: var(--border) transparent;");
expectBaseRule(css, ".agent-log-viewer-scroll", "scrollbar-width: thin;");
expectBaseRule(css, ".agent-log-viewer-scroll::-webkit-scrollbar", "width: 6px;");
expectBaseRule(css, ".agent-log-viewer-scroll::-webkit-scrollbar-thumb", "background: var(--border);");
});
it("renders markdown-body without detail-prompt class when prompt exists", () => {