// @ts-check const path = require('path') const fs = require('fs') const { test, expect } = require('@playwright/test') const BENUTZER = process.env.E2E_USER || 'e2e' const PASSWORT = process.env.E2E_PASSWORT || process.env.E2E_PASSWORD || 'e2e-testpasswort' // Screenshots einer Rechnung mit QR-Code im jeweiligen Format. const BEISPIELE = [ { datei: 'qr-epc.png', format: 'EPC-QR' }, { datei: 'qr-bezahlcode.png', format: 'BezahlCode' }, ] async function anmelden(page) { await page.goto('/login') await page.fill('#benutzername', BENUTZER) await page.fill('#passwort', PASSWORT) await page.click('button[type="submit"]') await expect(page).toHaveURL(/\/$/) } async function pruefeFelder(page) { await expect(page.locator('.meldung')).toContainText('QR-Code gelesen') await expect(page.locator('#empfaenger')).toHaveValue('Rheinwerk Verlag GmbH') await expect(page.locator('#iban')).toHaveValue('DE26380601863001400028') await expect(page.locator('#bic')).toHaveValue('GENODED1BRS') await expect(page.locator('#betrag')).toHaveValue('260,61') await expect(page.locator('#verwendungszweck')).toHaveValue('K042-SYUAU') } test.describe('Überweisung erfassen: QR-Code einlesen', () => { test.beforeEach(async ({ page }) => { await anmelden(page) await page.goto('/zahlungsverkehr/neu') await expect(page.locator('#qrbereich')).toBeVisible() }) for (const { datei, format } of BEISPIELE) { test(`${format}: Dateiauswahl im Dialog füllt die Felder`, async ({ page }) => { await page.click('#qrbereich') await expect(page.locator('#qrdialog')).toBeVisible() await page.setInputFiles('#qrdatei', path.join(__dirname, '..', 'fixtures', datei)) await expect(page.locator('#qrdialog')).toBeHidden() await pruefeFelder(page) }) test(`${format}: Bild aus der Zwischenablage füllt die Felder`, async ({ page }) => { const bytes = fs.readFileSync(path.join(__dirname, '..', 'fixtures', datei)).toString('base64') await page.click('#qrbereich') await page.evaluate(async (b64) => { // fetch() auf data:-URLs verbietet die Content-Security-Policy (connect-src). const blob = new Blob([Uint8Array.from(atob(b64), (z) => z.charCodeAt(0))], { type: 'image/png' }) const daten = new DataTransfer() daten.items.add(new File([blob], 'bild.png', { type: 'image/png' })) document.getElementById('qrdialog').dispatchEvent( new ClipboardEvent('paste', { clipboardData: daten, bubbles: true, cancelable: true })) }, bytes) await pruefeFelder(page) }) test(`${format}: Ziehen auf den Bereich füllt die Felder`, async ({ page }) => { const bytes = fs.readFileSync(path.join(__dirname, '..', 'fixtures', datei)).toString('base64') await page.evaluate(async (b64) => { // fetch() auf data:-URLs verbietet die Content-Security-Policy (connect-src). const blob = new Blob([Uint8Array.from(atob(b64), (z) => z.charCodeAt(0))], { type: 'image/png' }) const daten = new DataTransfer() daten.items.add(new File([blob], 'bild.png', { type: 'image/png' })) document.getElementById('qrbereich').dispatchEvent( new DragEvent('drop', { dataTransfer: daten, bubbles: true, cancelable: true })) }, bytes) await pruefeFelder(page) }) } test('Bild ohne QR-Code meldet einen Fehler und lässt die Felder leer', async ({ page }) => { await page.click('#qrbereich') await page.setInputFiles('#qrdatei', { name: 'leer.png', mimeType: 'image/png', // 1×1-Pixel-PNG buffer: Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==', 'base64'), }) await expect(page.locator('.meldung')).toContainText('kein QR-Code') await expect(page.locator('#iban')).toHaveValue('') }) })