2Tests for `chives.browser_fixtures`.
6from pathlib import Path
9from playwright.sync_api import sync_playwright
11from pytest import Pytester
14git_root_cmd = ["git", "rev-parse", "--show-toplevel"]
15GIT_ROOT = subprocess.check_output(git_root_cmd, text=True).strip()
18@pytest.fixture(scope="session")
19def playwright_browsers_path() -> str:
21 Return the cache directory where Playwright browsers are installed.
23 with sync_playwright() as p:
24 # In my local builds, this returns a path like:
26 # ~/Library/Caches/ms-playwright/webkit-2272/pw_run.sh
28 # Unwrap two levels to get to the `ms-playwright` folder.
29 return str(Path(p.webkit.executable_path).parent.parent)
33def playwright_pytester(pytester: Pytester, playwright_browsers_path: str) -> Pytester:
35 Return a `Pytester` instance for which tests have access to the
36 `browser` and `page` fixtures, and which use the shared Playwright cache.
38 if "SKIP_PLAYWRIGHT" in os.environ: # pragma: no cover
39 pytest.skip(reason="skip slow Playwright tests")
41 pytester.makeconftest(f"""
44 from chives.browser_fixtures import browser, page
46 os.environ["PLAYWRIGHT_BROWSERS_PATH"] = {playwright_browsers_path!r}
52class TestBrowserFixture:
54 Tests for the `browser` fixture.
57 def test_browser_fixture(self, playwright_pytester: Pytester) -> None:
59 Test the browser fixture.
61 playwright_pytester.makefile(".html", greeting="<p>Hello world!</p>")
62 playwright_pytester.makepyfile(
64 from playwright.sync_api import Browser, expect
65 from chives.browser_fixtures import file_uri
68 def test_browser(browser: Browser) -> None:
69 uri = file_uri("greeting.html")
71 p = browser.new_page()
73 expect(p.get_by_text("Hello world!")).to_be_visible()
76 playwright_pytester.runpytest().assert_outcomes(passed=1)
81 Tests for the `page` fixture.
84 def test_okay_page(self, playwright_pytester: Pytester) -> None:
86 Open a page and make a successful assertion about the contents.
88 playwright_pytester.makefile(".html", greeting="<p>Hello world!</p>")
89 playwright_pytester.makepyfile(
91 from playwright.sync_api import Page, expect
92 from chives.browser_fixtures import file_uri
95 def test_page(page: Page) -> None:
96 uri = file_uri("greeting.html")
98 expect(page.get_by_text("Hello world!")).to_be_visible()
101 playwright_pytester.runpytest().assert_outcomes(passed=1)
103 @pytest.mark.parametrize(
106 pytest.param("<script>invalid</script>", id="invalid_js"),
107 pytest.param("<script>console.warn('BOOM')</script>", id="console_warning"),
108 pytest.param("<script>console.warn('BOOM')</script>", id="console_error"),
109 pytest.param("<img src='doesnotexist.jpg'>", id="missing_image"),
112 def test_page_with_error(self, html: str, playwright_pytester: Pytester) -> None:
114 Open a page with errors/warnings, and check the fixture reports
117 playwright_pytester.makefile(".html", error=html)
118 playwright_pytester.makepyfile(
120 from playwright.sync_api import Page
121 from chives.browser_fixtures import file_uri
124 def test_page(page: Page) -> None:
125 uri = file_uri("error.html")
129 playwright_pytester.runpytest().assert_outcomes(passed=1, errors=1)
131 def test_non_existent_page_is_error(self, playwright_pytester: Pytester) -> None:
133 Opening a non-existent file with the `page` fixture fails the test.
135 playwright_pytester.makepyfile(
137 from playwright.sync_api import Page
138 from chives.browser_fixtures import file_uri
141 def test_page(page: Page) -> None:
142 uri = file_uri("does_not_exist.html")
146 playwright_pytester.runpytest().assert_outcomes(failed=1)
149def test_skip_playwright(pytester: Pytester) -> None:
151 If the SKIP_PLAYWRIGHT environment variable is set, the test is skipped.
153 pytester.makeconftest("""
156 from chives.browser_fixtures import browser, page
158 os.environ["SKIP_PLAYWRIGHT"] = "true"
162 from playwright.sync_api import Browser, Page
165 def test_browser(browser: Browser) -> None:
169 def test_page(page: Page) -> None:
173 pytester.runpytest().assert_outcomes(skipped=2)