mtg_python_deckbuilder/tests/e2e/run_e2e_tests.py

196 lines
6.3 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
"""
E2E Test Runner for MTG Deckbuilder (M3: Cypress/Playwright Smoke Tests)
This script sets up and runs end-to-end tests for the web UI.
It can start the development server if needed and run smoke tests.
Usage:
python run_e2e_tests.py --smoke # Run smoke tests only
python run_e2e_tests.py --full # Run all tests
python run_e2e_tests.py --mobile # Run mobile tests only
python run_e2e_tests.py --start-server # Start dev server then run tests
"""
import argparse
import asyncio
import subprocess
import sys
import os
import time
from pathlib import Path
class E2ETestRunner:
def __init__(self):
self.project_root = Path(__file__).parent.parent
self.server_process = None
self.base_url = os.getenv('TEST_BASE_URL', 'http://localhost:8080')
def start_dev_server(self):
"""Start the development server"""
print("Starting development server...")
# Try to start the web server
server_cmd = [
sys.executable,
"-m", "uvicorn",
"code.web.app:app",
"--host", "0.0.0.0",
"--port", "8080",
"--reload"
]
try:
self.server_process = subprocess.Popen(
server_cmd,
cwd=self.project_root,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
# Wait for server to start
print("Waiting for server to start...")
time.sleep(5)
# Check if server is running
if self.server_process.poll() is None:
print(f"✓ Server started at {self.base_url}")
return True
else:
print("❌ Failed to start server")
return False
except Exception as e:
print(f"❌ Error starting server: {e}")
return False
def stop_dev_server(self):
"""Stop the development server"""
if self.server_process:
print("Stopping development server...")
self.server_process.terminate()
try:
self.server_process.wait(timeout=10)
except subprocess.TimeoutExpired:
self.server_process.kill()
print("✓ Server stopped")
def install_playwright(self):
"""Install Playwright browsers if needed"""
print("Installing Playwright browsers...")
try:
subprocess.run([
sys.executable, "-m", "playwright", "install", "chromium"
], check=True, cwd=self.project_root)
print("✓ Playwright browsers installed")
return True
except subprocess.CalledProcessError as e:
print(f"❌ Failed to install Playwright browsers: {e}")
return False
def run_tests(self, test_type="smoke"):
"""Run the specified tests"""
print(f"Running {test_type} tests...")
test_dir = self.project_root / "tests" / "e2e"
if not test_dir.exists():
print(f"❌ Test directory not found: {test_dir}")
return False
# Build pytest command
cmd = [sys.executable, "-m", "pytest", str(test_dir)]
if test_type == "smoke":
cmd.extend(["-m", "smoke", "-v"])
elif test_type == "mobile":
cmd.extend(["-m", "mobile", "-v"])
elif test_type == "full":
cmd.extend(["-v"])
else:
cmd.extend(["-v"])
# Set environment variables
env = os.environ.copy()
env["TEST_BASE_URL"] = self.base_url
try:
result = subprocess.run(cmd, cwd=self.project_root, env=env)
return result.returncode == 0
except Exception as e:
print(f"❌ Error running tests: {e}")
return False
def run_quick_smoke_test(self):
"""Run a quick smoke test without pytest"""
print("Running quick smoke test...")
try:
# Import and run the smoke test function
sys.path.insert(0, str(self.project_root))
from tests.e2e.test_web_smoke import run_smoke_tests
# Set the base URL
os.environ["TEST_BASE_URL"] = self.base_url
asyncio.run(run_smoke_tests())
return True
except Exception as e:
print(f"❌ Quick smoke test failed: {e}")
return False
def main():
parser = argparse.ArgumentParser(description="Run E2E tests for MTG Deckbuilder")
parser.add_argument("--smoke", action="store_true", help="Run smoke tests only")
parser.add_argument("--full", action="store_true", help="Run all tests")
parser.add_argument("--mobile", action="store_true", help="Run mobile tests only")
parser.add_argument("--start-server", action="store_true", help="Start dev server before tests")
parser.add_argument("--quick", action="store_true", help="Run quick smoke test without pytest")
parser.add_argument("--install-browsers", action="store_true", help="Install Playwright browsers")
args = parser.parse_args()
runner = E2ETestRunner()
# Install browsers if requested
if args.install_browsers:
if not runner.install_playwright():
sys.exit(1)
# Start server if requested
server_started = False
if args.start_server:
if not runner.start_dev_server():
sys.exit(1)
server_started = True
try:
# Determine test type
if args.mobile:
test_type = "mobile"
elif args.full:
test_type = "full"
else:
test_type = "smoke"
# Run tests
if args.quick:
success = runner.run_quick_smoke_test()
else:
success = runner.run_tests(test_type)
if success:
print("🎉 All tests passed!")
sys.exit(0)
else:
print("❌ Some tests failed!")
sys.exit(1)
finally:
# Clean up
if server_started:
runner.stop_dev_server()
if __name__ == "__main__":
main()