/** * „Fehler zu dieser Frage melden“ im echten Fenster. * * Hier zählt vor allem eines: dass der Text wirklich in der Zwischenablage * des Systems landet. Die Oberflächentests prüfen das gegen eine Attrappe; * ob Electrons `clipboard` an dieser Stelle tut, was es soll, sagt nur der * echte Lauf. Der Weg über `navigator.clipboard` ist hier nachweislich * versperrt – siehe `shared/ipc.ts`, Kanal `system:kopieren`. */ import { type ElectronApplication, type Page } from '@playwright/test'; import { amStart, appStarten, bauPruefen } from './electron-hilfe'; import { expect, test } from './konsolenwache'; 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' }); 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); } } async function sitzungOeffnen(): Promise { await zumStart(); await fenster.getByRole('button', { name: /Weiterlernen/u }).click(); await fenster.getByRole('heading', { level: 1, name: /, Frage \d/u }).waitFor(); } test.describe('Fehler melden', () => { test('legt genau den angezeigten Text in die Zwischenablage', async () => { await sitzungOeffnen(); const aufklapper = fenster.getByText('Fehler zu dieser Frage melden'); await aufklapper.scrollIntoViewIfNeeded(); await aufklapper.click(); const feld = fenster.getByLabel('Meldetext'); await expect(feld).toBeVisible(); const angezeigt = await feld.inputValue(); expect(angezeigt).toContain('Fehlermeldung zur Waffensachkunde-Lernsoftware'); expect(angezeigt).toContain('Kennung '); await fenster.getByRole('button', { name: 'Text kopieren' }).click(); await expect(fenster.getByText(/liegt in der Zwischenablage/u)).toBeVisible(); /* Der Kern der Sache: Was in der Zwischenablage des Systems liegt, muss zeichengleich mit dem sein, was dastand. */ const inZwischenablage = await app!.evaluate(({ clipboard }) => clipboard.readText()); expect(inZwischenablage).toBe(angezeigt); }); test('nennt Fragenkennung, Katalogstand und Fassung', async () => { /* Die drei Angaben, ohne die eine Meldung nicht zu bearbeiten ist. Die Kennung ist dabei die wichtigere: 227 der 575 Fragen teilen ihre amtliche Nummer mit einer anderen. */ const inhalt = await fenster.getByLabel('Meldetext').inputValue(); expect(inhalt).toMatch(/Kennung [IVX]+/u); expect(inhalt).toContain('Stand 16.12.2024'); expect(inhalt).toContain('Programm: Fassung '); }); test('verrät nichts über die lernende Person', async () => { /* Der Text verlässt später das Gerät. Diese Prüfung läuft am echten Profil und am echten Lernstand – anders als der Einheitentest, der gegen erfundene Werte prüft. */ const inhalt = (await fenster.getByLabel('Meldetext').inputValue()).toLowerCase(); for (const verboten of ['standard', 'appdata', 'sqlite', '.db', 'lernstand von']) { expect(inhalt).not.toContain(verboten); } }); test('klappt bei der nächsten Frage wieder ein', async () => { /* Ein von Hand aufgeklapptes
bekommt React nicht wieder zu – es vergleicht Eigenschaften mit Eigenschaften, nie mit dem DOM. Der Block hängt deshalb an der Identität der Frage: Beim Wechsel entsteht ein neues Element, und das ist zu. Eigene Sitzung, damit dieser Test nicht davon abhängt, wo der vorige aufgehört hat. */ await sitzungOeffnen(); const aufklapper = fenster.getByText('Fehler zu dieser Frage melden'); await aufklapper.scrollIntoViewIfNeeded(); await aufklapper.click(); await expect(fenster.getByLabel('Meldetext')).toBeVisible(); const auswahl = fenster.getByRole('checkbox').or(fenster.getByRole('radio')); if ((await auswahl.count()) > 0) { await auswahl.first().check(); await fenster.getByRole('button', { name: /^Antwort bestätigen$/u }).click(); } else { await fenster.getByRole('button', { name: /^Musterantwort anzeigen$/u }).click(); await fenster.getByRole('button', { name: /^Gewusst$/u }).click(); } await fenster.getByRole('button', { name: /^Nächste Frage$/u }).click(); /* Am Zustand des
selbst gemessen, nicht daran, ob das Feld im DOM steht: Ein zugeklapptes
behält seine Kinder, es zeigt sie nur nicht. Genau diese Feinheit hat den ersten Anlauf dieses Tests fälschlich rot gemeldet. */ await expect(fenster.getByLabel('Meldetext')).toBeHidden(); expect( await fenster .locator('details.meldung') .evaluate((element) => (element as HTMLDetailsElement).open), ).toBe(false); await expect(fenster.getByText('Fehler zu dieser Frage melden')).toBeVisible(); await zumStart(); }); });