Finanzmanager/tests/e2e/specs/banking.spec.js
fds2610-bot 4d833f273b Fix #75: Knopf „Alle Umsätze abrufen“ ruft jede Bank der Reihe nach ab
Über der Tabelle der Bankverbindungen ruft ein neuer Knopf jede aktive
Bankverbindung einzeln nacheinander ab. Die Warteschlange (Services\Sammelabruf)
übersteht TAN-Runden in der Sitzung; nach der Freigabe geht es mit der nächsten
Bank weiter. Die TAN-Maske zeigt den Stand und erlaubt, eine Bank zu
überspringen. Am Ende steht je Bankverbindung eine eigene Meldung.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 12:38:24 +02:00

178 lines
7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// @ts-check
const { test, expect } = require('@playwright/test')
const BENUTZER = process.env.E2E_USER || 'e2e'
const PASSWORT = process.env.E2E_PASSWORD || 'e2e-testpasswort'
// Eindeutige Namen je Lauf: die Tests arbeiten auf einer bestehenden Instanz
// und dürfen sich nicht an Resten eines früheren Laufs stoßen.
const MARKE = Date.now().toString().slice(-6)
async function anmelden(page) {
await page.goto('/login')
if (page.url().includes('/einrichtung')) {
throw new Error(
'Instanz ist noch nicht eingerichtet. Zuerst einen Benutzer anlegen: ' +
'docker compose exec -u www-data php php scripts/e2e-benutzer.php'
)
}
await page.fill('#benutzername', BENUTZER)
await page.fill('#passwort', PASSWORT)
await page.click('button[type="submit"]')
await expect(page).toHaveURL(/\/$/)
}
test.describe('Bankverbindungen', () => {
test.beforeEach(async ({ page }) => {
await anmelden(page)
})
test('„Bankverbindung anlegen“ führt zur Wahl zwischen HBCI/FinTS und PayPal', async ({ page }) => {
await page.goto('/banking')
await page.click('a[href="/banking/neu"]')
await expect(page.locator('h2')).toContainText('Wie wird abgerufen?')
const karten = page.locator('.formatwahl .formatkarte')
await expect(karten).toHaveCount(2)
await expect(karten.nth(0)).toContainText('HBCI/FinTS')
await expect(karten.nth(1)).toContainText('PayPal')
})
test('Die erste Wahl führt in die bisherige Bankenmaske', async ({ page }) => {
await page.goto('/banking/neu')
await page.click('.formatkarte:has-text("HBCI/FinTS")')
await expect(page).toHaveURL(/\/banking\/neu\/fints$/)
await expect(page.locator('.schrittmarke')).toContainText('Schritt 1 von 3')
await expect(page.locator('#fints_url')).toBeVisible()
await expect(page.locator('#pin')).toBeVisible()
})
test('Die zweite Wahl führt in die PayPal-Maske mit allen Angaben für die Abfrage', async ({ page }) => {
await page.goto('/banking/neu')
await page.click('.formatkarte:has-text("PayPal")')
await expect(page).toHaveURL(/\/banking\/neu\/paypal$/)
// Die drei Angaben der NVP-Schnittstelle und der Endpunkt-Schalter.
await expect(page.locator('#api_benutzer')).toBeVisible()
await expect(page.locator('#api_kennwort')).toBeVisible()
await expect(page.locator('#api_signatur')).toBeVisible()
await expect(page.locator('input[name="sandbox"]')).toBeAttached()
// Die Kontenzuordnung steht hier im Formular, nicht auf einer eigenen Seite.
await expect(page.locator('#konto_id')).toBeVisible()
await expect(page.locator('#konto_id option[value="neu"]')).toHaveCount(1)
})
test('PayPal-Verbindung anlegen, dabei ein neues Konto anlegen und wiederfinden', async ({ page }) => {
const name = `E2E PayPal ${MARKE}`
const konto = `E2E PayPal-Guthaben ${MARKE}`
await page.goto('/banking/neu/paypal')
await page.fill('#name', name)
await page.fill('#api_benutzer', `e2e_api1.example.org`)
await page.fill('#api_kennwort', 'e2e-kennwort')
await page.fill('#api_signatur', 'e2e-signatur')
await page.check('input[name="sandbox"]')
// Die Felder des neuen Kontos sind erst nach dieser Wahl sichtbar.
await expect(page.locator('#neuer_name')).toBeHidden()
await page.selectOption('#konto_id', 'neu')
await expect(page.locator('#neuer_name')).toBeVisible()
await page.fill('#neuer_name', konto)
await page.fill('#anfangssaldo', '25,00')
await page.click('.formular button[type="submit"]')
await expect(page.locator('.meldung-erfolg')).toBeVisible()
await expect(page).toHaveURL(/\/banking$/)
// In der Übersicht steht die Verbindung mit ihrer Art.
const zeile = page.locator('table.liste tr', { hasText: name })
await expect(zeile).toContainText('PayPal')
// Und beim Öffnen steht das eben angelegte Konto zugeordnet da; die
// Geheimnisse werden nicht wieder angezeigt.
await zeile.locator('a').first().click()
await expect(page.locator('#api_benutzer')).toHaveValue('e2e_api1.example.org')
await expect(page.locator('#api_kennwort')).toHaveValue('')
await expect(page.locator('#konto_id option:checked')).toHaveText(konto)
await expect(page.locator('input[name="sandbox"]')).toBeChecked()
})
test('„nicht zugeordnet“ löst eine bestehende Zuordnung wieder', async ({ page }) => {
const name = `E2E PayPal Zuordnung ${MARKE}`
const konto = `E2E PayPal-Konto ${MARKE}`
await page.goto('/banking/neu/paypal')
await page.fill('#name', name)
await page.fill('#api_benutzer', 'e2e_api1.example.org')
await page.fill('#api_kennwort', 'e2e-kennwort')
await page.fill('#api_signatur', 'e2e-signatur')
await page.selectOption('#konto_id', 'neu')
await page.fill('#neuer_name', konto)
await page.click('.formular button[type="submit"]')
await expect(page).toHaveURL(/\/banking$/)
await page.locator('table.liste tr', { hasText: name }).locator('a').first().click()
await expect(page.locator('#konto_id option:checked')).toHaveText(konto)
// Die leere Wahl heißt hier ausdrücklich „Zuordnung lösen“ – sie darf
// nicht als „nichts geändert“ durchrutschen.
await page.selectOption('#konto_id', '')
await page.click('.formular button[type="submit"]')
await expect(page.locator('.meldung-erfolg')).toBeVisible()
await expect(page.locator('#konto_id option:checked')).toHaveText('– nicht zugeordnet –')
})
test('„Alle Umsätze abrufen“ steht über der Tabelle der Bankverbindungen', async ({ page }) => {
const name = `E2E PayPal Sammelabruf ${MARKE}`
await page.goto('/banking/neu/paypal')
await page.fill('#name', name)
await page.fill('#api_benutzer', 'e2e_api1.example.org')
await page.fill('#api_kennwort', 'e2e-kennwort')
await page.fill('#api_signatur', 'e2e-signatur')
await page.click('.formular button[type="submit"]')
await expect(page).toHaveURL(/\/banking$/)
// Abgeschickt wird hier nicht: Der Lauf ginge an echte Gegenstellen.
const form = page.locator('.seitenaktionen form#alle-abrufen')
await expect(form).toHaveAttribute('method', 'post')
await expect(form).toHaveAttribute('action', '/banking/alle-abrufen')
await expect(form.locator('button[type="submit"]')).toHaveText('Alle Umsätze abrufen')
// Der Knopf steht über der Tabelle, nicht in einer ihrer Zeilen.
const knopf = await form.boundingBox()
const tabelle = await page.locator('table.liste').first().boundingBox()
expect(knopf.y).toBeLessThan(tabelle.y)
})
test('Ein PayPal-Zugang kennt kein TAN-Verfahren', async ({ page }) => {
const name = `E2E PayPal ohne TAN ${MARKE}`
await page.goto('/banking/neu/paypal')
await page.fill('#name', name)
await page.fill('#api_benutzer', 'e2e_api1.example.org')
await page.fill('#api_kennwort', 'e2e-kennwort')
await page.fill('#api_signatur', 'e2e-signatur')
await page.click('.formular button[type="submit"]')
await expect(page).toHaveURL(/\/banking$/)
const ziel = await page
.locator('table.liste tr', { hasText: name })
.locator('a')
.first()
.getAttribute('href')
await page.goto(`${ziel}/verfahren`)
await expect(page.locator('.meldung-warnung')).toContainText('kein TAN-Verfahren')
await expect(page).toHaveURL(new RegExp(`${ziel}$`))
})
})