Skip to content

feat: record traces of playwright.request API contexts - #333

Merged
Pavel Feldman (pavelfeldman) merged 2 commits into
mainfrom
feat-137-api-request-tracing
Oct 8, 2026
Merged

Pavel Feldman (pavelfeldman) merged 2 commits into
mainfrom
feat-137-api-request-tracing

Conversation

@pavelfeldman

@pavelfeldman Pavel Feldman (pavelfeldman) commented Oct 7, 2026 •

Copy link
Copy Markdown
Member

--tracing only covered browser contexts, so API tests using playwright.request.new_context() produced no trace. APIRequestContext.tracing is public since playwright 1.60, so contexts created through playwright.request.new_context() are now traced per test:

  • Tracing starts when the context is created. Every chunk, including the first one, is titled after the test: contexts are usually created by fixtures before the test's artifacts recorder exists, so pytest_runtest_setup stores the current node id in config.stash for that.
  • Each test records its own chunk, so a session-scoped context shared by many tests (the pattern in the API testing docs) yields one trace per test. A chunk without any action is dropped only for contexts that existed before the test started (e.g. session-scoped ones the test did not use); contexts the test creates itself keep their trace, like browser contexts. The check reads Playwright's trace format and keeps the trace when in doubt.
  • Errors from stop_chunk surface like those from browser contexts instead of silently losing the trace; the context is still disposed (finally) when that happens.
  • The declared pytest floor becomes 7.0 for pytest-playwright and 8.2 for pytest-playwright-asyncio (what pytest-asyncio>=0.24 already requires). pytest.Parser, used since before this PR, and pytest.StashKey both need pytest 7; the plugin did not import on pytest 6 before either.
  • The traces go through the same retain-on-failure handling, trace-N.zip naming and report attachments as browser traces.

Tests that use Playwright but no page or context now get the artifacts recorder through a small autouse fixture. It only does so when tracing is enabled and the test transitively uses the playwright fixture. Reviewers should know that this also sets the recorder up for browser tests before their other function-scoped fixtures, rather than as a dependency of new_context; no behavior change was found. On playwright < 1.60 nothing changes.

Tests: session- and function-scoped API contexts with --tracing on (each trace contains only its test's requests and is titled after it; an unused self-created context keeps its trace; a test with a page and an API context gets trace-1.zip and trace-2.zip), --tracing retain-on-failure, and --tracing off leaving playwright.request.new_context untouched (sync + async).

Fixes #137

Stack created with GitHub Stacks CLI • Give Feedback 💬

@pavelfeldman
Pavel Feldman (pavelfeldman) added this pull request to stack #335 October 7, 2026 23:05
@pavelfeldman
Pavel Feldman (pavelfeldman) force-pushed the feat-137-api-request-tracing branch 4 times, most recently from 13763a2 to 6ffab8c Compare October 8, 2026 02:10
Base automatically changed from feat-121-report-artifacts to main October 8, 2026 02:12
@pavelfeldman
Pavel Feldman (pavelfeldman) removed this pull request from stack #335 October 8, 2026 02:19

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

It breaks declared pytest 6 compatibility and can skip API-context disposal when trace finalization fails.

4 open findings
What changed in this PR

Adds per-test tracing for Playwright API request contexts in both plugin variants.

Changes:

  • Instruments API context creation and disposal for trace collection.
  • Integrates API traces with existing artifact retention.
  • Adds synchronous and asynchronous integration coverage.
File Description
tests/​test_sync.py Tests synchronous API tracing scenarios.
tests/​test_asyncio.py Tests asynchronous API tracing scenarios.
pytest-playwright/​pytest_playwright/​pytest_playwright.py Implements synchronous API trace recording.
pytest-playwright-asyncio/​pytest_playwright_asyncio/​pytest_playwright.py Implements asynchronous API trace recording.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

# Set on a test item by _artifacts_recorder, picked up for the teardown report.
_ARTIFACTS_RECORDER_ATTR = "_playwright_artifacts_recorder"
# Node id of the test being set up, run or torn down, see _APIRequestContexts.
_CURRENT_TEST_NODEID_KEY = pytest.StashKey[str]()
# Set on a test item by _artifacts_recorder, picked up for the teardown report.
_ARTIFACTS_RECORDER_ATTR = "_playwright_artifacts_recorder"
# Node id of the test being set up, run or torn down, see _APIRequestContexts.
_CURRENT_TEST_NODEID_KEY = pytest.StashKey[str]()
Comment on lines +1013 to +1019
async def _dispose_wrapper(*args: Any, **kwargs: Any) -> None:
if context in self.live:
self.live.remove(context)
if self.recorder is not None:
await self.recorder.on_will_dispose_api_request_context(context)
self.tracing_chunk.discard(context)
await original_dispose(*args, **kwargs)
Comment on lines +1006 to +1012
def _dispose_wrapper(*args: Any, **kwargs: Any) -> None:
if context in self.live:
self.live.remove(context)
if self.recorder is not None:
self.recorder.on_will_dispose_api_request_context(context)
self.tracing_chunk.discard(context)
original_dispose(*args, **kwargs)
--tracing only covered browser contexts, so API tests using
playwright.request.new_context() produced no trace. With
APIRequestContext.tracing public since playwright 1.60, contexts created
through playwright.request.new_context() are now traced per test:

- tracing starts when the context is created;
- each test records its own chunk, so a session-scoped context shared by
  many tests yields one trace per test, and chunks without any action
  (a long-lived context the test did not use) are dropped;
- the traces go through the same retain-on-failure handling, file naming
  and report attachments as browser context traces.

Tests that use Playwright but no page or context now get the artifacts
recorder through a small autouse fixture when tracing is enabled.

Fixes #137
…traces of pre-existing contexts, let stop_chunk errors surface, stream the trace check; test mixed page+API traces and --tracing off
@pavelfeldman
Pavel Feldman (pavelfeldman) merged commit 80d7569 into main Oct 8, 2026
16 checks passed
@pavelfeldman
Pavel Feldman (pavelfeldman) deleted the feat-137-api-request-tracing branch October 8, 2026 20:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Tracing does not work with playwright.request.newcontext()

2 participants