Working with playwright¶
tursu does not provice playwright option, but you can works with both playwright and tursu for testing your web application.
Actually, it has been develop for that!
Installation¶
uv add tursu pytest-playwright
uv run playwright install chromium
uv tursu init --no-dummies -o tests/functionals-playwright/
playwright requires to download its own browsers, refer to the playwright documentation for more options.
The
--no-dummies
does not create dummy scenario.
Create a step¶
from playwright.sync_api import Page, expect
from tursu import given, then, when
@given("anonymous user on {path}")
@when("I visit {path}")
def i_visit(page: Page, path: str):
page.goto(path)
@then('I see the text "{text}"')
def assert_text(page: Page, text: str):
loc = page.get_by_text(text)
expect(loc).to_be_visible()
That’s it. You can just use the “Page” fixture provided by pytest-playwright directly.
Create a scenario¶
@wip
Feature: Basic Test
Scenario: Hello world
Given anonymous user on /
Then I see the text "Hello, World!"
Run the test¶
uv run pytest --base-url http://localhost:8888 --browser chromium -v tests/using_playwright/
Sure this tests will fail, this is BDD :)
Adding a fixture¶
import socket
import threading
import time
from http.server import BaseHTTPRequestHandler, HTTPServer
import pytest
from tursu.plugin import tursu_collect_file
tursu_collect_file()
class HelloWorldHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
self.wfile.write(b"<body>Hello, World!</body>")
def wait_for_socket(host: str, port: int, timeout: int = 5):
"""Wait until the socket is open before proceeding."""
for _ in range(timeout * 10): # Check every 0.1s for `timeout` seconds
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
if sock.connect_ex((host, port)) == 0:
return # Socket is open
time.sleep(0.1)
raise RuntimeError(f"Server on {host}:{port} did not start in time.")
@pytest.fixture(autouse=True)
def http_server():
"""Start the service I test in a thread."""
server_address = ("127.0.0.1", 8888)
httpd = HTTPServer(server_address, HelloWorldHandler)
thread = threading.Thread(target=httpd.serve_forever, daemon=True)
thread.start()
wait_for_socket(*server_address)
yield
httpd.shutdown()
thread.join()
Run the test¶
$ uv run pytest --base-url http://localhost:8888 --browser chromium -v tests/using_playwright/
================================= test session starts =================================
baseurl: http://localhost:8888
configfile: pyproject.toml
plugins: cov-6.0.0, playwright-0.7.0, base-url-2.1.0
collected 1 item
📄 Document: 01_basic.feature_Basic_Test.py::test_2_Hello_world[chromium]
🥒 Feature: Basic Test
🎬 Scenario: Hello world
✅ Given anonymous user on /
✅ Then I see the text "Hello, World!"
PASSED [100%]
================================== 1 passed in 0.94s ==================================
Tip
While doing continuous integration, always activate the option --tracing on
from pytest-playright, it will generate a trace.zip
file in a test-results
directory to configured as a build artefact.
Afterwhat you can see all step of the scenario using the show-trace command:
$ uv run playwright show-trace test-results/**/trace.zip