36e5a491ac | ||
---|---|---|
.github/workflows | ||
pytest_playwright | ||
tests | ||
.gitignore | ||
.pre-commit-config.yaml | ||
CODE_OF_CONDUCT.md | ||
CONTRIBUTING.md | ||
LICENSE | ||
README.md | ||
SECURITY.md | ||
local-requirements.txt | ||
setup.cfg | ||
setup.py |
README.md
Pytest plugin for Playwright
Write end-to-end tests for your web apps with Playwright and pytest.
- Support for all modern browsers including Chromium, WebKit and Firefox.
- Support for headless and headed execution.
- Built-in fixtures that provide browser primitives to test functions.
Usage
pip install pytest-playwright
Use the page
fixture to write a basic test. See more examples.
# test_my_application.py
def test_example_is_working(page):
page.goto("https://example.com")
assert page.inner_text('h1') == 'Example Domain'
page.click("text=More information")
To run your tests, use pytest CLI.
# Run tests (Chromium and headless by default)
pytest
# Run tests in headed mode
pytest --headed
# Run tests in a different browser (chromium, firefox, webkit)
pytest --browser firefox
# Run tests in multiple browsers
pytest --browser chromium --browser webkit
If you want to add the CLI arguments automatically without specifying them, you can use the pytest.ini file:
# content of pytest.ini
[pytest]
# Run firefox with UI
addopts = --headed --browser firefox
Fixtures
This plugin configures Playwright-specific fixtures for pytest. To use these fixtures, use the fixture name as an argument to the test function.
def test_my_app_is_working(fixture_name):
# Test using fixture_name
# ...
Function scope: These fixtures are created when requested in a test function and destroyed when the test ends.
context
: New browser context for a test.page
: New browser page for a test.
Session scope: These fixtures are created when requested in a test function and destroyed when all tests end.
browser
: Browser instance launched by Playwright.browser_name
: Browser name as string.browser_channel
: Browser Channel as string.is_chromium
,is_webkit
,is_firefox
: Booleans for the respective browser types.
Customizing fixture options: For browser
and context
fixtures, use the the following fixtures to define custom launch options.
browser_type_launch_args
: Override launch arguments forbrowserType.launch()
. It should return a Dict.browser_context_args
: Override the options forbrowser.new_context()
. It should return a Dict.
Examples
Configure Mypy typings for auto-completion
# test_my_application.py
from playwright.sync_api import Page
def test_visit_admin_dashboard(page: Page):
page.goto("/admin")
# ...
Configure slow mo
Run tests with slow mo with the --slowmo
argument.
pytest --slowmo 100
Skip test by browser
# test_my_application.py
import pytest
@pytest.mark.skip_browser("firefox")
def test_visit_example(page):
page.goto("https://example.com")
# ...
Run on a specific browser
# conftest.py
import pytest
@pytest.mark.only_browser("chromium")
def test_visit_example(page):
page.goto("https://example.com")
# ...
Run with a custom browser channel like Google Chrome or Microsoft Edge
pytest --browser-channel chrome # or chrome-beta, chrome-dev, chrome-canary, msedge, msedge-beta, msedge-dev, msedge-canary
# test_my_application.py
def test_example(page):
page.goto("https://example.com")
Configure base-url
Start Pytest with the base-url
argument.
pytest --base-url http://localhost:8080
# test_my_application.py
def test_visit_example(page):
page.goto("/admin")
# -> Will result in http://localhost:8080/admin
Ignore HTTPS errors
# conftest.py
import pytest
@pytest.fixture(scope="session")
def browser_context_args(browser_context_args):
return {
**browser_context_args,
"ignore_https_errors": True
}
Use custom viewport size
# conftest.py
import pytest
@pytest.fixture(scope="session")
def browser_context_args(browser_context_args):
return {
**browser_context_args,
"viewport": {
"width": 1920,
"height": 1080,
}
}
Device emulation
# conftest.py
import pytest
@pytest.fixture(scope="session")
def browser_context_args(browser_context_args, playwright):
iphone_11 = playwright.devices['iPhone 11 Pro']
return {
**browser_context_args,
**iphone_11,
}
Persistent context
# conftest.py
import pytest
from playwright.sync_api import BrowserType
from typing import Dict
@pytest.fixture(scope="session")
def context(
browser_type: BrowserType,
browser_type_launch_args: Dict,
browser_context_args: Dict
):
context = browser_type.launch_persistent_context("./foobar", **{
**browser_type_launch_args,
**browser_context_args,
"locale": "de-DE",
})
yield context
context.close()
When using that all pages inside your test are created from the persistent context.
Using with unittest.TestCase
See the following example for using it with unittest.TestCase
. This has a limitation,
that only a single browser can be specified and no matrix of multiple browsers gets
generated when specifying multiple.
import pytest
import unittest
from playwright.sync_api import Page
class MyTest(unittest.TestCase):
@pytest.fixture(autouse=True)
def setup(self, page: Page):
self.page = page
def test_foobar(self):
self.page.goto("https://microsoft.com")
self.page.click("#foobar")
assert self.page.evaluate("1 + 1") == 2
Debugging
Use with pdb
Use the breakpoint()
statement in your test code to pause execution and get a pdb REPL.
def test_bing_is_working(page):
page.goto("https://bing.com")
breakpoint()
# ...
Screenshot on test failure
You can capture screenshots for failed tests with a pytest runtest hook. Add this to your conftest.py
file.
Note that this snippet uses slugify
to convert test names to file paths, which can be installed with pip install python-slugify
.
# conftest.py
from slugify import slugify
from pathlib import Path
def pytest_runtest_makereport(item, call) -> None:
if call.when == "call":
if call.excinfo is not None and "page" in item.funcargs:
page = item.funcargs["page"]
screenshot_dir = Path(".playwright-screenshots")
screenshot_dir.mkdir(exist_ok=True)
page.screenshot(path=str(screenshot_dir / f"{slugify(item.nodeid)}.png"))
Deploy to CI
Use the Playwright GitHub Action or guides for other CI providers to deploy your tests to CI/CD
Special thanks
Thanks to Max Schmitt for creating and maintaining this project.