Finanzmanager/tests/e2e/specs/wertpapierdetail.spec.js
fds2610-bot be3ee6400e Detailseite eines Wertpapiers
Der Name in Bestandsübersicht, Depotbuchungen und Stammdaten führt jetzt auf
/wertpapiere/papier/{id}: Kennzahlen über die ganze Historie, Stammdaten und
Kurs, Bestand je Depot, Wertentwicklung und die Buchungen eines Zeitraums.

Depot::bestand() und Depot::entwicklung() nehmen dafür eine Wertpapiernummer
entgegen – die Detailseite rechnet nicht selbst, sondern bekommt dieselben
Zahlen wie die Übersicht. Neu sind Wertpapier::kurseckwerte() und
Depotbuchung::datumsgrenzen().

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-13 15:08:01 +02:00

146 lines
5.5 KiB
JavaScript
Raw Permalink 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')
/*
* Vom Namen in der Depotübersicht zur Detailseite des Wertpapiers: Stammdaten,
* Kennzahlen und darunter die Buchungen eines Zeitraums – voreingestellt das
* laufende Jahr.
*/
const BENUTZER = process.env.E2E_USER || 'e2e'
const PASSWORT = process.env.E2E_PASSWORD || 'e2e-testpasswort'
const MARKE = Date.now().toString().slice(-6)
const DEPOT = `E2E Detaildepot ${MARKE}`
const GIRO = `E2E Detailgiro ${MARKE}`
const PAPIER = `E2E Detailaktie ${MARKE}`
// Wie im Test des Wertpapiergeschäfts: Ein Papier wird über seine Kennung
// wiedergefunden, feste Kennungen hingen den zweiten Lauf an den ersten.
const ISIN = `DE0007${MARKE}`
// Die Zeiträume rechnen mit dem Tagesdatum, nicht mit festen Jahreszahlen –
// sonst liefe der Test am 1. Januar ins Leere.
const HEUTE = new Date()
const JAHR = HEUTE.getFullYear()
const DIESES_JAHR = `${JAHR}-03-04`
const VORJAHR = `${JAHR - 1}-03-04`
async function anmelden(page) {
await page.goto('/login')
if (page.url().includes('/einrichtung')) {
throw new Error(
'Instanz ist noch nicht eingerichtet: ' +
'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(/\/$/)
}
async function kontoAnlegen(page, name, kontoart, anfangssaldo) {
await page.goto('/konten/neu')
await page.fill('#name', name)
await page.selectOption('#kontoart', kontoart)
await page.fill('#anfangssaldo', anfangssaldo)
await page.click('.formular button[type="submit"]')
await expect(page).toHaveURL(/\/konten\/\d+\/bearbeiten/)
}
/** Ein Kauf über die Maske unter *Wertpapiere*. */
async function kaufErfassen(page, datum, stueck, kurs, neuesPapier) {
await page.goto('/wertpapiere/buchungen/neu')
await page.selectOption('#konto_id', { label: DEPOT })
await page.selectOption('#vorgang', 'kauf')
await page.fill('#datum', datum)
if (neuesPapier) {
await page.fill('#wertpapier_name', PAPIER)
await page.fill('#isin', ISIN)
} else {
await page.selectOption('#wertpapier_id', { label: `${PAPIER} (${ISIN})` })
}
await page.fill('#stueck', stueck)
await page.fill('#kurs', kurs)
await page.selectOption('#verrechnungskonto_id', { label: GIRO })
await page.click('.formular button[type="submit"]')
await expect(page.locator('.meldung-erfolg')).toBeVisible()
}
test.describe('Detailseite eines Wertpapiers', () => {
test.beforeAll(async ({ browser }) => {
const page = await browser.newPage()
await anmelden(page)
await kontoAnlegen(page, GIRO, 'bank', '10.000,00')
await kontoAnlegen(page, DEPOT, 'depot', '0,00')
// Zwei Käufe in zwei Jahren – der Zeitraumfilter muss sie trennen.
await kaufErfassen(page, VORJAHR, '4', '50', true)
await kaufErfassen(page, DIESES_JAHR, '6', '100', false)
// Ohne Kurs bliebe die Bewertung offen; der Kurs kommt von Hand. Der
// Name steht in der Stammdatenliste in einem Eingabefeld und nicht als
// Text – die Zeile wird deshalb über den Feldwert gesucht.
await page.goto('/wertpapiere/stammdaten')
const zeile = page.locator('tr').filter({ has: page.locator(`input[value="${PAPIER}"]`) })
await zeile.locator('input[name="kurs"]').fill('120')
await zeile.getByRole('button', { name: 'Setzen' }).click()
await expect(page.locator('.meldung-erfolg')).toBeVisible()
await page.close()
})
test.beforeEach(async ({ page }) => {
await anmelden(page)
})
test('Der Name in der Übersicht führt zu den Details', async ({ page }) => {
await page.goto('/wertpapiere')
await page.locator('tr', { hasText: PAPIER }).getByRole('link', { name: PAPIER }).click()
await expect(page).toHaveURL(/\/wertpapiere\/papier\/\d+/)
await expect(page.locator('h1')).toHaveText(PAPIER)
// Stammdaten und Kurs stehen in je einer Kachel.
await expect(page.locator('.kachel', { hasText: 'Stammdaten' }).locator('.merkmale'))
.toContainText(ISIN)
await expect(page.locator('.kachel', { hasText: 'Letzter Kurs' }).locator('.merkmale'))
.toContainText('120,00')
// Zehn Stück für 800 €, bewertet mit 1.200,00 €.
const kennzahlen = page.locator('.kennzahlenleiste')
await expect(kennzahlen).toContainText('10')
await expect(kennzahlen).toContainText('1.200,00')
await expect(kennzahlen).toContainText('800,00')
// Der Bestand steht je Depot – hier liegt alles in einem.
const bestand = page.locator('.kachel', { hasText: 'Bestand je Depot' })
await expect(bestand).toContainText(DEPOT)
await expect(bestand).toContainText('800,00')
})
test('Die Buchungen folgen dem gewählten Zeitraum', async ({ page }) => {
await page.goto('/wertpapiere')
await page.locator('tr', { hasText: PAPIER }).getByRole('link', { name: PAPIER }).click()
const liste = page.locator('table.liste').last()
// Voreingestellt ist das laufende Jahr: nur der Kauf von diesem Jahr.
await expect(page.locator('#zeitraum')).toHaveValue('aktuelles_jahr')
await expect(liste).toContainText(`04.03.${JAHR}`)
await expect(liste).not.toContainText(`04.03.${JAHR - 1}`)
await page.selectOption('#zeitraum', 'letztes_jahr')
await page.click('.filterleiste button[type="submit"]')
await expect(page.locator('table.liste').last()).toContainText(`04.03.${JAHR - 1}`)
await expect(page.locator('table.liste').last()).not.toContainText(`04.03.${JAHR}`)
// Die Kennzahlen oben gelten weiter für die ganze Historie.
await expect(page.locator('.kennzahlenleiste')).toContainText('800,00')
})
})