1from __future__ import annotations
2
3import os
4from collections.abc import Generator
5from typing import Any
6
7import pytest
8from plain.runtime import settings as plain_settings
9from plain.runtime import setup
10from plain.utils.dotenv import load_dotenv
11
12from .browser import TestBrowser
13
14
15def pytest_configure(config: Any) -> None:
16 # Load .env.test if it exists
17 if os.path.exists(".env.test"):
18 # ANSI codes: \033[2;3m = dim + italic, \033[0m = reset
19 print("\033[2;3mLoading environment variables from .env.test...\033[0m")
20 load_dotenv(".env.test", override=True)
21
22 # Run Plain setup before anything else
23 setup()
24
25
26class SettingsProxy:
27 def __init__(self) -> None:
28 self._original: dict[str, Any] = {}
29
30 def __getattr__(self, name: str) -> Any:
31 return getattr(plain_settings, name)
32
33 def __setattr__(self, name: str, value: Any) -> None:
34 if name.startswith("_"):
35 super().__setattr__(name, value)
36 else:
37 if name not in self._original:
38 self._original[name] = getattr(plain_settings, name, None)
39 setattr(plain_settings, name, value)
40
41 def _restore(self) -> None:
42 for key, value in self._original.items():
43 setattr(plain_settings, key, value)
44
45
46@pytest.fixture
47def settings() -> Generator[SettingsProxy]:
48 proxy = SettingsProxy()
49 yield proxy
50 proxy._restore()
51
52
53@pytest.fixture
54def testbrowser(browser: Any, request: Any) -> Generator[TestBrowser]:
55 """Use playwright and pytest-playwright to run browser tests against a test server."""
56 try:
57 # Check if isolated_db fixture is available from the plain-postgres package.
58 # If it is, then we need to run a server that has a database connection to the isolated database for this test.
59 request.getfixturevalue("isolated_db")
60
61 from plain.postgres import get_connection
62 from plain.postgres.database_url import build_database_url
63
64 # Get a database url for the isolated db that we can have the plain server connect to also.
65 database_url = build_database_url(get_connection().settings_dict)
66 except pytest.FixtureLookupError:
67 # isolated_db fixture not available, use empty database_url
68 database_url = ""
69
70 testbrowser = TestBrowser(browser=browser, database_url=database_url)
71
72 try:
73 testbrowser.run_server()
74 yield testbrowser
75 finally:
76 testbrowser.cleanup_server()