dev1/tests/e2e/28-chat-support-throttle.spec.mjs

71 lines
2.9 KiB
JavaScript

// @ts-check
import { test, expect } from '@playwright/test';
import { loadTestUser } from '../utils/testUser.js';
test.describe('@p0 Chat drawer — stream throttling (429) + recovery', () => {
test.setTimeout(20000);
test('second prompt hits 429 → shows fallback; third succeeds', async ({ page }) => {
const user = loadTestUser();
// Stub threads (list/create + preload)
const threadId = 'thread-throttle';
await page.route('**/api/chat/threads', async route => {
if (route.request().method() === 'GET') {
return route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ threads: [] }) });
}
if (route.request().method() === 'POST') {
return route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ id: threadId }) });
}
return route.fallback();
});
await page.route(`**/api/chat/threads/${threadId}`, async route => {
if (route.request().method() === 'GET') {
return route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ messages: [] }) });
}
return route.fallback();
});
// Stream endpoint: 1st -> 200, 2nd -> 429, 3rd -> 200
let callCount = 0;
await page.route('**/api/chat/threads/*/stream', async route => {
callCount += 1;
if (callCount === 2) {
return route.fulfill({ status: 429, contentType: 'text/event-stream', body: '' });
}
const text = callCount === 1 ? 'First OK reply.' : 'Recovered OK reply.';
return route.fulfill({ status: 200, headers: { 'Content-Type': 'text/event-stream' }, body: text + '\n' });
});
// Sign in
await page.context().clearCookies();
await page.goto('/signin', { waitUntil: 'networkidle' });
await page.getByPlaceholder('Username', { exact: true }).fill(user.username);
await page.getByPlaceholder('Password', { exact: true }).fill(user.password);
await page.getByRole('button', { name: /^Sign In$/ }).click();
await page.waitForURL('**/signin-landing**', { timeout: 15000 });
// Open chat
await page.getByRole('button', { name: /^Open chat$/i }).click();
// 1) First send → success
const input = page.getByPlaceholder('Ask me anything…');
const send = page.getByRole('button', { name: /^Send$/i });
await input.fill('hello 1');
await send.click();
await expect(page.getByText(/^First OK reply\./)).toBeVisible({ timeout: 8000 });
// 2) Second send → 429 throttled → fallback error appears
await input.fill('hello 2');
await send.click();
await expect(
page.getByText(/Sorry — something went wrong\. Please try again later\./i)
).toBeVisible({ timeout: 8000 });
// 3) Third send → recovery success
await input.fill('hello 3');
await send.click();
await expect(page.getByText(/^Recovered OK reply\./)).toBeVisible({ timeout: 8000 });
});
});