Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,675 changes: 1,675 additions & 0 deletions roo-code-messages.log
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops - this is the logging from the roomote agent. I'll add this to .gitignore.

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions webview-ui/jest.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,10 @@ module.exports = {
"^@src/utils/highlighter$": "<rootDir>/src/__mocks__/utils/highlighter.ts",
"^shiki$": "<rootDir>/src/__mocks__/shiki.ts",
"^react-markdown$": "<rootDir>/src/__mocks__/react-markdown.tsx",
"^remark-gfm$": "<rootDir>/src/__mocks__/remark-gfm.ts",
},
reporters: [["jest-simple-dot-reporter", {}]],
transformIgnorePatterns: [
"/node_modules/(?!(shiki|rehype-highlight|react-remark|unist-util-visit|unist-util-find-after|vfile|unified|bail|is-plain-obj|trough|vfile-message|unist-util-stringify-position|mdast-util-from-markdown|mdast-util-to-string|micromark|decode-named-character-reference|character-entities|markdown-table|zwitch|longest-streak|escape-string-regexp|unist-util-is|hast-util-to-text|@vscode/webview-ui-toolkit|@microsoft/fast-react-wrapper|@microsoft/fast-element|@microsoft/fast-foundation|@microsoft/fast-web-utilities|exenv-es6|vscrui)/)",
"/node_modules/(?!(shiki|rehype-highlight|react-remark|remark-gfm|mdast-util-gfm|mdast-util-gfm-table|mdast-util-gfm-strikethrough|mdast-util-gfm-task-list-item|mdast-util-gfm-autolink-literal|mdast-util-gfm-footnote|micromark-extension-gfm|micromark-extension-gfm-table|micromark-extension-gfm-strikethrough|micromark-extension-gfm-task-list-item|micromark-extension-gfm-autolink-literal|micromark-extension-gfm-footnote|unist-util-visit|unist-util-visit-parents|unist-util-find-after|unist-util-is|unist-util-stringify-position|vfile|vfile-message|unified|bail|is-plain-obj|trough|mdast-util-from-markdown|mdast-util-to-string|micromark|decode-named-character-reference|character-entities|markdown-table|zwitch|longest-streak|escape-string-regexp|hast-util-to-text|@vscode/webview-ui-toolkit|@microsoft/fast-react-wrapper|@microsoft/fast-element|@microsoft/fast-foundation|@microsoft/fast-web-utilities|exenv-es6|vscrui)/)",
],
roots: ["<rootDir>"],
moduleDirectories: ["node_modules", "src"],
Expand Down
3 changes: 0 additions & 3 deletions webview-ui/src/__mocks__/remark-gfm.ts

This file was deleted.

68 changes: 68 additions & 0 deletions webview-ui/src/components/common/MarkdownBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { memo, useEffect } from "react"
import { useRemark } from "react-remark"
import styled from "styled-components"
import { visit } from "unist-util-visit"
import remarkGfm from "remark-gfm"

import { vscode } from "@src/utils/vscode"
import { useExtensionState } from "@src/context/ExtensionStateContext"
Expand Down Expand Up @@ -119,12 +120,79 @@ const StyledMarkdown = styled.div`
text-decoration-color: var(--vscode-textLink-activeForeground);
}
}

/* Table styles for markdown tables */
table {
border-collapse: collapse;
margin: 1em 0;
width: 100%;
overflow-x: auto;
display: block;
white-space: nowrap;
}

table tbody {
display: table;
width: 100%;
}

table thead {
display: table-header-group;
}

table tr {
border-top: 1px solid var(--vscode-panel-border, var(--vscode-widget-border, #454545));
display: table-row;
}

table tr:nth-child(2n) {
background-color: var(--vscode-editor-background);
}

table th,
table td {
border: 1px solid var(--vscode-panel-border, var(--vscode-widget-border, #454545));
padding: 6px 13px;
display: table-cell;
text-align: left;
vertical-align: top;
}

table th {
font-weight: 600;
background-color: var(--vscode-editor-background);
color: var(--vscode-foreground);
}

table td {
color: var(--vscode-foreground);
}

/* Handle table overflow for responsive design */
table {
display: table;
width: 100%;
overflow-x: auto;
white-space: nowrap;
}

@media (max-width: 600px) {
table {
font-size: 0.875em;
}

table th,
table td {
padding: 4px 8px;
}
}
`

const MarkdownBlock = memo(({ markdown }: MarkdownBlockProps) => {
const { theme } = useExtensionState()
const [reactContent, setMarkdown] = useRemark({
remarkPlugins: [
remarkGfm, // Enable GitHub Flavored Markdown (includes tables)
remarkUrlToLink,
() => {
return (tree) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import "@testing-library/jest-dom"

// Simple test to verify the fix works
describe("MarkdownBlock Table Fix", () => {
it("should now use the real remark-gfm plugin", async () => {
// This test verifies that the real remark-gfm plugin is now being used
// (no more mock blocking it)
const { default: remarkGfm } = await import("remark-gfm")

// The real plugin should be a proper function
expect(typeof remarkGfm).toBe("function")

// The function should not be an empty mock function
expect(remarkGfm.toString()).not.toBe("() => {}")
expect(remarkGfm.toString()).not.toBe("function () { }")

// This confirms that the real remark-gfm plugin is now available,
// which should enable proper table rendering
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import React from "react"
import { render, screen } from "@testing-library/react"
import "@testing-library/jest-dom"
import MarkdownBlock from "../MarkdownBlock"
import { ExtensionStateContextProvider } from "@src/context/ExtensionStateContext"

// Mock the vscode module
jest.mock("@src/utils/vscode", () => ({
vscode: {
postMessage: jest.fn(),
},
}))

// Create a test wrapper with the required context
const TestWrapper = ({ children }: { children: React.ReactNode }) => {
return <ExtensionStateContextProvider>{children}</ExtensionStateContextProvider>
}

describe("MarkdownBlock Table Rendering", () => {
it("should render markdown tables as HTML tables", async () => {
const markdownWithTable = `
# Test Document

Here's a test table:

| Name | Age | City |
|------|-----|------|
| John | 25 | NYC |
| Jane | 30 | LA |
| Bob | 35 | Chicago |

End of document.
`

render(
<TestWrapper>
<MarkdownBlock markdown={markdownWithTable} />
</TestWrapper>,
)

// Wait for the component to render
await screen.findByText("Test Document")

// Check that table elements are rendered
const table = screen.getByRole("table")
expect(table).toBeInTheDocument()

// Check for table headers
expect(screen.getByRole("columnheader", { name: "Name" })).toBeInTheDocument()
expect(screen.getByRole("columnheader", { name: "Age" })).toBeInTheDocument()
expect(screen.getByRole("columnheader", { name: "City" })).toBeInTheDocument()

// Check for table data
expect(screen.getByRole("cell", { name: "John" })).toBeInTheDocument()
expect(screen.getByRole("cell", { name: "25" })).toBeInTheDocument()
expect(screen.getByRole("cell", { name: "NYC" })).toBeInTheDocument()
expect(screen.getByRole("cell", { name: "Jane" })).toBeInTheDocument()
expect(screen.getByRole("cell", { name: "30" })).toBeInTheDocument()
expect(screen.getByRole("cell", { name: "LA" })).toBeInTheDocument()
expect(screen.getByRole("cell", { name: "Bob" })).toBeInTheDocument()
expect(screen.getByRole("cell", { name: "35" })).toBeInTheDocument()
expect(screen.getByRole("cell", { name: "Chicago" })).toBeInTheDocument()
})

it("should render tables with proper styling", async () => {
const markdownWithTable = `
| Header 1 | Header 2 |
|----------|----------|
| Cell 1 | Cell 2 |
`

render(
<TestWrapper>
<MarkdownBlock markdown={markdownWithTable} />
</TestWrapper>,
)

const table = await screen.findByRole("table")
expect(table).toBeInTheDocument()

// Check that the table has the expected structure
const headers = screen.getAllByRole("columnheader")
expect(headers).toHaveLength(2)

const cells = screen.getAllByRole("cell")
expect(cells).toHaveLength(2)
})

it("should handle empty tables gracefully", async () => {
const markdownWithEmptyTable = `
| Header 1 | Header 2 |
|----------|----------|
`

render(
<TestWrapper>
<MarkdownBlock markdown={markdownWithEmptyTable} />
</TestWrapper>,
)

const table = await screen.findByRole("table")
expect(table).toBeInTheDocument()

// Should have headers but no data rows
const headers = screen.getAllByRole("columnheader")
expect(headers).toHaveLength(2)

const cells = screen.queryAllByRole("cell")
expect(cells).toHaveLength(0)
})

it("should not render raw markdown table syntax", async () => {
const markdownWithTable = `
| Name | Age |
|------|-----|
| John | 25 |
`

render(
<TestWrapper>
<MarkdownBlock markdown={markdownWithTable} />
</TestWrapper>,
)

// Should not contain raw markdown table syntax
expect(screen.queryByText("|------|-----|")).not.toBeInTheDocument()
expect(screen.queryByText("| Name | Age |")).not.toBeInTheDocument()
expect(screen.queryByText("| John | 25 |")).not.toBeInTheDocument()

// Should contain the actual table content
expect(screen.getByRole("table")).toBeInTheDocument()
expect(screen.getByRole("columnheader", { name: "Name" })).toBeInTheDocument()
expect(screen.getByRole("columnheader", { name: "Age" })).toBeInTheDocument()
expect(screen.getByRole("cell", { name: "John" })).toBeInTheDocument()
expect(screen.getByRole("cell", { name: "25" })).toBeInTheDocument()
})
})