fix: label pasted text attachments "Show in text field" (#120799)

This commit is contained in:
Vyctor H. Brzezowski
2026-08-09 01:01:12 -03:00
committed by GitHub
parent 632808a674
commit df2edbc9a6
4 changed files with 65 additions and 9 deletions
@@ -0,0 +1,55 @@
import { expect, it } from "vitest";
import { installMockGateway } from "../test-helpers/control-ui-e2e.ts";
import { createControlUiE2eSuite } from "./control-ui-e2e-suite.test-support.ts";
const suite = createControlUiE2eSuite({
name: "Control UI pasted text field action",
startServerBeforeBrowser: true,
unavailableMessage: (executablePath) => `Playwright Chromium is unavailable at ${executablePath}`,
});
const pastedText = `Quarterly launch plan\n\n${"x".repeat(1100)}`;
suite.define(() => {
it("returns a pasted text attachment to the text field without sending", async () => {
await suite.withPage(
{
locale: "en-US",
reducedMotion: "reduce",
serviceWorkers: "block",
viewport: { height: 900, width: 1280 },
},
async ({ page }) => {
const gateway = await installMockGateway(page);
await page.goto(`${suite.server.baseUrl}chat`);
const composer = page.locator(".agent-chat__composer-combobox textarea");
await composer.waitFor({ state: "visible" });
await composer.evaluate((element, text) => {
const clipboard = new DataTransfer();
clipboard.setData("text/plain", text);
element.dispatchEvent(
new ClipboardEvent("paste", {
bubbles: true,
cancelable: true,
clipboardData: clipboard,
}),
);
}, pastedText);
const showInTextField = page.getByRole("button", {
name: "Show in text field",
exact: true,
});
await showInTextField.waitFor({ state: "visible" });
expect((await showInTextField.textContent())?.trim()).toBe("Show in text field");
await showInTextField.click();
await expect.poll(() => page.locator(".chat-attachment-thumb").count()).toBe(0);
await expect.poll(() => composer.inputValue()).toBe(pastedText);
expect(await gateway.getRequests("chat.send")).toHaveLength(0);
},
);
});
});
+1
View File
@@ -5151,6 +5151,7 @@ export const en: TranslationMap = {
},
attachments: {
attachedFile: "Attached file",
showInTextField: "Show in text field",
outsideAllowedFolders: "Outside allowed folders",
unavailable: "Unavailable",
checking: "Checking...",
+7 -7
View File
@@ -4408,8 +4408,8 @@ describe("chat attachment picker", () => {
expect(container.querySelector(".chat-attachment-file__name")?.textContent).toContain(
"First words from a l...",
);
expect(container.querySelector(".chat-attachment-text-action")?.textContent).toContain(
"Restore",
expect(container.querySelector(".chat-attachment-text-action")?.textContent?.trim()).toBe(
"Show in text field",
);
});
@@ -4441,7 +4441,7 @@ describe("chat attachment picker", () => {
expect(onAttachmentsChange).not.toHaveBeenCalled();
});
it("moves a pasted text attachment back into the composer", async () => {
it("shows a pasted text attachment in the composer text field", async () => {
const onAttachmentsChange = vi.fn();
const firstRender = renderChatView({ onAttachmentsChange });
const textarea = getComposerTextarea(firstRender);
@@ -4467,13 +4467,13 @@ describe("chat attachment picker", () => {
}),
'renderChatView({ attachments: [attachment], draft: "intro", getDraft:... test invariant',
);
const showButton = requireElement(
const showInTextFieldButton = requireElement(
preview,
'[aria-label="Restore"]',
"show pasted text button",
'[aria-label="Show in text field"]',
"show pasted text in text field button",
) as HTMLButtonElement;
showButton.click();
showInTextFieldButton.click();
expect(onShowAttachmentsChange).toHaveBeenCalledWith([]);
expect(onDraftChange).toHaveBeenCalledWith(`intro\n\n${pastedText}`);
@@ -550,11 +550,11 @@ export function renderAttachmentPreview(props: ChatAttachmentControlsProps) {
<button
class="chat-attachment-text-action"
type="button"
aria-label=${t("worktrees.restore")}
aria-label=${t("chat.attachments.showInTextField")}
?disabled=${props.disabled}
@click=${() => showPastedTextInComposer(att, props)}
>
${t("worktrees.restore")}
${t("chat.attachments.showInTextField")}
<span aria-hidden="true">${icons.chevronRight}</span>
</button>
</span>