This commit is contained in:
javad committed 2026-09-10 11:34:19 +03:30
commit fa9d154db9
260 files changed
+17643

No files matched your search

+77
View File
@@ -0,0 +1,77 @@
from contextlib import contextmanager
import os
import pytest
from tests.e2e.config import E2ESettings
playwright_api = pytest.importorskip("playwright.sync_api")
# On Windows, ``localhost`` can resolve to IPv6 while Django's ephemeral live
# server is listening on IPv4. Pin the test-only server to IPv4 so navigation
# failures represent the application rather than resolver/bind ambiguity.
os.environ.setdefault("DJANGO_LIVE_TEST_SERVER_ADDRESS", "127.0.0.1:0")
@pytest.fixture(scope="session")
def e2e_settings():
return E2ESettings.from_environment()
@pytest.fixture
def application_base_url(live_server, e2e_settings):
"""Configured deployment URL, falling back to Django's isolated local server."""
return e2e_settings.base_url or live_server.url
@pytest.fixture
def browser_page(request, e2e_settings):
"""Return a page factory with per-test isolation and automatic failure artifacts."""
@contextmanager
def open_page(*, service_workers="block"):
with playwright_api.sync_playwright() as playwright:
launch_options = {"headless": e2e_settings.headless, "slow_mo": e2e_settings.slow_mo}
try:
browser = playwright.chromium.launch(**launch_options)
except playwright_api.Error as bundled_error:
try:
browser = playwright.chromium.launch(channel="chrome", **launch_options)
except playwright_api.Error:
raise RuntimeError(
"No Chromium browser is available. Run: python -m playwright install chromium"
) from bundled_error
context = browser.new_context(
viewport=e2e_settings.viewport,
locale="fa-IR",
timezone_id="Asia/Tehran",
service_workers=service_workers,
)
context.set_default_timeout(e2e_settings.action_timeout_ms)
context.set_default_navigation_timeout(e2e_settings.navigation_timeout_ms)
context.tracing.start(screenshots=True, snapshots=True, sources=True)
page = context.new_page()
page_errors = []
page.on("pageerror", lambda error: page_errors.append(str(error)))
safe_name = request.node.nodeid.replace("::", "__").replace("/", "_").replace("\\", "_")
artifact_dir = e2e_settings.artifact_dir / safe_name
failed = False
try:
yield page
if page_errors:
raise AssertionError(f"Browser JavaScript errors: {page_errors}")
except BaseException:
failed = True
artifact_dir.mkdir(parents=True, exist_ok=True)
page.screenshot(path=artifact_dir / "failure.png", full_page=True)
raise
finally:
if failed:
context.tracing.stop(path=artifact_dir / "trace.zip")
else:
context.tracing.stop()
context.close()
browser.close()
return open_page