AAIS
概述
AAI Script (AAIS) 是建立在 AAI 的 FindNode 之上的非常小的脚本,它有一个非常简单的语法和十几个命令,AAIS 不是复杂的 JS/REST API 的替代品,它对编写简单的测试非常有帮助并让我们远离复杂的脚本。AAIS 解析器将在执行期间将命令转换为 JavaScript(和 FindNode 命令)。它有几个不同于 JavaScript 的属性:
多行支持
AAIS 支持基本的多行支持。有两种方法可以进行多行支持:
"<文本 1>\
<文本 2>"
这适用于所有双引号,行尾的"\"将允许跨多行连接文本。例如:
{var a = 1, b = 2}
print "The sum of \
${a} and \
${b} is \
${a+b}"
将在日志文件中显示"1 和 2 的总和为 3”。
{ <查询/操作>
<查询/操作> }
这主要适用于"sendAai”,复杂的命令可能需要多个参数来完成任务。不匹配的“{}”或“[]”将收到脚本错误。
{var tp = "all"}
// 7 lines command
sendAai {actions:[
"getCount(+TP:\
${tp})",
"getCount(+TP:more)",
"getCount(+TP:basic)",
"getCount(+TP:reduced)"
]}
{
var output = getOutput();
firstNum = output.list[0].count;
lastNum = output.list[output.list.length -1].count;
log("firstNum = " + firstNum);
log("lastNum = " + lastNum);
}
print "From ${tp} template number of ${firstNum} reduced to ${lastNum}"
Log File:
2023-01-13 06:31:30 info system {name: 'samsung-SM-S908U1', object: 'device@1237418919', value: {count: 4, list: [{count: 162},{count: 69},{count: 64},{count: 63}]}, error: {}}
2023-01-13 06:31:30 info system firstNum = 162
2023-01-13 06:31:30 info system lastNum = 63
2023-01-13 06:31:30 info system From all template nodes number of 162 reduced to 63
笔记
AAIS 命令
点击/长按
单击或长按屏幕上的查询字符串或文本。如果未找到查询或文本,脚本将停止。有关查询语法,请参阅 FindNode 用户指南。如果在"寻找"或"等待"命令后没有参数的"点击”,它将单击查找命令的第一个匹配项。
用法:
点击/长按 <text|query>
例子:
点击 "T:About phone||OX:1"
长按 "Information"
// find and click John
寻找 "John"
点击
等待 "Click for detail"
点击
启动/重启
打开或重启应用程序,重启将强制关闭应用程序并重新启动。如果未找到应用程序,脚本将停止。
用法:
启动/重启 <package name>
启动/重启 <app name>
例子:
启动 "com.raider.skype"
等待 "Favorites"
重启 "Skype"
等待
该命令一直等到找到匹配项或超时到期。如果超时到期,脚本将停止。如果不指定超时,默认为 5000 毫秒。有关查询语法,请参阅 FindNode 用户指南。
用法:
等待 <text|query>
等待 <text|query>, <timeout in milliseconds>
例子:
等待 "Finish"
等待 "R:.icon_done", 20000
文本
在文本域中输入文本,文本域按位置或初始提示字符串定位,如果找不到文本域,脚本将报错停止。为了按位置准确定位文本字段,将根据文本字段位置从左上到右下对文本字段进行排序。
用法:
文本 <text> // Enter text in the first text field
文本 <text>, <position> // position starts with 0 – first text field, 1 – second text field, …
文本 <text>, <hint> // Enter into the text field with the initial hint string
例子:
文本 "Hello world"
文本 "Hello world", "Please input a message"
文本 "Hello world", 2
按键
按一个键码(和可选的元状态)或键码名称,错误的键码名称将停止脚本。
用法:
按键 <keycode name>
按键 KeyCode, <keycode>
按键 KeyCode, <keycode>, <meta state>
例子:
按键 Home
按键 KeyCode, 47, 1
有关所有键码名称,请参阅https://developer.android.com/reference/android/view/KeyEvent。
以下是流行的键码名称(不区分大小写):
Enter
Back
Home
Back_space
Search
Power
Tab
寻找
它将根据屏幕上的方向滚动,直到找到匹配项,如果找不到,脚本将因错误而停止。默认值为"向下”。
用法:
寻找 <text|query> [<direction>]
有4个方向:
例子:
寻找 "${name}"
寻找 "T:OK||C:.Button"
click
执行
执行另一个 AAIS 或 JavaScript,如果脚本产生错误将停止。默认位于 Documents\scripts 目录中。如果扩展名是“.js”,它作为 JavaScript 加载,如果扩展名是“.tst”,它作为 AAIS 加载。“exec"JavaScript 要么为 AAIS 集成提供函数/常量,要么执行 AAIS 中无法完成的任务。
用法:
执行 <file path and filename>
例子:
执行 "aais\\skype.tst"
执行 "C:\\aais\\skype.tst"
执行 "nestLib.js"
打印
将文本字符串打印到日志文件。
用法:
打印 <text>
延迟
临时暂停指定毫秒的脚本执行。
用法:
延迟 <time in milliseconds>
例子:
延迟 10000
选择
检查用于单击复选框,它接受真/假。“false"将取消检查,“true"将设置检查。
用法:
选择 <text|query> true|false
例子:
选择 "C:.Checkbox&&T:Milk"
进度
进度用于在滑块上设置一个值,例如“.SeekBar"的类名。它在 FindNode (getNodes(RI)) 中显示为"rangeInfo”,它具有整数或浮点数类型,具有最小值和最大值。确保该值在范围内。
用法:
进度 <query> <value in integer or float>
例子:
进度 "T:Notifications&&OY:1&&OX:1", 1200
get
从 FindNode 获取信息。它有4种get(需要时会增加),参数是可选的。返回值将保存到日志文件并从 JavaScript"getOutput()”获取。
用法:
get <query>, <type>
类型:
例子:
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 使用 "device.sendAai" 向 FindNode 发送命令,返回值将保存到日志文件并从 JavaScript "getOutput()" 获取。任何失败(从 FindNode 接收到 null)都将导致脚本停止。AAIS 目前不允许每条命令多行,下一版本将支持多行命令。
用法:
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)"]}
与 JavaScript 集成
AAIS 是一个解析器,读取带有“.tst"扩展名的AAIS 脚本并生成JavaScript 来执行,与JavaScript 的集成很简单,将JavaScript 括在“{}”中。在 AAIS 和 JS 之间传递数据:
例如
{ <JavaScript> code }
或者
{
<JavaScript code>
}
例子:
exec "phoneLib.js"
get "T:Android version&&OY:1", "text"
{
setVersion(getDevice(), getOutput().retval);
}
假设"phoneLib.js"定义了"setVersion()”函数。
由于 AAIS 脚本可以在多个设备上运行,因此所有 JS 命令块将一次执行多次,每个设备执行一次。所以在上面的例子中,如果选择了20个设备,就会执行20个"setVersion”。“getDevice()”将返回 20 个不同的设备。
您可以先执行(加载)一个 JS 库(带有常量或函数):
exec <library>.js
JS 代码块将与"exec"处于同一上下文中,因此您可以方便地访问它们。
此外,AAIS还附带了几个功能:
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 和 loadVar 与 getDevice() 相关,所以你 loadVar 总是会在同一个设备上返回 saveVar 而不会互相干扰。
如果你只想做一次而不是每个设备,请使用"doOnce()”。
exec "runLib.js"
get "T:Run ID", "text"
{
if (doOnce()) {
saveDatabase(getOutput().retval);
}
}
职能
AAIS JavaScript 中内置了几个函数:
getDevice() → 设备
将返回当前设备。
getDevices() → 设备数组
将返回所有选定的设备。
saveVar(<名称>, <值>)
将存储指定名称的变量,该变量存储在 getDevice() 的范围内。
loadVar(<名称>) → <值>
将加载具有指定名称的变量并返回值。该值仅在使用相同的 getDevice() 由 saveVar() 存储时可见。
saveGlobalVar(<名称>, <值>)
将存储在由名称标识的全局范围内,任何设备都可以访问它。
loadGlobalVar(<名称>) → <值>
将返回由名称标识的全局范围。
doOnce() → 真|假
将在第一次运行时返回 true,后续运行将返回 false。
getOutput() → 从 FindNode 输出
此函数仅对"get"和"sendAai"有效,JavaScript 代码块需要紧跟在"get"或"sendAai"命令之后,“getOutput"在其他命令上会产生错误并停止脚本执行。返回格式见日志文件中的内容。
getArg() → 字符串数组
Runner 允许用户将参数作为字符串数组传递给 JavaScript。这与变量替换一起可以在运行时创建查询/操作。当支持命令行模式时,getArg() 将返回命令模式下的参数。Runner 中有一个按钮可以设置参数。
日志(<消息>)
此功能类似于 AAIS 的"打印"功能,它将消息附加到现有 Runner 的日志文件中。
抛出(<消息>)
由于 AAIS 被翻译成 JavaScript,您可以使用 throw(<message>) 来停止执行。错误消息将被记录并显示给用户。
“……${<表达式>}……”
模板文字中的表达式允许任何双引号包含由 ${...} 括起来的 JavaScript 表达式。对于变量替换或简单的 JavaScript 表达式很有用。
AAIS 示例:
此示例打开 Tesla 应用程序并检索汽车的 VIN 和里程数:
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"
根据索引号打开应用程序,可以从 JavaScript 向 AAIS 输入"应用程序”:
{
var apps = ["Skype", "Whatsapp", "Telegram"];
var arguments = getArg();
var app = apps[0];
if (arguments.length > 0) {
var appNum;
if(isNaN(appNum = parseInt(arguments[0]))) {
throw "Need a number;"
}
if (appNum < 1 || appNum > apps.length) {
throw "Option out of range";
}
app = apps[appNum-1];
}
}
open "${app}"
print "${app} opened"
创建脚本
将脚本保存到扩展名为“.tst"的文本字段中,例如 skype.tst,或者您可以使用 Record 和 Replay 将脚本记录在 AAIS(您需要选择对象模式)文件中。
运行脚本
在Runner中运行AAIS脚本,结果会保存在"Task"中: