Skip to main content

browser_protocol/accessibility/
mod.rs

1use serde::{Serialize, Deserialize};
2use serde_json::Value as JsonValue;
3
4/// Unique accessibility node identifier.
5
6pub type AXNodeId = String;
7
8/// Enum of possible property types.
9
10#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
11pub enum AXValueType {
12    #[default]
13    Boolean,
14    Tristate,
15    BooleanOrUndefined,
16    Idref,
17    IdrefList,
18    Integer,
19    Node,
20    NodeList,
21    Number,
22    String,
23    ComputedString,
24    Token,
25    TokenList,
26    DomRelation,
27    Role,
28    InternalRole,
29    ValueUndefined,
30}
31
32/// Enum of possible property sources.
33
34#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
35pub enum AXValueSourceType {
36    #[default]
37    Attribute,
38    Implicit,
39    Style,
40    Contents,
41    Placeholder,
42    RelatedElement,
43}
44
45/// Enum of possible native property sources (as a subtype of a particular AXValueSourceType).
46
47#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
48pub enum AXValueNativeSourceType {
49    #[default]
50    Description,
51    Figcaption,
52    Label,
53    Labelfor,
54    Labelwrapped,
55    Legend,
56    Rubyannotation,
57    Tablecaption,
58    Title,
59    Other,
60}
61
62/// A single source for a computed AX property.
63
64#[derive(Debug, Clone, Serialize, Deserialize, Default)]
65#[serde(rename_all = "camelCase")]
66pub struct AXValueSource {
67    /// What type of source this is.
68
69    #[serde(rename = "type")]
70    pub type_: AXValueSourceType,
71    /// The value of this property source.
72
73    #[serde(skip_serializing_if = "Option::is_none")]
74    pub value: Option<AXValue>,
75    /// The name of the relevant attribute, if any.
76
77    #[serde(skip_serializing_if = "Option::is_none")]
78    pub attribute: Option<String>,
79    /// The value of the relevant attribute, if any.
80
81    #[serde(skip_serializing_if = "Option::is_none")]
82    pub attributeValue: Option<AXValue>,
83    /// Whether this source is superseded by a higher priority source.
84
85    #[serde(skip_serializing_if = "Option::is_none")]
86    pub superseded: Option<bool>,
87    /// The native markup source for this value, e.g. a '<label>' element.
88
89    #[serde(skip_serializing_if = "Option::is_none")]
90    pub nativeSource: Option<AXValueNativeSourceType>,
91    /// The value, such as a node or node list, of the native source.
92
93    #[serde(skip_serializing_if = "Option::is_none")]
94    pub nativeSourceValue: Option<AXValue>,
95    /// Whether the value for this property is invalid.
96
97    #[serde(skip_serializing_if = "Option::is_none")]
98    pub invalid: Option<bool>,
99    /// Reason for the value being invalid, if it is.
100
101    #[serde(skip_serializing_if = "Option::is_none")]
102    pub invalidReason: Option<String>,
103}
104
105
106#[derive(Debug, Clone, Serialize, Deserialize, Default)]
107#[serde(rename_all = "camelCase")]
108pub struct AXRelatedNode {
109    /// The BackendNodeId of the related DOM node.
110
111    pub backendDOMNodeId: crate::dom::BackendNodeId,
112    /// The IDRef value provided, if any.
113
114    #[serde(skip_serializing_if = "Option::is_none")]
115    pub idref: Option<String>,
116    /// The text alternative of this node in the current context.
117
118    #[serde(skip_serializing_if = "Option::is_none")]
119    pub text: Option<String>,
120}
121
122
123#[derive(Debug, Clone, Serialize, Deserialize, Default)]
124#[serde(rename_all = "camelCase")]
125pub struct AXProperty {
126    /// The name of this property.
127
128    pub name: AXPropertyName,
129    /// The value of this property.
130
131    pub value: AXValue,
132}
133
134/// A single computed AX property.
135
136#[derive(Debug, Clone, Serialize, Deserialize, Default)]
137#[serde(rename_all = "camelCase")]
138pub struct AXValue {
139    /// The type of this value.
140
141    #[serde(rename = "type")]
142    pub type_: AXValueType,
143    /// The computed value of this property.
144
145    #[serde(skip_serializing_if = "Option::is_none")]
146    pub value: Option<JsonValue>,
147    /// One or more related nodes, if applicable.
148
149    #[serde(skip_serializing_if = "Option::is_none")]
150    pub relatedNodes: Option<Vec<AXRelatedNode>>,
151    /// The sources which contributed to the computation of this property.
152
153    #[serde(skip_serializing_if = "Option::is_none")]
154    pub sources: Option<Vec<AXValueSource>>,
155}
156
157/// Values of AXProperty name:
158/// - from 'busy' to 'roledescription': states which apply to every AX node
159/// - from 'live' to 'root': attributes which apply to nodes in live regions
160/// - from 'autocomplete' to 'valuetext': attributes which apply to widgets
161/// - from 'checked' to 'selected': states which apply to widgets
162/// - from 'activedescendant' to 'owns': relationships between elements other than parent/child/sibling
163/// - from 'activeFullscreenElement' to 'uninteresting': reasons why this noode is hidden
164
165#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
166pub enum AXPropertyName {
167    #[default]
168    Actions,
169    Busy,
170    Disabled,
171    Editable,
172    Focusable,
173    Focused,
174    Hidden,
175    HiddenRoot,
176    Invalid,
177    Keyshortcuts,
178    Settable,
179    Roledescription,
180    Live,
181    Atomic,
182    Relevant,
183    Root,
184    Autocomplete,
185    HasPopup,
186    Level,
187    Multiselectable,
188    Orientation,
189    Multiline,
190    Readonly,
191    Required,
192    Valuemin,
193    Valuemax,
194    Valuetext,
195    Checked,
196    Expanded,
197    Modal,
198    Pressed,
199    Selected,
200    Activedescendant,
201    Controls,
202    Describedby,
203    Details,
204    Errormessage,
205    Flowto,
206    Labelledby,
207    Owns,
208    Url,
209    ActiveFullscreenElement,
210    ActiveModalDialog,
211    ActiveAriaModalDialog,
212    AriaHiddenElement,
213    AriaHiddenSubtree,
214    EmptyAlt,
215    EmptyText,
216    InertElement,
217    InertSubtree,
218    LabelContainer,
219    LabelFor,
220    NotRendered,
221    NotVisible,
222    PresentationalRole,
223    ProbablyPresentational,
224    InactiveCarouselTabContent,
225    Uninteresting,
226}
227
228/// A node in the accessibility tree.
229
230#[derive(Debug, Clone, Serialize, Deserialize, Default)]
231#[serde(rename_all = "camelCase")]
232pub struct AXNode {
233    /// Unique identifier for this node.
234
235    pub nodeId: AXNodeId,
236    /// Whether this node is ignored for accessibility
237
238    pub ignored: bool,
239    /// Collection of reasons why this node is hidden.
240
241    #[serde(skip_serializing_if = "Option::is_none")]
242    pub ignoredReasons: Option<Vec<AXProperty>>,
243    /// This 'Node''s role, whether explicit or implicit.
244
245    #[serde(skip_serializing_if = "Option::is_none")]
246    pub role: Option<AXValue>,
247    /// This 'Node''s Chrome raw role.
248
249    #[serde(skip_serializing_if = "Option::is_none")]
250    pub chromeRole: Option<AXValue>,
251    /// The accessible name for this 'Node'.
252
253    #[serde(skip_serializing_if = "Option::is_none")]
254    pub name: Option<AXValue>,
255    /// The accessible description for this 'Node'.
256
257    #[serde(skip_serializing_if = "Option::is_none")]
258    pub description: Option<AXValue>,
259    /// The value for this 'Node'.
260
261    #[serde(skip_serializing_if = "Option::is_none")]
262    pub value: Option<AXValue>,
263    /// All other properties
264
265    #[serde(skip_serializing_if = "Option::is_none")]
266    pub properties: Option<Vec<AXProperty>>,
267    /// ID for this node's parent.
268
269    #[serde(skip_serializing_if = "Option::is_none")]
270    pub parentId: Option<AXNodeId>,
271    /// IDs for each of this node's child nodes.
272
273    #[serde(skip_serializing_if = "Option::is_none")]
274    pub childIds: Option<Vec<AXNodeId>>,
275    /// The backend ID for the associated DOM node, if any.
276
277    #[serde(skip_serializing_if = "Option::is_none")]
278    pub backendDOMNodeId: Option<crate::dom::BackendNodeId>,
279    /// The frame ID for the frame associated with this nodes document.
280
281    #[serde(skip_serializing_if = "Option::is_none")]
282    pub frameId: Option<crate::page::FrameId>,
283}
284
285#[derive(Debug, Clone, Serialize, Deserialize, Default)]
286pub struct DisableParams {}
287
288impl DisableParams { pub const METHOD: &'static str = "Accessibility.disable"; }
289
290impl crate::CdpCommand for DisableParams {
291    const METHOD: &'static str = "Accessibility.disable";
292    type Response = crate::EmptyReturns;
293}
294
295#[derive(Debug, Clone, Serialize, Deserialize, Default)]
296pub struct EnableParams {}
297
298impl EnableParams { pub const METHOD: &'static str = "Accessibility.enable"; }
299
300impl crate::CdpCommand for EnableParams {
301    const METHOD: &'static str = "Accessibility.enable";
302    type Response = crate::EmptyReturns;
303}
304
305/// Fetches the accessibility node and partial accessibility tree for this DOM node, if it exists.
306
307#[derive(Debug, Clone, Serialize, Deserialize, Default)]
308#[serde(rename_all = "camelCase")]
309pub struct GetPartialAXTreeParams {
310    /// Identifier of the node to get the partial accessibility tree for.
311
312    #[serde(skip_serializing_if = "Option::is_none")]
313    pub nodeId: Option<crate::dom::NodeId>,
314    /// Identifier of the backend node to get the partial accessibility tree for.
315
316    #[serde(skip_serializing_if = "Option::is_none")]
317    pub backendNodeId: Option<crate::dom::BackendNodeId>,
318    /// JavaScript object id of the node wrapper to get the partial accessibility tree for.
319
320    #[serde(skip_serializing_if = "Option::is_none")]
321    pub objectId: Option<crate::runtime::RemoteObjectId>,
322    /// Whether to fetch this node's ancestors, siblings and children. Defaults to true.
323
324    #[serde(skip_serializing_if = "Option::is_none")]
325    pub fetchRelatives: Option<bool>,
326}
327
328/// Fetches the accessibility node and partial accessibility tree for this DOM node, if it exists.
329
330#[derive(Debug, Clone, Serialize, Deserialize, Default)]
331#[serde(rename_all = "camelCase")]
332pub struct GetPartialAXTreeReturns {
333    /// The 'Accessibility.AXNode' for this DOM node, if it exists, plus its ancestors, siblings and
334    /// children, if requested.
335
336    pub nodes: Vec<AXNode>,
337}
338
339impl GetPartialAXTreeParams { pub const METHOD: &'static str = "Accessibility.getPartialAXTree"; }
340
341impl crate::CdpCommand for GetPartialAXTreeParams {
342    const METHOD: &'static str = "Accessibility.getPartialAXTree";
343    type Response = GetPartialAXTreeReturns;
344}
345
346/// Fetches the entire accessibility tree for the root Document
347
348#[derive(Debug, Clone, Serialize, Deserialize, Default)]
349#[serde(rename_all = "camelCase")]
350pub struct GetFullAXTreeParams {
351    /// The maximum depth at which descendants of the root node should be retrieved.
352    /// If omitted, the full tree is returned.
353
354    #[serde(skip_serializing_if = "Option::is_none")]
355    pub depth: Option<i64>,
356    /// The frame for whose document the AX tree should be retrieved.
357    /// If omitted, the root frame is used.
358
359    #[serde(skip_serializing_if = "Option::is_none")]
360    pub frameId: Option<crate::page::FrameId>,
361}
362
363/// Fetches the entire accessibility tree for the root Document
364
365#[derive(Debug, Clone, Serialize, Deserialize, Default)]
366#[serde(rename_all = "camelCase")]
367pub struct GetFullAXTreeReturns {
368
369    pub nodes: Vec<AXNode>,
370}
371
372impl GetFullAXTreeParams { pub const METHOD: &'static str = "Accessibility.getFullAXTree"; }
373
374impl crate::CdpCommand for GetFullAXTreeParams {
375    const METHOD: &'static str = "Accessibility.getFullAXTree";
376    type Response = GetFullAXTreeReturns;
377}
378
379/// Fetches the root node.
380/// Requires 'enable()' to have been called previously.
381
382#[derive(Debug, Clone, Serialize, Deserialize, Default)]
383#[serde(rename_all = "camelCase")]
384pub struct GetRootAXNodeParams {
385    /// The frame in whose document the node resides.
386    /// If omitted, the root frame is used.
387
388    #[serde(skip_serializing_if = "Option::is_none")]
389    pub frameId: Option<crate::page::FrameId>,
390}
391
392/// Fetches the root node.
393/// Requires 'enable()' to have been called previously.
394
395#[derive(Debug, Clone, Serialize, Deserialize, Default)]
396#[serde(rename_all = "camelCase")]
397pub struct GetRootAXNodeReturns {
398
399    pub node: AXNode,
400}
401
402impl GetRootAXNodeParams { pub const METHOD: &'static str = "Accessibility.getRootAXNode"; }
403
404impl crate::CdpCommand for GetRootAXNodeParams {
405    const METHOD: &'static str = "Accessibility.getRootAXNode";
406    type Response = GetRootAXNodeReturns;
407}
408
409/// Fetches a node and all ancestors up to and including the root.
410/// Requires 'enable()' to have been called previously.
411
412#[derive(Debug, Clone, Serialize, Deserialize, Default)]
413#[serde(rename_all = "camelCase")]
414pub struct GetAXNodeAndAncestorsParams {
415    /// Identifier of the node to get.
416
417    #[serde(skip_serializing_if = "Option::is_none")]
418    pub nodeId: Option<crate::dom::NodeId>,
419    /// Identifier of the backend node to get.
420
421    #[serde(skip_serializing_if = "Option::is_none")]
422    pub backendNodeId: Option<crate::dom::BackendNodeId>,
423    /// JavaScript object id of the node wrapper to get.
424
425    #[serde(skip_serializing_if = "Option::is_none")]
426    pub objectId: Option<crate::runtime::RemoteObjectId>,
427}
428
429/// Fetches a node and all ancestors up to and including the root.
430/// Requires 'enable()' to have been called previously.
431
432#[derive(Debug, Clone, Serialize, Deserialize, Default)]
433#[serde(rename_all = "camelCase")]
434pub struct GetAXNodeAndAncestorsReturns {
435
436    pub nodes: Vec<AXNode>,
437}
438
439impl GetAXNodeAndAncestorsParams { pub const METHOD: &'static str = "Accessibility.getAXNodeAndAncestors"; }
440
441impl crate::CdpCommand for GetAXNodeAndAncestorsParams {
442    const METHOD: &'static str = "Accessibility.getAXNodeAndAncestors";
443    type Response = GetAXNodeAndAncestorsReturns;
444}
445
446/// Fetches a particular accessibility node by AXNodeId.
447/// Requires 'enable()' to have been called previously.
448
449#[derive(Debug, Clone, Serialize, Deserialize, Default)]
450#[serde(rename_all = "camelCase")]
451pub struct GetChildAXNodesParams {
452
453    pub id: AXNodeId,
454    /// The frame in whose document the node resides.
455    /// If omitted, the root frame is used.
456
457    #[serde(skip_serializing_if = "Option::is_none")]
458    pub frameId: Option<crate::page::FrameId>,
459}
460
461/// Fetches a particular accessibility node by AXNodeId.
462/// Requires 'enable()' to have been called previously.
463
464#[derive(Debug, Clone, Serialize, Deserialize, Default)]
465#[serde(rename_all = "camelCase")]
466pub struct GetChildAXNodesReturns {
467
468    pub nodes: Vec<AXNode>,
469}
470
471impl GetChildAXNodesParams { pub const METHOD: &'static str = "Accessibility.getChildAXNodes"; }
472
473impl crate::CdpCommand for GetChildAXNodesParams {
474    const METHOD: &'static str = "Accessibility.getChildAXNodes";
475    type Response = GetChildAXNodesReturns;
476}
477
478/// Query a DOM node's accessibility subtree for accessible name and role.
479/// This command computes the name and role for all nodes in the subtree, including those that are
480/// ignored for accessibility, and returns those that match the specified name and role. If no DOM
481/// node is specified, or the DOM node does not exist, the command returns an error. If neither
482/// 'accessibleName' or 'role' is specified, it returns all the accessibility nodes in the subtree.
483
484#[derive(Debug, Clone, Serialize, Deserialize, Default)]
485#[serde(rename_all = "camelCase")]
486pub struct QueryAXTreeParams {
487    /// Identifier of the node for the root to query.
488
489    #[serde(skip_serializing_if = "Option::is_none")]
490    pub nodeId: Option<crate::dom::NodeId>,
491    /// Identifier of the backend node for the root to query.
492
493    #[serde(skip_serializing_if = "Option::is_none")]
494    pub backendNodeId: Option<crate::dom::BackendNodeId>,
495    /// JavaScript object id of the node wrapper for the root to query.
496
497    #[serde(skip_serializing_if = "Option::is_none")]
498    pub objectId: Option<crate::runtime::RemoteObjectId>,
499    /// Find nodes with this computed name.
500
501    #[serde(skip_serializing_if = "Option::is_none")]
502    pub accessibleName: Option<String>,
503    /// Find nodes with this computed role.
504
505    #[serde(skip_serializing_if = "Option::is_none")]
506    pub role: Option<String>,
507}
508
509/// Query a DOM node's accessibility subtree for accessible name and role.
510/// This command computes the name and role for all nodes in the subtree, including those that are
511/// ignored for accessibility, and returns those that match the specified name and role. If no DOM
512/// node is specified, or the DOM node does not exist, the command returns an error. If neither
513/// 'accessibleName' or 'role' is specified, it returns all the accessibility nodes in the subtree.
514
515#[derive(Debug, Clone, Serialize, Deserialize, Default)]
516#[serde(rename_all = "camelCase")]
517pub struct QueryAXTreeReturns {
518    /// A list of 'Accessibility.AXNode' matching the specified attributes,
519    /// including nodes that are ignored for accessibility.
520
521    pub nodes: Vec<AXNode>,
522}
523
524impl QueryAXTreeParams { pub const METHOD: &'static str = "Accessibility.queryAXTree"; }
525
526impl crate::CdpCommand for QueryAXTreeParams {
527    const METHOD: &'static str = "Accessibility.queryAXTree";
528    type Response = QueryAXTreeReturns;
529}