/** * Die dauerhafte Kapitelabwahl im echten Fenster. * * Was die Vitest-Tests an einer Attrappe und an einer Wegwerf-Datenbank * prüfen, läuft hier am echten Katalog mit seinen 575 Fragen und an der * echten SQLite-Datei: Der Schalter schreibt wirklich in die Profilzeile, * die Zahl im Gesamtfortschritt ändert sich wirklich, und die Umstellung * überlebt einen Neuaufbau der Oberfläche wirklich. * * Der Neuaufbau geschieht per `reload()` – kein Prozessneustart, aber genau * der Weg, um den es geht: React baut frisch auf und liest die Profilzeile * neu aus der Datenbank. */ import { type ElectronApplication, type Page } from '@playwright/test'; import { amStart, appStarten, bauPruefen } from './electron-hilfe'; import { expect, test } from './konsolenwache'; /** Der amtliche Katalog, und was ohne Kapitel IV davon übrig bleibt. */ const GESAMT = 575; const OHNE_KAPITEL_IV = 486; let app: ElectronApplication | undefined; let fenster: Page; test.beforeAll(async () => { bauPruefen(); ({ app, fenster } = await appStarten()); }); test.afterAll(async () => { await app?.close(); }); test.describe.configure({ mode: 'serial' }); function schalter() { return fenster.getByRole('checkbox', { name: /Kapitel IV .* mitlernen/u }); } /** * Der Lernumfang, wie ihn die Ampel ausweist. * * Aus `aria-valuemax` statt aus dem Text: Der Satz der Ampel ändert seine * Form je nach Stufe – bei leerem Stand nennt er die Regel statt einer Zahl –, * die Obergrenze des Balkens ist dagegen immer der Umfang. */ async function umfang(): Promise { const wert = await fenster .getByRole('progressbar', { name: 'Prüfungsreife insgesamt' }) .getAttribute('aria-valuemax'); return Number(wert ?? 0); } async function zumStart(): Promise { for (let i = 0; i < 4; i++) { if (await amStart(fenster)) { return; } const zurueck = fenster.getByRole('button', { name: /^(Zum Start|Sitzung beenden)$/u }); if ((await zurueck.count()) === 0) { return; } await zurueck.first().click(); await fenster.waitForTimeout(250); } } test.describe('Kapitel IV dauerhaft abwählen', () => { test('nimmt Kapitel IV aus dem Lernumfang und sagt es an', async () => { await zumStart(); expect(await umfang()).toBe(GESAMT); await schalter().click(); /* Die Ansage steht nur für Bildschirmleser im Dokument, ist aber ein echtes Element – sichtbar im Sinne von Playwright ist sie nicht. */ await expect(fenster.getByText(/Kapitel IV ist für dieses Profil abgewählt/u)).toBeAttached(); await expect.poll(umfang).toBe(OHNE_KAPITEL_IV); }); test('überlebt den Neuaufbau der Oberfläche', async () => { /* Der Punkt der ganzen Übung: „dauerhaft“ heißt in der Profilzeile, nicht im Zustand einer React-Komponente. */ await fenster.reload(); await fenster.waitForLoadState('domcontentloaded'); await fenster.waitForSelector('h1', { state: 'visible' }); await expect(schalter()).not.toBeChecked(); await expect.poll(umfang).toBe(OHNE_KAPITEL_IV); }); test('lässt die Suche den ganzen Katalog behalten', async () => { /* Abgewählt heißt: zählt nicht mit. Nicht: gibt es nicht mehr. Wer im Lehrgang nach einer Signalpistole gefragt wird, muss sie nachschlagen können. */ await fenster.getByRole('button', { name: /Fragen durchsuchen/u }).click(); await fenster.getByRole('heading', { name: 'Fragen durchsuchen', level: 1 }).waitFor(); await expect( fenster.getByText(`Durchsucht wird der Wortlaut aller ${String(GESAMT)} amtlichen Fragen`, { exact: false, }), ).toBeVisible(); await fenster.getByLabel('Suchbegriff').fill('Seenotsignalmittel'); await expect(fenster.locator('.treffer__frage').first()).toBeVisible(); }); test('vermerkt das Kapitel in der Kapitelwahl, statt es zu verbergen', async () => { /* Weder verschwinden noch sperren: Verschwände es, fände niemand den Weg zurück zum Schalter; und ein gesperrter Knopf nimmt keinen Fokus – die Erklärung daneben würde nie vorgelesen. */ await zumStart(); await fenster.getByRole('button', { name: /Kapitel wählen/u }).click(); await fenster.getByRole('heading', { name: 'Kapitel wählen', level: 1 }).waitFor(); await expect(fenster.getByText(/Für dieses Profil abgewählt/u)).toBeVisible(); await expect(fenster.getByRole('button', { name: /Ganzes Kapitel IV üben/u })).toBeEnabled(); }); test('holt das Kapitel vollständig zurück', async () => { /* Zuletzt, damit die Datei den Zustand hinterlässt, in dem sie ihn vorgefunden hat – die übrigen Prüfläufe rechnen mit 575. */ await zumStart(); await schalter().click(); await expect(fenster.getByText(/Kapitel IV wird wieder mitgelernt/u)).toBeAttached(); await expect.poll(umfang).toBe(GESAMT); }); });