diff --git a/tests/runner-e2e/runner.spec.ts b/tests/runner-e2e/runner.spec.ts index b37debb0e02..5e4de77ee77 100644 --- a/tests/runner-e2e/runner.spec.ts +++ b/tests/runner-e2e/runner.spec.ts @@ -550,6 +550,7 @@ for (const execution of executions) { let selectedRuns: RunRecord[] = []; let runtimeLeases: EnvironmentLeaseRecord[] = []; let matcherResults: MatcherResult[] = []; + let downloadedResponseProof: Awaited> | undefined; let firstTaskEvidence: RunnerE2EResult["firstTask"]; let turnTimings: NonNullable | undefined; const turnSubmissionTimesMs: number[] = []; @@ -1953,9 +1954,9 @@ for (const execution of executions) { ), ); if (execution.suite.id === "api-response-reading") { - const proof = await readResponseProof(api, issue.id, run.id); - fileObservations["api-response-proof.txt"] = proof.content; - await writeSanitizedJson(snapshotsDir, "downloaded-response-proof.json", proof, secrets); + downloadedResponseProof = await readResponseProof(api, issue.id, run.id); + fileObservations["api-response-proof.txt"] = downloadedResponseProof.content; + await writeSanitizedJson(snapshotsDir, "downloaded-response-proof.json", downloadedResponseProof, secrets); } matcherResults = await Promise.all( taskMatchers.map((matcher) => @@ -2417,7 +2418,13 @@ for (const execution of executions) { const visibleAgentReplies = page .getByTestId("task-chat-thread") .getByTestId("task-chat-agent-bubble"); - if (execution.task.flow === "warm_three_turn") { + if (execution.suite.id === "api-response-reading") { + // File delivery renders a card instead of an exact summary bubble. + // Prove the visible link points to the same independently checked bytes. + const proofLink = page.getByRole("link", { name: "Open api-response-proof.txt", exact: true }); + await expect(proofLink).toBeVisible({ timeout: 30_000 }); + await expect(proofLink).toHaveAttribute("href", `/api/attachments/${downloadedResponseProof!.attachmentId}/content`); + } else if (execution.task.flow === "warm_three_turn") { // Prove the persisted user-facing response is visible, independently // of the byte-for-byte workspace checks and lease continuity checks. expect(finalRunMessage.trim()).not.toBe("");