101 lines
4.3 KiB
TypeScript
101 lines
4.3 KiB
TypeScript
import { test, expect, Page } from '@playwright/test'
|
|
|
|
test.describe('Frontend', () => {
|
|
let page: Page
|
|
|
|
test.beforeAll(async ({ browser }) => {
|
|
const context = await browser.newContext()
|
|
page = await context.newPage()
|
|
})
|
|
|
|
test('can load homepage', async () => {
|
|
await page.goto('http://localhost:3000')
|
|
await expect(page).toHaveTitle(/Payload Website Template/)
|
|
const heading = page.locator('h1').first()
|
|
await expect(heading).toHaveText('Payload Website Template')
|
|
})
|
|
})
|
|
|
|
test.describe('Participation process timeline', () => {
|
|
for (const viewport of [
|
|
{ width: 1440, height: 900 },
|
|
{ width: 1024, height: 768 },
|
|
{ width: 768, height: 1024 },
|
|
{ width: 390, height: 844 },
|
|
]) {
|
|
test(`keeps all steps reachable at ${viewport.width}px`, async ({ page }) => {
|
|
await page.setViewportSize(viewport)
|
|
await page.goto('http://localhost:3000/teilnahme#schritte')
|
|
|
|
const timeline = page.locator('#schritte')
|
|
const eligibility = page.locator('#voraussetzungen')
|
|
const steps = timeline.locator('[data-testid^="timeline-step-"]')
|
|
|
|
await expect(timeline).toBeVisible()
|
|
if (viewport.width < 768) {
|
|
await expect(timeline.locator('h3')).toHaveCount(4)
|
|
} else {
|
|
await expect(steps).toHaveCount(4)
|
|
const nextButton = timeline.getByRole('button', { name: 'Nächster Schritt', exact: true })
|
|
const visibleTrackRatio = async (index: number) => steps.nth(index).evaluate((card) => {
|
|
const track = card.closest('[data-testid="timeline-track"]')
|
|
if (!track) return 0
|
|
const cardRect = card.getBoundingClientRect()
|
|
const trackRect = track.getBoundingClientRect()
|
|
const visibleWidth = Math.max(
|
|
0,
|
|
Math.min(cardRect.right, trackRect.right) - Math.max(cardRect.left, trackRect.left),
|
|
)
|
|
return visibleWidth / cardRect.width
|
|
})
|
|
|
|
for (let index = 0; index < 4; index += 1) {
|
|
await expect.poll(() => visibleTrackRatio(index)).toBeGreaterThan(0.55)
|
|
if (index < 3) {
|
|
await nextButton.click()
|
|
await expect(timeline.locator('[data-testid="timeline-progress-label"]')).toHaveText(
|
|
`${String(index + 2).padStart(2, '0')} / 04`,
|
|
)
|
|
}
|
|
}
|
|
|
|
const cardsOverlap = await steps.evaluateAll((cards) => cards.some((card, index) => {
|
|
const nextCard = cards[index + 1]
|
|
return nextCard ? card.getBoundingClientRect().right > nextCard.getBoundingClientRect().left : false
|
|
}))
|
|
expect(cardsOverlap).toBe(false)
|
|
expect(await timeline.evaluate((element) => element.getBoundingClientRect().height)).toBeLessThan(900)
|
|
}
|
|
|
|
const sectionGap = await page.evaluate(() => {
|
|
const timelineElement = document.querySelector('#schritte')
|
|
const eligibilityElement = document.querySelector('#voraussetzungen')
|
|
if (!timelineElement || !eligibilityElement) return Number.POSITIVE_INFINITY
|
|
return eligibilityElement.getBoundingClientRect().top - timelineElement.getBoundingClientRect().bottom
|
|
})
|
|
expect(Math.abs(sectionGap)).toBeLessThanOrEqual(2)
|
|
})
|
|
}
|
|
|
|
test('uses a fully readable non-animated reduced-motion interaction', async ({ page }) => {
|
|
await page.emulateMedia({ reducedMotion: 'reduce' })
|
|
await page.setViewportSize({ width: 1024, height: 768 })
|
|
await page.goto('http://localhost:3000/teilnahme#schritte')
|
|
|
|
const timeline = page.locator('#schritte')
|
|
await timeline.getByRole('button', { name: 'Nächster Schritt', exact: true }).click()
|
|
|
|
await expect(timeline.locator('[data-testid="timeline-progress-label"]')).toHaveText('02 / 04')
|
|
await expect.poll(() => timeline.locator('[data-testid="timeline-step-2"]').evaluate((card) => {
|
|
const track = card.closest('[data-testid="timeline-track"]')
|
|
if (!track) return 0
|
|
const cardRect = card.getBoundingClientRect()
|
|
const trackRect = track.getBoundingClientRect()
|
|
return Math.max(0, Math.min(cardRect.right, trackRect.right) - Math.max(cardRect.left, trackRect.left)) / cardRect.width
|
|
})).toBeGreaterThan(0.55)
|
|
expect(await timeline.locator('[data-testid="timeline-track"]').evaluate((element) => (
|
|
getComputedStyle(element).scrollBehavior
|
|
))).toBe('auto')
|
|
})
|
|
})
|