Buchungskalender: UI-Durchlauf – Screenshots wie im Webshop, Sichtbarkeitsprüfung

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
knsoandClaude Opus 5.5 committed 2026-10-07 15:10:00 +00:00
1 parent 838bc96d1b
commit 2df56eccc5
1 file changed
+31 -3
+31 -3
View File
@@ -59,11 +59,17 @@ let nummer = 0
/** Screenshot der ganzen Seite in der aktuellen Fensterbreite (Name: fortlaufende Nummer, Beschreibung, Breite). */
async function shot(page, name) {
nummer += 1
const breite = page.viewportSize().width
const vorher = page.viewportSize()
const breite = vorher.width
await page.evaluate(() => Promise.all(document.getAnimations().filter((a) => a.effect.getComputedTiming().iterations !== Infinity).map((a) => a.finished.catch(() => {})))).catch(() => {})
await page.waitForTimeout(150)
// wie test/ui/shop.ui.mjs: Fenster auf Seitenhoehe stellen statt fullPage (die Portalansicht blendet sonst leer ein)
const hoehe = await page.evaluate(() => Math.min(Math.max(document.documentElement.scrollHeight, window.innerHeight), 3600))
await page.setViewportSize({ width: breite, height: hoehe })
await page.waitForTimeout(100)
const datei = `${SHOTS}/${String(nummer).padStart(2, '0')}-${name}-${breite}.png`
await page.screenshot({ path: datei, fullPage: true })
await page.screenshot({ path: datei })
await page.setViewportSize(vorher)
return datei
}
/** Dieselbe Seite zusaetzlich in der anderen Breite aufnehmen und zurueckstellen. */
@@ -174,14 +180,27 @@ async function lauf(name, fn) {
// ---------------------------------------------------------------- Portal-Helfer
/** Sichtbarkeit wirklich pruefen (nicht nur DOM): sichtbar, Hoehe > 0, nicht durchsichtig (Einblend-Animation fertig). */
async function sichtbar(locator, name) {
await warteBis(async () => {
if (!(await locator.first().isVisible().catch(() => false))) return false
const box = await locator.first().boundingBox()
const deckend = await locator.first().evaluate((el) => { let o = 1; for (let e = el; e; e = e.parentElement) o *= Number(getComputedStyle(e).opacity); return o > 0.99 })
return Boolean(box) && box.height > 0 && box.width > 0 && deckend
}, `${name} sichtbar`, 5000).catch(() => ok(false, `${name} ist nicht sichtbar (Hoehe 0, hidden oder durchsichtig)`))
}
const oeffnePortal = async (page) => {
await page.goto(`${srv.portalUrl}/dashboard.html#buchungen`)
await page.locator('#view-buchungen.active').waitFor()
await page.locator('#buchungen-body .sh-reiterleiste').waitFor()
await sichtbar(page.locator('#view-buchungen'), 'Ansicht Buchungskalender')
await sichtbar(page.locator('#view-buchungen h1'), 'Titel Buchungskalender')
await sichtbar(page.locator('[data-reiter="anfragen"]'), 'Reiter Anfragen')
}
const reiter = async (page, key) => {
await page.locator(`[data-reiter="${key}"]`).click()
await page.locator(`#bk-tab-${key}[aria-selected="true"]`).waitFor()
await sichtbar(page.locator('#bk-panel > *'), `Inhalt des Reiters ${key}`)
}
const warteMeldung = async (page, teil) => {
await warteBis(async () => enthaelt(await page.locator('#buchungen-body .sh-meldung').innerText().catch(() => ''), teil), `Meldung „${teil}“`)
@@ -308,7 +327,16 @@ async function szenario() {
await portal.locator('#bk-p-ust-re').fill('19')
await portal.locator('#bk-p-frist').fill('3')
await portal.locator('[data-aktion="storno-muster"]').click()
ok((await portal.locator('#bk-p-storno').inputValue()).startsWith('1. Stornierung durch den Gast.'), 'Mustertext in die Stornobedingungen übernommen')
const muster = await portal.locator('#bk-p-storno').inputValue()
ok(muster.startsWith('1. Stornierung durch den Gast.'), 'Mustertext in die Stornobedingungen übernommen')
// mit den Platzhaltern wird nicht gespeichert
await portal.locator('[data-aktion="preise-speichern"]').click()
await warteBis(async () => enthaelt(await portal.locator('[data-fehler="stornobedingungen"]').innerText(), 'Bitte ersetze die Platzhalter in eckigen Klammern durch deine Werte.'), 'Platzhalter-Fehler am Feld')
ok(srv.preise().length === 0, 'Preise mit Platzhaltern nicht gespeichert')
await shot(portal, 'preise-platzhalter-fehler')
// Platzhalter durch Werte ersetzen
await portal.locator('#bk-p-storno').fill(muster.replace('[E-Mail-Adresse des Vermieters]', 'buchung@donau-home.example').replace(/\[(\d+)\]/g, '$1'))
ok(!/\[[^\]]*\]/.test(await portal.locator('#bk-p-storno').inputValue()), 'keine eckigen Klammern mehr in den Stornobedingungen')
await shot(portal, 'preise-ausgefuellt')
await portal.locator('[data-aktion="preise-speichern"]').click()
await warteMeldung(portal, 'Die Preise sind gespeichert')