AAIS

Overview

AAI Script (AAIS) is very small script built on top of AAI's FindNode, it has a very simple syntax and with a dozen of commands, AAIS is not a replacement of complex JS/REST API, it is useful to write simple tests or throw away scripts. AAIS parser will translate command to JavaScript (and FindNode commands) during execution. It has several properties that is different from JavaScript:

  • There is no condition, no loop, simple variables, not suitable for complex scripting.
  • Any failure/error will cause the script to stop.
  • It is built to run on multiple devices, users select set of devices (1 to 100), start the script.
  • Support both MDCC (multi-device control center) and WDM (Windows desktop mode).
  • Any error messages or output from "print", "get" and "sendAai" will be kept in the log file.
  • JavaScript code block is enclosed in "{}". Will be looped multiple times.
  • "//" is comment characters, anything after "//" will be ignored.
  • Since it is built on top of FindNode, it inherits properties of FindNode:
    • Object-based, not coordinate based.
    • 100% compatible with FindNode's query language.
    • Support scripts in mixed device environment (different resolution and sized).
    • Use "find" to replace device dependent page down/up. "find" will scroll until the node is found.

AAIS Command

click/longClick

Click or longclick on query string or text on the screen. If the query or text is not found, the script will stop. See FindNode User Guide on the query syntax. If "click" without argument after the "find" or "wait" commands, it will click the first match of the find command.

Usage:

click/longClick <text|query>

Examples:

click "T:About phone||OX:1"
longClick "Information" 
// find and click John
find "John"
click
wait "Click for detail"
click

open/restart

open or restart an application, the restart will force-close the application and start again. If the application is not found, the script will stop.

Usage:

open/restart <package name>
open/restart <app name>

Examples:

open "com.raider.skype"
wait "Favorites"
	
restart "Skype"

wait

The command waits until the match is found or timeout expires. If the timeout expires, the script will stop. Without the timeout specified, the default is 5000ms. See FindNode User Guide on the query syntax.

Usage:

wait <text|query>
wait <text|query>, <timeout in milliseconds>

Examples:

wait "Finish"
wait "R:.icon_done", 20000

text

Enter text into the text field, the text field is located by position or initial hint string, the script will stop with error if the text field cannot be found. To accurate locate the text field by position, the text field will be sorted based on the text field location from top-left to bottom-right.

Usage:

text <text>		// Enter text in the first text field
text <text>, <position> 	// position starts with 0 – first text field, 1 – second text field, …
text <text>, <label>	// Enter into the text field with the initial hint string

Examples:

text "Hello world"
text "Hello world", "Please input a message"
text "Hello world", 2

press

Press a keycode (and optional meta state) or keycode name, wrong keycode name will stop the script.

Usage:

press <keycode name>
press KeyCode, <keycode>
press KeyCode, <keycode>, <meta state>

Examples:

press Home
press KeyCode, 47, 1

Refer to https://developer.android.com/reference/android/view/KeyEvent for all the keycode names. The following are the popular keycode name (case insensitive):

Enter
Back
Home
Back_space
Search
Power
Tab

find

It will scroll based on the direction on the screen until the match is found, it not found, the script will stop with error. The default is "down".

Usage:

find <text|query> [<direction>]

There are 4 directions

  • "down": From current position, search downward (default if not specify).
  • "up": From the current position, search upward.
  • "fromTop": From top of the app and start scroll down.
  • "fromBottom": Scroll to bottom of the app and search upward.

Examples:

find "John"
find "T:OK||C:.Button"
click

exec

Execute another AAIS or JavaScript, if will stop if the script generates error. The default is on the Documents\scripts directory. If the extension is ".js" it is loaded as JavaScript, if the extension is ".tst", it is loaded as AAIS. "exec" JavaScript is either provide functions/constants to AAIS integration or perform tasks that cannot be done in AAIS.

Usage:

exec <file path and filename>

Examples:

exec "aais\\skype.tst"
exec "C:\\aais\\skype.tst"
exec "nestLib.js"

print

Print the text string to the log file.

Usage:

print <text>

delay

Temporary pause the execution of the script for specified milliseconds.

Usage:

delay <time in milliseconds> 

Examples:

delay 10000

check

The check is used to click a checkbox, it accepts true/false. "false" will remove the check and "true" will set check.

Usage:

check <text|query> true|false

Example:

Check "C:.Checkbox&&T:Milk"

progress

Progress is used to set a value on slider such as class name of ".SeekBar". It is shown as "rangeInfo" in FindNode (getNodes(RI)), it has type of integer or float with minimum and maximum value. Make sure the value is within the range.

Usage:

progress <query> <value in integer or float>

Example:

progress "T:Notifications&&OY:1&&OX:1", 1200

get

Obtain information from FindNode. It has 4 types of get (more will be added when required), the argument is optional. The return value will be saved to log file and obtained from JavaScript "getOutput()".

Usage:

get <query>, <type>

Type:

"id": Obtain the id/ids of the query. No argument.

"text": Obtain the text information of the query matching nodes. No argument.

"description": Obtain the description of the query matching nodes. No argument.

"node": Obtain the information of the matching nodes based on the optional argument.

Example:

exec "volumeLib.js"
get "T:Notifications&&OY:1&&OX:1", “node”
{ 
	var rangeInfo = getOutput().list[0].rangeInfo;
    var current = rangeInfo.current;
    var min = rangeInfo.min;
    var max = rangeInfo.max;
    var mid = (max-min)/4;
    if (current > mid*3) {
        tooLoud(getDevice(), current);
    } else if (current < mid) {
        tooSoft(getDevice(), current);
    }
}

sendAai

sendAai use "device.sendAai" to send commands to FindNode, the return value will be saved to log file and obtained from JavaScript "getOutput()". Any failure (receive null from FindNode) will cause the script to stop. AAIS currently does not allow multiple lines per command, next version will support multi-line command.

Usage:

sendAai {<query or action>}
sendAai {actions:["openAndroidSetting(application development settings)", "scrollIntoView(T:Window animation scale)", "click", "click(+T:Animation scale .5x)", "sendKey(Back)", "sendKey(Back)"]}

Integration with JavaScript

AAIS is a parser that read the AAIS script with ".tst" extension and generate JavaScript for execution, the integration with JavaScript is simple, enclose JavaScript in "{}". Currently, only JavaScript can access output from "get" and "sendAai", next version, AAIS can include JavaScript expression (e.g. ${…}).

E.g.

{ <JavaScript> code }

Or

{
    <JavaScript code>
}

Example:

exec "phoneLib.js"
get "T:Android version&&OY:1", "text"
{ 
	setVersion(getDevice(), getOutput().retval); 
}

Assuming "phoneLib.js" has "setVersion()" function defined.

Since AAIS script can run on multiple devices, all JS command block will be executed multiple times one at a time, once for each device. So in the above example, if 20 devices are selected, it will execute 20 "setVersion". "getDevice()" will return 20 difference devices.

You can exec (load) a JS library (with constant or functions) first:

exec .js

The JS code block will be in the same context as "exec", so you can access them conveniently.

In addition, AAIS also comes with several functions:

exec "phoneLib.js"
get "T:Model name&&OX:1", "text"
{ saveVar("modelName", getOutput().retval) }
get "T:Model number&&OX:1", "text"
{ saveVar("modelNumber", getOutput().retval) }
get "T:IMEI&&OX:1", "text"
{ 
    saveInfo(getDevice(), 
    loadVar("modelName"), 
    loadVar("modelNumber"), 
    getOutput().retval); 
}

saveVar and loadVar is related to getDevice(), so you loadVar will always return the saveVar on the same device without interfering each other.

If you want to do just once instead of each device, use "doOnce()".

exec "runLib.js"
get "T:Run ID", "text"
{ 
	if (doOnce()) {
		saveDatabase(getOutput().retval); 
	}
}

Functions

There are several functions built into AAIS JavaScript:

getDevice() → device

Will return the current device.

getDevices() → Array of devices

Will return all the selected devices.

saveVar(<name>, <value>)

Will store the variable with the name specified, the variable is stored in scope of getDevice().

loadVar(<name>) → <value>

Will load the variable with the name specified and return the value. The value is only visible when store by saveVar() with the same getDevice().

saveGlobalVar(<name>, <value>)

Will store in the global scope identified by name, any device will be able to access it.

loadGlobalVar(<name>) → <value>

Will return the global scope identified by name.

doOnce() → true|false

Will return true on the first run, subsequent run will return false.

getOutput() → output from FindNode

This function only works for "get" and "sendAai", the JavaScript code block needs to immediately follow the "get" or "sendAai" commands, "getOutput" on other commands will generate error and stop the script execution. For the return format, see the content in the log file.

AAIS Example:

exec "teslaLib.js"
open "Tesla"
find "T:VIN:"
get "T:VIN:&&OX:1", "text"
{ saveVar("vin", getOutput().retval) }
get "T:/[0-9,]+ miles/", "text"
{ saveMileage(new Date(), loadVar("vin"), getOutput().retval) }
print "Done"

Creating Scripts

Save the scripts into a text field with ".tst" extension, e.g. skype.tst, alternatively you can use Record and Replay to record the script in AAIS (you need to select Object mode) file.

Running Scripts

Running AAIS scripts in Runner, the result will be stored in "Task":

  • MDCC:
    • Open MDCC window.
    • Select the device by thumbnail device or select a group. Main device will always be selected.
    • Click "Runner".
    • Select one or multiple scripts, when the checkbox is clicked, it will show execution order.
    • Click Run button, it will run scripts on the devices. Error will be shown in the message box next to Runner. Click "Log" to access the log.
  • WDM:
    • In WDM device window, click menu "Runner".
    • Select one or multiple scripts, when the checkbox is clicked, it will show execution order.
    • Click Run button, it will run scripts on the devices.
    • The Task window will show up, can view the progress and generated log file.