/** * Lernprofile im echten Fenster. * * Was die Vitest-Tests mit einer Attrappe pruefen, laeuft hier gegen die * echte SQLite-Datei und die echten Einstellungen: Ein zweites Profil * entsteht wirklich, die Startfrage kommt beim naechsten Aufbau wirklich, * und die Wahl ueberlebt ihn wirklich. * * Der Neuaufbau geschieht per `reload()`. Das ist kein Neustart des * Prozesses, prueft aber genau den Weg, um den es geht: React baut frisch * auf, liest die Profilliste aus der Datenbank und die zuletzt benutzte * Nummer aus den Einstellungen. */ import { type ElectronApplication, type Page } from '@playwright/test'; import { appStarten, bauPruefen } from './electron-hilfe'; import { expect, test } from './konsolenwache'; let app: ElectronApplication | undefined; let fenster: Page; test.beforeAll(async () => { // Fehlender oder veralteter Bau ist ein Fehler, kein Grund zum Schweigen. bauPruefen(); ({ app, fenster } = await appStarten()); }); test.afterAll(async () => { await app?.close(); }); /** Baut die Oberflaeche neu auf, ohne die Daten zu verlieren. */ async function neuAufbauen(): Promise { await fenster.reload(); await fenster.waitForLoadState('domcontentloaded'); await fenster.waitForSelector('h1', { state: 'visible' }); } test.describe.configure({ mode: 'serial' }); test.describe('Lernprofile', () => { test('fragt bei einem Profil nicht, wer lernt', async () => { await expect(fenster.getByRole('heading', { name: 'Heute lernen' })).toBeVisible(); await expect(fenster.getByRole('heading', { name: 'Wer lernt?' })).toHaveCount(0); }); test('legt ein zweites Profil an', async () => { await fenster.getByRole('button', { name: 'Neues Profil anlegen' }).click(); await fenster.getByLabel('Name des neuen Profils').fill('Zweiter'); await fenster.getByRole('button', { name: 'Profil anlegen' }).click(); await expect(fenster.getByText(/Das Profil „Zweiter“ ist angelegt/u)).toBeVisible(); await expect(fenster.locator('.profile__liste > li')).toHaveCount(2); }); test('fragt ab dem zweiten Profil beim Aufbau, wer lernt', async () => { await neuAufbauen(); await expect(fenster.getByRole('heading', { name: 'Wer lernt?' })).toBeVisible(); // Das bisherige Profil steht vorausgewaehlt – die Eingabetaste genuegt. await expect(fenster.getByRole('radio', { name: 'Standard' })).toBeChecked(); await expect(fenster.getByRole('heading', { name: 'Heute lernen' })).toHaveCount(0); }); test('wechselt erst auf ausdrueckliche Anforderung (WCAG 3.2.2)', async () => { await fenster.getByRole('radio', { name: 'Zweiter' }).check(); /* Die Auswahl allein darf den Zusammenhang nicht aendern: Der Startbildschirm ist noch nicht da. */ await expect(fenster.getByRole('heading', { name: 'Heute lernen' })).toHaveCount(0); await fenster.getByRole('button', { name: 'Weiter' }).click(); await expect(fenster.getByRole('heading', { name: 'Heute lernen' })).toBeVisible(); await expect(fenster.locator('.einstieg__profil')).toHaveText('Lernstand von Zweiter'); }); test('merkt sich die Wahl fuer den naechsten Aufbau', async () => { await neuAufbauen(); await expect(fenster.getByRole('radio', { name: 'Zweiter' })).toBeChecked(); }); test('loescht ein Profil erst nach einer Rueckfrage', async () => { await fenster.getByRole('button', { name: 'Weiter' }).click(); await expect(fenster.getByRole('heading', { name: 'Heute lernen' })).toBeVisible(); const zeile = fenster.locator('.profile__liste > li', { hasText: 'Standard' }); await zeile.getByRole('button', { name: /^Löschen/u }).click(); await expect( fenster.getByRole('heading', { name: 'Profil „Standard“ wirklich löschen?' }), ).toBeVisible(); await fenster.getByRole('button', { name: 'Nein, behalten' }).click(); await expect(fenster.locator('.profile__liste > li')).toHaveCount(2); await zeile.getByRole('button', { name: /^Löschen/u }).click(); await fenster.getByRole('button', { name: 'Ja, Profil löschen' }).click(); await expect(fenster.getByText(/Das Profil „Standard“ ist gelöscht/u)).toBeVisible(); await expect(fenster.locator('.profile__liste > li')).toHaveCount(1); }); test('laesst das letzte Profil stehen', async () => { /* Ohne Profil haette die Anwendung keinen Ort fuer Antworten mehr. */ await expect( fenster.locator('.profile__liste').getByRole('button', { name: /^Löschen/u }), ).toHaveCount(0); await expect(fenster.getByText(/Das letzte Profil lässt sich nicht löschen/u)).toBeVisible(); }); });