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
This commit is contained in:
@@ -0,0 +1 @@
|
||||
404: Not Found
|
||||
@@ -0,0 +1 @@
|
||||
404: Not Found
|
||||
@@ -0,0 +1 @@
|
||||
404: Not Found
|
||||
@@ -0,0 +1,101 @@
|
||||
from playwright.sync_api import sync_playwright
|
||||
import sys
|
||||
|
||||
def test_all_pages():
|
||||
with sync_playwright() as p:
|
||||
browser = p.chromium.launch(headless=True)
|
||||
page = browser.new_page()
|
||||
|
||||
console_errors = []
|
||||
page.on("console", lambda msg: console_errors.append(msg.text) if msg.type == "error" else None)
|
||||
|
||||
# Login first
|
||||
print("Logging in...")
|
||||
page.goto('http://localhost:3000/login')
|
||||
page.wait_for_load_state('networkidle')
|
||||
page.fill('input[id="username"]', 'admin')
|
||||
page.fill('input[id="password"]', 'admin123')
|
||||
page.click('button[type="submit"]')
|
||||
page.wait_for_url('**/dashboard**', timeout=10000)
|
||||
print("✓ Logged in\n")
|
||||
|
||||
# Test dashboard
|
||||
print("Testing Dashboard...")
|
||||
page.wait_for_load_state('networkidle')
|
||||
h1 = page.locator('h1').first
|
||||
print(f" Title: {h1.text_content()}")
|
||||
page.screenshot(path='/tmp/01_dashboard.png', full_page=True)
|
||||
print(" ✓ Screenshot saved\n")
|
||||
|
||||
# Navigate to wrestlers
|
||||
print("Testing Wrestlers page...")
|
||||
page.click('text=Ringer')
|
||||
page.wait_for_url('**/wrestlers**', timeout=5000)
|
||||
page.wait_for_load_state('networkidle')
|
||||
h1 = page.locator('h1').first
|
||||
print(f" Title: {h1.text_content()}")
|
||||
page.screenshot(path='/tmp/02_wrestlers.png', full_page=True)
|
||||
print(" ✓ Screenshot saved\n")
|
||||
|
||||
# Navigate to trainers
|
||||
print("Testing Trainers page...")
|
||||
page.click('text=Trainer')
|
||||
page.wait_for_url('**/trainers**', timeout=5000)
|
||||
page.wait_for_load_state('networkidle')
|
||||
h1 = page.locator('h1').first
|
||||
print(f" Title: {h1.text_content()}")
|
||||
page.screenshot(path='/tmp/03_trainers.png', full_page=True)
|
||||
print(" ✓ Screenshot saved\n")
|
||||
|
||||
# Navigate to exercises
|
||||
print("Testing Exercises page...")
|
||||
page.click('text=Übungen')
|
||||
page.wait_for_url('**/exercises**', timeout=5000)
|
||||
page.wait_for_load_state('networkidle')
|
||||
h1 = page.locator('h1').first
|
||||
print(f" Title: {h1.text_content()}")
|
||||
page.screenshot(path='/tmp/04_exercises.png', full_page=True)
|
||||
print(" ✓ Screenshot saved\n")
|
||||
|
||||
# Navigate to trainings
|
||||
print("Testing Trainings page...")
|
||||
page.click('text=Training')
|
||||
page.wait_for_url('**/trainings**', timeout=5000)
|
||||
page.wait_for_load_state('networkidle')
|
||||
h1 = page.locator('h1').first
|
||||
print(f" Title: {h1.text_content()}")
|
||||
page.screenshot(path='/tmp/05_trainings.png', full_page=True)
|
||||
print(" ✓ Screenshot saved\n")
|
||||
|
||||
# Navigate to homework
|
||||
print("Testing Homework page...")
|
||||
page.click('text=Hausaufgaben')
|
||||
page.wait_for_url('**/homework**', timeout=5000)
|
||||
page.wait_for_load_state('networkidle')
|
||||
h1 = page.locator('h1').first
|
||||
print(f" Title: {h1.text_content()}")
|
||||
page.screenshot(path='/tmp/06_homework.png', full_page=True)
|
||||
print(" ✓ Screenshot saved\n")
|
||||
|
||||
# Navigate to clubs
|
||||
print("Testing Clubs page...")
|
||||
page.click('text=Clubs')
|
||||
page.wait_for_url('**/clubs**', timeout=5000)
|
||||
page.wait_for_load_state('networkidle')
|
||||
h1 = page.locator('h1').first
|
||||
print(f" Title: {h1.text_content()}")
|
||||
page.screenshot(path='/tmp/07_clubs.png', full_page=True)
|
||||
print(" ✓ Screenshot saved\n")
|
||||
|
||||
# Check for console errors
|
||||
if console_errors:
|
||||
print(f"⚠ Console errors: {console_errors}")
|
||||
else:
|
||||
print("✓ No console errors")
|
||||
|
||||
browser.close()
|
||||
print("\n✅ All page tests passed!")
|
||||
print("Screenshots saved to /tmp/01_dashboard.png through /tmp/07_clubs.png")
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_all_pages()
|
||||
@@ -0,0 +1,80 @@
|
||||
from playwright.sync_api import sync_playwright
|
||||
import sys
|
||||
|
||||
def test_login_page():
|
||||
with sync_playwright() as p:
|
||||
browser = p.chromium.launch(headless=True)
|
||||
page = browser.new_page()
|
||||
|
||||
# Navigate to login page
|
||||
print("Navigating to login page...")
|
||||
page.goto('http://localhost:3000/login')
|
||||
page.wait_for_load_state('networkidle')
|
||||
|
||||
# Check page title
|
||||
title = page.title()
|
||||
print(f"Page title: {title}")
|
||||
|
||||
# Check for login form elements
|
||||
print("Checking form elements...")
|
||||
|
||||
# Logo/branding
|
||||
logo = page.locator('text=WrestleDesk').first
|
||||
if logo.is_visible():
|
||||
print("✓ Logo 'WrestleDesk' is visible")
|
||||
else:
|
||||
print("✗ Logo 'WrestleDesk' not found")
|
||||
browser.close()
|
||||
sys.exit(1)
|
||||
|
||||
# Username input
|
||||
username_input = page.locator('input[id="username"]')
|
||||
if username_input.is_visible():
|
||||
print("✓ Username input is visible")
|
||||
else:
|
||||
print("✗ Username input not found")
|
||||
browser.close()
|
||||
sys.exit(1)
|
||||
|
||||
# Password input
|
||||
password_input = page.locator('input[id="password"]')
|
||||
if password_input.is_visible():
|
||||
print("✓ Password input is visible")
|
||||
else:
|
||||
print("✗ Password input not found")
|
||||
browser.close()
|
||||
sys.exit(1)
|
||||
|
||||
# Submit button
|
||||
submit_btn = page.locator('button[type="submit"]')
|
||||
if submit_btn.is_visible():
|
||||
print("✓ Submit button is visible")
|
||||
print(f" Button text: {submit_btn.text_content()}")
|
||||
else:
|
||||
print("✗ Submit button not found")
|
||||
browser.close()
|
||||
sys.exit(1)
|
||||
|
||||
# Check for console errors
|
||||
console_errors = []
|
||||
page.on("console", lambda msg: console_errors.append(msg.text) if msg.type == "error" else None)
|
||||
|
||||
# Reload to capture console errors
|
||||
page.reload()
|
||||
page.wait_for_load_state('networkidle')
|
||||
|
||||
if console_errors:
|
||||
print(f"⚠ Console errors found: {console_errors}")
|
||||
else:
|
||||
print("✓ No console errors")
|
||||
|
||||
# Take screenshot
|
||||
screenshot_path = '/tmp/login_page.png'
|
||||
page.screenshot(path=screenshot_path, full_page=True)
|
||||
print(f"✓ Screenshot saved to {screenshot_path}")
|
||||
|
||||
browser.close()
|
||||
print("\n✅ All tests passed!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_login_page()
|
||||
@@ -0,0 +1,64 @@
|
||||
from playwright.sync_api import sync_playwright
|
||||
import sys
|
||||
|
||||
def test_login_flow():
|
||||
with sync_playwright() as p:
|
||||
browser = p.chromium.launch(headless=True)
|
||||
page = browser.new_page()
|
||||
|
||||
console_errors = []
|
||||
page.on("console", lambda msg: console_errors.append(msg.text) if msg.type == "error" else None)
|
||||
|
||||
# Navigate to login page
|
||||
print("1. Navigating to login page...")
|
||||
page.goto('http://localhost:3000/login')
|
||||
page.wait_for_load_state('networkidle')
|
||||
print(" ✓ Page loaded")
|
||||
|
||||
# Fill in login form
|
||||
print("2. Filling login form...")
|
||||
page.fill('input[id="username"]', 'admin')
|
||||
page.fill('input[id="password"]', 'admin123')
|
||||
print(" ✓ Credentials entered")
|
||||
|
||||
# Submit form
|
||||
print("3. Submitting form...")
|
||||
page.click('button[type="submit"]')
|
||||
|
||||
# Wait for navigation to dashboard
|
||||
page.wait_for_url('**/dashboard**', timeout=10000)
|
||||
print(f" ✓ Redirected to: {page.url}")
|
||||
|
||||
# Wait for dashboard to load
|
||||
page.wait_for_load_state('networkidle')
|
||||
|
||||
# Check dashboard elements
|
||||
print("4. Checking dashboard elements...")
|
||||
|
||||
# Check for sidebar
|
||||
sidebar = page.locator('nav').first
|
||||
if sidebar.is_visible():
|
||||
print(" ✓ Sidebar navigation is visible")
|
||||
|
||||
# Check for page title
|
||||
h1 = page.locator('h1').first
|
||||
if h1.is_visible():
|
||||
title_text = h1.text_content()
|
||||
print(f" ✓ Dashboard title: '{title_text}'")
|
||||
|
||||
# Check for console errors
|
||||
if console_errors:
|
||||
print(f"⚠ Console errors: {console_errors}")
|
||||
else:
|
||||
print(" ✓ No console errors")
|
||||
|
||||
# Take screenshot
|
||||
screenshot_path = '/tmp/dashboard.png'
|
||||
page.screenshot(path=screenshot_path, full_page=True)
|
||||
print(f" ✓ Screenshot saved to {screenshot_path}")
|
||||
|
||||
browser.close()
|
||||
print("\n✅ Login flow test passed!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_login_flow()
|
||||
@@ -0,0 +1,106 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Start one or more servers, wait for them to be ready, run a command, then clean up.
|
||||
|
||||
Usage:
|
||||
# Single server
|
||||
python scripts/with_server.py --server "npm run dev" --port 5173 -- python automation.py
|
||||
python scripts/with_server.py --server "npm start" --port 3000 -- python test.py
|
||||
|
||||
# Multiple servers
|
||||
python scripts/with_server.py \
|
||||
--server "cd backend && python server.py" --port 3000 \
|
||||
--server "cd frontend && npm run dev" --port 5173 \
|
||||
-- python test.py
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import socket
|
||||
import time
|
||||
import sys
|
||||
import argparse
|
||||
|
||||
def is_server_ready(port, timeout=30):
|
||||
"""Wait for server to be ready by polling the port."""
|
||||
start_time = time.time()
|
||||
while time.time() - start_time < timeout:
|
||||
try:
|
||||
with socket.create_connection(('localhost', port), timeout=1):
|
||||
return True
|
||||
except (socket.error, ConnectionRefusedError):
|
||||
time.sleep(0.5)
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Run command with one or more servers')
|
||||
parser.add_argument('--server', action='append', dest='servers', required=True, help='Server command (can be repeated)')
|
||||
parser.add_argument('--port', action='append', dest='ports', type=int, required=True, help='Port for each server (must match --server count)')
|
||||
parser.add_argument('--timeout', type=int, default=30, help='Timeout in seconds per server (default: 30)')
|
||||
parser.add_argument('command', nargs=argparse.REMAINDER, help='Command to run after server(s) ready')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Remove the '--' separator if present
|
||||
if args.command and args.command[0] == '--':
|
||||
args.command = args.command[1:]
|
||||
|
||||
if not args.command:
|
||||
print("Error: No command specified to run")
|
||||
sys.exit(1)
|
||||
|
||||
# Parse server configurations
|
||||
if len(args.servers) != len(args.ports):
|
||||
print("Error: Number of --server and --port arguments must match")
|
||||
sys.exit(1)
|
||||
|
||||
servers = []
|
||||
for cmd, port in zip(args.servers, args.ports):
|
||||
servers.append({'cmd': cmd, 'port': port})
|
||||
|
||||
server_processes = []
|
||||
|
||||
try:
|
||||
# Start all servers
|
||||
for i, server in enumerate(servers):
|
||||
print(f"Starting server {i+1}/{len(servers)}: {server['cmd']}")
|
||||
|
||||
# Use shell=True to support commands with cd and &&
|
||||
process = subprocess.Popen(
|
||||
server['cmd'],
|
||||
shell=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE
|
||||
)
|
||||
server_processes.append(process)
|
||||
|
||||
# Wait for this server to be ready
|
||||
print(f"Waiting for server on port {server['port']}...")
|
||||
if not is_server_ready(server['port'], timeout=args.timeout):
|
||||
raise RuntimeError(f"Server failed to start on port {server['port']} within {args.timeout}s")
|
||||
|
||||
print(f"Server ready on port {server['port']}")
|
||||
|
||||
print(f"\nAll {len(servers)} server(s) ready")
|
||||
|
||||
# Run the command
|
||||
print(f"Running: {' '.join(args.command)}\n")
|
||||
result = subprocess.run(args.command)
|
||||
sys.exit(result.returncode)
|
||||
|
||||
finally:
|
||||
# Clean up all servers
|
||||
print(f"\nStopping {len(server_processes)} server(s)...")
|
||||
for i, process in enumerate(server_processes):
|
||||
try:
|
||||
process.terminate()
|
||||
process.wait(timeout=5)
|
||||
except subprocess.TimeoutExpired:
|
||||
process.kill()
|
||||
process.wait()
|
||||
print(f"Server {i+1} stopped")
|
||||
print("All servers stopped")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user