1. 关于dogtail
dogtail 是 使用可访问性(A11Y,Accessibility)技术与桌面应用程序通信的图形用户界面GUI测试工具和自动化框架。
dogtail 是 用 Python 编写,是python 中的一个第三方包。
dogtail 适用于Linux系统
2. 安装dogtail
①首先需要安装依赖包
sudo apt-get install python3-pyatspi python3-pyqt5
②再进入该网站下载安装包,并且解压。terminal中切换到解压的安装包目录下,并且输入如下命令进行安装
sudo python3 setup.py install
或者
sudo pip3 install dogtail (我执行这个,sniff不能用)
3. sniff 组件
在 dogtail 的发行包中,自带了一个 sniff 组件(嗅探器),该组件在 GUI 程序追踪方面非常有用。
在terminal终端,输入 sniff 命令并执行,会弹出一个 AT-SPI Browser 界面,里面包含了所有正在运行的程序。所有程序是以 tree 的形式显示。
- 获取元素控件的标签名称
为了方便查看元素控件对应的位置,建议现在上方工具栏点击Actions,然后勾选Hightlight Items。
在 AT-SPI Browser 界面中点击相应的应用标签tree,点击相应的元素控件,在工具的下方会显示元素空间的Name,这个就是标签名。
4. dogtail的 应用
4.1 启动应用
dogtail 中utils 模块下提供run()方法,用于启动应用。
run(string, timeout=30, interval=0.5, desktop=None, dumb=False, appName='')
# Runs an application.
这种方法的优点是采用进程的方式直接启动,不依赖与UI,无论桌面或任务栏上是否存在应用图标,都可以正常启动。
应用:
from dogtail.utils import *
run('deepin-music')
4.2 获取应用程序
dogtail 中tree 模块下root类 提供了一个application方法,用于启动应用。
API具体 方法:
1. applications(self) # Get all applications.
2. application(self, appName, retry=True) #Gets an application by name, returning an Application instance or raising an exception. This is implemented using findChild, and hence will automatically retry if no such child is found, and will eventually raise an exception. It also logs the search.
源码:请看这里哦
应用:
from dogtail.tree import *
root.application(AppName,) ## 获取应用程序(根据程序名称查找)
4.3. 定位元素控件
应用对象使用child()方法
from dogtail.tree import *
app_obj = root.application(AppName,) # 获取应用程序(根据程序名称查找)
element = app_obj.child('element_name') # 定位元素控件
我们可以通过传入元素的Name,获取到相应元素的对象。Name可以通过sniff查看
4.4. 操作元素
单击
element.click(button=1) #button 1 —>左键,2—>滚轮,3—>右键,默认为1
双击
element.doubleClick(button=1)
鼠标移动到元素控件上
element.point()
4.5.控制键盘和鼠标操作
dogtail中控制键盘和鼠标操作,依赖于rawinput包
首先需要导入rawinput包
from dogtail import rawinput
4.5.1鼠标相关操作
点击
rawinput.click(x, y, button=1, check=True)
#1.x, y 为所要点击的坐标
#2.button为鼠标左右键,1代表左键,2代表滚轮,3代表右键,默认参数,可以不传
#3.check为坐标检查,如果为负数,会抛异常,默认参数,可以不传
双击
rawinput.doubleClick(x, y, button=1, check=True)
长按鼠标左键不放
rawinput.press(x, y, button=1, check=True)
长按鼠标左键后松开
rawinput.release(x, y, button=1, check=True)
鼠标移动(相对位置、绝对位置)
# 一.鼠标移动到相对位置
rawinput.relativeMotion(x, y, mouseDelay=None)
# 1.x, y 为所要移动的相对位置,比如从当前位置移动100,100,注意和绝对位置的区别
# 2.mouseDelay为鼠标移动的延迟时间,默认参数,可以不传
# 二. 鼠标移动到绝对位置
rawinput.absoluteMotion(x, y, mouseDelay=None, check=True)
# 1.x, y 为所要移动到的坐标
# 2.mouseDelay为鼠标移动的延迟时间,默认参数,可以不传
# 3.check为坐标检查,如果为负数,会抛异常,默认参数,可以不传
- 绝对位置
rawinput.drag(fromXY, toXY, button=1, check=True)
# 1.fromXY 起始位置的坐标(x, y )
# 2.toXY 目标位置的坐标(x, y )
- 相对位置
rawinput没有提供相对位置的拖拽,但是我们可以通过如下代码,进行二次封装实现相对位置的拖拽。
rawinput.press(x, y )
rawinput.relativeMotion(x, y)
rawinput.release(x, y)
4.5.2 键盘相关操作
键盘输入文本
rawinput.typeText(string) #传入要输入的字符串即可
注意: 不支持中文输入,经过分析源码,输入的功能实际是遍历字符串里面的每一个字符然后调用的pressKey,也就是敲键盘的方式实现输入,所以中文输入的bug无解。在UOS上使用这个方法输入中文的时候,系统直接崩溃(注销)。
键盘按键
rawinput.pressKey(keyName)
# 其中 keyName = {
'enter': 'Return',
'esc': 'Escape',
'alt': 'Alt_L',
'control': 'Control_L',
'ctrl': 'Control_L',
'shift': 'Shift_L',
'del': 'Delete',
'ins': 'Insert',
'pageup': 'Page_Up',
'pagedown': 'Page_Down',
' ': 'space',
'\t': 'Tab',
'\n': 'Return'
}
键盘组合按键
rawinput.keyCombo(comboString)
# comboString组合按键,比如:
'<Control><Alt>p'
'<Control><Shift>PageUp'
'<Control>q'