Files
PaperClipAI/tests/e2e/text-attachment-tabs.spec.ts
T
DottaandPaperclip d13aeb36f4 fix(ui): preserve review and download actions for text artifacts
Keep Markdown review documents available alongside explicit attachment tabs. Preserve direct card downloads and separate the preview action. Regressions fail with the text context enabled before the fix; 199 focused tests and both desktop/mobile browser cases pass afterward.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-09-27 16:54:33 -05:00

84 lines
6.0 KiB
TypeScript

import { randomUUID } from "node:crypto";
import fs from "node:fs/promises";
import { expect, test, type APIRequestContext } from "@playwright/test";
async function json(response: Awaited<ReturnType<APIRequestContext["get"]>>) {
expect(response.ok(), `${response.status()}: ${await response.text()}`).toBe(true);
return response.json();
}
for (const mobile of [false, true]) {
test(`opens uploaded text in task tabs and downloads the original (mobile=${mobile})`, async ({ page, request }, testInfo) => {
await page.setViewportSize(mobile ? { width: 390, height: 844 } : { width: 1440, height: 1000 });
const company = await json(await request.post("/api/companies", { data: { name: `Text files ${randomUUID()}` } }));
const issue = await json(await request.post(`/api/companies/${company.id}/issues`, {
data: { title: "Review uploaded text files", status: "backlog" },
}));
const files = [
{ name: "AGENTS.md", mimeType: "text/markdown", buffer: Buffer.from("# File charter\n\nKeep **original** bytes.\n") },
{ name: "notes.txt", mimeType: "text/plain", buffer: Buffer.from("Plain text <script>never execute</script>\n") },
];
const attachments = [];
for (const file of files) attachments.push(await json(await request.post(`/api/companies/${company.id}/issues/${issue.id}/attachments`, { multipart: { file } })));
await json(await request.post(`/api/issues/${issue.id}/comments`, {
data: { body: "Review the attached files.", attachmentIds: attachments.map((attachment) => attachment.id) },
}));
for (const [index, attachment] of attachments.entries()) {
await json(await request.post(`/api/issues/${issue.id}/work-products`, {
data: {
type: "artifact", provider: "paperclip", title: `Delivered ${files[index]!.name}`, status: "ready_for_review",
metadata: {
attachmentId: attachment.id, contentType: attachment.contentType, byteSize: attachment.byteSize,
originalFilename: files[index]!.name, contentPath: attachment.contentPath,
openPath: attachment.contentPath, downloadPath: `${attachment.contentPath}?download=1`,
},
},
}));
}
await page.goto(`/${company.issuePrefix}/issues/${issue.identifier}`);
await page.getByRole("link", { name: "Open AGENTS.md", exact: true }).click();
const panel = mobile ? page.getByTestId("mobile-task-side-panel") : page.locator("aside").filter({ has: page.getByRole("tab", { name: "AGENTS.md", exact: true }) });
await expect(panel.getByRole("tab", { name: "AGENTS.md", exact: true })).toHaveAttribute("aria-selected", "true");
await expect(panel.getByRole("heading", { name: "File charter", exact: true })).toBeVisible();
const raw = panel.getByRole("button", { name: "Raw", exact: true });
await raw.click();
await expect(raw).toHaveAttribute("aria-pressed", "true");
await expect(panel.getByLabel("AGENTS.md raw text")).toContainText("# File charter");
await panel.getByRole("button", { name: "Rendered", exact: true }).click();
await expect(panel.getByRole("heading", { name: "File charter", exact: true })).toBeVisible();
await page.screenshot({ path: testInfo.outputPath("markdown-rendered.png"), fullPage: true });
const markdownDownload = page.waitForEvent("download");
await panel.getByRole("link", { name: "Download AGENTS.md", exact: true }).click();
expect(await fs.readFile((await (await markdownDownload).path())!)).toEqual(files[0]!.buffer);
if (mobile) await panel.getByRole("button", { name: "Toggle side panel", exact: true }).click();
await page.getByRole("link", { name: "Open notes.txt", exact: true }).click();
await expect(panel.getByRole("tab", { name: "notes.txt", exact: true })).toHaveAttribute("aria-selected", "true");
await expect(panel.getByLabel("notes.txt raw text")).toContainText("<script>never execute</script>");
await expect(panel.getByRole("group", { name: "Markdown view", exact: true })).toHaveCount(0);
const textDownload = page.waitForEvent("download");
await panel.getByRole("link", { name: "Download notes.txt", exact: true }).click();
expect(await fs.readFile((await (await textDownload).path())!)).toEqual(files[1]!.buffer);
await page.screenshot({ path: testInfo.outputPath("plain-text-download.png"), fullPage: true });
await panel.getByRole("tab", { name: "AGENTS.md", exact: true }).click();
await expect(panel.getByRole("heading", { name: "File charter", exact: true })).toBeVisible();
await expect(panel.getByRole("tab", { name: "AGENTS.md", exact: true })).toHaveCount(1);
await panel.getByRole("button", { name: "Open a new tab", exact: true }).click();
await page.getByRole("option", { name: "Artifacts", exact: true }).click();
const review = panel.getByRole("button", { name: /Delivered AGENTS.md.*For review/ });
await review.click();
await expect(review).toHaveAttribute("aria-expanded", "true");
await expect(panel.getByRole("heading", { name: "File charter", exact: true })).toBeVisible();
await expect(review).toContainText("Rev 1");
await expect(panel.getByRole("link", { name: "Download Delivered AGENTS.md", exact: true })).toBeVisible();
const cardDownload = page.waitForEvent("download");
await panel.getByRole("link", { name: "Download: Delivered notes.txt", exact: true }).click();
expect(await fs.readFile((await (await cardDownload).path())!)).toEqual(files[1]!.buffer);
await expect(panel.getByRole("tab", { name: "Artifacts", exact: true })).toHaveAttribute("aria-selected", "true");
await panel.getByRole("button", { name: "Open in tab: Delivered notes.txt", exact: true }).click();
await expect(panel.getByRole("tab", { name: "notes.txt", exact: true })).toHaveAttribute("aria-selected", "true");
await panel.getByRole("tab", { name: "Artifacts", exact: true }).click();
await panel.getByRole("button", { name: "Open in tab: Delivered AGENTS.md", exact: true }).click();
await expect(panel.getByRole("tab", { name: "AGENTS.md", exact: true })).toHaveAttribute("aria-selected", "true");
});
}