SeleniumScript
基于selenium-java的自定义脚本语言工具类
一、可执行jar包
releases提供了一个可执行jar包的下载,也可通过clone本项目,通过mvn package自行打包。
原先通过**仓库jar包引用方式由于调用过于麻烦,已废弃。
只支持windows下运行。
使用方法
下载SeleniumScript.jar后,命令行执行
注意:脚本文件编码请使用utf-8,否则中文将会乱码
:: 脚本后缀不必是txt,这里只是举个例子
java -jar SeleniumScript.jar -s "D://你的测试脚本.txt"
:: 或者
java -jar SeleniumScript.jar -script "D://你的测试脚本.txt"
:: 指定驱动路径
java -jar SeleniumScript.jar -script "D://你的测试脚本.txt" -driver "D://chromedriver.exe"
:: 以websocket服务启动,当需执行脚本非本地文件存储时使用。
java -jar SeleniumScript.jar -ws
测试脚本
set keyword www.iceolive.com
open http://www.baidu.com
type #kw %keyword%
click #su
sleep 2
click '.result a'
set a
<script>
return 0
</script>
repeat 5
begin
set a
<script>
return arguments[0]['a']+1;
</script>
end
二、目录说明
- tests目录为测试脚本目录,里面附带了一个测试脚本
三、开发背景
selenium是个强大的自动化测试工具,但是我还是想让它和js脚本语言一样,支持解释执行。并且我希望它的语法还能更简单一些。
为了支持我在运行时修改脚本,无需重新编译,并且减少代码的编写量,所以开发了这样看起来有点蹩脚的脚本语言。
四、脚本语法说明:
- 第一个参数为指令
- 其他行内参数请用单引号包裹,如参数没有包含空格,也可省略单引号。
- js脚本请使用 <script> 和</script>包裹,且标签需独占一行。
- begin,then,else,end为包裹多条指令用,需独占一行,
- 行内除了第一个参数外,其他参数均可使用
%变量名%
动态赋值,本质都是替换字符串。
1.打开页面
//第二个参数为网址
open 'http://www.baidu.com'
2.文本框输入内容
//第二个参数为css选择器,同document.querySelector
//第三个参数为输入的值,如需清除值,请使用clear命令
type '#username' 'wangmainzhe'
3.清除文本框内容
//第二个参数为css选择器,同document.querySelector
clear '#username'
4.点击按钮
//第二个参数为css选择器,同document.querySelector
click '#btn'
5.触发回车
enter '#username'
6.拖动元素
//第二个参数为css选择器,同document.querySelector
//第三个参数为拖动的位置
drag '#username' '300,0'
7.滚动条
//第二个参数为滚动的坐标位置。
scroll '0,1314'
8.切进iframe
如果你需要控制的元素在iframe里面,你必须执行切换才可操作他们。
//第二个参数为iframe的id或name,也可以用数字表示第几个。
//如果不带第二个参数,则切回主文档
switch 'frame';
9.执行js
exec
<script>
alert(1);
</script>
10.异步执行js
使用_$cb进行回调
execAsync
<script>
setTimeout(function(){
_$cb()
},1000)
</script>
11.存储值
必须有return,return的值将会存储在map中。
如要在<script></script>中获取设置过的值,可以通过argument[0][key]获取。
//字符串赋值
//a 为存储的key
set a 123
//复杂类型赋值,支持object,array,number,string
//a 为存储的key
set a
<script>
return 1;
</script>
12.异步存储值
使用_$cb进行回调,参数值将会存储在map中,一般用于在页面fetch接口获取值后进行回调。
setAsync a
<script>
fetch('http://xxx.xx/api/xxx').then(m=>{return m.text()}).then(m=>{
_$cb(m)
})
</script>
13.强制等待
//第二个参数为等待的秒数,这里可以为小数,如0.5表示等待0.5秒
sleep 2
14.等待并执行操作(目前只支持三种等待)
该指令不一定需要带then和else操作。
//等待元素可见
//第二个参数为css选择器,同document.querySelector
//第三个参数固定为visible
//第四个参数为超时的秒数,必须为整数秒
wait '#username' visible 3
//then里面的指令为元素出现后才执行的操作
then
click '#btn'
//else里面的指令为超时元素还未出现时才执行的操作
else
click '#btn2'
end
//等待元素可见
//第二个参数为css选择器,同document.querySelector
//第三个参数固定为invisible
//第四个参数为超时的秒数,必须为整数秒
wait '#username' invisible 3
//then里面的指令为元素不可见后才执行的操作
then
click '#btn'
//else里面的指令为超时元素还未出现时才执行的操作
else
click '#btn2'
end
//等待url跳转到指定网页
//第二个参数为url地址,可以为正则表达式
//第三个参数固定url
//第四个参数为超时的秒数,必须为整数秒
wait 'http://www.baidu.com' url 3
//then里面的指令为url跳转完成才执行的操作
then
click '#btn'
//else里面的指令为超时url还未跳转到指定页面才执行的操作
else
click '#btn2'
end
15.逻辑判断
when后面必须紧跟着<script></script>,然后才跟着then,else,end。else如果没有内容可省略。
js脚本必须有return,且返回值为boolean型。
set flag
<script>
return true
</script>
when
<script>
return argument[0]['flag']
</script>
//when里面为当true时执行的指令
then
click '#btn'
//else里面为当false时执行的指令
else
click '#btn2'
end
16.循环指令
- 指定循环次数
当指定循环次数时,可不添加<script></script>控制脚本,当然也可以使用脚本,当脚本return false则可提前退出循环。
注意:脚本判断在执行循环前执行。
repeat 10
begin
click #nextBtn
end
- 不指定循环次数
repeat后面必须紧跟着<script></script>,然后才跟着begin,end。
js脚本必须有return,且返回值为boolean型,返回值为false时退出循环
注意:脚本判断在执行循环前执行。
set flag
<script>
return 1
</script>
repeat
<script>
return argument[0]['flag']<5
</script>
begin
click '#btn'
set flag
<script>
return argument[0]['flag']+1;
</script>
end
- 支持下标及遍历列表
//指定循环次数时获取下标,第一个参数为循环次数,第二个参数为下标变量名,下标从0开始
repeat 3 i
begin
//输出下标
log %i%
end
set a
<script>
return [1,2,3]
</script>
//第一个参数可以为列表的变量名,第二个参数为下标变量名,下标从0开始,第三个参数为遍历的元素变量名。
repeat a i b
begin
//输出下标
log %i%
//输出元素
log %b%
end
17.页面提示语
alert '提示内容'
18.网页下载存储值的文件,支持json和csv
//第二个参数为存储值的key,值必须为对象数组,即[{a:1,b:2},{a:3,b:4}]。
//第三个参数为保存的文件名,文件名暂不支持变量
saveCsv list list.csv
//第二个参数为存储值的key,值可以为对象也可以为数组。
//第三个参数为保存的文件名,文件名暂不支持变量
saveJson obj obj.json
19.截图
//第二个参数为要截图的元素
//第三个参数为保存的文件路径,图片格式应为png,也可保存为pdf
screenshot body 1.png
20.日志
//第二个参数为日志内容
log '程序启动'
21.停止
//不继续执行
stop
22.模拟按键
//目前支持 f5,home,end
keydown f5
//一般用来触发下拉翻页
keydown end
keydown home
23.newHar
//需写在open前,用于获取请求日志,只有当启动BrowserMobProxy代理才生效
newHar
24.endHar
//需写在open后,获取请求日志,并赋值到logs中。格式[{url:'xxx',method:'get',content:'xxx'},...]
endHar logs
25.最大化
maximize
26.读取excel
//读取excel数据,并赋值到list,对象数组,对象所有字段类型均为字符串,excel首行为标题行
loadExcel 'D://1.xlsx' list
27.prompt
else 为超时时的操作。 该指令不一定需要带then和else操作。
//弹窗输入框,用户输入后,点击确定,将输入值赋给变量a,等待超时时间60秒
prompt a 请输入网址 60
then
alert hello
else
alert timeout
end
28.创建数据库连接
第二个参数为自定义的连接名,和set变量是两套存储容器,不会引起变量名冲突
第三个参数为数据库连接字符串,参考jdbc,目前支持h2,mysql,sqlserver和达梦
第四个参数为用户名
第五个参数为密码
setConn conn_a 'jdbc:mysql://127.0.0.1:3306/db?serverTimezone=UTC&useSSL=false&characterEncoding=utf-8' root 123456
29.查询数据库
只允许执行一个select
第二个参数为结果集存储的key,结果集类型为对象数组,为了和网页数据交互,时间类型字段会转为字符串,格式统一为"yyyy-MM-dd HH:mm:ss"
第三个参数为连接名
sql脚本通过<sql></sql>
包裹,如有入参变量请使用#{}或${}包裹变量名
set id 1
querySql list conn_a
<sql>
select * from tb1 where id = #{id} limit 1
</sql>
如果是动态拼接sql请使用<script></script>
代替<sql></sql>
set id 1
querySql list conn_a
<script>
return 'select * from tb1 where id = '+_$map.id+' limit 1'
</script>
30.执行sql
支持多条sql执行,多条语句请用分号隔开
当只执行一条sql时,才会返回insert的自增主键
第二个参数为更新记录数存储的key
第三个参数为连接名
第四个参数为insert返回的自增主键存储的key,非必要
sql脚本通过<sql></sql>
包裹,如有入参变量请使用#{}或${}包裹变量名
set name '张三'
execSql i conn_a id
<sql>
insert into tb1(name) values(#{name})
</sql>
如果是动态拼接sql请使用<script></script>
代替<sql></sql>
set name '张三'
execSql i conn_a id
<script>
return "insert into tb1(name) values('"+_$map.name+"')"
</scripit>
31.执行cmd脚本
第二个参数为结果存储的key,处理结果为批处理打印的字符串,非必要
<script></script>
包裹的是执行的命令,如果需调用外部变量,请使用_$map.xxx
代替,本质为替换字符串
set a www.baidu.com
cmd b
<script>
ping _$map.a
log %b%
</script>
32.执行wsh脚本
第二个参数为结果存储的key,处理结果为批处理打印的字符串,非必要
<script></script>
包裹的是执行的命令,如果需调用外部变量,请使用_$map.xxx
代替,本质为替换字符串
set a 1
wscript
<script>
WScript.Echo("_$map.a")
</script>
33.win32
//根据窗口标题查找窗口句柄(long),并存储到第二个参数设置的key中。
win32_getByTitle hwnd 任务管理器
//根据进程pid获取所有窗口句柄(List<long>),并存储到第二个参数设置的key中。
win32_getAllByPID hwnds 11202
//根据窗口句柄获取所有子控件句柄(List<Long>),并存储到第二个参数设置的key中
win32_getChildren hwnds 134642
//根据窗口句柄获取窗口标题,并存储到第二个参数的key中
win32_getTitle 134642
//根据窗口句柄设置窗口置顶
win32_setTopMost 134642
//控制窗口最大化最小化,第二个参数为窗口句柄,第三个参数 1 正常 2 最小化 3 最大化 或 normal min max
win32_showWindow 134642 3
//根据窗口句柄获取进程id,并存储到第二个参数设置的key中。
win32_getPID pid 134642
//获取桌面句柄(long),并存储到第二个参数的key中
win32_getDesktop hwnd
//根据窗口句柄截图并保存
win32_screenshot 134642 1.jpg
34.无浏览器窗口模式
启动时检查如果存在以下指令则启动无浏览器窗口模式
#headless
35.计时器
StopWatch的缩写
//开始计时,此时a存储的是当前的时间戳(long)
newStw a
//结束计时,此时a存储的是时间差,单位毫秒(long)
endStw a