From e60f73de9dbf8ab536942265b217c8d8e2a0cd87 Mon Sep 17 00:00:00 2001 From: pacnpal <183241239+pacnpal@users.noreply.github.com> Date: Tue, 24 Dec 2024 14:32:16 -0500 Subject: [PATCH] Add test setup, cleanup, and fixtures --- .../management/commands/cleanup_test_data.py | 67 +++++++++++++ tests/e2e/cleanup.sh | 25 +++++ tests/e2e/conftest.py | 99 +++++++++++++++++++ tests/e2e/setup.sh | 55 +++++++++++ 4 files changed, 246 insertions(+) create mode 100644 accounts/management/commands/cleanup_test_data.py create mode 100755 tests/e2e/cleanup.sh create mode 100644 tests/e2e/conftest.py create mode 100755 tests/e2e/setup.sh diff --git a/accounts/management/commands/cleanup_test_data.py b/accounts/management/commands/cleanup_test_data.py new file mode 100644 index 00000000..c59380ae --- /dev/null +++ b/accounts/management/commands/cleanup_test_data.py @@ -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")) diff --git a/tests/e2e/cleanup.sh b/tests/e2e/cleanup.sh new file mode 100755 index 00000000..790c3942 --- /dev/null +++ b/tests/e2e/cleanup.sh @@ -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!" \ No newline at end of file diff --git a/tests/e2e/conftest.py b/tests/e2e/conftest.py new file mode 100644 index 00000000..7725ebfc --- /dev/null +++ b/tests/e2e/conftest.py @@ -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 diff --git a/tests/e2e/setup.sh b/tests/e2e/setup.sh new file mode 100755 index 00000000..61f56ea6 --- /dev/null +++ b/tests/e2e/setup.sh @@ -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" \ No newline at end of file