Files
Andrej Spielmann 3fefc550fe Initial commit: WrestleDesk full project
- Django backend with DRF (clubs, wrestlers, trainers, exercises, templates, trainings, homework, locations, leistungstest)
- Next.js 16 frontend with React, Shadcn UI, Tailwind
- JWT authentication
- Full CRUD for all entities
- Calendar view for trainings
- Homework management system
- Leistungstest tracking
2026-03-26 13:24:57 +01:00

138 lines
4.6 KiB
TypeScript

import { test, expect, Page } from '@playwright/test'
const adminCredentials = { username: 'admin', password: 'admin123' }
// Helper: ensure user is logged in; if not, perform login flow
async function ensureLoggedIn(page: Page) {
await page.goto('/dashboard', { waitUntil: 'domcontentloaded' })
const url = page.url()
if (url.includes('/login')) {
await page.goto('/login')
// Try multiple selectors for username field
const userSelectors = [
'input[name="username"]',
'input[name="email"]',
'input#username',
'input#email',
'input[placeholder="Username"]',
'input[placeholder="Email"]',
]
let filledUser = false
for (const sel of userSelectors) {
const el = page.locator(sel)
if (await el.count() > 0) {
await el.fill(adminCredentials.username)
filledUser = true
break
}
}
if (!filledUser) {
const label = page.locator('label', { hasText: /username|email/i })
if (await label.count() > 0) {
const input = label.locator('xpath=following-sibling::input[1]')
if (await input.count() > 0) await input.fill(adminCredentials.username)
}
}
// Password
const passSelectors = [
'input[name="password"]',
'input#password',
'input[placeholder="Password"]',
'input[aria-label="Password"]',
]
for (const sp of passSelectors) {
const el = page.locator(sp)
if (await el.count() > 0) {
await el.fill(adminCredentials.password)
break
}
}
const loginBtn = page.locator('button', { hasText: /log|sign in|anmelden|einloggen/i })
if (await loginBtn.count() > 0) {
await loginBtn.first().click()
} else {
await page.keyboard.press('Enter')
}
await page.waitForURL('**/dashboard', { timeout: 10000 })
}
}
test.describe('WrestleDesk End-to-End (Partial) - Auth and Core Views', () => {
test('Login page - valid credentials', async ({ page }) => {
await page.goto('/login')
const userSelectors = [
'input[name="username"]',
'input[name="email"]',
'input#username',
'input#email',
'input[placeholder="Username"]',
'input[placeholder="Email"]',
]
let filled = false
for (const sel of userSelectors) {
const el = page.locator(sel)
if (await el.count() > 0) {
await el.fill(adminCredentials.username)
filled = true
break
}
}
if (!filled) {
const label = page.locator('label', { hasText: /username|email/i })
if (await label.count() > 0) {
const input = label.locator('xpath=following-sibling::input[1]')
if (await input.count() > 0) await input.fill(adminCredentials.username)
}
}
const passSelectors = [
'input[name="password"]',
'input#password',
'input[placeholder="Password"]',
'input[aria-label="Password"]',
]
filled = false
for (const sp of passSelectors) {
const el = page.locator(sp)
if (await el.count() > 0) {
await el.fill(adminCredentials.password)
filled = true
break
}
}
if (!filled) {
const pwd = page.locator('input[type="password"]')
if (await pwd.count() > 0) await pwd.fill(adminCredentials.password)
}
const loginBtn = page.locator('button', { hasText: /log|sign in|anmelden|einloggen/i })
if (await loginBtn.count() > 0) {
await loginBtn.first().click()
} else {
await page.keyboard.press('Enter')
}
await page.waitForURL('**/dashboard', { timeout: 10000 })
await page.screenshot({ path: '/tmp/test-results/login.png', fullPage: true })
expect(page.url()).toContain('/dashboard')
})
test('Dashboard loads and navigates to Wrestlers', async ({ page }) => {
await ensureLoggedIn(page)
await expect(page).toHaveURL(/.*dashboard/)
const hasWrestlersCard = await page.locator('text=/Wrestlers|Wrestler(s)?/i').first().count()
await page.screenshot({ path: '/tmp/test-results/dashboard.png', fullPage: true })
expect(hasWrestlersCard).toBeGreaterThan(0)
const wrestlersLink = page.locator('a', { hasText: /Wrestler|Wrestlers/i })
if (await wrestlersLink.count() > 0) {
await wrestlersLink.first().click()
await page.waitForURL(/.*wrestlers/i)
await page.screenshot({ path: '/tmp/test-results/dashboard-to-wrestlers.png', fullPage: true })
} else {
await page.goto('/wrestlers')
await page.waitForURL(/.*wrestlers/i)
await page.screenshot({ path: '/tmp/test-results/navigate-wrestlers.png', fullPage: true })
}
})
// Additional blocks would be added here for Wrestlers CRUD, Trainers CRUD, etc.
})