From 1d529b4e95d0c4ea60561c261b2bde4b1710c863 Mon Sep 17 00:00:00 2001 From: Dotta Date: Thu, 5 Nov 2026 22:57:32 -0600 Subject: [PATCH] test(chat): match production confirmation prompt whitespace Co-Authored-By: Paperclip --- .../external-company-secret-confirmation-ui.test.ts | 12 ++++++++++++ .../external-company-secret-confirmation.ts | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/tests/runner-e2e/chat-catalog-domains/external-company-secret-confirmation-ui.test.ts b/tests/runner-e2e/chat-catalog-domains/external-company-secret-confirmation-ui.test.ts index 6204af94c40..e95ce87cb14 100644 --- a/tests/runner-e2e/chat-catalog-domains/external-company-secret-confirmation-ui.test.ts +++ b/tests/runner-e2e/chat-catalog-domains/external-company-secret-confirmation-ui.test.ts @@ -1,5 +1,6 @@ import {expect,it} from "vitest"; import {chromium} from "@playwright/test"; +import {createRequire} from "node:module"; import {readFile} from "node:fs/promises"; import {acceptCompanySecretConfirmation,companySecretConfirmationHandoff,visibleCompanySecretConfirmationURL} from "./external-company-secret-confirmation.js"; import {deploymentSecretGuidance} from "./external-company-secret.js"; @@ -19,3 +20,14 @@ it.skipIf(process.env.PAPERCLIP_CHAT_EVAL_SECRET_ROUTE_CANARY!=="1")("uses the a await page.close(); }}finally{await browser.close();} },15000); + +it.skipIf(process.env.PAPERCLIP_CHAT_EVAL_SECRET_ROUTE_CANARY!=="1")("matches whitespace rendered by the actual production confirmation prompt",async()=>{ + const source=await readFile(new URL("../../../ui/src/components/IssueThreadInteractionCard.tsx",import.meta.url),"utf8"); + const jsx=source.match(/
]*>\s*\{interaction.payload.prompt\}\s*<\/div>/)?.[0];expect(jsx).toBeDefined(); + const require=createRequire(new URL("../../../ui/package.json",import.meta.url)),React=require("react"),{renderToStaticMarkup}=require("react-dom/server"),{transformSync}=require("esbuild"); + const render=new Function("React","interaction","compact",transformSync(`const rendered = (${jsx});`,{loader:"tsx",jsxFactory:"React.createElement"}).code+";return rendered;"); + const prompt="In Settings > Secrets (`/RUN/company/settings/secrets`),\n choose New secret and save the value, then accept this card. Do not paste it in chat."; + const markup=renderToStaticMarkup(render(React,{payload:{prompt}},true)); + const browser=await chromium.launch({headless:true,...(process.env.PAPERCLIP_RUNNER_E2E_CHROMIUM_EXECUTABLE?{executablePath:process.env.PAPERCLIP_RUNNER_E2E_CHROMIUM_EXECUTABLE}:{})}); + try{const page=await browser.newPage();await page.setContent(`
${markup}
`);expect(await visibleCompanySecretConfirmationURL(page,{prompt},"http://127.0.0.1:3300","RUN",()=>700)).toBe("http://127.0.0.1:3300/RUN/company/settings/secrets");await page.locator("[data-decision-prompt]").evaluate(node=>node.textContent="Different secure-save request");await expect(visibleCompanySecretConfirmationURL(page,{prompt},"http://127.0.0.1:3300","RUN",()=>700)).rejects.toThrow();}finally{await browser.close();} +},10000); diff --git a/tests/runner-e2e/chat-catalog-domains/external-company-secret-confirmation.ts b/tests/runner-e2e/chat-catalog-domains/external-company-secret-confirmation.ts index e63fbde653b..f981057279c 100644 --- a/tests/runner-e2e/chat-catalog-domains/external-company-secret-confirmation.ts +++ b/tests/runner-e2e/chat-catalog-domains/external-company-secret-confirmation.ts @@ -31,7 +31,7 @@ export async function visibleCompanySecretConfirmationURL(page:Page,handoff:{pro for(let p=node.parentElement;p;p=p.parentElement){const style=getComputedStyle(p),box=p.getBoundingClientRect();if(/hidden|clip/.test(style.overflowX)&&(rect.right<=box.left||rect.left>=box.right)||/hidden|clip/.test(style.overflowY)&&(rect.bottom<=box.top||rect.top>=box.bottom))throw new Error("Company confirmation is clipped");} return (node as HTMLElement).innerText; }); - if(text!==handoff.prompt)throw new Error("Company confirmation visible text changed"); + if(text.replace(/\s+/g," ").trim()!==handoff.prompt.replace(/\s+/g," ").trim())throw new Error("Company confirmation visible text changed"); const supported=(token:string)=>{try{const url=new URL(token,origin);return url.origin===origin&&url.pathname===`/${prefix}/company/settings/secrets`&&!url.username&&!url.password&&!url.search&&!url.hash?url.href:undefined;}catch{return;}}; const tokens=text.match(/https?:\/\/[^\s`<>"')]+|(?"')]+/g)??[],urls=tokens.map(supported); if(!tokens.length||urls.some(url=>!url)||new Set(urls).size!==1)throw new Error("Company confirmation lacks its actual current-company route");