browser_fixtures: make browser be session-scoped; improve docs
- ID
108ddb5- date
2026-07-16 20:41:19+00:00- author
Alex Chan <alex@alexwlchan.net>- parent
76d0c27- message
browser_fixtures: make browser be session-scoped; improve docs- changed files
3 files, 58 additions, 7 deletions
Changed files
CHANGELOG.md (5957) → CHANGELOG.md (6148)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9726b45..a1e39f3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
# CHANGELOG
+## v46 - 2026-07-16
+
+Change the `browser` fixture to be session-scoped, so the browser only needs to be started once per test suite.
+
+Also, improve the documentation for `browser_fixtures`.
+
## v45 - 2026-07-16
Fix a bug with SRT subtitle files that contain a [byte order mark (BOM)][wiki-bom].
src/chives/__init__.py (391) → src/chives/__init__.py (391)
diff --git a/src/chives/__init__.py b/src/chives/__init__.py
index 1ac2f82..eec5a4d 100644
--- a/src/chives/__init__.py
+++ b/src/chives/__init__.py
@@ -11,4 +11,4 @@ I share across multiple sites.
"""
-__version__ = "45"
+__version__ = "46"
src/chives/browser_fixtures.py (1614) → src/chives/browser_fixtures.py (3361)
diff --git a/src/chives/browser_fixtures.py b/src/chives/browser_fixtures.py
index 71854b3..0141729 100644
--- a/src/chives/browser_fixtures.py
+++ b/src/chives/browser_fixtures.py
@@ -1,7 +1,38 @@
"""
Provide a set of Playwright fixtures to use when testing static sites.
-See https://alexwlchan.net/2026/playwright/
+You can start an instance of a web browser, open a URL or local HTML file,
+and make Playwright assertions about the page.
+
+The `browser` fixture gives you an instance of a Playwright Browser.
+In this example, we open the local file `greeting.html` and check it
+contains the phrase `Hello world!`:
+
+ from playwright.sync_api import Browser, expect
+ from chives.browser_fixtures import browser, file_uri
+
+
+ def test_browser(browser: Browser) -> None:
+ uri = file_uri("greeting.html")
+
+ p = browser.new_page()
+ p.goto(uri)
+ expect(p.get_by_text("Hello world!")).to_be_visible()
+
+The `page` fixture gives you an instance of a Playwright Page.
+It automatically listens for console warnings, console errors, and
+page errors, and raises an assertion error on teardown if any occurred:
+
+ from playwright.sync_api import Page, expect
+ from chives.browser_fixtures import page, file_uri
+
+
+ def test_page(page: Page) -> None:
+ uri = file_uri("greeting.html")
+ page.goto(uri)
+ expect(page.get_by_text("Hello world!")).to_be_visible()
+
+For more information, see https://alexwlchan.net/2026/playwright/
"""
from collections.abc import Iterator
@@ -13,19 +44,29 @@ import pytest
from playwright.sync_api import Browser, Page, sync_playwright
+__all__ = ["file_uri", "browser", "page"]
+
+
def file_uri(p: Path | str) -> str:
"""
- Convert a path to a file:/// URI.
+ Convert a file path into a valid `file:///` URI for browser loading.
"""
p = Path(p)
absolute_path = str(p.absolute())
return pathname2url(absolute_path, add_scheme=True)
-@pytest.fixture
+@pytest.fixture(scope="session")
def browser() -> Iterator[Browser]:
"""
- Launch an instance of WebKit we can interact with in tests.
+ Launch an instance of WebKit for testing.
+
+ WebKit is my primary browser, so it's the only engine where I need
+ my static websites to work. My sites are simple enough that they're
+ unlikely to rely on WebKit-specific behavior or break in other browsers.
+
+ If the environment variable `SKIP_PLAYWRIGHT` is set, this fixture will
+ automatically skip any tests that depend on it to speed up test runs.
"""
if "SKIP_PLAYWRIGHT" in os.environ:
pytest.skip(reason="skip slow Playwright tests")
@@ -36,10 +77,14 @@ def browser() -> Iterator[Browser]:
browser.close()
-@pytest.fixture
+@pytest.fixture(scope="function")
def page(browser: Browser) -> Iterator[Page]:
"""
- Open a new browser page which checks for errors and warnings.
+ Open a browser page that monitors for errors.
+
+ On teardown (after your test function finishes), this fixture asserts
+ that no console warnings, console errors, or unhandled exceptions
+ occurred during the page session.
"""
p = browser.new_page()