Skip to main content

playwright_rs_trace/
lib.rs

1//! Programmatic parser for [Playwright][pw] trace zip files
2//! (trace format v8, verified against traces recorded by the bundled
3//! Playwright 1.61 driver).
4//!
5//! # When to reach for this crate
6//!
7//! Pairs with the producer side, `playwright-rs::Tracing` (which
8//! writes `.trace.zip` files during a test run). This crate is the
9//! consumer side: a streaming, no-Playwright-server-required parser
10//! for those files. Typical users:
11//!
12//! - CI bots that comment on PRs with "test X failed at this Locator"
13//! - Dashboards that aggregate flaky-test root causes across runs
14//! - AI agent feedback loops that learn from past trace failures
15//! - Post-mortem analyzers run from a Rust binary or `xtask`
16//!
17//! No runtime dependency on the main `playwright-rs` crate — pull in
18//! only this crate (typically as a `[dev-dependencies]` entry) when
19//! you want to read traces.
20//!
21//! # Quick example
22//!
23//! ```no_run
24//! use playwright_rs_trace::open;
25//!
26//! let mut reader = open("trace.zip")?;
27//! println!(
28//!     "trace v{} from {}",
29//!     reader.context().version,
30//!     reader.context().browser_name,
31//! );
32//!
33//! for action in reader.actions()? {
34//!     let action = action?;
35//!     if action.error.is_some() {
36//!         eprintln!(
37//!             "failed: {}.{} ({:?})",
38//!             action.class, action.method, action.error,
39//!         );
40//!     }
41//! }
42//! # Ok::<(), playwright_rs_trace::TraceError>(())
43//! ```
44//!
45//! The reader is a **streaming iterator** — events / actions are yielded
46//! lazily as the underlying zip stream is read, so a large trace
47//! doesn't need to fit in memory before processing begins.
48//!
49//! # Four streaming entry points on [`TraceReader`]
50//!
51//! - [`raw_events`] — every JSONL line as raw JSON. Forward-compat
52//!   escape hatch for callers dispatching on event kinds we don't
53//!   model.
54//! - [`events`] — same lines parsed into a typed [`TraceEvent`] enum.
55//!   Unknown / future kinds surface as [`TraceEvent::Unknown`].
56//! - [`actions`] — `before` + optional `input` + zero-or-more `log` +
57//!   `after` chunks reassembled into a logical [`Action`]. The common
58//!   case; use this unless you specifically need the raw event stream.
59//! - [`network`] — `NetworkEntry`s from the `trace.network` HAR-shape
60//!   stream (request / response pairs). Independent of the action
61//!   stream — collect-and-sort if you need a merged chronological
62//!   view.
63//!
64//! [`raw_events`]: TraceReader::raw_events
65//! [`events`]: TraceReader::events
66//! [`actions`]: TraceReader::actions
67//! [`network`]: TraceReader::network
68//!
69//! # Forward compatibility
70//!
71//! Every JSONL line is preserved losslessly via
72//! [`TraceReader::raw_events`]. The typed iterators
73//! ([`TraceReader::events`], [`TraceReader::actions`]) deserialize what
74//! the parser models and route anything else to
75//! [`TraceEvent::Unknown`] so nothing is silently dropped.
76//!
77//! See the crate `README.md` for the full slice-plan and roadmap.
78//!
79//! [pw]: https://playwright.dev/
80
81mod action;
82mod error;
83mod event;
84mod jsonl;
85mod network;
86mod trace;
87
88pub use action::{Action, ActionStream, LogLine};
89pub use error::{Result, TraceError};
90pub use event::{
91    ActionError, AfterEvent, BeforeEvent, ConsoleEvent, ConsoleLocation, ContextOptions,
92    FrameSnapshotEvent, InputEvent, LogEvent, Point, RawEvent, ResourceOverride,
93    ScreencastFrameEvent, SystemEvent, TraceEvent, Viewport,
94};
95pub use network::{
96    HeaderEntry, NetworkEntry, RequestPostData, RequestSnapshot, ResponseContent, ResponseSnapshot,
97};
98pub use trace::{TraceReader, open};
99
100// crates.io renders README.md, so its example is the first code a prospective
101// user copies — and it was marked `ignore`, which rustdoc never compiles. It
102// had rotted: `actions()` returns a `Result`, and the `?` was missing. Pull the
103// file into the doctest harness so `cargo test --doc` compiles it like any
104// other example.
105#[cfg(doctest)]
106#[doc = include_str!("../README.md")]
107struct ReadmeDoctests;