django-components/tests/e2e/utils.py
Juro Oravec f100cc1836
Some checks are pending
Docs - build & deploy / docs (push) Waiting to run
Run tests / build (ubuntu-latest, 3.10) (push) Waiting to run
Run tests / build (ubuntu-latest, 3.11) (push) Waiting to run
Run tests / build (ubuntu-latest, 3.12) (push) Waiting to run
Run tests / build (ubuntu-latest, 3.13) (push) Waiting to run
Run tests / build (ubuntu-latest, 3.8) (push) Waiting to run
Run tests / test_sampleproject (3.13) (push) Waiting to run
Run tests / build (ubuntu-latest, 3.9) (push) Waiting to run
Run tests / build (windows-latest, 3.10) (push) Waiting to run
Run tests / build (windows-latest, 3.11) (push) Waiting to run
Run tests / build (windows-latest, 3.12) (push) Waiting to run
Run tests / build (windows-latest, 3.13) (push) Waiting to run
Run tests / build (windows-latest, 3.8) (push) Waiting to run
Run tests / build (windows-latest, 3.9) (push) Waiting to run
Run tests / test_docs (3.13) (push) Waiting to run
refactor: replace isort, black and flake8 with ruff (#1346)
2025-09-10 14:06:53 +02:00

75 lines
2.5 KiB
Python

# ruff: noqa: T201
import functools
import subprocess
import sys
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").resolve()
# Start the Django dev server in the background
print("Starting Django dev server...")
proc = subprocess.Popen(
# NOTE: Use `sys.executable` so this works both for Unix and Windows OS
[sys.executable, "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}/poll") # noqa: S113
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.")