mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 12:31:22 -05:00
Add test setup, cleanup, and fixtures
This commit is contained in:
67
accounts/management/commands/cleanup_test_data.py
Normal file
67
accounts/management/commands/cleanup_test_data.py
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
from django.core.management.base import BaseCommand
|
||||||
|
from django.contrib.auth import get_user_model
|
||||||
|
from django.contrib.auth.models import Group
|
||||||
|
from reviews.models import Review
|
||||||
|
from parks.models import Park
|
||||||
|
from rides.models import Ride
|
||||||
|
from media.models import Photo
|
||||||
|
|
||||||
|
User = get_user_model()
|
||||||
|
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
help = "Cleans up test users and data created during e2e testing"
|
||||||
|
|
||||||
|
def handle(self, *args, **kwargs):
|
||||||
|
# Delete test users
|
||||||
|
test_users = User.objects.filter(username__in=["testuser", "moderator"])
|
||||||
|
count = test_users.count()
|
||||||
|
test_users.delete()
|
||||||
|
self.stdout.write(self.style.SUCCESS(f"Deleted {count} test users"))
|
||||||
|
|
||||||
|
# Delete test reviews
|
||||||
|
reviews = Review.objects.filter(author__username__in=["testuser", "moderator"])
|
||||||
|
count = reviews.count()
|
||||||
|
reviews.delete()
|
||||||
|
self.stdout.write(self.style.SUCCESS(f"Deleted {count} test reviews"))
|
||||||
|
|
||||||
|
# Delete test photos
|
||||||
|
photos = Photo.objects.filter(uploader__username__in=["testuser", "moderator"])
|
||||||
|
count = photos.count()
|
||||||
|
photos.delete()
|
||||||
|
self.stdout.write(self.style.SUCCESS(f"Deleted {count} test photos"))
|
||||||
|
|
||||||
|
# Delete test parks
|
||||||
|
parks = Park.objects.filter(name__startswith="Test Park")
|
||||||
|
count = parks.count()
|
||||||
|
parks.delete()
|
||||||
|
self.stdout.write(self.style.SUCCESS(f"Deleted {count} test parks"))
|
||||||
|
|
||||||
|
# Delete test rides
|
||||||
|
rides = Ride.objects.filter(name__startswith="Test Ride")
|
||||||
|
count = rides.count()
|
||||||
|
rides.delete()
|
||||||
|
self.stdout.write(self.style.SUCCESS(f"Deleted {count} test rides"))
|
||||||
|
|
||||||
|
# Clean up test files
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
|
||||||
|
# Clean up test uploads
|
||||||
|
media_patterns = [
|
||||||
|
"media/uploads/test_*",
|
||||||
|
"media/avatars/test_*",
|
||||||
|
"media/park/test_*",
|
||||||
|
"media/rides/test_*",
|
||||||
|
]
|
||||||
|
|
||||||
|
for pattern in media_patterns:
|
||||||
|
files = glob.glob(pattern)
|
||||||
|
for f in files:
|
||||||
|
try:
|
||||||
|
os.remove(f)
|
||||||
|
self.stdout.write(self.style.SUCCESS(f"Deleted {f}"))
|
||||||
|
except OSError as e:
|
||||||
|
self.stdout.write(self.style.WARNING(f"Error deleting {f}: {e}"))
|
||||||
|
|
||||||
|
self.stdout.write(self.style.SUCCESS("Test data cleanup complete"))
|
||||||
25
tests/e2e/cleanup.sh
Executable file
25
tests/e2e/cleanup.sh
Executable file
@@ -0,0 +1,25 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e # Exit on error
|
||||||
|
|
||||||
|
echo "Cleaning up test data..."
|
||||||
|
|
||||||
|
# Run Django cleanup command
|
||||||
|
uv run manage.py cleanup_test_data
|
||||||
|
|
||||||
|
# Clean up test fixtures
|
||||||
|
echo "Cleaning up test fixtures..."
|
||||||
|
rm -f tests/fixtures/test_photo.jpg
|
||||||
|
rm -f tests/fixtures/test_avatar.jpg
|
||||||
|
|
||||||
|
# Clean up Playwright artifacts
|
||||||
|
echo "Cleaning up Playwright artifacts..."
|
||||||
|
rm -rf test-results/
|
||||||
|
rm -rf playwright-report/
|
||||||
|
|
||||||
|
# Clean up pytest cache
|
||||||
|
echo "Cleaning up pytest cache..."
|
||||||
|
rm -rf .pytest_cache/
|
||||||
|
rm -rf tests/e2e/__pycache__/
|
||||||
|
find . -type d -name "__pycache__" -exec rm -r {} + 2>/dev/null || true
|
||||||
|
|
||||||
|
echo "Cleanup complete!"
|
||||||
99
tests/e2e/conftest.py
Normal file
99
tests/e2e/conftest.py
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
import pytest
|
||||||
|
from playwright.sync_api import Page
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def setup_test_data():
|
||||||
|
"""Setup test data before each test session"""
|
||||||
|
subprocess.run(["uv", "run", "manage.py", "create_test_users"], check=True)
|
||||||
|
yield
|
||||||
|
subprocess.run(["uv", "run", "manage.py", "cleanup_test_data"], check=True)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def setup_page(page: Page):
|
||||||
|
"""Configure page for tests"""
|
||||||
|
# Set viewport size
|
||||||
|
page.set_viewport_size({"width": 1280, "height": 720})
|
||||||
|
|
||||||
|
# Set default navigation timeout
|
||||||
|
page.set_default_timeout(5000)
|
||||||
|
|
||||||
|
# Listen for console errors
|
||||||
|
page.on(
|
||||||
|
"console",
|
||||||
|
lambda msg: print(f"Browser console {msg.type}: {msg.text}")
|
||||||
|
if msg.type == "error"
|
||||||
|
else None,
|
||||||
|
)
|
||||||
|
|
||||||
|
yield page
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def auth_page(page: Page):
|
||||||
|
"""Fixture for authenticated page"""
|
||||||
|
# Login
|
||||||
|
page.goto("http://localhost:8000/accounts/login/")
|
||||||
|
page.get_by_label("Username").fill("testuser")
|
||||||
|
page.get_by_label("Password").fill("testpass123")
|
||||||
|
page.get_by_role("button", name="Sign In").click()
|
||||||
|
|
||||||
|
yield page
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mod_page(page: Page):
|
||||||
|
"""Fixture for moderator page"""
|
||||||
|
# Login as moderator
|
||||||
|
page.goto("http://localhost:8000/accounts/login/")
|
||||||
|
page.get_by_label("Username").fill("moderator")
|
||||||
|
page.get_by_label("Password").fill("modpass123")
|
||||||
|
page.get_by_role("button", name="Sign In").click()
|
||||||
|
|
||||||
|
yield page
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def test_park(auth_page: Page):
|
||||||
|
"""Fixture for test park"""
|
||||||
|
# Create test park
|
||||||
|
auth_page.goto("http://localhost:8000/parks/create/")
|
||||||
|
auth_page.get_by_label("Name").fill("Test Park")
|
||||||
|
auth_page.get_by_label("Location").fill("Orlando, FL")
|
||||||
|
auth_page.get_by_label("Description").fill("A test theme park")
|
||||||
|
auth_page.get_by_label("Photo").set_input_files("tests/fixtures/test_photo.jpg")
|
||||||
|
auth_page.get_by_role("button", name="Create Park").click()
|
||||||
|
|
||||||
|
yield auth_page
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def test_ride(test_park: Page):
|
||||||
|
"""Fixture for test ride"""
|
||||||
|
# Create test ride
|
||||||
|
test_park.goto("http://localhost:8000/rides/create/")
|
||||||
|
test_park.get_by_label("Name").fill("Test Ride")
|
||||||
|
test_park.get_by_label("Park").select_option("Test Park")
|
||||||
|
test_park.get_by_label("Type").select_option("Roller Coaster")
|
||||||
|
test_park.get_by_label("Description").fill("A test ride")
|
||||||
|
test_park.get_by_label("Photo").set_input_files("tests/fixtures/test_photo.jpg")
|
||||||
|
test_park.get_by_role("button", name="Create Ride").click()
|
||||||
|
|
||||||
|
yield test_park
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def test_review(test_park: Page):
|
||||||
|
"""Fixture for test review"""
|
||||||
|
# Create test review
|
||||||
|
test_park.goto("http://localhost:8000/parks/test-park/")
|
||||||
|
test_park.get_by_role("tab", name="Reviews").click()
|
||||||
|
test_park.get_by_role("button", name="Write Review").click()
|
||||||
|
test_park.get_by_label("Rating").select_option("5")
|
||||||
|
test_park.get_by_label("Title").fill("Test Review")
|
||||||
|
test_park.get_by_label("Review").fill("This is a test review")
|
||||||
|
test_park.get_by_role("button", name="Submit Review").click()
|
||||||
|
|
||||||
|
yield test_park
|
||||||
55
tests/e2e/setup.sh
Executable file
55
tests/e2e/setup.sh
Executable file
@@ -0,0 +1,55 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e # Exit on error
|
||||||
|
|
||||||
|
# Function to check command exists
|
||||||
|
check_command() {
|
||||||
|
if ! command -v $1 &> /dev/null; then
|
||||||
|
echo "Error: $1 is required but not installed."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check required commands
|
||||||
|
check_command uv
|
||||||
|
check_command curl
|
||||||
|
check_command playwright
|
||||||
|
|
||||||
|
# Clean up any existing test data
|
||||||
|
echo "Cleaning up any existing test data..."
|
||||||
|
uv run manage.py cleanup_test_data || true
|
||||||
|
|
||||||
|
# Install Python dependencies
|
||||||
|
echo "Installing Python dependencies..."
|
||||||
|
uv pip install -r requirements.txt
|
||||||
|
|
||||||
|
# Install Playwright browsers
|
||||||
|
echo "Installing Playwright browsers..."
|
||||||
|
playwright install chromium firefox webkit
|
||||||
|
|
||||||
|
# Create test fixtures directory
|
||||||
|
echo "Setting up test fixtures..."
|
||||||
|
mkdir -p tests/fixtures
|
||||||
|
|
||||||
|
# Download test images
|
||||||
|
echo "Downloading test images..."
|
||||||
|
curl -L "https://picsum.photos/1920/1080" -o tests/fixtures/test_photo.jpg
|
||||||
|
curl -L "https://picsum.photos/500/500" -o tests/fixtures/test_avatar.jpg
|
||||||
|
|
||||||
|
# Verify images were downloaded
|
||||||
|
if [ ! -f tests/fixtures/test_photo.jpg ] || [ ! -f tests/fixtures/test_avatar.jpg ]; then
|
||||||
|
echo "Error: Failed to download test images"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create test users
|
||||||
|
echo "Creating test users..."
|
||||||
|
uv run manage.py create_test_users
|
||||||
|
|
||||||
|
# Make cleanup script executable
|
||||||
|
chmod +x tests/e2e/cleanup.sh
|
||||||
|
|
||||||
|
echo "Setup complete! You can now:"
|
||||||
|
echo "1. Run all tests: pytest tests/e2e/"
|
||||||
|
echo "2. Run specific tests: pytest tests/e2e/test_auth.py"
|
||||||
|
echo "3. Run with specific browser: pytest --browser firefox tests/e2e/"
|
||||||
|
echo "4. Clean up test data: ./tests/e2e/cleanup.sh"
|
||||||
Reference in New Issue
Block a user