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(``);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");