browser_commander/traces/recorder_options.rs
1//! What a caller tells the trace recorder, and what it gets back (issue #108).
2//!
3//! The options of `startTrace()`, `trace.checkpoint()` and `trace.stop()` in
4//! `js/src/traces/recorder.js`, typed; [`super::recorder`] reads them.
5
6use std::path::PathBuf;
7
8use super::bundle::{TraceClock, TraceLimits, TraceProblem};
9use super::jsonfmt::JsonObject;
10use super::links::TraceLinksOptions;
11use super::redaction::TracePrivacyOptions;
12use super::schema::TraceMode;
13
14/// How long one capture may take before it is dropped, in milliseconds.
15pub const DEFAULT_CAPTURE_TIMEOUT_MS: u64 = 15_000;
16
17/// When a checkpoint takes a screenshot.
18#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
19pub enum TraceScreenshots {
20 /// Never (`screenshots: false`).
21 Off,
22 /// At every checkpoint (`'checkpoints'` or `true`), the default.
23 #[default]
24 Checkpoints,
25 /// Only at a checkpoint whose reason is `failure`.
26 OnlyOnFailure,
27}
28
29/// Whether a trace starts with a checkpoint of the page as it is.
30#[derive(Debug, Clone, PartialEq, Eq)]
31pub enum TraceInitialCheckpoint {
32 /// No base checkpoint.
33 Skip,
34 /// A base checkpoint named `initial`.
35 Take,
36 /// A base checkpoint with this name.
37 Named(String),
38}
39
40/// What a checkpoint captures of the DOM.
41#[derive(Debug, Clone, Copy, PartialEq, Eq)]
42pub struct TraceDomOptions {
43 /// Keep the serialized HTML.
44 pub html: bool,
45 /// Keep form control values at checkpoints.
46 pub live_control_state: bool,
47 /// Record typing, checking, selecting, focus and scroll as they happen.
48 pub live_state: bool,
49 /// Record DOM mutations between checkpoints; `None` turns them on for a
50 /// continuous trace only.
51 pub mutations: Option<bool>,
52 /// Descend into open shadow roots.
53 pub open_shadow_roots: bool,
54}
55
56impl Default for TraceDomOptions {
57 fn default() -> Self {
58 Self {
59 html: true,
60 live_control_state: true,
61 live_state: true,
62 mutations: None,
63 open_shadow_roots: true,
64 }
65 }
66}
67
68/// Options for [`start_trace`](super::start_trace), `startTrace()` in JavaScript.
69#[derive(Clone)]
70pub struct TraceOptions {
71 /// The bundle directory.
72 pub output: PathBuf,
73 /// One of [`TraceMode`]; `checkpoints` unless set.
74 pub mode: String,
75 /// `None` takes a base checkpoint in continuous mode only.
76 pub initial_checkpoint: Option<TraceInitialCheckpoint>,
77 /// When checkpoints take screenshots.
78 pub screenshots: TraceScreenshots,
79 /// What checkpoints capture.
80 pub dom: TraceDomOptions,
81 /// Event sources to record, from [`TRACE_EVENT_SOURCES`](super::TRACE_EVENT_SOURCES); `None` records
82 /// all of them and an empty list none.
83 pub events: Option<Vec<String>>,
84 /// What is redacted before anything is written.
85 pub privacy: TracePrivacyOptions,
86 /// Size ceilings.
87 pub limits: TraceLimits,
88 /// Also write a Links Notation export as the trace records.
89 pub links: Option<TraceLinksOptions>,
90 /// Fail instead of recording a `dropped` event.
91 pub strict: bool,
92 /// Budget for one capture in milliseconds; `0` means none.
93 pub capture_timeout_ms: u64,
94 /// Written to the manifest; this crate's version unless set.
95 pub commander_version: Option<String>,
96 /// Written to the manifest; the page's engine unless set.
97 pub engine: Option<String>,
98 /// Where timestamps come from.
99 pub clock: TraceClock,
100}
101
102impl TraceOptions {
103 /// Options that record into `output`, with every default.
104 pub fn new(output: impl Into<PathBuf>) -> Self {
105 Self {
106 output: output.into(),
107 mode: TraceMode::CHECKPOINTS.to_string(),
108 initial_checkpoint: None,
109 screenshots: TraceScreenshots::default(),
110 dom: TraceDomOptions::default(),
111 events: None,
112 privacy: TracePrivacyOptions::default(),
113 limits: TraceLimits::default(),
114 links: None,
115 strict: false,
116 capture_timeout_ms: DEFAULT_CAPTURE_TIMEOUT_MS,
117 commander_version: Some(env!("CARGO_PKG_VERSION").to_string()),
118 engine: None,
119 clock: TraceClock::default(),
120 }
121 }
122}
123
124/// Who took a checkpoint and why.
125#[derive(Debug, Clone, Default, PartialEq, Eq)]
126pub struct TraceCheckpointOptions {
127 /// `automation` unless set.
128 pub actor: Option<String>,
129 /// One of [`TraceCheckpointReason`](super::TraceCheckpointReason); `checkpoint` unless set.
130 pub reason: Option<String>,
131}
132
133/// The error a run ended with, recorded as a fatal `pageerror`.
134#[derive(Debug, Clone, PartialEq, Eq)]
135pub struct TraceFailure {
136 /// The error message.
137 pub message: String,
138 /// A stack or backtrace, when there is one.
139 pub stack: Option<String>,
140}
141
142impl TraceFailure {
143 /// A failure with this message and no stack.
144 pub fn new(message: impl Into<String>) -> Self {
145 Self {
146 message: message.into(),
147 stack: None,
148 }
149 }
150}
151
152/// How a trace is stopped.
153#[derive(Debug, Clone, Default, PartialEq, Eq)]
154pub struct TraceStopOptions {
155 /// Delete the bundle and the export once they are finished.
156 pub discard: bool,
157 /// The error the run ended with.
158 pub error: Option<TraceFailure>,
159}
160
161/// What [`TraceRecorder::stop`](super::TraceRecorder::stop) returns.
162#[derive(Debug, Clone, PartialEq)]
163pub struct TraceResult {
164 /// The bundle directory.
165 pub path: PathBuf,
166 /// The manifest as written.
167 pub manifest: JsonObject,
168 /// One entry per checkpoint, as recorded on the timeline.
169 pub checkpoints: Vec<JsonObject>,
170 /// What the bundle and the export could not record.
171 pub problems: Vec<TraceProblem>,
172 /// The Links Notation export, when one was written.
173 pub links: Option<PathBuf>,
174 /// Whether the bundle was deleted.
175 pub discarded: bool,
176}