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