| 185 | // The earlier repro only waited for text to start appearing, which exercised an |
| 186 | // in-flight mock-stream resume gap rather than a completed-chat switch. |
| 187 | async function waitForMockResponse(page: Page, marker: string): Promise<void> { |
| 188 | await page.waitForFunction( |
| 189 | (marker: string) => { |
| 190 | const messages = document.querySelectorAll("[data-message-block]"); |
| 191 | const lastMessage = messages.length > 0 ? messages[messages.length - 1] : null; |
| 192 | const lastMessageText = lastMessage?.textContent ?? ""; |
| 193 | const actionButtonCount = |
| 194 | lastMessage?.querySelectorAll("[data-message-meta-actions] button").length ?? 0; |
| 195 | return lastMessageText.includes(`Mock response: ${marker}`) && actionButtonCount > 1; |
| 196 | }, |
| 197 | marker, |
| 198 | { timeout: 60_000 } |
| 199 | ); |
| 200 | } |
| 201 | |
| 202 | async function captureOpenTransition(args: { |
| 203 | page: Page; |