test: Cypress en Playwright e2e-suites voor login, agenda, cortex en verpleegrapportage
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>
This commit is contained in:
110
tests/playwright/fixtures/ai-mocks.ts
Normal file
110
tests/playwright/fixtures/ai-mocks.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
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');
|
||||
}
|
||||
Reference in New Issue
Block a user