(page: Page)
| 158 | * Get the last assistant message text from the chat |
| 159 | */ |
| 160 | export async function getAssistantMessage(page: Page): Promise<string> { |
| 161 | // First try to get messages from the debug panel JSON |
| 162 | const messages = await getMessages(page) |
| 163 | |
| 164 | // Find the last assistant message (searching from the end) |
| 165 | for (let i = messages.length - 1; i >= 0; i--) { |
| 166 | const msg = messages[i] |
| 167 | if (msg.role === 'assistant') { |
| 168 | // Extract text content from parts |
| 169 | const textParts = msg.parts?.filter( |
| 170 | (p: any) => p.type === 'text' && p.content, |
| 171 | ) |
| 172 | if (textParts?.length > 0) { |
| 173 | return textParts.map((p: any) => p.content).join(' ') |
| 174 | } |
| 175 | // If no text parts, check if there's direct content |
| 176 | if (msg.content) { |
| 177 | return msg.content |
| 178 | } |
| 179 | } |
| 180 | } |
| 181 | |
| 182 | // Fallback: try to get text from the rendered chat messages |
| 183 | // Look for the AI indicator badge and get the adjacent prose content |
| 184 | try { |
| 185 | // The chat shows messages with an "AI" badge for assistant messages |
| 186 | // Get all message containers and find ones with assistant role indicator |
| 187 | const aiMessages = page.locator('.rounded-lg.mb-2').filter({ |
| 188 | has: page.locator('text="AI"'), |
| 189 | }) |
| 190 | const count = await aiMessages.count() |
| 191 | if (count > 0) { |
| 192 | const lastAiMessage = aiMessages.last() |
| 193 | const proseContent = lastAiMessage.locator('.prose') |
| 194 | if ((await proseContent.count()) > 0) { |
| 195 | const textContent = await proseContent |
| 196 | .first() |
| 197 | .textContent({ timeout: 5000 }) |
| 198 | return textContent || '' |
| 199 | } |
| 200 | } |
| 201 | } catch { |
| 202 | // Ignore errors in fallback |
| 203 | } |
| 204 | |
| 205 | return '' |
| 206 | } |
| 207 | |
| 208 | /** |
| 209 | * Get all messages as parsed JSON from the debug panel |
no test coverage detected