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