diff --git a/webview-ui/src/components/history/CopyButton.tsx b/webview-ui/src/components/history/CopyButton.tsx
index c11624ab8c..3c51285703 100644
--- a/webview-ui/src/components/history/CopyButton.tsx
+++ b/webview-ui/src/components/history/CopyButton.tsx
@@ -16,7 +16,10 @@ export const CopyButton = ({ itemTask }: CopyButtonProps) => {
const onCopy = useCallback(
(e: React.MouseEvent) => {
e.stopPropagation()
- !isCopied && copy(itemTask)
+ const tempDiv = document.createElement('div');
+ tempDiv.innerHTML = itemTask;
+ const text = tempDiv.textContent || tempDiv.innerText || "";
+ !isCopied && copy(text)
},
[isCopied, copy, itemTask],
)
diff --git a/webview-ui/src/components/history/HistoryView.tsx b/webview-ui/src/components/history/HistoryView.tsx
index 64528cb0ea..79c0918a64 100644
--- a/webview-ui/src/components/history/HistoryView.tsx
+++ b/webview-ui/src/components/history/HistoryView.tsx
@@ -104,6 +104,7 @@ const HistoryView = ({ onDone }: HistoryViewProps) => {
}}
data={tasks}
data-testid="virtuoso-container"
+ initialTopMostItemIndex={0}
components={{
List: React.forwardRef((props, ref) => (
@@ -172,6 +173,7 @@ const HistoryView = ({ onDone }: HistoryViewProps) => {
wordBreak: "break-word",
overflowWrap: "anywhere",
}}
+ data-testid="task-content"
dangerouslySetInnerHTML={{ __html: item.task }}
/>
diff --git a/webview-ui/src/components/history/__tests__/HistoryView.test.tsx b/webview-ui/src/components/history/__tests__/HistoryView.test.tsx
index 4470e5d02d..379f7ccda7 100644
--- a/webview-ui/src/components/history/__tests__/HistoryView.test.tsx
+++ b/webview-ui/src/components/history/__tests__/HistoryView.test.tsx
@@ -8,7 +8,6 @@ import { vscode } from "../../../utils/vscode"
jest.mock("../../../context/ExtensionStateContext")
jest.mock("../../../utils/vscode")
jest.mock("../../../i18n/TranslationContext")
-
jest.mock("react-virtuoso", () => ({
Virtuoso: ({ data, itemContent }: any) => (
@@ -71,6 +70,12 @@ describe("HistoryView", () => {
})
it("handles search functionality", () => {
+ // Setup clipboard mock that resolves immediately
+ const mockClipboard = {
+ writeText: jest.fn().mockResolvedValue(undefined),
+ }
+ Object.assign(navigator, { clipboard: mockClipboard })
+
const onDone = jest.fn()
render()
@@ -97,6 +102,14 @@ describe("HistoryView", () => {
// Verify radio button is checked
const updatedRadio = within(radioGroup).getByTestId("radio-most-relevant")
expect(updatedRadio).toBeInTheDocument()
+
+ // Verify copy the plain text content of the task when the copy button is clicked
+ const taskContainer = screen.getByTestId("virtuoso-item-1")
+ fireEvent.mouseEnter(taskContainer)
+ const copyButton = within(taskContainer).getByTestId("copy-prompt-button")
+ fireEvent.click(copyButton)
+ const taskContent = within(taskContainer).getByTestId("task-content")
+ expect(navigator.clipboard.writeText).toHaveBeenCalledWith(taskContent.textContent)
})
it("handles sort options correctly", async () => {