django-components/tests/e2e/utils.py
Juro Oravec 849a869a66
feat: add JS dependency manager (#666)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-09-22 16:42:41 +02:00

71 lines
2.4 KiB
Python

import functools
import subprocess
import time
from pathlib import Path
import requests
from playwright.async_api import async_playwright
TEST_SERVER_PORT = "8000"
TEST_SERVER_URL = f"http://127.0.0.1:{TEST_SERVER_PORT}"
# NOTE: Ideally we'd use Django's setUpClass and tearDownClass methods
# to instantiate the browser instance only once. But didn't have luck with that.
# So instead we have to create a browser instance for each test.
#
# Additionally, Django's documentation is lacking on async setUp and tearDown,
# so instead we use a decorator to run async code before/after each test.
def with_playwright(test_func):
"""Decorator that sets up and tears down Playwright browser instance."""
@functools.wraps(test_func)
async def wrapper(self, *args, **kwargs):
# Setup
self.playwright = await async_playwright().start()
self.browser = await self.playwright.chromium.launch()
# Test
await test_func(self, *args, **kwargs)
# Teardown
await self.browser.close()
await self.playwright.stop()
return wrapper
def run_django_dev_server():
"""Fixture to run Django development server in the background."""
# Get the path where testserver is defined, so the command doesn't depend
# on user's current working directory.
testserver_dir = (Path(__file__).parent / "testserver").absolute()
# Start the Django dev server in the background
print("Starting Django dev server...")
proc = subprocess.Popen(
["python", "manage.py", "runserver", f"127.0.0.1:{TEST_SERVER_PORT}", "--noreload"],
cwd=testserver_dir,
)
# Wait for the server to start by polling
start_time = time.time()
while time.time() - start_time < 30: # timeout after 30 seconds
try:
response = requests.get(f"http://127.0.0.1:{TEST_SERVER_PORT}")
if response.status_code == 200:
print("Django dev server is up and running.")
break
except requests.RequestException:
time.sleep(0.1)
else:
proc.terminate()
raise RuntimeError("Django server failed to start within the timeout period")
yield # Hand control back to the test session
# Teardown: Kill the server process after the tests
proc.terminate()
proc.wait()
print("Django dev server stopped.")