xref: /aosp_15_r20/external/autotest/docs/chrome-automation-codelab.md (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1*9c5db199SXin Li# Codelab: Finding UI elements using chrome.automation API
2*9c5db199SXin Li
3*9c5db199SXin LiA common task in autotests is to make hardware changes and verify that UI gets
4*9c5db199SXin Liupdated or interact with UI elements and verify that hardware is updated. We can
5*9c5db199SXin Liuse the [chrome.automation] API to help with both of these tasks.
6*9c5db199SXin Li
7*9c5db199SXin Li[TOC]
8*9c5db199SXin Li
9*9c5db199SXin Li## Getting familiar with chrome.automation API
10*9c5db199SXin Li
11*9c5db199SXin LiDetailed information about chrome.automation API can be found at
12*9c5db199SXin Lihttps://developer.chrome.com/extensions/automation.
13*9c5db199SXin Li
14*9c5db199SXin LiIn short, the API is a wrapper around Chrome's hierarchy of accessibility nodes
15*9c5db199SXin Lithat describe Chrome UI elements. The most important attributes of accessibility
16*9c5db199SXin Linodes are **role** and **name**. See the section on [Accessibility Attributes]
17*9c5db199SXin Liof the accessiblity overview.
18*9c5db199SXin Li
19*9c5db199SXin Li## Setup
20*9c5db199SXin Li
21*9c5db199SXin LiFollow the steps in [Loading autotest extension on
22*9c5db199SXin Lidevice](loading-autotest-extension-on-device.md). Loading the AutotestPrivate
23*9c5db199SXin Liextension will give you access to chrome.automation API as well.
24*9c5db199SXin Li
25*9c5db199SXin Li## To find a specific UI element
26*9c5db199SXin Li
27*9c5db199SXin LiLoad a js console connected to the autotest extension's background page. See the
28*9c5db199SXin Liprevious section for steps on how to connect to the extension's background page.
29*9c5db199SXin Li
30*9c5db199SXin Li**NOTE**: The following steps are meant to be run interactively in the console
31*9c5db199SXin Liand will not work if used in a real test. Section [Using chrome.automation in
32*9c5db199SXin Liautotests](#Using-chrome_automation-in-autotests) shows how to use the API
33*9c5db199SXin Liin a real test.
34*9c5db199SXin Li
35*9c5db199SXin LiLet's start by grabbing a reference to the root node of the accessibility tree.
36*9c5db199SXin Li
37*9c5db199SXin Li``` js
38*9c5db199SXin Livar root;
39*9c5db199SXin Lichrome.automation.getDesktop(r => root = r);
40*9c5db199SXin Li```
41*9c5db199SXin Li
42*9c5db199SXin Li### Finding a button in the hierarchy
43*9c5db199SXin Li
44*9c5db199SXin LiLet's demonstrate how to simulate a click on the launcher button in the system
45*9c5db199SXin Lishelf.
46*9c5db199SXin Li
47*9c5db199SXin LiWe'll start by listing all buttons visible in the tree.
48*9c5db199SXin Li
49*9c5db199SXin Li``` js
50*9c5db199SXin Liroot.findAll({attributes: {role: "button"}}).map(node => node.name);
51*9c5db199SXin Li```
52*9c5db199SXin Li
53*9c5db199SXin LiAfter typing that into the console you should get a response such as this:
54*9c5db199SXin Li
55*9c5db199SXin Li``` js
56*9c5db199SXin Li> (7) ["Back", "Launcher", "Chromium", "Stylus tools", "Status tray, time 4:21
57*9c5db199SXin LiPM, Battery is 22% full.", "Connected to Ethernet", "Battery is 22% full. Time
58*9c5db199SXin Li left until battery is empty, 1 hour and 39 minutes"]
59*9c5db199SXin Li```
60*9c5db199SXin Li
61*9c5db199SXin Li**NOTE**: Names will change depending on the locale of the device. We currently
62*9c5db199SXin Lidon't have a locale independent way of identifying UI nodes.
63*9c5db199SXin Li
64*9c5db199SXin LiJust by looking at button names we can easily guess that the button named
65*9c5db199SXin Li"Launcher" is the one we're looking for.
66*9c5db199SXin Li
67*9c5db199SXin LiFinally, to simulate a click on our button:
68*9c5db199SXin Li
69*9c5db199SXin Li``` js
70*9c5db199SXin Livar launcher = root.find({attributes: {role: "button", name: "Launcher"}});
71*9c5db199SXin Lilauncher.doDefault();
72*9c5db199SXin Li```
73*9c5db199SXin Li
74*9c5db199SXin LiThe `doDefault` method performs an action based on the node's *role*, which for
75*9c5db199SXin Libuttons is a button click.
76*9c5db199SXin Li
77*9c5db199SXin LiThe `find` method supports multiple attributes filters. It returns UI elements
78*9c5db199SXin Lithat satisfy all conditions.
79*9c5db199SXin Li
80*9c5db199SXin Li## Important roles
81*9c5db199SXin Li
82*9c5db199SXin LiThe API supports interactions with many types of UI elements.
83*9c5db199SXin Li
84*9c5db199SXin LiThe following table contains chrome.automation roles for common UI elements:
85*9c5db199SXin Li
86*9c5db199SXin Li| views class      | chorme.automation role |
87*9c5db199SXin Li|-----------------:|------------------------|
88*9c5db199SXin Li| views::Button    | button                 |
89*9c5db199SXin Li| views::Label     | staticText             |
90*9c5db199SXin Li| views::ImageView | image                  |
91*9c5db199SXin Li| views::TextField | textField              |
92*9c5db199SXin Li
93*9c5db199SXin Li## Finding name and role of a view subclass
94*9c5db199SXin Li
95*9c5db199SXin LiView subclasses override the `GetAccessibleNodeData` method to provide role and
96*9c5db199SXin Liname information.
97*9c5db199SXin Li
98*9c5db199SXin LiFor example, look at [views::Button::GetAccessibleNodeData].
99*9c5db199SXin Li
100*9c5db199SXin Li## Using chrome.automation in autotests
101*9c5db199SXin Li
102*9c5db199SXin Lichrome.automation extension can be accessed through the autotest extension.
103*9c5db199SXin Li
104*9c5db199SXin Li``` python
105*9c5db199SXin Liwith Chrome.chrome(autotest_ext=True) as cr:
106*9c5db199SXin Li    ext = cr.autotest_ext
107*9c5db199SXin Li    ext.ExecuteJavaScript("""
108*9c5db199SXin Li        chrome.automation.getDesktop(root => {
109*9c5db199SXin Li            var launcher = root.find({attributes: {role: 'button', name: 'Launcher'}});
110*9c5db199SXin Li            launcher.doDefault();
111*9c5db199SXin Li        });
112*9c5db199SXin Li    """)
113*9c5db199SXin Li```
114*9c5db199SXin Li
115*9c5db199SXin Li[chrome.automation]: https://developer.chrome.com/extensions/automation
116*9c5db199SXin Li[Accessibility Attributes]: https://chromium.googlesource.com/chromium/src/+/HEAD/docs/accessibility/overview.md#the-accessibility-tree-and-accessibility-attributes
117*9c5db199SXin Li[views::Button::GetAccessibleNodeData]: https://cs.chromium.org/search/?q=views::Button::GetAccessibleNodeData
118*9c5db199SXin Li[Getting to a command prompt]: https://www.chromium.org/chromium-os/poking-around-your-chrome-os-device#TOC-Getting-to-a-command-prompt
119*9c5db199SXin Li[Run Chromium with flags]: https://www.chromium.org/developers/how-tos/run-chromium-with-flags
120