93 lines
3.2 KiB
JavaScript
93 lines
3.2 KiB
JavaScript
// @ts-check
|
|
import { test, expect } from '@playwright/test';
|
|
import { loadTestUser } from '../utils/testUser.js';
|
|
|
|
test.describe('@p0 Chat drawer — Support stream', () => {
|
|
test.setTimeout(20000);
|
|
|
|
test('FAB opens Support → create/load thread → send prompt → assistant reply appears', async ({ page }) => {
|
|
const user = loadTestUser();
|
|
|
|
// ---- Stub chat API before the app mounts (ensureSupportThread runs on mount) ----
|
|
let createdId = 'thread-e2e';
|
|
// list existing -> none
|
|
await page.route('**/api/chat/threads', async (route) => {
|
|
if (route.request().method() === 'GET') {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: 'application/json',
|
|
body: JSON.stringify({ threads: [] }),
|
|
});
|
|
return;
|
|
}
|
|
// create new
|
|
if (route.request().method() === 'POST') {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: 'application/json',
|
|
body: JSON.stringify({ id: createdId }),
|
|
});
|
|
return;
|
|
}
|
|
await route.fallback();
|
|
});
|
|
|
|
// preload thread messages -> empty
|
|
await page.route(`**/api/chat/threads/${createdId}`, async (route) => {
|
|
if (route.request().method() === 'GET') {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: 'application/json',
|
|
body: JSON.stringify({ messages: [] }),
|
|
});
|
|
return;
|
|
}
|
|
await route.fallback();
|
|
});
|
|
|
|
// streaming endpoint -> return simple line chunks as text/event-stream
|
|
await page.route('**/api/chat/threads/*/stream', async (route) => {
|
|
const reply = 'E2E assistant reply.';
|
|
await route.fulfill({
|
|
status: 200,
|
|
headers: { 'Content-Type': 'text/event-stream' },
|
|
body: `${reply}\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 via FAB (forces Support pane) ----
|
|
const fab = page.getByRole('button', { name: /^Open chat$/i });
|
|
await expect(fab).toBeVisible({ timeout: 5000 });
|
|
await fab.click();
|
|
|
|
// Drawer visible; Support tab selected
|
|
const supportTab = page.getByRole('button', { name: /^Aptiva\s*Support$/i });
|
|
await expect(supportTab).toBeVisible({ timeout: 5000 });
|
|
|
|
// Input and Send present
|
|
const input = page.getByPlaceholder('Ask me anything…');
|
|
const send = page.getByRole('button', { name: /^Send$/i });
|
|
await expect(input).toBeVisible();
|
|
await expect(send).toBeDisabled(); // empty prompt
|
|
|
|
// Send a message -> should render user bubble + streamed assistant reply
|
|
await input.fill('Hi from E2E');
|
|
await expect(send).toBeEnabled();
|
|
await send.click();
|
|
|
|
// User bubble
|
|
await expect(page.getByText(/^Hi from E2E$/)).toBeVisible({ timeout: 5000 });
|
|
|
|
// Assistant reply (from our stream stub)
|
|
await expect(page.getByText(/^E2E assistant reply\./)).toBeVisible({ timeout: 8000 });
|
|
});
|
|
});
|