waffensachkunde

Waffensachkunde – Lernsoftware für die Sachkundeprüfung nach § 7 WaffG. Barrierefrei, offline, EUPL-1.2.

/ app e2e profile.spec.ts

4,5 KB Rohdatei
app/e2e/profile.spec.ts — 112 Zeilen
1 /**
2 * Lernprofile im echten Fenster.
3 *
4 * Was die Vitest-Tests mit einer Attrappe pruefen, laeuft hier gegen die
5 * echte SQLite-Datei und die echten Einstellungen: Ein zweites Profil
6 * entsteht wirklich, die Startfrage kommt beim naechsten Aufbau wirklich,
7 * und die Wahl ueberlebt ihn wirklich.
8 *
9 * Der Neuaufbau geschieht per `reload()`. Das ist kein Neustart des
10 * Prozesses, prueft aber genau den Weg, um den es geht: React baut frisch
11 * auf, liest die Profilliste aus der Datenbank und die zuletzt benutzte
12 * Nummer aus den Einstellungen.
13 */
14
15 import { type ElectronApplication, type Page } from '@playwright/test';
16
17 import { appStarten, bauPruefen } from './electron-hilfe';
18 import { expect, test } from './konsolenwache';
19
20 let app: ElectronApplication | undefined;
21 let fenster: Page;
22
23 test.beforeAll(async () => {
24 // Fehlender oder veralteter Bau ist ein Fehler, kein Grund zum Schweigen.
25 bauPruefen();
26 ({ app, fenster } = await appStarten());
27 });
28
29 test.afterAll(async () => {
30 await app?.close();
31 });
32
33 /** Baut die Oberflaeche neu auf, ohne die Daten zu verlieren. */
34 async function neuAufbauen(): Promise<void> {
35 await fenster.reload();
36 await fenster.waitForLoadState('domcontentloaded');
37 await fenster.waitForSelector('h1', { state: 'visible' });
38 }
39
40 test.describe.configure({ mode: 'serial' });
41
42 test.describe('Lernprofile', () => {
43 test('fragt bei einem Profil nicht, wer lernt', async () => {
44 await expect(fenster.getByRole('heading', { name: 'Heute lernen' })).toBeVisible();
45 await expect(fenster.getByRole('heading', { name: 'Wer lernt?' })).toHaveCount(0);
46 });
47
48 test('legt ein zweites Profil an', async () => {
49 await fenster.getByRole('button', { name: 'Neues Profil anlegen' }).click();
50 await fenster.getByLabel('Name des neuen Profils').fill('Zweiter');
51 await fenster.getByRole('button', { name: 'Profil anlegen' }).click();
52
53 await expect(fenster.getByText(/Das Profil „Zweiter“ ist angelegt/u)).toBeVisible();
54 await expect(fenster.locator('.profile__liste > li')).toHaveCount(2);
55 });
56
57 test('fragt ab dem zweiten Profil beim Aufbau, wer lernt', async () => {
58 await neuAufbauen();
59
60 await expect(fenster.getByRole('heading', { name: 'Wer lernt?' })).toBeVisible();
61 // Das bisherige Profil steht vorausgewaehlt – die Eingabetaste genuegt.
62 await expect(fenster.getByRole('radio', { name: 'Standard' })).toBeChecked();
63 await expect(fenster.getByRole('heading', { name: 'Heute lernen' })).toHaveCount(0);
64 });
65
66 test('wechselt erst auf ausdrueckliche Anforderung (WCAG 3.2.2)', async () => {
67 await fenster.getByRole('radio', { name: 'Zweiter' }).check();
68
69 /* Die Auswahl allein darf den Zusammenhang nicht aendern: Der
70 Startbildschirm ist noch nicht da. */
71 await expect(fenster.getByRole('heading', { name: 'Heute lernen' })).toHaveCount(0);
72
73 await fenster.getByRole('button', { name: 'Weiter' }).click();
74
75 await expect(fenster.getByRole('heading', { name: 'Heute lernen' })).toBeVisible();
76 await expect(fenster.locator('.einstieg__profil')).toHaveText('Lernstand von Zweiter');
77 });
78
79 test('merkt sich die Wahl fuer den naechsten Aufbau', async () => {
80 await neuAufbauen();
81
82 await expect(fenster.getByRole('radio', { name: 'Zweiter' })).toBeChecked();
83 });
84
85 test('loescht ein Profil erst nach einer Rueckfrage', async () => {
86 await fenster.getByRole('button', { name: 'Weiter' }).click();
87 await expect(fenster.getByRole('heading', { name: 'Heute lernen' })).toBeVisible();
88
89 const zeile = fenster.locator('.profile__liste > li', { hasText: 'Standard' });
90 await zeile.getByRole('button', { name: /^Löschen/u }).click();
91
92 await expect(
93 fenster.getByRole('heading', { name: 'Profil „Standard“ wirklich löschen?' }),
94 ).toBeVisible();
95 await fenster.getByRole('button', { name: 'Nein, behalten' }).click();
96 await expect(fenster.locator('.profile__liste > li')).toHaveCount(2);
97
98 await zeile.getByRole('button', { name: /^Löschen/u }).click();
99 await fenster.getByRole('button', { name: 'Ja, Profil löschen' }).click();
100
101 await expect(fenster.getByText(/Das Profil „Standard“ ist gelöscht/u)).toBeVisible();
102 await expect(fenster.locator('.profile__liste > li')).toHaveCount(1);
103 });
104
105 test('laesst das letzte Profil stehen', async () => {
106 /* Ohne Profil haette die Anwendung keinen Ort fuer Antworten mehr. */
107 await expect(
108 fenster.locator('.profile__liste').getByRole('button', { name: /^Löschen/u }),
109 ).toHaveCount(0);
110 await expect(fenster.getByText(/Das letzte Profil lässt sich nicht löschen/u)).toBeVisible();
111 });
112 });