| # Codelab: Finding UI elements using chrome.automation API |
| |
| A common task in autotests is to make hardware changes and verify that UI gets |
| updated or interact with UI elements and verify that hardware is updated. We can |
| use the [chrome.automation] API to help with both of these tasks. |
| |
| [TOC] |
| |
| ## Getting familiar with chrome.automation API |
| |
| Detailed information about chrome.automation API can be found at |
| https://developer.chrome.com/extensions/automation. |
| |
| In short, the API is a wrapper around Chrome's hierarchy of accessibility nodes |
| that describe Chrome UI elements. The most important attributes of accessibility |
| nodes are **role** and **name**. See the section on [Accessibility Attributes] |
| of the accessiblity overview. |
| |
| ## Setup |
| |
| Follow the steps in [Loading autotest extension on |
| device](loading-autotest-extension-on-device.md). Loading the AutotestPrivate |
| extension will give you access to chrome.automation API as well. |
| |
| ## To find a specific UI element |
| |
| Load a js console connected to the autotest extension's background page. See the |
| previous section for steps on how to connect to the extension's background page. |
| |
| **NOTE**: The following steps are meant to be run interactively in the console |
| and will not work if used in a real test. Section [Using chrome.automation in |
| autotests](#Using-chrome_automation-in-autotests) shows how to use the API |
| in a real test. |
| |
| Let's start by grabbing a reference to the root node of the accessibility tree. |
| |
| ``` js |
| var root; |
| chrome.automation.getDesktop(r => root = r); |
| ``` |
| |
| ### Finding a button in the hierarchy |
| |
| Let's demonstrate how to simulate a click on the launcher button in the system |
| shelf. |
| |
| We'll start by listing all buttons visible in the tree. |
| |
| ``` js |
| root.findAll({attributes: {role: "button"}}).map(node => node.name); |
| ``` |
| |
| After typing that into the console you should get a response such as this: |
| |
| ``` js |
| > (7) ["Back", "Launcher", "Chromium", "Stylus tools", "Status tray, time 4:21 |
| PM, Battery is 22% full.", "Connected to Ethernet", "Battery is 22% full. Time |
| left until battery is empty, 1 hour and 39 minutes"] |
| ``` |
| |
| **NOTE**: Names will change depending on the locale of the device. We currently |
| don't have a locale independent way of identifying UI nodes. |
| |
| Just by looking at button names we can easily guess that the button named |
| "Launcher" is the one we're looking for. |
| |
| Finally, to simulate a click on our button: |
| |
| ``` js |
| var launcher = root.find({attributes: {role: "button", name: "Launcher"}}); |
| launcher.doDefault(); |
| ``` |
| |
| The `doDefault` method performs an action based on the node's *role*, which for |
| buttons is a button click. |
| |
| The `find` method supports multiple attributes filters. It returns UI elements |
| that satisfy all conditions. |
| |
| ## Important roles |
| |
| The API supports interactions with many types of UI elements. |
| |
| The following table contains chrome.automation roles for common UI elements: |
| |
| | views class | chorme.automation role | |
| |-----------------:|------------------------| |
| | views::Button | button | |
| | views::Label | staticText | |
| | views::ImageView | image | |
| | views::TextField | textField | |
| |
| ## Finding name and role of a view subclass |
| |
| View subclasses override the `GetAccessibleNodeData` method to provide role and |
| name information. |
| |
| For example, look at [views::Button::GetAccessibleNodeData]. |
| |
| ## Using chrome.automation in autotests |
| |
| chrome.automation extension can be accessed through the autotest extension. |
| |
| ``` python |
| with Chrome.chrome(autotest_ext=True) as cr: |
| ext = cr.autotest_ext |
| ext.ExecuteJavaScript(""" |
| chrome.automation.getDesktop(root => { |
| var launcher = root.find({attributes: {role: 'button', name: 'Launcher'}}); |
| launcher.doDefault(); |
| }); |
| """) |
| ``` |
| |
| [chrome.automation]: https://developer.chrome.com/extensions/automation |
| [Accessibility Attributes]: https://chromium.googlesource.com/chromium/src/+/HEAD/docs/accessibility/overview.md#the-accessibility-tree-and-accessibility-attributes |
| [views::Button::GetAccessibleNodeData]: https://cs.chromium.org/search/?q=views::Button::GetAccessibleNodeData |
| [Getting to a command prompt]: https://www.chromium.org/chromium-os/poking-around-your-chrome-os-device#TOC-Getting-to-a-command-prompt |
| [Run Chromium with flags]: https://www.chromium.org/developers/how-tos/run-chromium-with-flags |