/** * E2E: Compliance Advisor widget UX — topic threads, new-topic vs follow-up, delete, copy, fullscreen. * Stubs the chat endpoint with an answer fixture so every ask yields a finished case. */ import { test, expect } from '../fixtures/sdk-fixtures' const CHAT_ROUTE = '**/api/sdk/compliance-advisor/chat' const openAdvisor = 'Compliance Advisor oeffnen' const ANSWER = { mode: 'answer', question: '', clarity: { is_underspecified: false, dominant_context: 'cyber', concentration: 0.9 }, general_answer: null, answer: 'Musterantwort [1].', scoped_query: null, evidence: [{ evidence_id: 'e1', document: 'DSGVO', section: 'Art. 5', bindingness: 'binding' }], citations: [{ citation_id: 'c1', number: 1, evidence_id: 'e1', document: 'DSGVO', section: 'Art. 5' }], visual_evidence: [], footnotes: [], } async function stub(page: import('@playwright/test').Page) { await page.route(CHAT_ROUTE, (r) => r.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify(ANSWER) }), ) } test('new topic creates a second thread; copy control + fullscreen available', async ({ sdkPage }) => { await stub(sdkPage) await sdkPage.getByRole('button', { name: openAdvisor }).click() const input = sdkPage.getByPlaceholder('Frage eingeben...') await input.fill('Erste Frage') await input.press('Enter') await expect(sdkPage.getByText(/Musterantwort/)).toBeVisible() // expand -> the topic tree ("Themen") appears in the left menu await sdkPage.getByRole('button', { name: 'Vergroessern' }).click() await expect(sdkPage.getByText('Themen')).toBeVisible() await expect(sdkPage.getByText('Erste Frage').first()).toBeVisible() // a second, separate topic await sdkPage.getByPlaceholder('Folgefrage eingeben...').fill('Zweites Thema') await sdkPage.getByRole('button', { name: 'Neues Thema' }).click() await expect(sdkPage.getByText('Zweites Thema').first()).toBeVisible() await expect(sdkPage.getByText('Erste Frage').first()).toBeVisible() // copy affordance + fullscreen toggle await expect(sdkPage.getByRole('button', { name: 'Diese Frage kopieren' }).first()).toBeVisible() await sdkPage.getByRole('button', { name: 'Vollbild' }).click() await expect(sdkPage.getByRole('button', { name: 'Vollbild verlassen' })).toBeVisible() }) test('delete removes a question from the thread', async ({ sdkPage }) => { await stub(sdkPage) await sdkPage.getByRole('button', { name: openAdvisor }).click() const input = sdkPage.getByPlaceholder('Frage eingeben...') await input.fill('Zu löschen') await input.press('Enter') await expect(sdkPage.getByText(/Musterantwort/)).toBeVisible() await sdkPage.getByRole('button', { name: 'Vergroessern' }).click() await expect(sdkPage.getByText('Zu löschen').first()).toBeVisible() await sdkPage.getByRole('button', { name: 'Frage löschen' }).first().click() await expect(sdkPage.getByText('Zu löschen')).toHaveCount(0) })