Plain is headed towards 1.0! Subscribe for development updates →

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