mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-31 06:04:11 +01:00
Restrict renamed labels to existing product chips. Reuse the company routing helper and current task URL, with browser regressions for prefixes, fragments and wrong task/company targets. Co-Authored-By: Paperclip <noreply@paperclip.ing>
48 lines
3.4 KiB
TypeScript
48 lines
3.4 KiB
TypeScript
import { expect, test } from "@playwright/test";
|
|
import { readBoundTaskFinalReply } from "./native-task-reply.js";
|
|
|
|
const markdown = "I **couldn't retrieve** the pages. See [Connection outcome](/QA/issues/QA-123#document-outcome).";
|
|
const rendered = "I <strong>couldn't retrieve</strong> the pages. See <a data-mention-kind='issue' href='/QA/issues/QA-123#document-outcome'><svg aria-hidden='true'></svg>QA-123</a>.";
|
|
const run = { id: "final-run", companyId: "company", agentId: "agent", status: "succeeded", runtimeMode: "native",
|
|
resultJson: { presentationDecision: { commentId: "selected" } } };
|
|
const comment = { id: "selected", authorAgentId: "agent", createdByRunId: run.id, body: markdown };
|
|
|
|
for (const [name, content, passes] of [
|
|
["decorated document link and bold text", rendered, true],
|
|
["ordinary link with its source label", rendered.replace(" data-mention-kind='issue'", "").replace(">QA-123</a>", ">Connection outcome</a>"), true],
|
|
["renamed ordinary link", rendered.replace(" data-mention-kind='issue'", ""), false],
|
|
["wrong destination", rendered.replace("#document-outcome", "#document-other"), false],
|
|
["missing link", rendered.replace(/<a.*?<\/a>/, "QA-123"), false],
|
|
["extra visible text", rendered + " Extra.", false],
|
|
["hidden source text", rendered.replace("couldn't retrieve", "<span hidden>couldn't retrieve</span>"), false],
|
|
] as const) test(`reloaded task reply: ${name}`, async ({ page }) => {
|
|
await page.route("https://fixture.test/task", route => route.fulfill({ contentType: "text/html", body:
|
|
`<div data-testid='task-chat-thread'><div data-thread-anchor='selected'><div data-testid='task-chat-agent-bubble'>${content}</div></div></div>` }));
|
|
await page.goto("https://fixture.test/task");
|
|
const result = readBoundTaskFinalReply({ page, runId: run.id, agentId: "agent", deadlineAt: Date.now() + (passes ? 3000 : 300),
|
|
load: async () => ({ run, comments: [comment], events: [] }) });
|
|
if (passes) {
|
|
const receipt = await result;
|
|
expect(receipt.source).toBe("posted-comment");
|
|
expect(receipt.sourceBody).toBe(markdown);
|
|
expect(receipt.body).toBe(content.includes(">Connection outcome</a>") ? "I couldn't retrieve the pages. See Connection outcome." : "I couldn't retrieve the pages. See QA-123.");
|
|
expect(receipt.observedAfterReload).toBe(true);
|
|
} else await expect(result).rejects.toThrow();
|
|
});
|
|
|
|
for (const [sourceHref, renderedHref, passes] of [
|
|
["/issues/QA-123#document-outcome", "/QA/issues/QA-123#document-outcome", true],
|
|
["#document-outcome", "/QA/issues/QA-123#document-outcome", true],
|
|
["/issues/QA-123#document-outcome", "/OTHER/issues/QA-123#document-outcome", false],
|
|
["#document-outcome", "/QA/issues/QA-999#document-outcome", false],
|
|
] as const) test(`reloaded link ${sourceHref} to ${renderedHref}`, async ({ page }) => {
|
|
const url = "https://fixture.test/QA/issues/QA-123";
|
|
await page.route(url, route => route.fulfill({ contentType: "text/html", body:
|
|
`<div data-testid='task-chat-thread'><div data-thread-anchor='selected'><div data-testid='task-chat-agent-bubble'>Read <a href='${renderedHref}'>Outcome</a></div></div></div>` }));
|
|
await page.goto(url);
|
|
const result = readBoundTaskFinalReply({ page, runId: run.id, agentId: "agent", deadlineAt: Date.now() + (passes ? 3000 : 300),
|
|
load: async () => ({ run, comments: [{ ...comment, body: `Read [Outcome](${sourceHref})` }], events: [] }) });
|
|
if (passes) expect((await result).pageUrl).toBe(url);
|
|
else await expect(result).rejects.toThrow();
|
|
});
|