mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 17:31:09 -05:00
Add comprehensive e2e tests with Playwright
This commit is contained in:
56
accounts/management/commands/create_test_users.py
Normal file
56
accounts/management/commands/create_test_users.py
Normal file
@@ -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="testpass123",
|
||||
)
|
||||
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="modpass123",
|
||||
)
|
||||
|
||||
# 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"))
|
||||
116
tests/e2e/README.md
Normal file
116
tests/e2e/README.md
Normal file
@@ -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
|
||||
28
tests/e2e/pytest.ini
Normal file
28
tests/e2e/pytest.ini
Normal file
@@ -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
|
||||
92
tests/e2e/test_auth.py
Normal file
92
tests/e2e/test_auth.py
Normal file
@@ -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()
|
||||
131
tests/e2e/test_parks.py
Normal file
131
tests/e2e/test_parks.py
Normal file
@@ -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)
|
||||
172
tests/e2e/test_profiles.py
Normal file
172
tests/e2e/test_profiles.py
Normal file
@@ -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()
|
||||
161
tests/e2e/test_reviews.py
Normal file
161
tests/e2e/test_reviews.py
Normal file
@@ -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()
|
||||
166
tests/e2e/test_rides.py
Normal file
166
tests/e2e/test_rides.py
Normal file
@@ -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()
|
||||
33
tests/fixtures/README.md
vendored
Normal file
33
tests/fixtures/README.md
vendored
Normal file
@@ -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.
|
||||
Reference in New Issue
Block a user