Configs voor beide runners, login via session caching, AI-chat mocks (SSE) voor deterministische Cortex-tests. Supabase local config toegevoegd. Auth-state en reports zijn gitignored. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
111 lines
3.0 KiB
TypeScript
111 lines
3.0 KiB
TypeScript
import type { Page } from '@playwright/test';
|
|
|
|
/**
|
|
* Builds a mock SSE response body for the Cortex chat endpoint.
|
|
* The chat route streams: { type: 'content', text } chunks, then { type: 'done' }.
|
|
*/
|
|
function buildSSEBody(text: string, actionJson?: object): string {
|
|
const encoder = new TextEncoder();
|
|
const parts: string[] = [];
|
|
|
|
// Stream text in one chunk for simplicity
|
|
const fullText = actionJson
|
|
? `${text}\n\n\`\`\`json\n${JSON.stringify(actionJson, null, 2)}\n\`\`\``
|
|
: text;
|
|
|
|
parts.push(`data: ${JSON.stringify({ type: 'content', text: fullText })}\n\n`);
|
|
parts.push(`data: ${JSON.stringify({ type: 'done' })}\n\n`);
|
|
|
|
return parts.join('');
|
|
}
|
|
|
|
/** Mock de Cortex chat endpoint voor een dagnotitie intent. */
|
|
export async function mockDagnotitieChat(page: Page, patientName = 'Jan de Vries') {
|
|
await page.route('**/api/cortex/chat', async (route) => {
|
|
const action = {
|
|
type: 'action',
|
|
intent: 'dagnotitie',
|
|
entities: {
|
|
patientName,
|
|
category: 'observatie',
|
|
content: 'Patiënt voelt zich goed vandaag.',
|
|
},
|
|
confidence: 0.95,
|
|
artifact: {
|
|
type: 'dagnotitie',
|
|
prefill: {
|
|
patientName,
|
|
category: 'observatie',
|
|
content: 'Patiënt voelt zich goed vandaag.',
|
|
},
|
|
},
|
|
};
|
|
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: 'text/event-stream',
|
|
body: buildSSEBody('Genoteerd.', action),
|
|
});
|
|
});
|
|
}
|
|
|
|
/** Mock de Cortex chat endpoint voor een zoeken intent. */
|
|
export async function mockZoekenChat(page: Page, query = 'Jan') {
|
|
await page.route('**/api/cortex/chat', async (route) => {
|
|
const action = {
|
|
type: 'action',
|
|
intent: 'zoeken',
|
|
entities: { query },
|
|
confidence: 0.97,
|
|
artifact: {
|
|
type: 'zoeken',
|
|
prefill: { query },
|
|
},
|
|
};
|
|
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: 'text/event-stream',
|
|
body: buildSSEBody('Even kijken.', action),
|
|
});
|
|
});
|
|
}
|
|
|
|
/** Mock de Cortex chat endpoint voor een overdracht intent. */
|
|
export async function mockOverdrachtChat(page: Page) {
|
|
await page.route('**/api/cortex/chat', async (route) => {
|
|
const action = {
|
|
type: 'action',
|
|
intent: 'overdracht',
|
|
entities: {},
|
|
confidence: 0.98,
|
|
artifact: {
|
|
type: 'overdracht',
|
|
prefill: {},
|
|
},
|
|
};
|
|
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: 'text/event-stream',
|
|
body: buildSSEBody('Overdracht klaar.', action),
|
|
});
|
|
});
|
|
}
|
|
|
|
/** Mock de Cortex chat endpoint voor een onduidelijke intent (geen artifact). */
|
|
export async function mockOnbekendChat(page: Page) {
|
|
await page.route('**/api/cortex/chat', async (route) => {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: 'text/event-stream',
|
|
body: buildSSEBody('Hmm, snap niet helemaal wat je bedoelt. Kun je het anders zeggen?'),
|
|
});
|
|
});
|
|
}
|
|
|
|
/** Verwijder alle actieve route mocks op de chat endpoint. */
|
|
export async function clearChatMocks(page: Page) {
|
|
await page.unroute('**/api/cortex/chat');
|
|
}
|