diff --git a/accounts/management/commands/create_test_users.py b/accounts/management/commands/create_test_users.py new file mode 100644 index 00000000..c18e0ea3 --- /dev/null +++ b/accounts/management/commands/create_test_users.py @@ -0,0 +1,56 @@ +from django.core.management.base import BaseCommand +from django.contrib.auth import get_user_model +from django.contrib.auth.models import Group, Permission + +User = get_user_model() + + +class Command(BaseCommand): + help = "Creates test users for e2e testing" + + def handle(self, *args, **kwargs): + # Create regular test user + if not User.objects.filter(username="testuser").exists(): + user = User.objects.create_user( + username="testuser", + email="testuser@example.com", + [PASSWORD-REMOVED]", + ) + self.stdout.write(self.style.SUCCESS(f"Created test user: {user.username}")) + else: + self.stdout.write(self.style.WARNING("Test user already exists")) + + # Create moderator user + if not User.objects.filter(username="moderator").exists(): + moderator = User.objects.create_user( + username="moderator", + email="moderator@example.com", + [PASSWORD-REMOVED]", + ) + + # Create moderator group if it doesn't exist + moderator_group, created = Group.objects.get_or_create(name="Moderators") + + # Add relevant permissions + permissions = Permission.objects.filter( + codename__in=[ + "change_review", + "delete_review", + "change_park", + "change_ride", + "moderate_photos", + "moderate_comments", + ] + ) + moderator_group.permissions.add(*permissions) + + # Add user to moderator group + moderator.groups.add(moderator_group) + + self.stdout.write( + self.style.SUCCESS(f"Created moderator user: {moderator.username}") + ) + else: + self.stdout.write(self.style.WARNING("Moderator user already exists")) + + self.stdout.write(self.style.SUCCESS("Test users setup complete")) diff --git a/tests/e2e/README.md b/tests/e2e/README.md new file mode 100644 index 00000000..0e952203 --- /dev/null +++ b/tests/e2e/README.md @@ -0,0 +1,116 @@ +# ThrillWiki E2E Tests + +This directory contains end-to-end tests for ThrillWiki using Playwright and pytest. + +## Setup + +1. Install dependencies: +```bash +uv pip install -r requirements.txt +``` + +2. Install Playwright browsers: +```bash +playwright install +``` + +3. Create test fixtures: +```bash +mkdir -p tests/fixtures +``` + +4. Add test assets: +Place the following files in `tests/fixtures/`: +- `test_photo.jpg` - A sample photo for testing uploads +- `test_avatar.jpg` - A sample avatar image for profile tests + +## Running Tests + +### Run all tests: +```bash +pytest tests/e2e/ +``` + +### Run specific test files: +```bash +pytest tests/e2e/test_auth.py +pytest tests/e2e/test_parks.py +pytest tests/e2e/test_rides.py +pytest tests/e2e/test_reviews.py +pytest tests/e2e/test_profiles.py +``` + +### Run tests by marker: +```bash +pytest -m auth +pytest -m parks +pytest -m rides +pytest -m reviews +pytest -m profiles +``` + +### Run tests with different browsers: +```bash +pytest --browser chromium +pytest --browser firefox +pytest --browser webkit +``` + +### Run tests headlessly: +```bash +pytest --headless +``` + +## Test Structure + +- `test_auth.py` - Authentication tests (login, signup, logout) +- `test_parks.py` - Theme park tests (listing, details, reviews, photos) +- `test_rides.py` - Ride tests (listing, details, reviews, photos) +- `test_reviews.py` - Review tests (creation, editing, moderation) +- `test_profiles.py` - User profile tests (settings, preferences) + +## Test Data + +The tests expect the following test users to exist in the database: + +1. Regular User: + - Username: testuser + - Password: testpass123 + +2. Moderator: + - Username: moderator + - Password: modpass123 + +You can create these users using Django management commands: +```bash +python manage.py create_test_users +``` + +## Test Environment + +Tests expect: +1. Django development server running on http://localhost:8000 +2. Database with test data loaded +3. Media handling configured for test uploads + +## Debugging + +1. Use `--headed` flag to see browser during test execution +2. Use `--slowmo 1000` to slow down test execution +3. Use `--debug` for detailed logging +4. Screenshots are saved in `test-results/` on failure + +## Common Issues + +1. **Connection Refused**: Ensure Django server is running +2. **Element Not Found**: Check selectors and page load timing +3. **Upload Failures**: Verify test fixtures exist +4. **Authentication Errors**: Verify test users exist in database + +## Contributing + +1. Add new tests in appropriate test files +2. Follow existing test patterns +3. Include comments explaining test scenarios +4. Update README for new test categories +5. Add new fixtures as needed \ No newline at end of file diff --git a/tests/e2e/pytest.ini b/tests/e2e/pytest.ini new file mode 100644 index 00000000..9d9a4c68 --- /dev/null +++ b/tests/e2e/pytest.ini @@ -0,0 +1,28 @@ +[pytest] +# Base URL for tests +base_url = http://localhost:8000 + +# Test file patterns +python_files = test_*.py +python_classes = Test* +python_functions = test_* + +# Playwright specific settings +addopts = --headed --browser chromium + +# Markers +markers = + auth: authentication related tests + parks: theme park related tests + rides: ride related tests + reviews: review related tests + profiles: user profile related tests + +# Test timeout +timeout = 30 + +# Logging settings +log_cli = true +log_cli_level = INFO +log_cli_format = %(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s) +log_cli_date_format = %Y-%m-%d %H:%M:%S \ No newline at end of file diff --git a/tests/e2e/test_auth.py b/tests/e2e/test_auth.py new file mode 100644 index 00000000..0c5c538b --- /dev/null +++ b/tests/e2e/test_auth.py @@ -0,0 +1,92 @@ +import pytest +from playwright.sync_api import expect, Page + + +def test_login_page(page: Page): + # Navigate to login page + page.goto("http://localhost:8000/accounts/login/") + + # Check login form elements + expect(page.get_by_label("Username")).to_be_visible() + expect(page.get_by_label("Password")).to_be_visible() + expect(page.get_by_role("button", name="Sign In")).to_be_visible() + + # Check social login buttons + expect(page.get_by_role("link", name="Sign in with Google")).to_be_visible() + expect(page.get_by_role("link", name="Sign in with Discord")).to_be_visible() + + +def test_successful_login(page: Page): + # Navigate to login page + page.goto("http://localhost:8000/accounts/login/") + + # Fill in login form + page.get_by_label("Username").fill("testuser") + page.get_by_label("Password").fill("testpass123") + + # Click login button + page.get_by_role("button", name="Sign In").click() + + # Verify redirect to home page + expect(page).to_have_url("http://localhost:8000/") + expect(page.get_by_role("link", name="Profile")).to_be_visible() + + +def test_failed_login(page: Page): + # Navigate to login page + page.goto("http://localhost:8000/accounts/login/") + + # Fill in incorrect credentials + page.get_by_label("Username").fill("wronguser") + page.get_by_label("Password").fill("wrongpass") + + # Click login button + page.get_by_role("button", name="Sign In").click() + + # Verify error message + expect(page.get_by_text("Invalid username or password")).to_be_visible() + + +def test_signup_page(page: Page): + # Navigate to signup page + page.goto("http://localhost:8000/accounts/signup/") + + # Check signup form elements + expect(page.get_by_label("Username")).to_be_visible() + expect(page.get_by_label("Email")).to_be_visible() + expect(page.get_by_label("Password")).to_be_visible() + expect(page.get_by_label("Password (again)")).to_be_visible() + expect(page.get_by_role("button", name="Sign Up")).to_be_visible() + + +def test_successful_signup(page: Page): + # Navigate to signup page + page.goto("http://localhost:8000/accounts/signup/") + + # Fill in signup form + page.get_by_label("Username").fill("newuser") + page.get_by_label("Email").fill("newuser@example.com") + page.get_by_label("Password").fill("newpass123") + page.get_by_label("Password (again)").fill("newpass123") + + # Click signup button + page.get_by_role("button", name="Sign Up").click() + + # Verify redirect to home page + expect(page).to_have_url("http://localhost:8000/") + expect(page.get_by_role("link", name="Profile")).to_be_visible() + + +def test_logout(page: Page): + # First 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() + + # Click logout + page.get_by_role("link", name="Logout").click() + + # Verify redirect to home page and logged out state + expect(page).to_have_url("http://localhost:8000/") + expect(page.get_by_role("link", name="Login")).to_be_visible() diff --git a/tests/e2e/test_parks.py b/tests/e2e/test_parks.py new file mode 100644 index 00000000..06266910 --- /dev/null +++ b/tests/e2e/test_parks.py @@ -0,0 +1,131 @@ +import pytest +from playwright.sync_api import expect, Page + + +def test_parks_list_page(page: Page): + # Navigate to parks page + page.goto("http://localhost:8000/parks/") + + # Check parks list elements + expect(page.get_by_role("heading", name="Theme Parks")).to_be_visible() + expect(page.get_by_role("searchbox", name="Search parks")).to_be_visible() + + # Check filter options + expect(page.get_by_role("combobox", name="Country")).to_be_visible() + expect(page.get_by_role("combobox", name="State/Region")).to_be_visible() + + +def test_park_search(page: Page): + # Navigate to parks page + page.goto("http://localhost:8000/parks/") + + # Search for a park + search_box = page.get_by_role("searchbox", name="Search parks") + search_box.fill("Universal") + search_box.press("Enter") + + # Verify search results + expect(page.get_by_text("Universal Studios")).to_be_visible() + expect(page.get_by_text("Universal's Islands of Adventure")).to_be_visible() + + +def test_park_filters(page: Page): + # Navigate to parks page + page.goto("http://localhost:8000/parks/") + + # Select country filter + page.get_by_role("combobox", name="Country").select_option("United States") + + # Select state filter + page.get_by_role("combobox", name="State/Region").select_option("Florida") + + # Verify filtered results + expect(page.get_by_text("Walt Disney World")).to_be_visible() + expect(page.get_by_text("Universal Orlando Resort")).to_be_visible() + + +def test_park_detail_page(page: Page): + # Navigate to a specific park page + page.goto("http://localhost:8000/parks/walt-disney-world/") + + # Check park details + expect(page.get_by_role("heading", name="Walt Disney World")).to_be_visible() + expect(page.get_by_text("Location:")).to_be_visible() + expect(page.get_by_text("Orlando, Florida")).to_be_visible() + + # Check park sections + expect(page.get_by_role("tab", name="Overview")).to_be_visible() + expect(page.get_by_role("tab", name="Rides")).to_be_visible() + expect(page.get_by_role("tab", name="Reviews")).to_be_visible() + expect(page.get_by_role("tab", name="Photos")).to_be_visible() + + +def test_add_park_review(page: Page): + # First 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() + + # Navigate to park page + page.goto("http://localhost:8000/parks/walt-disney-world/") + + # Click on Reviews tab + page.get_by_role("tab", name="Reviews").click() + + # Click Write Review button + page.get_by_role("button", name="Write Review").click() + + # Fill review form + page.get_by_label("Rating").select_option("5") + page.get_by_label("Title").fill("Amazing Experience") + page.get_by_label("Review").fill("Had a fantastic time at the park!") + + # Submit review + page.get_by_role("button", name="Submit Review").click() + + # Verify review appears + expect(page.get_by_text("Amazing Experience")).to_be_visible() + expect(page.get_by_text("Had a fantastic time at the park!")).to_be_visible() + + +def test_add_park_photo(page: Page): + # First 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() + + # Navigate to park page + page.goto("http://localhost:8000/parks/walt-disney-world/") + + # Click on Photos tab + page.get_by_role("tab", name="Photos").click() + + # Click Add Photo button + page.get_by_role("button", name="Add Photo").click() + + # Upload photo + page.get_by_label("Photo").set_input_files("tests/fixtures/test_photo.jpg") + page.get_by_label("Caption").fill("Beautiful castle at sunset") + + # Submit photo + page.get_by_role("button", name="Upload Photo").click() + + # Verify photo appears + expect(page.get_by_text("Beautiful castle at sunset")).to_be_visible() + + +def test_park_map(page: Page): + # Navigate to park page + page.goto("http://localhost:8000/parks/walt-disney-world/") + + # Check map exists + expect(page.locator("#park-map")).to_be_visible() + + # Check map controls + expect(page.get_by_role("button", name="Zoom in")).to_be_visible() + expect(page.get_by_role("button", name="Zoom out")).to_be_visible() + + # Verify map markers + expect(page.locator(".map-marker")).to_have_count.greater_than(0) diff --git a/tests/e2e/test_profiles.py b/tests/e2e/test_profiles.py new file mode 100644 index 00000000..d484bcb4 --- /dev/null +++ b/tests/e2e/test_profiles.py @@ -0,0 +1,172 @@ +import pytest +from playwright.sync_api import expect, Page + + +def test_profile_page(page: Page): + # First 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() + + # Navigate to profile + page.get_by_role("link", name="Profile").click() + + # Check profile sections + expect(page.get_by_role("heading", name="Profile")).to_be_visible() + expect(page.get_by_role("tab", name="Overview")).to_be_visible() + expect(page.get_by_role("tab", name="Reviews")).to_be_visible() + expect(page.get_by_role("tab", name="Photos")).to_be_visible() + expect(page.get_by_role("tab", name="Settings")).to_be_visible() + + +def test_edit_profile(page: Page): + # First 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() + + # Navigate to profile settings + page.get_by_role("link", name="Profile").click() + page.get_by_role("tab", name="Settings").click() + + # Edit profile information + page.get_by_label("Display Name").fill("Test User") + page.get_by_label("Bio").fill("Theme park enthusiast") + page.get_by_label("Location").fill("Orlando, FL") + + # Upload avatar + page.get_by_label("Avatar").set_input_files("tests/fixtures/test_avatar.jpg") + + # Save changes + page.get_by_role("button", name="Save Changes").click() + + # Verify updates + expect(page.get_by_text("Profile updated successfully")).to_be_visible() + expect(page.get_by_text("Test User")).to_be_visible() + expect(page.get_by_text("Theme park enthusiast")).to_be_visible() + expect(page.get_by_text("Orlando, FL")).to_be_visible() + + +def test_change_password(page: Page): + # First 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() + + # Navigate to profile settings + page.get_by_role("link", name="Profile").click() + page.get_by_role("tab", name="Settings").click() + + # Click change password + page.get_by_role("link", name="Change Password").click() + + # Fill password form + page.get_by_label("Current Password").fill("testpass123") + page.get_by_label("New Password").fill("newpass123") + page.get_by_label("Confirm New Password").fill("newpass123") + + # Submit form + page.get_by_role("button", name="Change Password").click() + + # Verify password changed + expect(page.get_by_text("Password changed successfully")).to_be_visible() + + +def test_email_preferences(page: Page): + # First 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() + + # Navigate to profile settings + page.get_by_role("link", name="Profile").click() + page.get_by_role("tab", name="Settings").click() + + # Click email preferences + page.get_by_role("link", name="Email Preferences").click() + + # Update preferences + page.get_by_label("Newsletter").check() + page.get_by_label("Review Notifications").check() + page.get_by_label("Photo Comments").uncheck() + + # Save changes + page.get_by_role("button", name="Save Preferences").click() + + # Verify updates + expect(page.get_by_text("Email preferences updated")).to_be_visible() + + +def test_privacy_settings(page: Page): + # First 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() + + # Navigate to profile settings + page.get_by_role("link", name="Profile").click() + page.get_by_role("tab", name="Settings").click() + + # Click privacy settings + page.get_by_role("link", name="Privacy Settings").click() + + # Update settings + page.get_by_label("Show Email").uncheck() + page.get_by_label("Show Location").check() + page.get_by_label("Public Profile").check() + + # Save changes + page.get_by_role("button", name="Save Privacy Settings").click() + + # Verify updates + expect(page.get_by_text("Privacy settings updated")).to_be_visible() + + +def test_connected_accounts(page: Page): + # First 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() + + # Navigate to profile settings + page.get_by_role("link", name="Profile").click() + page.get_by_role("tab", name="Settings").click() + + # Click connected accounts + page.get_by_role("link", name="Connected Accounts").click() + + # Check available connections + expect(page.get_by_role("link", name="Connect Google")).to_be_visible() + expect(page.get_by_role("link", name="Connect Discord")).to_be_visible() + + +def test_delete_account(page: Page): + # First 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() + + # Navigate to profile settings + page.get_by_role("link", name="Profile").click() + page.get_by_role("tab", name="Settings").click() + + # Click delete account + page.get_by_role("link", name="Delete Account").click() + + # Confirm deletion + page.get_by_label("Password").fill("testpass123") + page.get_by_label("Confirm").check() + + # Click delete button + page.get_by_role("button", name="Delete Account").click() + + # Verify redirect to home and logged out + expect(page).to_have_url("http://localhost:8000/") + expect(page.get_by_role("link", name="Login")).to_be_visible() diff --git a/tests/e2e/test_reviews.py b/tests/e2e/test_reviews.py new file mode 100644 index 00000000..e2c6156c --- /dev/null +++ b/tests/e2e/test_reviews.py @@ -0,0 +1,161 @@ +import pytest +from playwright.sync_api import expect, Page + + +def test_reviews_list_page(page: Page): + # Navigate to reviews page + page.goto("http://localhost:8000/reviews/") + + # Check reviews list elements + expect(page.get_by_role("heading", name="Latest Reviews")).to_be_visible() + expect(page.get_by_role("searchbox", name="Search reviews")).to_be_visible() + + # Check filter options + expect(page.get_by_role("combobox", name="Type")).to_be_visible() + expect(page.get_by_role("combobox", name="Rating")).to_be_visible() + expect(page.get_by_role("combobox", name="Sort By")).to_be_visible() + + +def test_review_search(page: Page): + # Navigate to reviews page + page.goto("http://localhost:8000/reviews/") + + # Search for reviews + search_box = page.get_by_role("searchbox", name="Search reviews") + search_box.fill("great experience") + search_box.press("Enter") + + # Verify search results + expect(page.get_by_text("great experience", exact=False)).to_be_visible() + + +def test_review_filters(page: Page): + # Navigate to reviews page + page.goto("http://localhost:8000/reviews/") + + # Select type filter + page.get_by_role("combobox", name="Type").select_option("Parks") + + # Select rating filter + page.get_by_role("combobox", name="Rating").select_option("5 Stars") + + # Select sort order + page.get_by_role("combobox", name="Sort By").select_option("Most Recent") + + # Verify filtered results + expect(page.get_by_text("Park Review")).to_be_visible() + expect(page.locator(".five-star-rating")).to_be_visible() + + +def test_review_detail_page(page: Page): + # Navigate to a specific review + page.goto("http://localhost:8000/reviews/1/") + + # Check review details + expect(page.get_by_role("heading", name="Review")).to_be_visible() + expect(page.locator(".review-rating")).to_be_visible() + expect(page.locator(".review-date")).to_be_visible() + expect(page.locator(".review-author")).to_be_visible() + expect(page.locator(".review-content")).to_be_visible() + + +def test_review_voting(page: Page): + # First 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() + + # Navigate to review + page.goto("http://localhost:8000/reviews/1/") + + # Click helpful button + page.get_by_role("button", name="Helpful").click() + + # Verify vote registered + expect(page.get_by_text("You found this review helpful")).to_be_visible() + expect(page.locator(".helpful-count")).to_contain_text("1") + + +def test_review_comments(page: Page): + # First 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() + + # Navigate to review + page.goto("http://localhost:8000/reviews/1/") + + # Add comment + page.get_by_label("Comment").fill("Great review! Very helpful.") + page.get_by_role("button", name="Post Comment").click() + + # Verify comment appears + expect(page.get_by_text("Great review! Very helpful.")).to_be_visible() + + +def test_review_moderation(page: Page): + # First 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() + + # Navigate to review + page.goto("http://localhost:8000/reviews/1/") + + # Check moderation options + expect(page.get_by_role("button", name="Edit Review")).to_be_visible() + expect(page.get_by_role("button", name="Delete Review")).to_be_visible() + expect(page.get_by_role("button", name="Flag Review")).to_be_visible() + + +def test_review_reporting(page: Page): + # First 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() + + # Navigate to review + page.goto("http://localhost:8000/reviews/1/") + + # Click report button + page.get_by_role("button", name="Report Review").click() + + # Fill report form + page.get_by_label("Reason").select_option("inappropriate") + page.get_by_label("Details").fill("This review contains inappropriate content") + + # Submit report + page.get_by_role("button", name="Submit Report").click() + + # Verify report confirmation + expect(page.get_by_text("Review reported successfully")).to_be_visible() + + +def test_review_editing(page: Page): + # First login as review author + 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() + + # Navigate to own review + page.goto("http://localhost:8000/reviews/1/") + + # Click edit button + page.get_by_role("button", name="Edit Review").click() + + # Modify review + page.get_by_label("Title").fill("Updated Review Title") + page.get_by_label("Review").fill("Updated review content") + + # Save changes + page.get_by_role("button", name="Save Changes").click() + + # Verify updates + expect(page.get_by_text("Updated Review Title")).to_be_visible() + expect(page.get_by_text("Updated review content")).to_be_visible() + expect(page.get_by_text("(edited)")).to_be_visible() diff --git a/tests/e2e/test_rides.py b/tests/e2e/test_rides.py new file mode 100644 index 00000000..1825ef9c --- /dev/null +++ b/tests/e2e/test_rides.py @@ -0,0 +1,166 @@ +import pytest +from playwright.sync_api import expect, Page + + +def test_rides_list_page(page: Page): + # Navigate to rides page + page.goto("http://localhost:8000/rides/") + + # Check rides list elements + expect(page.get_by_role("heading", name="Rides & Attractions")).to_be_visible() + expect(page.get_by_role("searchbox", name="Search rides")).to_be_visible() + + # Check filter options + expect(page.get_by_role("combobox", name="Park")).to_be_visible() + expect(page.get_by_role("combobox", name="Type")).to_be_visible() + expect(page.get_by_role("combobox", name="Manufacturer")).to_be_visible() + expect(page.get_by_role("combobox", name="Status")).to_be_visible() + + +def test_ride_search(page: Page): + # Navigate to rides page + page.goto("http://localhost:8000/rides/") + + # Search for a ride + search_box = page.get_by_role("searchbox", name="Search rides") + search_box.fill("Space Mountain") + search_box.press("Enter") + + # Verify search results + expect(page.get_by_text("Space Mountain")).to_be_visible() + expect(page.get_by_text("Walt Disney World")).to_be_visible() + + +def test_ride_filters(page: Page): + # Navigate to rides page + page.goto("http://localhost:8000/rides/") + + # Select park filter + page.get_by_role("combobox", name="Park").select_option("Walt Disney World") + + # Select type filter + page.get_by_role("combobox", name="Type").select_option("Roller Coaster") + + # Select manufacturer filter + page.get_by_role("combobox", name="Manufacturer").select_option("Vekoma") + + # Verify filtered results + expect(page.get_by_text("Space Mountain")).to_be_visible() + expect(page.get_by_text("Roller Coaster")).to_be_visible() + expect(page.get_by_text("Vekoma")).to_be_visible() + + +def test_ride_detail_page(page: Page): + # Navigate to a specific ride page + page.goto("http://localhost:8000/rides/space-mountain-magic-kingdom/") + + # Check ride details + expect(page.get_by_role("heading", name="Space Mountain")).to_be_visible() + expect(page.get_by_text("Park:")).to_be_visible() + expect(page.get_by_text("Walt Disney World")).to_be_visible() + expect(page.get_by_text("Type:")).to_be_visible() + expect(page.get_by_text("Roller Coaster")).to_be_visible() + expect(page.get_by_text("Manufacturer:")).to_be_visible() + expect(page.get_by_text("Vekoma")).to_be_visible() + + # Check ride sections + expect(page.get_by_role("tab", name="Overview")).to_be_visible() + expect(page.get_by_role("tab", name="Stats")).to_be_visible() + expect(page.get_by_role("tab", name="Reviews")).to_be_visible() + expect(page.get_by_role("tab", name="Photos")).to_be_visible() + + +def test_ride_stats(page: Page): + # Navigate to ride page + page.goto("http://localhost:8000/rides/space-mountain-magic-kingdom/") + + # Click on Stats tab + page.get_by_role("tab", name="Stats").click() + + # Check stats are visible + expect(page.get_by_text("Height:")).to_be_visible() + expect(page.get_by_text("Length:")).to_be_visible() + expect(page.get_by_text("Speed:")).to_be_visible() + expect(page.get_by_text("Duration:")).to_be_visible() + expect(page.get_by_text("Height Requirement:")).to_be_visible() + + +def test_add_ride_review(page: Page): + # First 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() + + # Navigate to ride page + page.goto("http://localhost:8000/rides/space-mountain-magic-kingdom/") + + # Click on Reviews tab + page.get_by_role("tab", name="Reviews").click() + + # Click Write Review button + page.get_by_role("button", name="Write Review").click() + + # Fill review form + page.get_by_label("Rating").select_option("5") + page.get_by_label("Title").fill("Best Coaster Ever") + page.get_by_label("Review").fill("Such a thrilling experience in the dark!") + + # Submit review + page.get_by_role("button", name="Submit Review").click() + + # Verify review appears + expect(page.get_by_text("Best Coaster Ever")).to_be_visible() + expect(page.get_by_text("Such a thrilling experience in the dark!")).to_be_visible() + + +def test_add_ride_photo(page: Page): + # First 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() + + # Navigate to ride page + page.goto("http://localhost:8000/rides/space-mountain-magic-kingdom/") + + # Click on Photos tab + page.get_by_role("tab", name="Photos").click() + + # Click Add Photo button + page.get_by_role("button", name="Add Photo").click() + + # Upload photo + page.get_by_label("Photo").set_input_files("tests/fixtures/test_photo.jpg") + page.get_by_label("Caption").fill("Awesome ride entrance") + + # Submit photo + page.get_by_role("button", name="Upload Photo").click() + + # Verify photo appears + expect(page.get_by_text("Awesome ride entrance")).to_be_visible() + + +def test_ride_wait_times(page: Page): + # Navigate to ride page + page.goto("http://localhost:8000/rides/space-mountain-magic-kingdom/") + + # Check wait time section + expect(page.get_by_text("Current Wait Time:")).to_be_visible() + expect(page.get_by_text("minutes")).to_be_visible() + + # Check historical wait times + expect(page.get_by_text("Average Wait Times")).to_be_visible() + expect(page.locator("#wait-time-chart")).to_be_visible() + + +def test_ride_location(page: Page): + # Navigate to ride page + page.goto("http://localhost:8000/rides/space-mountain-magic-kingdom/") + + # Check location section + expect(page.get_by_text("Location in Park")).to_be_visible() + expect(page.locator("#ride-location-map")).to_be_visible() + + # Verify map marker + expect(page.locator(".ride-marker")).to_be_visible() diff --git a/tests/fixtures/README.md b/tests/fixtures/README.md new file mode 100644 index 00000000..3f7507e0 --- /dev/null +++ b/tests/fixtures/README.md @@ -0,0 +1,33 @@ +# Test Fixtures + +This directory contains test assets used by the e2e tests. + +## Required Files + +1. `test_photo.jpg` + - Used for testing photo uploads for parks and rides + - Recommended size: 1920x1080 + - Max size: 5MB + +2. `test_avatar.jpg` + - Used for testing profile avatar uploads + - Recommended size: 500x500 + - Max size: 2MB + +## Generating Test Images + +You can create these test images using any image editing software, or download placeholder images from: +- https://picsum.photos/1920/1080 (for test_photo.jpg) +- https://picsum.photos/500/500 (for test_avatar.jpg) + +Save the downloaded images with the correct filenames in this directory. + +## Usage + +The test files reference these images using relative paths: +```python +page.get_by_label("Photo").set_input_files("tests/fixtures/test_photo.jpg") +page.get_by_label("Avatar").set_input_files("tests/fixtures/test_avatar.jpg") +``` + +Make sure these files exist before running the tests. \ No newline at end of file