Airtest

UI Automation Framework for Games and Apps

APACHE-2.0 License

Downloads
17.3K
Stars
8.2K
Committers
60

Bot releases are visible (Hide)

Airtest - v1.3.4 Latest Release

Published by ZSCharlie 6 months ago

ADD:

  • 增加了minicap对于Android 14版本的支持

ADD:

  • Added minicap support for Android 14 version.
Airtest - v1.3.3

Published by yimelia 10 months ago

ADD:

  • touch, swipe接口新增相对坐标的支持
    • 例如点击中心点 touch((0.5, 0.5))
    • 从右往左滑动 swipe((0.7, 0.5), (0.2, 0.5))
    • 目前android/ios/win都支持
  • windows新增了剪贴板相关的接口
    • get_clipboard 获取剪贴板内容,set_clipboard 设置剪贴板内容, paste 粘贴
    • 因此如果有大段文字需要输入,原本使用text接口将会一个一个输入,效率很低,现在可以使用set_clipboard 设置到剪贴板之后,再使用paste粘贴即可
    • 剪贴板三个接口目前win/ios/android都支持了
  • Android支持手动指定touch_method,来强制指定ADBTOUCH, 或 MINITOUCH, MAXTOUCH
    • dev.touch_method = "ADBTOUCH"

FIX:

  • Yosemite.apk更新,新增了判断输入法是否完全启动的接口,避免输入失败
  • 修复了某些低版本iOS设备使用swipe接口会报错的问题(报错信息为:Invalid parameter not satisfying: allAttributesForKey != nil
  • 修复了1.3.2版本引入的adb路径为None的bug
  • 修复了部分安卓设备屏幕只显示一半,并且无法恢复的问题

ADD:

  • touch, swipe interfaces add support for relative coordinates
    • For example, click the center point touch((0.5, 0.5))
    • Swipe from right to left swipe((0.7, 0.5), (0.2, 0.5))
    • Currently supported by android/ios/win
  • Windows has added a new clipboard-related interface
    • get_clipboard gets the clipboard content, set_clipboard sets the clipboard content, paste pastes
    • Therefore, if there is a large section of text that needs to be entered, the original text interface will be entered one by one, which is very inefficient. Now you can use set_clipboard to set it to the clipboard, and then use paste to paste it.
    • The three clipboard interfaces are currently supported by win/ios/android.
  • Android supports manually specifying touch_method to force specifying ADBTOUCH, or MINITOUCH, MAXTOUCH
    • dev.touch_method = "ADBTOUCH"

FIX:

  • Yosemite.apk has been updated, adding an interface to determine whether the input method is fully started to avoid input failures.
  • Fixed an issue where some lower version iOS devices would report an error when using the swipe interface (the error message is: Invalid parameter not satisfying: allAttributesForKey != nil)
  • Fixed the bug that the adb path introduced in version 1.3.2 is None
  • Fixed the issue where the screen of some Android devices is only half displayed and cannot be restored
Airtest - v1.3.2

Published by yimelia 11 months ago

  1. 【重要】ADB升级至41版本,与之前的ADB版本不兼容,请注意保证系统环境中所有的ADB版本一致,否则可能会导致无法连接设备
  2. iOS模块新增一个Error类型,LocalDeviceError,部分接口只有本地USB连接的iOS设备才可以用,远程设备将会抛出这个异常。因此若有需要,可以catch住这个异常,并对远程设备做一些额外的兼容和处理。
  3. 更新了yosemite.apk,对一些设备的兼容性更好
  4. 修复了一些其他问题

  1. [Important] ADB has been upgraded to version 41, which is incompatible with previous ADB versions. Please ensure that all ADB versions in the system environment are consistent, otherwise the device may not be connected.
  2. The iOS module adds a new Error type, LocalDeviceError. Some interfaces can only be used by local USB-connected iOS devices, and the remote device will throw this exception. Therefore, if necessary, you can catch this exception and do some additional compatibility and processing for the remote device.
  3. Updated yosemite.apk to have better compatibility with some devices
  4. Fixed some other issues
Airtest - v1.3.1

Published by yimelia about 1 year ago

  1. 报告中现在将会显示connect_device接口连接的设备
  2. ios和android设备在连接时,支持传入name参数,用于指定它的udid(ios)或serial number(android)
    例如: ios:///http://10.240.145.171:20092?name=83282c400efc9122e3bcba60c803cf318a6b3822
    安卓远程设备: android://127.0.0.1:5037/10.227.71.86:20029?name=serialno
  3. adb现在将会优先使用当前的adb进程,或者是系统变量设置了ANDROID_HOME中的adb,如果都找不到,才会使用airtest里的adb。
    同时也支持直接指定adb_path,例如:
from airtest.core.android.android import Android, ADB

adb = ADB(adb_path=r"D:\adb\adb.exe")

# 或者可以初始化一个指定了adb_path的Android设备对象
dev = Android(serialno="5TSSMVBYUSEQNRY5", adb_path=r"D:\test\adb41\adb.exe")
  1. 剪贴板的相关接口增加了安卓的支持,增加了粘贴接口(paste,效果等同于执行 text(get_clipboard())
text = "test_clipboard"
set_clipboard(text)

get_text = get_clipboard()
print(get_text)  # -> test_clipboard

paste()  # => text(get_clipboard())

bug修复:
修复了一些小问题
如果遇到了手机画面只有一半的情况,重新连接画面即可恢复。


  1. The report will now display the devices connected to the connect_device interface.
  2. When connecting ios and android devices, the name parameter can be passed in to specify its udid (ios) or serial number (android)
    For example: ios:///http://10.240.145.171:20092?name=83282c400efc9122e3bcba60c803cf318a6b3822
    Android remote device: android://127.0.0.1:5037/10.227.71.86:20029?name=serialno
  3. adb will now give priority to using the current adb process, or the system variable is set to adb in ANDROID_HOME. If neither is found, adb in airtest will be used.
    It also supports directly specifying adb_path, for example:
from airtest.core.android.android import Android, ADB

adb = ADB(adb_path=r"D:\adb\adb.exe")

# Or specify adb_path when initializing the Android object
dev = Android(serialno="5TSSMVBYUSEQNRY5", adb_path=r"D:\test\adb41\adb.exe")
  1. The relevant interfaces of the clipboard have been added with Android support and a paste interface (paste, the effect is equivalent to executing text(get_clipboard()))
text = "test_clipboard"
set_clipboard(text)

get_text = get_clipboard()
print(get_text) # -> test_clipboard

paste() # => text(get_clipboard())

bug fixes:
Fixed some minor issues
If you encounter a situation where the screen on your phone is only half full, you can restore the screen by reconnecting.

Airtest - v1.3.0

Published by yimelia over 1 year ago

重要改动

从airtest v1.3.0起,放弃对python2的支持

新增

ios设备接口新增

iOS设备对象IOS,新增以下接口的支持:

  1. (仅支持本地USB设备)安装 install
install(r"D:\demo\test.ipa") # install iOS ipa
install("http://www.example.com/test.ipa") # install iOS ipa from url

#获取当前设备
dev = device()

#通过本地.ipa文件安装APP
dev.install_app(r"D:\demo\test.ipa")  # install iOS ipa

#通过下载链接安装APP
dev.install_app("http://www.example.com/test.ipa") # install iOS ipa from url
  1. (仅支持本地USB设备)卸载 uninstall
uninstall("com.netease.cloudmusic")

dev = device()

dev.uninstall_app("com.netease.godlike")
  1. (仅支持本地USB设备)列出所有的app,list_app

list_app("user") 传入要列出的app类型,可以得到app列表
参数可选user/system/all 分别表示列出用户安装的app/系统app/全部app
返回值示例:[('com.apple.mobilesafari', 'Safari', '8.0'), ...]

dev = device()

#列出全部APP
all_app = dev.list_app("all")
print(all_app)

#打印系统APP
print(dev.list_app("system"))

#列出用户安装的APP
user_app = dev.list_app("user")
print(user_app)
  1. 获取剪贴板内容, get_clipboard
text = get_clipboard()
print(text)

注意:当iOS设备为远程设备、或者安装了不止一个wda时,需要指定具体的wda_bundle_id才能使用:

text = get_clipboard(wda_bundle_id="com.WebDriverAgentRunner.xctrunner")
  1. 设置剪贴板内容,set_clipboard

注意:当iOS设备为远程设备、或者安装了不止一个wda时,需要指定具体的wda_bundle_id才能使用

set_clipboard("content")  # local iOS

# When the iOS device is a remote device, or more than one wda is installed on the device, you need to specify the wda_bundle_id
set_clipboard("content", wda_bundle_id="com.WebDriverAgentRunner.xctrunner")

iOS新增tidevice相关接口

针对本地USB接入的设备,airtest结合tidevice的能力,封装了一个TIDevice对象,提供了几个常用接口如下:

  • devices:列出USB连接的所有设备的 UDID 列表
  • list_app: 列出手机上安装的应用列表,支持对类型进行筛选,包括 user/system/all
  • list_wda: 列出手机上安装的所有WDA的bundleID
  • device_info:获取手机信息
  • install_app:安装ipa包,支持本地路径或URL
  • uninstall_app:卸载bundle_id对应的包体
  • start_app:启动 bundle_id 对应的包体
  • stop_app:停止 bundle_id 对应的包体
  • ps: 获取当前的进程列表
  • ps_wda: 获取当前启动中的WDA列表
  • xctest:启动wda

可以参考:https://github.com/AirtestProject/Airtest/blob/master/tests/test_tidevice.py

代码执行效果示例:

>>> from airtest.core.ios.ios import TIDevice
>>> devices = TIDevice.devices()
>>> print(devices)
['10da21b9091f799891557004e4105ebab3416cb9']
>>> udid = devices[0]

>>> print(TIDevice.list_app(udid))
[ ('com.230316modified.WebDriverAgentRunner.xctrunner', 'wda-Runner', '1.0'),]

>>> print(TIDevice.list_app(udid, "system"))
[('com.apple.calculator', 'Calculator', '1.0.0'),]

>>> print(TIDevice.list_wda(udid))
['com.test.WebDriverAgentRunner.xctrunner']

>>> print(TIDevice.device_info(udid))
{'productVersion': '12.4.8', 'productType': 'iPhone7,2', 'modelNumber': 'MG472', 'serialNumber': 'DNPNW6EJG5MN', 'timeZone': 'Asia/Shanghai', 'uniqueDeviceID': '10da21b9091f799891557004e4105ebab3416cb9', 'marketName': 'iPhone 6'}

>>> 
>>> TIDevice.start_app(udid, "com.apple.mobilesafari")

>>> TIDevice.stop_app(udid, "com.apple.mobilesafari")

>>> print(TIDevice.ps(udid))
[ {'pid': 215, 'name': 'MobileMail', 'bundle_id': 'com.apple.mobilemail', 'display_name': 'MobileMail'}]

>>> print(TIDevice.ps_wda(udid))
['com.test.WebDriverAgentRunner.xctrunner']

TIDevice.xctest接口的执行示例如下:

import threading
wda_bundle_id = TIDevice.list_wda(udid)[0]
# 创建一个线程,执行xctest
t = threading.Thread(target=TIDevice.xctest, args=(udid, wda_bundle_id), daemon=True)
t.start()
time.sleep(5)
ps_wda = TIDevice.ps_wda(udid)
print(ps_wda)
time.sleep(5)
# 终止线程
t.join(timeout=3)

using接口的改动

using接口的作用是,支持在脚本中引用另外一个脚本,同时还能够让airtest正确地读取到其他脚本中的图片路径。

假设目录结构如下:

            demo/
                foo/
                    bar.air
                baz.air
                main.py

如果我们希望在main.py中引用 foo/bar.airbaz.air,可以将项目根路径设置到ST.PROJECT_ROOT,或者确保项目根路径是当前工作目录:

            # main.py
            from airtest.core.api import *
            ST.PROJECT_ROOT = r"D:\demo"  # This line can be ignored if it is the current working directory
            using("foo/bar.air")
            using("baz.air")

如果我们希望在 foo/bar.air 中引用 baz.air,可以这样写:

            # foo/bar.air
            from airtest.core.api import *
            using("../baz.air")

新增错误类型NoDeviceError

如果当前未连接任何设备,但又调用了某些需要连接设备才可以调用的接口时,抛出异常:NoDeviceError("No devices added.")

其他改动

  1. 当airtest脚本引发了assert异常时,退出码为20,以便和其他报错区分
  2. 更新了Yosemite.apk,修复了一些稳定性问题
  3. windows平台新增接口 set_focus,与原先的set_foreground 功能相同

Important changes

From airtest v1.3.0, drop support for python2

add

ios function enhancement

iOS adds support for the following interfaces:

  1. (Only local USB devices are supported) Install install
install(r"D:\demo\test.ipa") # install iOS ipa
install("http://www.example.com/test.ipa") # install iOS ipa from url

or

# Get the current device
dev = device()

#Install APP through local .ipa file
dev.install_app(r"D:\demo\test.ipa") # install iOS ipa

#Install the APP through the download link
dev.install_app("http://www.example.com/test.ipa") # install iOS ipa from url
  1. (Only local USB devices are supported) Uninstall uninstall
uninstall("com.netease.cloudmusic")

or

dev = device()

dev.uninstall_app("com.netease.godlike")
  1. (Only support local USB devices) list all apps, list_app

list_app("user") Pass in the app type to be listed, and you can get the app list
Optional parameter user/system/all means to list the app installed by the user/system app/all apps respectively
Return value example: [('com.apple.mobilesafari', 'Safari', '8.0'), ...]

dev = device()

#List all APPs
all_app = dev. list_app("all")
print(all_app)

#Print System APP
print(dev. list_app("system"))

#List the apps installed by the user
user_app = dev. list_app("user")
print(user_app)
  1. Get clipboard content, get_clipboard
text = get_clipboard()
print(text)

Note: When the iOS device is a remote device, or more than one wda is installed, you need to specify a specific wda_bundle_id to use:

text = get_clipboard(wda_bundle_id="com.WebDriverAgentRunner.xctrunner")
  1. Set clipboard content, set_clipboard

Note: When the iOS device is a remote device, or more than one wda is installed, you need to specify a specific wda_bundle_id to use

set_clipboard("content") # local iOS

# When the iOS device is a remote device, or more than one wda is installed on the device, you need to specify the wda_bundle_id
set_clipboard("content", wda_bundle_id="com.WebDriverAgentRunner.xctrunner")

New tidevice related interface for iOS

For devices with local USB access, airtest combines the capabilities of tidevice to encapsulate a TIDevice object, providing several common interfaces as follows:

  • devices: list the UDIDs of all devices connected by USB
  • list_app: Lists the list of apps installed on the phone, supports filtering by type, including user/system/all
  • list_wda: list the bundleIDs of all WDAs installed on the phone
  • device_info: get phone information
  • install_app: install ipa package, support local path or URL
  • uninstall_app: Uninstall the package body corresponding to bundle_id
  • start_app: start the package body corresponding to bundle_id
  • stop_app: Stop the package body corresponding to bundle_id
  • ps: get the current process list
  • ps_wda: Get a list of WDAs currently booting
  • xctest: start wda

You can refer to: https://github.com/AirtestProject/Airtest/blob/master/tests/test_tidevice.py

Example of code execution effect:

>>> from airtest.core.ios.ios import TIDevice
>>> devices = TIDevice.devices()
>>> print(devices)
['10da21b9091f799891557004e4105ebab3416cb9']
>>> udid = devices[0]

>>> print(TIDevice.list_app(udid))
[ ('com.230316modified.WebDriverAgentRunner.xctrunner', 'wda-Runner', '1.0'),]

>>> print(TIDevice.list_app(udid, "system"))
[('com.apple.calculator', 'Calculator', '1.0.0'),]

>>> print(TIDevice.list_wda(udid))
['com.test.WebDriverAgentRunner.xctrunner']

>>> print(TIDevice.device_info(udid))
{'productVersion': '12.4.8', 'productType': 'iPhone7,2', 'modelNumber': 'MG472', 'serialNumber': 'DNPNW6EJG5MN', 'timeZone': 'Asia/Shanghai', 'uniqueDeviceID': '10da21b9091f799891557004e4105ebab3416cb9', 'marketName': 'iPhone 6'}

>>> TIDevice.start_app(udid, "com.apple.mobilesafari")

>>> TIDevice.stop_app(udid, "com.apple.mobilesafari")

>>> print(TIDevice.ps(udid))
[ {'pid': 215, 'name': 'MobileMail', 'bundle_id': 'com.apple.mobilemail', 'display_name': 'MobileMail'}]

>>> print(TIDevice.ps_wda(udid))
['com.test.WebDriverAgentRunner.xctrunner']

The execution example of the TIDevice.xctest interface is as follows:

import threading
wda_bundle_id = TIDevice.list_wda(udid)[0]
# Create a thread to execute xctest
t = threading.Thread(target=TIDevice.xctest, args=(udid, wda_bundle_id), daemon=True)
t. start()
time. sleep(5)
ps_wda = TIDevice.ps_wda(udid)
print(ps_wda)
time. sleep(5)
# Terminate thread
t.join(timeout=3)

Changes to the using interface

The function of the using interface is to support another script to be referenced in the script, and at the same time, it can also allow airtest to correctly read the image path in other scripts.

Suppose the directory structure is as follows:

            demo/
                foo/
                    bar.air
                baz.air
                main.py

If we want to reference foo/bar.air and baz.air in main.py, we can set the project root path to ST.PROJECT_ROOT, or make sure the project root path is the current working directory:

            # main.py
            from airtest.core.api import *
            ST.PROJECT_ROOT = r"D:\demo" # This line can be ignored if it is the current working directory
            using("foo/bar. air")
            using("baz. air")

If we wanted to reference baz.air in foo/bar.air, we could write:

            # foo/bar.air
            from airtest.core.api import *
            using("../baz.air")

New error type NoDeviceError

If no device is currently connected, but some interfaces that need to be connected to the device are called, an exception will be thrown: NoDeviceError("No devices added.")

Other changes

  1. When the airtest script raises an assert exception, the exit code is 20 to distinguish it from other errors
  2. Updated Yosemite.apk and fixed some stability issues
  3. The new interface set_focus on the windows platform has the same function as the original set_foreground
Airtest - v1.2.10.2

Published by yimelia over 1 year ago

录屏相关

Android录屏目前提供两种模式,yosemiteffmpeg,区别如下:

  • yosemite:原有的默认模式,录屏清晰度和质量较高,但兼容性较差,部分机型可能有问题
    • 支持的参数:orientation, max_time, bit_rate, bit_rate_level
  • ffmpeg: 在1.2.9之后加入的新模式,录屏帧率和质量较低,但兼容性更好,能兼容绝大多数设备
    • 支持的参数: orientation, max_size, max_time, fps, snapshot_sleep

在1.2.10.2中的改动:

  • 在1.2.9中提供的cv2模式已经被舍弃,因为容易引发错误,效果也不如ffmpeg
  • win/ios的start_recording 就无需再有mode参数,只有android需要mode参数
  • 录屏的ffmpeg模式增加了max_size参数,能够指定录屏结果的图像大小,因为屏幕图片越大,在录屏时造成的系统负载越大(CPU和内存占用)

代码示例:

dev = connect_device("android:///")
dev.start_recording(output="test.mp4", mode="ffmpeg", max_size=800)  # Android 支持mode指定使用ffmpeg模式

其他改动

  • 如果Android出现了屏幕有一半黑屏的情况,可以再次重连
  • 去掉了numpy的版本号限制

Record screen

Android screen recording currently provides two modes, yosemite and ffmpeg, the differences are as follows:

  • yosemite: the original default mode, the recording resolution and quality are higher, but the compatibility is poor, and some models may have problems
    • Supported parameters: max_time, orientation, bit_rate, bit_rate_level
  • ffmpeg: a new mode added after 1.2.9, the screen recording frame rate and quality are lower, but the compatibility is better, compatible with most devices
    • Supported parameters: max_time, fps, max_size, snapshot_sleep

Changes in 1.2.10.2:

  • The cv2 mode provided in 1.2.9 has been abandoned, because it is prone to errors and the effect is not as good as ffmpeg
  • The start_recording of win/ios does not need to have the mode parameter, only android needs the mode parameter
  • The ffmpeg mode of screen recording adds the max_size parameter, which can specify the image size of the screen recording result, because the larger the screen image, the greater the system load caused by the screen recording (CPU and memory usage)

Code example:

dev = connect_device("android:///")
dev.start_recording(output="test.mp4", mode="ffmpeg", max_size=800) # Android supports mode to specify the use of ffmpeg mode

Other changes

  • If the Android screen is half black, you can reconnect again
  • Removed numpy version number restriction
  1. 兼容最新版本的ios-tagent master 的改动:
    • 新增了一个点击接口、一个滑动接口,速度比appium/wda的接口更快
    • 具体详细改动内容:iOS-Tagent接口改动说明
    • airtest将在检查到当前ios手机使用的是ios-tagent时,调用新增接口,否则调用wda原本的点击和滑动接口
  2. 更新了yosemite.apk,修复了一个小米6手机横屏画面获取错误的问题
  3. airtest的脚本内容支持 if __name__ == "__main__" 的写法了

  1. Compatible with the latest version of ios-tagent master changes:
    • Added a click interface and a sliding interface, which are faster than the appium/wda interface
    • Specific detailed changes: iOS-Tagent interface change description
    • airtest will call the new interface when it checks that the current ios phone is using ios-tagent, otherwise it will call the original click and slide interface of wda
  2. Updated yosemite.apk, and fixed a problem that the horizontal screen image of Mi 6 mobile phone was incorrectly obtained
  3. The script content of airtest supports the writing method of if __name__ == "__main__"
Airtest - v1.2.9 新版本录屏方法和windows截图优化

Published by yimelia over 1 year ago

功能新增

新增windows窗口录屏功能、iOS录屏功能,同时也迭代了安卓录屏

目前录屏功能不仅支持Android设备,还支持了windows、iOS设备!

函数 start_recording() 参数修改如下:

  • max_time: 录屏最长时间限制,默认为1800,单位是秒
  • output: 录像保存文件地址, 默认为None,将会自动保存在log目录下,自动以当前时间命名——原先output参数在stop_recording中,现在改为在start_recording里
  • fps=10 # 输出视频的帧率,目前暂时限定不超过10fps,默认为10(仅对ffmpeg和cv2生效)
  • mode="yosemite" # 保存视频的方法,仅支持安卓,可选 'ffmpeg' 'yosemite',区别如下:
    • ffmpeg:对机型兼容较好,但cpu占用较高,第一次运行将会预先下载ffmpeg,有一定的额外空间占用(几十M)
    • yosemite:Android旧版本的录屏方案,假如当前设备是Android,默认会使用这个模式录屏,必须要事先安装yosemite.apk,并支持旧的参数,帧率比ffmpeg高,但兼容性差,有一些手机不支持
  • snapshot_sleep=0.001 # 截图间隔
  • orientation=0 # 视频朝向模式 1 竖屏 2 横屏 0 方形填充,默认是0

其中大部分参数使用默认值即可,最重要的参数有两个:

  • 新增参数orientation:
    • 当跑测过程中大部分时间是竖屏时,可以考虑将orientation=1,或 orientation="portrait"
    • 当跑测过程中大部分是横屏,可以orientation=2,或orientation="lanscape",适合游戏等横屏应用
    • 横竖屏都有可能的话,可以不指定参数,默认值为0,会用一个正方形来容纳视频内容,方便横竖屏转换
  • output=xxx.mp4,默认将录屏文件存放在log目录下,如果有重命名需求的话可以传这个参数,否则直接所有参数用默认值即可

代码示例:

            Record 30 seconds of video and export to the current directory test.mp4::

            >>> from airtest.core.api import connect_device, sleep
            >>> dev = connect_device("Android:///")
            >>> save_path = dev.start_recording(output="test.mp4")
            >>> sleep(30)
            >>> dev.stop_recording()
            >>> print(save_path)

            >>> # the screen is portrait
            >>> portrait_mp4 = dev.start_recording(output="portrait.mp4", orientation=1)  # or orientation="portrait"
            >>> sleep(30)
            >>> dev.stop_recording()

            >>> # the screen is landscape
            >>> landscape_mp4 = dev.start_recording(output="landscape.mp4", orientation=2)  # or orientation="landscape"

IOS支持传入udid参数

iOS的初始化字符串中,支持传入名为 serialno/udid/uuid的字段,用于设置这台iOS的设备udid,示例:

>>> connect_device("iOS:///http://localhost:8100/?mjpeg_port=9100")  # iOS with mjpeg port
>>> connect_device("iOS:///http://localhost:8100/?mjpeg_port=9100&&udid=00008020-001270842E88002E")  # iOS with mjpeg port and udid
>>> connect_device("iOS:///http://localhost:8100/?mjpeg_port=9100&&uuid=00008020-001270842E88002E")  # udid/uuid/serialno are all ok

该名称无论使用udid/uuid/serialno中任何一个名字传入都可以生效,可以在连接后,通过以下方式获取到这个值:

dev = connect_device("iOS:///http://localhost:8100/?uuid=00008020-001270842E88002E")
print(dev.uuid)

增加这个参数的主要原因是,在wda中获取不到ios手机的udid,但在某些情况下可能需要用到这个值,因此支持主动传入保存。

支持Android 13

目前支持了Android 13

问题修复

修复了部分windows下,游戏无法正确截屏的问题

迭代了windows的snapshot,修复了部分游戏截屏图像重复、黑屏等问题,同时修复了在双屏下的截图区域错误问题。

修改了报告中对于运行结果是否成功的判定

原先的逻辑是:只要整个运行过程中出现traceback,就认为此次任务运行失败
但通常会遇到一种情况是:在运行过程中会出现一些不太重要的脚本异常,我们希望脚本不卡在这里,而是catch住异常后继续往下跑,只要能跑到最后就算脚本成功。

因此将脚本的成功判断改为:当步骤列表的最后一个步骤有traceback,才认为本次脚本运行失败。

对报告中一些显示效果做了一点微调

  1. 做了一些样式调整,修复了一些显示问题

  2. 报告html支持上下左右按键切换预览图片。


New features

Added windows window screen recording function, iOS screen recording function, and iterative Android screen recording function

Currently, the screen recording function not only supports Android devices, but also supports Windows and iOS devices!

The parameters of the function start_recording() are modified as follows:

  • max_time: The maximum time limit for screen recording, the default is 1800, the unit is second
  • output: The address of the video save file, the default is None, it will be automatically saved in the log directory, automatically named after the current time - the original output parameter is in stop_recording, now it is changed to start_recording
  • fps=10 # The frame rate of the output video is currently limited to no more than 10fps, and the default is 10 (only valid for ffmpeg and cv2)
  • mode="ffmpeg" # (Android Only) The background to save the video, optional 'ffmpeg' 'yosemite', the differences between the three modes are as follows:
    • ffmpeg: Compatibility with models is better, but the cpu usage is high, the first run will pre-download ffmpeg, there is a certain amount of extra space occupied (tens of M)
    • cv2: (Android default) No need to occupy additional space, the generated video volume is larger than ffmpeg
    • yosemite: The screen recording solution of the old version of Android. If the current device is Android, this mode will be used to record the screen by default. You must install yosemite.apk in advance, and support the old parameters. The frame rate is higher than ffmpeg and cv2, but compatible Poor performance, some mobile phones do not support
  • snapshot_sleep=0.001 # screenshot interval
  • orientation=0 # Video orientation mode 1 portrait 2 landscape 0 square padding, the default is 0

Most of the parameters can use the default values, and there are two most important parameters:

  • New parameter orientation:
    • When most of the time during the running test is a vertical screen, you can consider setting orientation=1, or orientation="portrait"
    • When most of the running tests are horizontal screens, you can use orientation=2, or orientation="lanscape", which is suitable for horizontal screen applications such as games
    • If both horizontal and vertical screens are possible, no parameter can be specified, the default value is 0, and a square will be used to accommodate the video content, which is convenient for horizontal and vertical screen conversion
  • output=xxx.mp4, by default, the screen recording file will be stored in the log directory. If there is a need to rename it, you can pass this parameter, otherwise you can use the default value for all parameters

Code example:

            Record 30 seconds of video and export to the current directory test.mp4::

            >>> from airtest.core.api import connect_device, sleep
            >>> dev = connect_device("Android:///")
            >>> save_path = dev.start_recording(output="test.mp4")
            >>> sleep(30)
            >>> dev.stop_recording()
            >>> print(save_path)

            >>> # the screen is portrait
            >>> portrait_mp4 = dev.start_recording(output="portrait.mp4", orientation=1)  # or orientation="portrait"
            >>> sleep(30)
            >>> dev.stop_recording()

            >>> # the screen is landscape
            >>> landscape_mp4 = dev.start_recording(output="landscape.mp4", orientation=2)  # or orientation="landscape"

IOS supports passing in udid parameters

In the initialization string of iOS, it is supported to pass in a field named serialno/udid/uuid, which is used to set the udid of this iOS device, for example:

>>> connect_device("iOS:///http://localhost:8100/?mjpeg_port=9100") # iOS with mjpeg port
>>> connect_device("iOS:///http://localhost:8100/?mjpeg_port=9100&&udid=00008020-001270842E88002E") # iOS with mjpeg port and udid
>>> connect_device("iOS:///http://localhost:8100/?mjpeg_port=9100&&uuid=00008020-001270842E88002E") # udid/uuid/serialno are all ok

The name can take effect no matter which name is used in udid/uuid/serialno, and this value can be obtained in the following way after connection:

dev = connect_device("iOS:///http://localhost:8100/?uuid=00008020-001270842E88002E")
print(dev.uuid)

The main reason for adding this parameter is that the udid of the ios phone cannot be obtained in wda, but this value may be needed in some cases, so it is supported to actively pass in and save.

Support Android 13

Currently supports Android 13

bug fixes

Fixed the problem that the game could not take screenshots correctly under some windows

Iterated the snapshot of windows, fixed some game screenshot image duplication, black screen and other problems, and also fixed the wrong area of ​​the screenshot under dual screen.

Modified the judgment on whether the running result is successful or not in the report

The original logic is: as long as a traceback occurs during the entire running process, it is considered that the task failed.
But there is usually a situation where some unimportant script exceptions will appear during the running process. We hope that the script will not get stuck here, but continue to run after catching the exception. As long as it can run to the end, it will be considered as a script. success.

Therefore, the success judgment of the script is changed to: When the last step in the step list has a traceback, the script is considered to have failed.

Fine-tuned some display effects in the report

  1. Made some style adjustments and fixed some display issues

  2. The report html supports up, down, left, and right buttons to switch the preview image.

Airtest - v1.2.7

Published by yimelia about 2 years ago

1. 更新内容

1.2.7版本主要是新增了设备释放接口、大量断言的语句,新增了对Android 12L的支持,对安装接口的增强,和若干bug的修复。

2. Airtest版本提升至1.2.7

1)新增了device.disconnect()接口

原先的Airtest,在脚本长时间运行、或是使用了AirtestIDE反复连接多个不同手机时,可能会 建立大量adb连接未释放 ,一直占用资源。

这也会导致在部分手机上,反复切换横屏和竖屏应用时,会有概率出现 屏幕一半内容变成黑屏 的问题。

因此,1.2.7版本的Airtest新增了device.disconnect()接口,用于:

  • 在脚本中允许手动调用,让设备创建出的所有adb连接都强制释放掉,dev.disconnect(),如果还要继续使用这个设备对象,最好重新再创建一次 dev = connect_device("android:///")
  • 同时对连接的创建进行了更进一步的清理操作,避免黑屏问题的发生
2)新增了大量的断言语句

在脚本编写中,断言语句是非常重要的组成部分,但airtest旧版只支持 assert_existsassert_equal 两种类型的断言语句。

现在Airtest1.2.7版本,将所有断言语句单独放在 airtest/core/assertions.py 中,增加了更多类型,方便脚本编写工作。

目前Airtest1.2.7支持的断言列表: assertions

  • assert_exists
  • assert_not_exists
  • assert_equal
  • assert_not_equal
  • assert_true
  • assert_false
  • assert_is
  • assert_is_not
  • assert_is_none
  • assert_is_not_none
  • assert_in
  • assert_not_in
  • assert_is_instance
  • assert_not_is_instance
  • assert_greater
  • assert_greater_equal
  • assert_less
  • assert_less_equal
3)支持设置断言时附带当前截图

Airtest1.2.7除了让断言语句更加丰富以外,还支持设置断言时截取当前画面的图片,然后显示在Airtest报告中,这样报告的断言内容会更加清晰,也更具有airtest的截图特色:

# 默认情况下,断言截图会开启
assert_exists()

# 如不需要断言时截取当前画面,则可以设置关闭断言的截图
assert_exists(截图, snapshot=False)
4)新增对Android12L的支持

已增加 minicap 对android 12L的支持,Poco的支持可以等待poco后续的更新。

5)安装接口pm_install的增强

pm_install 接口进行了较大的增强:

  • 支持了安装参数的传入(与 adb.install 保持一致),
  • 支持了中文路径、一些包含特殊符号路径
  • 对路径的改动同时影响到了 adb.pull()adb.push() 接口,支持了中文路径、包含斜杠的路径(比如 \g 这样的字符也会有问题)、包含特殊符号(空格、括号等)的路径
  • pm_install 安装完毕后,会进行 adb shell rm apk 的操作,超时时间30秒
6)logwrap增加截图参数

如果希望把自定义的函数显示到airtest的报告中,可以使用@logwrap,例如:

@logwrap
def func1():
    pass

如果希望在报告显示func1内容的同时,还附带一张当前设备的截图的话,可以增加snapshot=True参数在func1()的定义中:

@logwrap
def func1(snapshot=True):
    pass
7)bug修复
  • 尝试修复偶现的一个报告读取不到图片导致生成报告失败的问题
  • 兼容了adb 获取屏幕信息超时的情况
  • 修复了一个 adb.text() 在输入字母+数字时可能会导致乱序的问题,同时支持空格
8)新增了3个PR的支持
  • 在Windows环境下,初始化 airtest.core.win.Windows 对象时,允许开发者选择性跳过 connect() 方法中的 set_foreground() 功能 #1068
  • Android.get_render_resolution 中增加应用包名参数,
    使得 get_render_resolution 能够获取到除top activity以外的应用的渲染区域 #1070
  • 修复win和linux的start_app缺少的传参 #1056

3. 如何更新

pip install -U airtest

1. Update content

Version 1.2.7 mainly added device release interface, a large number of assertion statements, added support for Android 12L, enhanced installation interface, and fixed several bugs.

2. Airtest version upgraded to 1.2.7

1) Added device.disconnect() interface

The original Airtest, when the script runs for a long time, or uses AirtestIDE to repeatedly connect to multiple different mobile phones, may establish a large number of adb connections but not release, which will always occupy resources.

This will also lead to the problem of half of the screen becoming a black screen when switching between landscape and portrait applications repeatedly on some mobile phones.

Therefore, version 1.2.7 of Airtest has added the device.disconnect() interface for:

  • Allow manual calls in the script, so that all adb connections created by the device are forcibly released, dev.disconnect(), if you want to continue to use this device object, it is best to recreate it again dev = connect_device(" android:///")
  • At the same time, the creation of the connection has been further cleaned up to avoid the black screen problem
2) Added a large number of assertion statements

In scripting, assertion statement is a very important part, but the old version of airtest only supports assert_exists and assert_equal two types of assertion statement.

Now Airtest 1.2.7 version, put all assertion statements in airtest/core/assertions.py separately, adding more types to facilitate scripting work.

List of assertions currently supported by Airtest1.2.7: assertions

  • assert_exists
  • assert_not_exists
  • assert_equal
  • assert_not_equal
  • assert_true
  • assert_false
  • assert_is
  • assert_is_not
  • assert_is_none
  • assert_is_not_none
  • assert_in
  • assert_not_in
  • assert_is_instance
  • assert_not_is_instance
  • assert_greater
  • assert_greater_equal
  • assert_less
  • assert_less_equal
3) Support setting assertion with current screenshot

In addition to enriching the assertion statement, Airtest 1.2.7 also supports capturing a picture of the current screen when setting an assertion, and then displaying it in the Airtest report, so that the assertion content of the report will be clearer and more characteristic of airtest screenshots:

# By default, assertion screenshots are enabled
assert_exists()

# If you do not need to take a screenshot of the current screen when asserting, you can set a screenshot of closing the assertion
assert_exists(screenshot, snapshot=False)
4) Added support for Android12L

Added minicap support for android 12L, Poco support can wait for poco's subsequent updates.

5) Enhancement of installation interface pm_install

Major enhancements to the pm_install interface:

  • Supports the passing of installation parameters (consistent with adb.install),
  • Support Chinese paths, some paths containing special symbols
  • Changes to paths affect both adb.pull() and adb.push() interfaces, supports Chinese paths, paths containing slashes (such as \g and other characters will also problem), paths that contain special symbols (spaces, brackets, etc.)
  • After pm_install is installed, the adb shell rm apk operation will be performed with a timeout of 30 seconds
6) Logwrap adds screenshot parameters

If you want to display a custom function in the airtest report, you can use @logwrap, for example:

@logwrap
def func1():
    pass

If you want the report to display the contents of func1 and also attach a screenshot of the current device, you can add the snapshot=True parameter to the definition of func1():

@logwrap
def func1(snapshot=True):
    pass
7) Bug fix
  • Attempt to fix an occasional issue where the report could not be read, causing the report to fail to be generated
  • Compatible with the timeout of adb getting screen information
  • Fixed an issue where adb.text() could cause out-of-order when entering letters + numbers, while supporting spaces
8) Added support for 3 PRs
  • In Windows environment, when initializing airtest.core.win.Windows object, allow developers to selectively skip set_foreground() function in connect() method #1068
  • Add the application package name parameter in Android.get_render_resolution,
    Enable get_render_resolution to get the rendering area of ​​applications other than top activity #1070
  • Fix the missing parameter of start_app of win and linux #1056

3. How to update

pip install -U airtest
Airtest - v1.2.5 - v1.2.6

Published by yimelia over 2 years ago

Airtest 1.2.5 - 1.2.6

Add 新增

  • iOS投屏速度优化,新增MJPEG模式,以更高的速度查看iOS屏幕画面
  • iOS点击速度优化,请配合更新iOS-Tagent到最新版本(如果原先使用了Appium/WebDriverAgent项目的,可以替换成我们这个版本),更新之后可以极大降低点击延迟
  • 请使用最新版本的AirtestIDE 1.2.14,可以体验到最佳效果,否则可能导致点击位置错误的问题
  • 如果使用了Poco,请更新至1.0.87版本,否则可能导致点击位置错误的问题

相关注意事项:

  1. 极少部分设备上,可能点击位置会有偏移,目前在AirtestIDE上无法修正鼠标点击的偏移,但是可以在代码中修复,例如:

    我们测试到一台iPhone 7Plus手机,在点击时有坐标偏移的现象,因此通过如下方式在运行代码时可以修正:

    >>> device = connect_device("iOS:///")
    >>> device.touch((100, 100))  # wrong position
    >>> print(device.touch_factor)
    0.333333
    >>> device.touch_factor = 1 / 3.3  # default is 1/3
    >>> device.touch((100, 100))
    

    关于touch_factor的解释:

    touch_factor这个值用于换算iOS设备的点击坐标:

    手机真实坐标 = touch_factor * 屏幕坐标
    默认计算方式是: self.display_info['window_height'] / self.display_info['height']
    但在部分特殊型号手机上可能不准确,例如iOS14.4的7P,默认值为 1/3,但部分7P点击位置不准确,可自行设置为:self.touch_factor = 1 / 3.3

Poco相关的注意事项:

  1. 由于iOS的Poco延迟很高,开启时可能也会导致卡顿
  2. 部分ipad可能在横屏+桌面下,拿到的Poco位置不对,不建议在桌面上点击某个图标来打开app,尽量使用start_app来打开,但本接口目前必须传入手机中已有的app包名,如果传入的包名不存在,可能会导致报错

BUG 修复

  1. 修复了一个Android录屏时没有完全释放系统资源的BUG,该问题可能会导致内存溢出
  2. 稍微优化了mstpl的识别效果
  3. 修复了Android10以上版本的手机可能存在的点击失败问题
  4. 去除了安装时对numpy版本号的限制
  5. 兼容了jinja2>3.1版本
  6. 修复Android6.0.1系统下,adb.file_size接口获取文件大小失败的问题

Airtest 1.2.5

Add new

  • iOS screen projection speed optimization, new MJPEG mode, viewing iOS screen images at a higher speed
  • iOS click speed optimization, please update iOS-Tagent to the latest version (if you originally used the Appium/WebDriverAgent project, you can replace it with our version) , after the update can greatly reduce the click delay
  • Please use the latest version of AirtestIDE 1.2.14, you can experience the best effect, otherwise it may cause the problem of wrong click position
  • If you use Poco, please update to version 1.0.87, otherwise it may cause the problem of wrong click position

Related Notes:

  1. On a very small number of devices, the click position may be offset. At present, the offset of the mouse click cannot be corrected on AirtestIDE, but it can be fixed in the code, for example:

    We tested an iPhone 7Plus mobile phone, and there is a coordinate offset phenomenon when clicking, so it can be corrected when running the code in the following way:

    >>> device = connect_device("iOS:///")
    >>> device.touch((100, 100))  # wrong position
    >>> print(device.touch_factor)
    0.333333
    >>> device.touch_factor = 1 / 3.3  # default is 1/3
    >>> device.touch((100, 100))
    

Explanation about touch_factor:

touch_factor This value is used to convert the touch coordinates of iOS devices:

Phone real coordinates = touch_factor * screen coordinates
The default calculation is: self.display_info['window_height'] / self.display_info['height']
But it may be inaccurate on some special models of mobile phones, such as 7P of iOS14.4, the default value is 1/3, but the click position of some 7P is inaccurate, you can set it yourself: self.touch_factor = 1 / 3.3

Poco related notes:

  1. Due to the high latency of Poco on iOS, it may also cause lag when it is turned on.
  2. Some ipads may be in landscape + desktop, and the Poco obtained is in the wrong position. It is not recommended to click an icon on the desktop to open the app, try to use start_app to open it, but this interface must be transferred to the mobile phone. For some app package names, if the incoming package name does not exist, an error may be reported

BUG fixes

  1. Fixed a bug that system resources were not completely released when Android screen recording, which may lead to memory overflow
  2. Slightly optimized the recognition effect of mstpl
  3. Fixed the possible click failure problem on mobile phones with Android 10 and above
  4. Removed the restriction on numpy version number during installation
  5. Compatible with jinja2>3.1 version
  6. Fix the problem that the adb.file_size interface fails to obtain the file size under the Android 6.0.1 system
Airtest - v1.2.4

Published by yimelia almost 3 years ago

Fix:

  • 安卓在录屏强制中止的情况下,下一次启动录屏时优先清理之前的录屏再开始新录屏,避免启动录屏失败
  • 部分手机如oppo/vivo等,在没有安装/启用yosemite输入法时无法使用,改用adb shell input text输入(不支持中文)
  • wake接口先尝试使用keyevent22482解锁android屏幕,如果解锁失败,再尝试用yosemite解锁
  • 图像识别:计算置信度过程加入极限值噪点,修复纯色状态时置信度异常高的问题。RGB模式对极限值进行裁剪,修复色相角度计算异常的问题。

Add:

  • 新增Android 12的minicap截图支持

Fix:

  • When Android screen recording is forcibly suspended, the next time you start screen recording, it will prioritize cleaning up the previous recording screen before starting a new screen recording to avoid starting screen recording failure
  • Some mobile phones such as oppo/vivo cannot be used without yosemite input method installed/enabled. Use adb shell input text instead (Chinese is not supported)
  • wake interface first try to use keyevent224 and 82 to unlock the android screen, if the unlocking fails, try to unlock it with yosemite
  • Image recognition: Add limit value noise to the process of calculating the confidence level to fix the problem of abnormally high confidence in the pure color state. RGB mode cuts the limit value and fixes the problem of abnormal hue angle calculation.

Add:

  • Added Android 12 minicap screenshot support
Airtest - 1.2.3

Published by yimelia about 3 years ago

主要改动:

  • 修改了获取Android设备屏幕尺寸的方式,尽量兼容了手机、平板、特殊车机设备
Airtest - 1.2.1-1.2.2

Published by yimelia about 3 years ago

Airtest 1.2.1-1.2.2

本次更新以bug修复、图像识别效果提升为主,更新内容如下:

  • 修复上个版本改动带来的问题
    • 修复在使用py2、或者是某些特殊版本的python时,导致的一些报错
    • 初始化minitouch时,不再额外增加一个(0, 0)坐标的点击,避免误点
  • 图像识别算法的改进
    • 优化了mstpl算法,提升了判定的严格程度,可以有效降低当目标图片不在当前画面中的误检率
    • tpl算法被添加回设置里,可以在mstpl失败时作为补充方案
    • 修复了mstpl算法在参数错误时的容错
  • adb.pm_install接口中增加安装完毕后自动删除apk包的功能,避免调用完之后没清理,残留大量apk包的问题
  • 其他BUG修复

This update focuses on bug fixes and improved image recognition effects. The update content is as follows:

  • Fix the problems caused by the changes of the previous version
    • Fix some errors caused when using py2 or some special versions of python
    • When initializing the minitouch, no additional clicks with (0, 0) coordinates are added to avoid mistakes
  • Improvement of image recognition algorithm
    • Optimized the mstpl algorithm to improve the strictness of the judgment, which can effectively reduce the false detection rate when the target picture is not in the current picture
    • The tpl algorithm is added back to the settings, which can be used as a supplementary solution when mstpl fails
    • Fixed the fault tolerance of mstpl algorithm when the parameters are wrong
  • Add the function of automatically deleting the apk package after the installation is completed in the adb.pm_install interface to avoid the problem of a large number of apk packages that are not cleaned up after the call is completed
  • Other bug fixes
Airtest - 1.2.0

Published by yimelia over 3 years ago

Airtest1.2.0更新

English Version

新增:图像识别算法mstpl

我们新增了一个改良版本的模板匹配识别算法,能够大幅度增加原有的模板匹配的成功率,更好地适配分辨率变化的场景。

将Airtest更新至1.2.0以上版本即可使用,如果您正在使用AirtestIDE,也请同步更新至1.2.10以上版本,最新的版本已经将该算法设置为首选使用的算法。

请参考以下代码示例:

from airtest.core.api import *

touch(Template("search.png", scale_max=800, scale_step=0.005))

在Template图片对象初始化时,与图像识别有关的参数如下:

  • threshold:用于设置图像识别的筛选阈值,默认为0.8,因此需要图像识别效果大于0.8时,才会认为此次识别是成功的
  • rgb:是否要进行彩色识别,默认为False,意思是airtest默认会将图片处理为灰度图片,因此如果需要加入彩色三通道的识别,需要将它设置为True
  • 新加入scale_max:新算法专用参数,用于调节匹配的最大范围,如果要查找的目标UI很小的话,可以适当增大这个数值,默认值 800, 推荐值 740, 800, 1000 取值范围 [700 , 2000]
  • 新加入scale_step:新算法专用参数,用于控制搜索比例步长,如果要查找的目标UI很小的话,可以适当减小这个数值,默认值0.005,推荐值 0.02, 0.005, 0.001 取值范围 [0.001, 0.1]

如果在图像识别时遇到问题或异常报错,请将当前界面截图、与脚本中使用的图片一起提交issue。

接口改动:连接手机时无需设置参数

在Airtest 1.2.0以上版本中,我们不再希望大家连接手机时,手动指定各连接参数了,包括cap_methodtouch_methodori_method

因此我们进行了一些改动,在初始化手机时,如果遇到问题,Airtest将会自动尝试进行兼容,并选取备用方案进行连接,直到成功为止。

需要关注的重要改动如下:

  • 目前Android12暂时还没有很好地支持,屏幕画面效果很差

  • 新增Android.screen_proxy,类似于之前的touch_proxy,统一使用它作为屏幕截图方法的调用入口

  • 初始化Android()对象时,可以不再强制指定cap_method="MINICAP""JAVACAP"screen_proxy会自动按照顺序进行初始化,直到选取到可以成功初始化的截图方法。

    • 例如,之前在连接模拟器时,需要在IDE上勾选use javacap,或是在脚本运行时指定cap_method=JAVACAP,现在可以不指定,也能成功初始化
    • 删除了cap_method=MINICAP_STREAM这个参数,请不要再传MINICAP_STREAM这个值
    • 初始化的优先顺序为:自定义的截图方法 > MINICAP > JAVACAP > ADBCAP,其中,如果调用到了ADBCAP,将会打印一个warning,告诉用户此时截图效率很低
    • 保留了旧的一些调用入口,方便兼容旧的代码
      • 例如dev.minicap,将会返回dev.screen_proxy对象,依然可以使用dev.minicap.get_frame_from_stream()接口
      • 例如dev.cap_method,将会返回当前使用的截图方法名称(比如"MINICAP"),同样也可以使用dev.cap_method = "JAVACAP"来强制指定截图方法
  • 在获取图片时,再也不需要进行大量的类型判断然后调用对应的截图方法了

    • 直接使用dev.screen_proxy.get_frame_from_stream()即可

    • 即以前的这种代码可以废弃了:

    • if dev.cap_method == CAP_METHOD.MINICAP:
          dev.minicap.get_frame_from_stream()
      elif dev.cap_method == xxx:
          ...
      
  • 如果希望实现自定义的新截图方法:在airtest.core.android.cap_methods.base_cap中,实现了所有截图方法的基类BaseCap,可以通过继承它,并实现get_frame_from_stream这个接口,就能新增一个自定义的截图方法,将它注册到ScreenProxy中就可以使用了

    • from airtest.core.android.cap_methods.base_cap import BaseCap
      class TestCap(BaseCap):
          def get_frame_from_stream(self):
              return b"frame"
      
      ScreenProxy.register_method("TESTCPY", TestCap)
      # 默认优先初始化为自定义的TestCap
      cap = ScreenProxy.auto_setup(dev.adb)
      

仅airtest开发者需要关注的改动如下:

  • 原先的android.get_display_info()默认会返回minicap.get_display_info(),现在改为默认直接返回adb.get_display_info() https://github.com/AirtestProject/Airtest/pull/913/commits/43a9c56813641b01a1489bd3174db330183135ba

    • 因为如果默认没有使用minicap,在这里还会强制触发一次minicap的初始化,很浪费时间
    • 希望能够让ori_method=ADBORI这个参数真正只与屏幕旋转方向做关联,默认情况下使用rotation_watcher.jar来获取屏幕方向,如果失败了,则可以指定此参数改为每隔2秒使用ADB获取一次当前屏幕旋转方向(一般是一些车机设备/特殊平板等设备)。原先的逻辑里,ADBORI的指定有可能是因为该设备minicap初始化失败,也可能是rotation_watcher拿到的屏幕方向不对,会造成问题难以排查。
  • 所有截图方法都包含有snapshot()这个接口,默认会处理截取的图片,返回一个cv2的图片,去掉了android.snapshot里的大量类型判断。

  • screen_proxy类似,为touch_proxy添加了auto_setup逻辑,在初始化手机时,会先尝试初始化minitouch,如果失败会尝试maxtouch,最后选择adbtouch,这样可以避免一些机型虽然不是android10,但是也需要使用maxtouch的问题 https://github.com/AirtestProject/Airtest/pull/913/commits/e4efe9e8fc0801350b8398776e5457041ced4b38

  • 为上述改动增加了对应的单元测试用例

  • 解决了在连接过程中,由于失败可能导致的socket未关闭或subprocess未关闭输入输出流的问题

其他BUG修复


Airtest 1.2.0 update

New: image recognition algorithm mstpl

We have added an improved version of the template matching recognition algorithm, which can greatly increase the success rate of the original template matching and better adapt to scenes with changing resolutions.

Update Airtest to version 1.2.0 or higher. If you are using AirtestIDE, please also update to version 1.2.10 or higher. The latest version has set this algorithm as the preferred algorithm.

Please refer to the following code example:

from airtest.core.api import *

touch(Template("search.png", scale_max=800, scale_step=0.005))

When the Template image object is initialized, the parameters related to image recognition are as follows:

  • threshold: used to set the screening threshold of image recognition, the default is 0.8, so the recognition effect is required to be greater than 0.8 before the recognition is considered successful
  • rgb: Whether to perform color recognition, the default is False, which means that airtest will process the picture as a grayscale picture by default, so if you need to add color three-channel recognition, you need to set it to True
  • Newly added scale_max: new algorithm special parameter, used to adjust the maximum range of matching, If the target UI to be searched is small, you can increase this value appropriately, the default value is 800, the recommended value is 740, 800 , 1000 Value range [700, 2000]
  • Newly added scale_step: a new algorithm dedicated parameter, used to control the search scale step size, If the target UI to be found is small, you can appropriately reduce this value, the default value is 0.005, the recommended value is 0.02, 0.005 , 0.001 Value range [0.001, 0.1]

If you encounter problems or abnormal errors during image recognition, please take a screenshot of the current interface and submit an issue together with the pictures used in the script.

Interface changes: No need to set parameters when connecting to a mobile phone

In Airtest 1.2.0 and above, we no longer want everyone to manually specify the connection parameters when connecting to the phone, including cap_method, touch_method, and ori_method.

Therefore, we have made some changes. When initializing the phone, if there is a problem, Airtest will automatically try to be compatible and select a backup plan to connect until it succeeds.

The important changes that need attention are as follows:

  • Currently Android12 is not yet well supported, the screen effect is very poor
  • Added Android.screen_proxy, which is similar to the previous touch_proxy and uses it as the call entry of the screenshot method.
  • When initializing the Android() object, you can no longer force to specify cap_method="MINICAP" or "JAVACAP", screen_proxy will automatically initialize in order until the screenshot method that can be successfully initialized is selected .
    • For example, when connecting to the simulator before, you need to check use javacap on the IDE, or specify cap_method=JAVACAP when the script is running. Now it is not necessary to specify it, and it can be initialized successfully.
    • Deleted the parameter cap_method=MINICAP_STREAM, please do not pass the value of MINICAP_STREAM again
    • The priority order of initialization is custom screenshot method > MINICAP > JAVACAP > ADBCAP. If ADBCAP is called, a warning will be printed to tell the user that the screenshot efficiency is very low at this time.
    • Keep some of the old call entry points, which is convenient to be compatible with the old code
      • For example, dev.minicap will return the dev.screen_proxy object, and the dev.minicap.get_frame_from_stream() interface can still be used
      • For example, dev.cap_method will return the name of the currently used screenshot method (such as "MINICAP"), and you can also use dev.cap_method = "JAVACAP" to force the specified screenshot method
  • When acquiring pictures, there is no need to perform a lot of type judgment and then call the corresponding screenshot method
    • Use dev.screen_proxy.get_frame_from_stream() directly
    • That is, the previous code can be discarded:
    • if dev.cap_method == CAP_METHOD.MINICAP:
          dev.minicap.get_frame_from_stream()
      elif dev.cap_method == xxx:
          ...
      
  • If you want to implement a new custom screenshot method: In airtest.core.android.cap_methods.base_cap, the base class BaseCap, which implements all screenshot methods, can be inherited and implement the interface get_frame_from_stream. A custom screenshot method can be added, and it can be used by registering it in ScreenProxy
    • from airtest.core.android.cap_methods.base_cap import BaseCap
      class TestCap(BaseCap):
          def get_frame_from_stream(self):
              return b"frame"
      
      ScreenProxy.register_method("TESTCPY", TestCap)
      # The default priority is initialized to the custom TestCap
      cap = ScreenProxy.auto_setup(dev.adb)
      

Other bug fixes

  • nbsp added an auto_kill parameter, which can automatically kill the socket when the phone is disconnected to avoid memory leaks
  • Solved several warnings that did not completely close the io stream at the end
  • Compatible with / at the end of the script path passed in when the script is running
  • The SIFT algorithm patent has been lifted, so the SIFT algorithm has been re-added as the default algorithm, but it is limited by the version number of OpenCV. Not all version numbers can be used directly https://github.com/AirtestProject/Airtest/commit/c8e9bba038b3bb1b5201bb336b5f99a1f5f7c71a
  • Fixed an issue where the display_info size obtained in landscape mode was reversed on some new models of mobile phones. This issue would cause the screen to display incorrectly in landscape mode on the IDE https://github.com/AirtestProject/Airtest/pull/913/commits/9bcccdf06485b0121df2adf504f95693e9af3825
    • Many models have been tested to fix this problem (such as vivo iQOO Neo5, Huawei Mate40Pro, etc.)
    • If there are still models with the wrong display when the screen is rotated horizontally and vertically, please tell us the specific model
Airtest - 1.1.10-1.1.11

Published by yimelia over 3 years ago

  • pypi打包版本补充了缺失的ios资源文件

  • py2不再要求安装facebook-wda库,避免了安装过程中可能因为第三方库依赖py3而报错(airtest的ios模块,在py2下无法使用)

  • 修复了在极少数情况下可能会获取不到手机渲染分辨率,导致获取的手机尺寸为0的问题

  • rotationwatcher.jar缩减包体大小到7kb

  • 恢复了iOS手机端口转发功能,可以使用iOS上面的unity-poco了(linux下如果是ubuntu,可以运行apt-get install libusbmuxd-tools)

  • 增加了一个自动chmod +x的操作,能自动为adb和iproxy文件增加可执行权限

  • 修正了一些wda兼容性的问题

  • The pypi packaged version supplements the missing ios resource files

  • py2 no longer requires the installation of the facebook-wda library, which avoids errors that may be reported during the installation process due to third-party libraries relying on py3 (airtest's ios module cannot be used under py2)

  • Fixed the issue that in rare cases the rendering resolution of the phone may not be obtained, resulting in the size of the obtained phone being 0

  • rotationwatcher.jar reduces the package size to 7kb

  • The port forwarding function of iOS mobile phones has been restored, and unity-poco on iOS can be used (if it is ubuntu under linux, you can run apt-get install libusbmuxd-tools)

  • Added an automatic chmod +x operation, which can automatically increase executable permissions for adb and iproxy files

  • Fixed some wda compatibility issues

Airtest -

Published by yimelia over 3 years ago

新增功能或优化项

  • 重新恢复iOS的端口转发功能,能够对本机USB线连接的iOS上的端口进行转发,也就是说,目前恢复了iOS上面的Unity-Poco的支持
    • 请mac用户在使用本功能时,最好安装iproxy,在终端中运行:brew install usbmuxd
  • 新手机初始化的时候,去掉了RotationWatcher.apk的安装,减少一个安装程序
  • 优化了图像识别算法在使用rgb=True参数时的效果,现在能够更好地识别出不同颜色图片了

BUG修复:

  • log的时间改为24小时制
  • 修复了ios swipe接口遗漏了一个参数的BUG
  • 修复了adb.file_size不能正确获取到文件大小的bug
  • 在大于python3.7的环境中,由于opencv图像算法的版权问题,导致有部分算法不能使用,因此把默认使用的算法都改为可用的算法,删除了报错日志

New features or optimization items

  • Restore the iOS port forwarding function, which can forward the port on iOS connected with the USB cable of the machine, that is to say, the support of Unity-Poco on iOS has been restored.
    • When using this function for mac users, it is best to install iproxy and run in the terminal: brew install usbmuxd
  • When the new phone is initialized, the installation of RotationWatcher.apk is removed, reducing one installation procedure
  • Optimized the effect of the image recognition algorithm when using the rgb=True parameter, and now it can better recognize pictures with different colors

BUG fix:

  • The log time is changed to a 24-hour system
  • Fixed a bug where a parameter was missing from the ios swipe interface
  • Fixed the bug that adb.file_size could not get the file size correctly
  • In an environment greater than python3.7, due to the copyright issue of the opencv image algorithm, some of the algorithms cannot be used, so all the algorithms used by default are changed to available algorithms, and the error log is deleted
Airtest -

Published by yimelia over 3 years ago

iOS模块全面迭代

重做了airtest/core/ios模块,主要改动如下:

  • 支持Appium的WebDriverAgent工具,因此能够支持更新版本的iOS(>=14)以及新版本的xcode

  • Appium的WebDriverAgent与我们的iOS-Tagent,只需要选择其中一个部署即可,若原先已经部署了iOS-Tagent,请更新至最新版本

  • 重要: 由于facebook-wda只支持python3,因此假如想升级到这个版本,更好地使用ios模块以及下方提及的接口的话,必须使用python3

  • 新增了弹窗相关接口:

    • alert_accept :适用于拥有2个按钮的iOS弹窗,会点击弹窗右边的按钮,通常是“同意”或者“好”

      • from airtest.core.ios.ios import IOS, wda
        ios = IOS("http://localhost:8100/")
        
        # 点击弹窗右边的按钮
        ios.alert_accept()
        
    • alert_dismiss:适用于拥有2个按钮的iOS弹窗,会点击弹窗左边的按钮,例如“不同意”

      • from airtest.core.ios.ios import IOS, wda
        ios = IOS("http://localhost:8100/")
        
        # 点击弹窗左边的按钮
        ios.alert_dismiss()
        
    • alert_buttons:以列表形式返回弹窗的按钮文字

      • # 返回设备弹窗的按钮的文字
        ios.alert_buttons()
        
    • alert_click:点击弹窗上的指定按钮

      • # 点击弹窗上面的指定按钮,可传入列表按顺序查找
        ios.alert_click(['设置', '允许', '好'])
        
    • alert_exists:判断弹窗是否存在

      • ios.alert_exists()
        
    • alert_watch_and_click:监控弹窗出现并点击指定按钮

      • from airtest.core.ios.ios import IOS, wda
        ios = IOS("http://localhost:8100/")
        
        # 默认情况下监控此类弹窗:["使用App时允许", "好", "稍后", "稍后提醒", "确定", "允许", "以后"]
        with ios.alert_watch_and_click():
            sleep(5)
            
        # 监控指定弹窗出现并点击
        with ios.alert_watch_and_click(["Cancel"]):
            sleep(5)
            
        # 设置监控的时间间隔为2.0s
        with ios.alert_watch_and_click(interval=2.0):
            sleep(5)
        
    • alert.text: 返回弹窗上面的描述文字

      • # 返回弹窗上面的描述文字
        print(ios.driver.alert.text)
        
  • keyevent接口增加音量控制事件

    • 支持使用 keyevent 接口对iOS设备的音量进行加减控制:

    • # 音量增加
      keyevent("volumeUp")
      
      # 音量减少
      keyevent("volumeDown")
      
  • app_state接口返回包体状态

    • dev = device()
      start_app('com.apple.mobilesafari')
      print(dev.app_state('com.apple.mobilesafari')["value"])  # --> output is 4
      home()
      print(dev.app_state('com.apple.mobilesafari')["value"])  # --> output is 3
      stop_app('com.apple.mobilesafari')
      print(dev.app_state('com.apple.mobilesafari')["value"])  # --> output is 1
      
  • app_current返回当前运行应用

    • print(ios.app_current())
      # output is {"pid": 1281,
      		     "name": "",
      		     "bundleId": "com.netease.cloudmusic"}
      
  • 加锁相关接口

    • is_locked 当前是否锁屏

    • unlock 解锁设备

    • lock 为设备锁屏

    • from airtest.core.ios.ios import IOS, wda
      ios = IOS("http://localhost:8100/")
      
      # 判断当前iOS设备是否上锁
      print(ios.is_locked())
      ios.unlock()
      ios.lock()
      
  • device_info 返回设备信息

    • print(ios.device_info())
      >>> AttrDict({
                      'timeZone': 'GMT+0800',
                      'currentLocale': 'zh_CN',
                      'model': 'iPhone',
                      'uuid': '90CD6AB7-11C7-4E52-B2D3-61FA31D791EC',
                      'userInterfaceIdiom': 0,
                      'userInterfaceStyle': 'light',
                      'name': 'iPhone',
                      'isSimulator': False})
      
  • home_interface 判断是否在home桌面

    • print(ios.home_interface())
      
  • 其他ios相关的bug修复和优化:

    • 修复了部分设备在屏幕旋转时,屏幕画面显示异常、点击位置错误的问题,以及在poco框选节点时,框选位置错误的问题
    • 优化了同时有多个进程连接单个ios时的表现和连接稳定性,略微加快了点击和滑动操作的速度。另外部分设备(例如ipad, 6P/7P/8P)的操作速度会比别的型号手机更慢,这些型号的设备在竖屏情况下使用体验会更好

BUG FIX

  1. 如果minicap没有成功启动、或是RotationWatcher.apk没安装成功,就换用adb获取ori信息,新增了使用ADB线程不断获取ori信息的逻辑 1b85fc7
  2. 如果ori_method运行失败、Yosemite.apk安装失败(如果已经安装过旧版,允许跳过安装),也能保证基础功能的运行 b1c8568 f1f095c
  3. 修复上个版本引入的问题,py2下不能正常截图 a6e8f68

iOS module full iteration

Reworked the airtest/core/ios module, the main changes are as follows:

  • Support Appium's WebDriverAgent tool, so it can support updated versions of iOS (>=14) and new versions of xcode

  • Appium’s WebDriverAgent and our iOS-Tagent, you only need to choose one of them to deploy. Yes, if iOS-Tagent is already deployed, please update to the latest version

  • Important: Since facebook-wda only supports python3, if you want to upgrade to this version and better use the ios module and the interfaces mentioned below, you must use python3

  • Added pop-up related interfaces:

    • alert_accept: Applicable to iOS pop-up windows with 2 buttons, you will click the button on the right side of the pop-up window, usually "Agree" or "OK"

      • from airtest.core.ios.ios import IOS, wda
        ios = IOS("http://localhost:8100/")
        
        ios.alert_accept()
        
    • alert_dismiss: Applicable to iOS pop-up windows with 2 buttons, you will click the button on the left side of the pop-up window, such as "disagree"

      • from airtest.core.ios.ios import IOS, wda
        ios = IOS("http://localhost:8100/")
        
        ios.alert_dismiss()
        
    • alert_buttons: return the button text of the pop-up window as a list

      • ios.alert_buttons()
        
    • alert_click: Click the specified button on the pop-up window

      • # Click the specified button on the pop-up window, you can enter the list and search in order
        ios.alert_click(['Settings','Allow','OK'])
        
    • alert_exists: Determine whether the pop-up window exists

    • alert_watch_and_click: The monitoring pop-up window appears and click the specified button

      • from airtest.core.ios.ios import IOS, wda
        ios = IOS("http://localhost:8100/")
        
        # This type of pop-up window is monitored by default: ["Allow when using App", "OK", "Later", "Remind later", "OK", "Allow", "Later"]
        with ios.alert_watch_and_click():
            sleep(5)
            
        # Monitor the specified pop-up window appears and click
        with ios.alert_watch_and_click(["Cancel"]):
            sleep(5)
            
        # Set the monitoring interval to 2.0s
        with ios.alert_watch_and_click(interval=2.0):
            sleep(5)
        
    • alert.text: Return the description text on the pop-up window

      • print(ios.driver.alert.text)
        
  • keyevent interface adds volume control events

    • Support using the keyevent interface to control the volume of iOS devices:

    • # 音量增加
      keyevent("volumeUp")
      
      # 音量减少
      keyevent("volumeDown")
      
  • The app_state interface returns the package state

    • dev = device()
      start_app('com.apple.mobilesafari')
      print(dev.app_state('com.apple.mobilesafari')["value"])  # --> output is 4
      home()
      print(dev.app_state('com.apple.mobilesafari')["value"])  # --> output is 3
      stop_app('com.apple.mobilesafari')
      print(dev.app_state('com.apple.mobilesafari')["value"])  # --> output is 1
      
  • Lock related interface

    • is_locked whether the screen is currently locked

    • unlock to unlock the device

    • lock to lock the device screen

    • from airtest.core.ios.ios import IOS
      ios = IOS("http://localhost:8100/")
      
      # Determine whether the current iOS device is locked
      print(ios.is_locked())
      ios.unlock()
      ios.lock()
      
  • device_info returns device information

    • print(ios.device_info())
      >>> AttrDict({
                      'timeZone': 'GMT+0800',
                      'currentLocale': 'zh_CN',
                      'model': 'iPhone',
                      'uuid': '90CD6AB7-11C7-4E52-B2D3-61FA31D791EC',
                      'userInterfaceIdiom': 0,
                      'userInterfaceStyle': 'light',
                      'name': 'iPhone',
                      'isSimulator': False})
      
  • home_interface determines whether it is on the home desktop

    • print(ios.home_interface())
      
  • Other iOS related bug fixes and optimizations:

    • Fixed the problem of abnormal screen display and wrong click position when the screen is rotated on some devices, and the wrong position of the box selection when selecting nodes in poco
    • Optimized the performance and connection stability when there are multiple processes connected to a single ios at the same time, and slightly accelerated the speed of clicking and sliding operations. In addition, the operating speed of some devices (such as ipad, 6P/7P/8P) will be slower than other models of mobile phones, and these models will have a better experience in portrait mode.

BUG FIX

  1. If minicap is not successfully started or RotationWatcher.apk is not installed successfully, use adb to obtain ori information, and add the logic of using ADB thread to continuously obtain ori information [1b85fc7](https://github.com /AirtestProject/Airtest/commit/1b85fc7c26813e0b6c429cadb48adef5362943ed)
  2. If ori_method fails to run and Yosemite.apk fails to install (if you have already installed the old version, you can skip the installation), it can also ensure the operation of basic functions [b1c8568](https://github.com/AirtestProject/Airtest/ commit/b1c8568792bd710674a64c6a45b0566dafde1a60) f1f095c
  3. Fix the problem introduced in the previous version, the screenshot cannot be taken normally under py2 a6e8f68
Airtest - v1.1.7 update

Published by yimelia almost 4 years ago

新增功能与重要API调整:

  1. 目前可以自由选择是否保存脚本运行过程中的截图了,方式如下:
  • 在命令行airtest run xx.air的时候,新增一个参数 --no-image ,只要在运行时传入这个参数,就能够在任务运行过程中不再保存截图 https://github.com/AirtestProject/Airtest/commit/2ed128c201be94d1fda0f364641296bec7e68a52 , 示例:

    airtest run test.air --device Android:/// --log logs/ --no-image
    
  • 目前settings新增了一个配置ST.SAVE_IMAGE ,默认为True, 如果改为False,就不保存截图,直到这个值再次设为True,示例:

from airtest.core.api import *
# 暂时关闭截图
ST.SAVE_IMAGE = False
touch((100, 100))  # 这条语句将不会保存当前画面图片

# 继续截图
ST.SAVE_IMAGE = True
touch((100, 100))
  • 命令行传入--no-image参数时,实际上也是将ST.SAVE_IMAGE设为False,因此第二种方式会更加灵活,大家可以在脚本运行过程中自由决定当前是否要保存图片
  1. 当调用log()接口来保存对应log到报告中时,也同时将它print到当前终端,方便查看。 https://github.com/AirtestProject/Airtest/commit/b7d98f640fb3ddad339efe2617270488e8ec83c6

  2. 去掉了requirements.txtopencv-contrib-python的版本依赖,目前python3.8和python3.9都能安装了

注意:python3.9如果安装完毕还不能使用airtest,报错ImportError: numpy.core.multiarray failed to import,可以手工将numpy版本号降级至1.19.3就能使用了。

  1. Android的录屏接口start_recording修改了参数,增加了一个更简单的bit_rate_level,可以设置1-5的清晰度级别,默认为1,数字越大会越清晰 https://github.com/AirtestProject/Airtest/pull/834/commits/2220863d9f82e066c9543b3a1f34d7242fdd75c4 , 示例:

    from airtest.core.api import connect_device, sleep
    dev = connect_device("Android:///")
    # Record the screen with the lowest quality
    dev.start_recording(bit_rate_level=1)
    sleep(30)
    dev.stop_recording(output="test.mp4")
    

    更多示例,请参考文档

  2. 重新整理了LogToHtml里面路径相关的参数logfilelogdir,现在支持通过修改ST.LOG_DIRST.LOG_FILE,来自主设置log文件夹和log.txt的文件名。修改完毕后,还可以直接用LogToHtml生成报告,同时简化了参数的传递 https://github.com/AirtestProject/Airtest/pull/834/commits/a4b43cb824d9d99855d80a0055ba09694889744c , 示例:

    from airtest.report.report import LogToHtml
    # 假设脚本为当前目录下的run.air, log目录为当前目录下的./log
    # 默认将认为log存放在ST.LOG_DIR中,如果ST.LOG_DIR为空,则尝试寻找当前目录下的log文件夹
    rpt = LogToHtml("test.air")
    rpt.report()
    

    自定义ST.LOG_DIRST.LOG_FILE的示例:

    from airtest.core.helper import set_logdir
    new_logfile = "log123.txt"
    new_logdir = "./logs_new"
    # set logfile = ./logs_new/log123.txt
    ST.LOG_FILE = new_logfile
    set_logdir(new_logdir)
    
    # ...
    
    rpt = LogToHtml("test.air")
    # LogToHtml将会默认选择ST.LOG_FILE作为logfile,ST.LOG_DIR作为log_root,生成对应的log.html内容
    rpt.report()
    

修复以下bug:

  1. 修复在log()接口中,如果desc包含关键词assert,可能会导致步骤被错误认定为assert步骤的问题 https://github.com/AirtestProject/Airtest/commit/bfa4617058afa97feeac44ac3ada5054fab295c0
  2. 修复了一个报告中缩略图没有被正确缩小的BUG(之前报告缩略图一般都只有3-5K大小,上个版本有问题,缩略图还是正常图片的大小) https://github.com/AirtestProject/Airtest/commit/39dc8346baa262050f12ae5596be34112079f030
  3. 修复了在高版本android手机中,adb.start_app_timing获取不到app启动时间的问题 https://github.com/AirtestProject/Airtest/commit/002a17077a846010eec69093bfe42abdb094035f
  4. 修复了get_top_activity在获取含有$符号的包名时会报错的问题(java允许命名时出现$符号) https://github.com/AirtestProject/Airtest/commit/c9e00e878c7aef6f0cc4f5ff2faa9caf82ae5c4f
  5. adb.file_size更换了获取文件大小的命令,兼容更低版本的android手机,顺便修改了minitouch和maxtouch的安装过程,更简洁一点 https://github.com/AirtestProject/Airtest/commit/75e4665d2dcfc14993a1a8935fba6112dfa2fbb6
  6. 修复了多线程同时截图时的generator already executing报错 https://github.com/AirtestProject/Airtest/commit/3a69dc89ac6f4b797e5175a057121f05b94892f8
  7. 在获取sdk版本时偶尔会失败,尝试增加重试次数,但是是否修复此问题还有待观察 https://github.com/AirtestProject/Airtest/commit/ac08555a75eccb392fc0a6e9bf2642717dc12124
  8. 修复部分手机初始化minitouch失败的问题,因为会有额外的log,导致正则匹配失败 https://github.com/AirtestProject/Airtest/commit/ece127b09ca3ea5b55a7b4ee9bfd8d604b834b47
  9. 初始化RotationWatcher的时机改为在get_display_info的时候,避免在特殊情况下,因为它没有及时初始化,导致横竖屏转换时不能正确获取屏幕信息的问题。(假设连手机时是竖屏,开始运行后切换成了横屏,接下来运行纯poco脚本的click语句,就会导致点击位置横竖屏错误。因为poco语句在点击时不涉及截图,导致没有走到rotationwatcher的初始化逻辑里。) https://github.com/AirtestProject/Airtest/pull/834/commits/1ec622364e3a1ac780629245d4a1b7c8c3314ee9
  10. Android.get_top_activity_name_and_pid的功能与get_top_activity重复,因此删除一个。 https://github.com/AirtestProject/Airtest/pull/834/commits/1df9afc0bde7720d408435e99e90f5506aecd6a3

New features and important API adjustments:

  1. At present, you can freely choose whether to save the screenshot during the script running process or not. The method is as follows:
  • In the command line airtest run xx.air, a new parameter --no-image is added. As long as this parameter is passed in at runtime, the screenshot can no longer be saved during the task run https:// github.com/AirtestProject/Airtest/commit/2ed128c201be94d1fda0f364641296bec7e68a52, example:
airtest run test.air --device Android:/// --log logs/ --no-image
  • Currently there is a new configuration ST.SAVE_IMAGE in settings, the default is True, if it is changed to False, the screenshot will not be saved until the value is set to True again, example:
from airtest.core.api import *
# Temporarily close the screenshot
ST.SAVE_IMAGE = False
touch((100, 100)) # This statement will not save the current screen picture

# Continue to take screenshot
ST.SAVE_IMAGE = True
touch((100, 100))
  • When passing the --no-image parameter from the command line, it actually sets ST.SAVE_IMAGE to False, so the second method will be more flexible. You can freely decide whether the current script is currently running or not. To save the picture
  1. When calling the log() interface to save the corresponding log to the report, it will also be printed to the current terminal for easy viewing. https://github.com/AirtestProject/Airtest/commit/b7d98f640fb3ddad339efe2617270488e8ec83c6

  2. Removed the version dependency of opencv-contrib-python in requirements.txt, currently both python3.8 and python3.9 can be installed.

Note: If you cannot use airtest after installing python3.9, you will get an error of ImportError: numpy.core.multiarray failed to import, you can manually downgrade the numpy version number to 1.19.3 to use it.

  1. Android’s Screen Recording Interface, start_recording has modified the parameters and added a simpler bit_rate_level, which can set the clarity level from 1-5, the default is 1, the larger the number, the clearer it will be (https://github.com/AirtestProject/Airtest/pull/834/commits/2220863d9f82e066c9543b3a1f34d7242fdd75c4), example:
from airtest.core.api import connect_device, sleep
dev = connect_device("Android:///")
# Record the screen with the lowest quality
dev.start_recording(bit_rate_level=1)
sleep(30)
dev.stop_recording(output="test.mp4")

For more examples, please refer to document

  1. Reorganized the path-related parameters logfile and logdir in LogToHtml, and now supports modifying ST.LOG_DIR and ST.LOG_FILE, from the main settings log folder and the file name of log.txt. After modification, you can also directly use LogToHtml to generate a report, and at the same time simplify the transfer of parameters (https://github.com/AirtestProject/Airtest/pull/834/commits/a4b43cb824d9d99855d80a0055ba09694889744c), example:
from airtest.report.report import LogToHtml
# Assuming that the script is run.air in the current directory, and the log directory is ./log in the current directory
# By default, log will be considered to be stored in ST.LOG_DIR, if ST.LOG_DIR is empty, try to find the log folder in the current directory
rpt = LogToHtml("test.air")
rpt.report()

Examples of customizing ST.LOG_DIR and ST.LOG_FILE:

from airtest.core.helper import set_logdir
new_logfile = "log123.txt"
new_logdir = "./logs_new"
# set logfile = ./logs_new/log123.txt
ST.LOG_FILE = new_logfile
set_logdir(new_logdir)

# ...

rpt = LogToHtml(OWL)
# LogToHtml will select ST.LOG_FILE as logfile and ST.LOG_DIR as log_root by default, and generate the corresponding log.html content
rpt.report()

Fix the following bugs:

  1. Fix the problem that if desc contains the keyword assert in the log() interface, the step may be incorrectly identified as an assert step https://github.com/AirtestProject/Airtest/commit/bfa4617058afa97feeac44ac3ada5054fab295c0
  2. Fixed a bug where the thumbnails in a report were not correctly reduced (the thumbnails of the previous reports were generally only 3-5K in size, there was a problem with the previous version, the thumbnails were still the size of normal pictures) https://github.com/ AirtestProject/Airtest/commit/39dc8346baa262050f12ae5596be34112079f030
  3. Fixed the issue that adb.start_app_timing could not get app start time in high version android phones https://github.com/AirtestProject/Airtest/commit/002a17077a846010eec69093bfe42abdb094035f
  4. Fixed the problem that get_top_activity would report an error when obtaining the package name containing the $ symbol (java allows the $ symbol to appear when naming it) https://github.com/AirtestProject/Airtest/commit/c9e00e878c7aef6f0cc4f5ff2faa9caf82ae5c4f
  5. adb.file_size has replaced the command to obtain the file size, compatible with lower versions of android phones, and modified the installation process of minitouch and maxtouch by the way to be more concise https://github.com/AirtestProject/Airtest/commit/75e4665d2dcfc14993a1a8935fba6112dfa2fbb6
  6. Fixed the error of generator already executing when taking screenshots from multiple threads at the same time https://github.com/AirtestProject/Airtest/commit/3a69dc89ac6f4b797e5175a057121f05b94892f8
  7. It occasionally fails when getting the SDK version, try to increase the number of retries, but it remains to be seen whether this problem is fixed https://github.com/AirtestProject/Airtest/commit/ac08555a75eccb392fc0a6e9bf2642717dc12124
  8. Fix the problem that some mobile phones failed to initialize minitouch, because there will be extra logs, causing regular matching to fail https://github.com/AirtestProject/Airtest/commit/ece127b09ca3ea5b55a7b4ee9bfd8d604b834b47
  9. The timing of initializing RotationWatcher is changed to when get_display_info, to avoid the problem that the screen information cannot be correctly obtained during the horizontal and vertical screen conversion because it is not initialized in time under special circumstances. (Assuming that the phone is connected to the vertical screen and switched to the horizontal screen after starting to run, then running the click statement of the pure poco script will cause the click position to be wrong. Because the poco statement does not involve screenshots when clicking, it does not go Into the initialization logic of rotationwatcher.) https://github.com/AirtestProject/Airtest/pull/834/commits/1ec622364e3a1ac780629245d4a1b7c8c3314ee9
  10. The function of Android.get_top_activity_name_and_pid is duplicated with get_top_activity, so delete one. https://github.com/AirtestProject/Airtest/pull/834/commits/1df9afc0bde7720d408435e99e90f5506aecd6a3
Airtest - v1.1.5-1.1.6 update

Published by yimelia about 4 years ago

新功能与接口改动:

  1. 增加了对Android 11的支持

  2. 在脚本中用于记录log的log()接口进行了大幅度改动,支持4个参数:arg, timestamp=None, desc="", snapshot=False,(https://github.com/AirtestProject/Airtest/commit/777b5ffe51cfc41c7c05b3bcf289edc38f861774
    https://github.com/AirtestProject/Airtest/commit/77a4893be37bb7a3094171af27993fb6b593a0c1https://github.com/AirtestProject/Airtest/pull/802/commits/ced1201bbf1a3c244e7a5f5131b684b19b37b18a ),删掉了原先的trace参数

  • args 可以是字符串或是traceback对象,现在还支持传入非字符串,并且对py2做了一下兼容。假如传入的是traceback对象,将会自动在报告中标记为报错步骤,否则就是显示正常的log内容
  • timestamp参数可以自定义当前这条log的时间戳,默认为当前时间(在记录一些长时间的回调中获取到的log时,原本默认使用写入本条log的时间,但是可能需要修改为log产生的时间,比如几分钟前)
  • desc 自定义一个log标题,在报告中有更好的展示效果
  • snapshot 是否需要截取一张当前的屏幕图像并显示到报告中,方便查看。(同时,因为这个参数的加入,现在airtest脚本如果因为执行Poco语句失败报错而终止时,能够额外截取一张当前画面,方便大家排查问题。)
  • 调用示例:
data = {"test": 123, "time": 123456}
log(data, timestamp=time.time(), desc="title", snapshot=True)
try:
    1/0
except Exception as e:
    log(e, snapshot=True)
log("中文")

  1. 新增一个设置ST.IMAGE_MAXSIZE,用于指定截图的最大尺寸,假如设置为1200,则最后保存的截图长宽都都不会超过1200,有利于进一步缩小截图的图片尺寸。 https://github.com/AirtestProject/Airtest/pull/802/commits/ffe7ebc5ad92dcb7139d0f91437658c8518da886

同时,对于单张截图精度和全局截图精度也支持自定义 https://github.com/AirtestProject/Airtest/commit/31e40122e723a36cc23e13716a48d336069a73ea:

  • snapshot接口支持传入quality参数,单独指定本次截图的图像精度
  • 目前可以使用ST.SNAPSHOT_QUALITY = xx 设置全局截图精度,在运行脚本时,报告的步骤截图也会采用这个数值进行压缩,默认为10

调用示例:

# 默认截图质量为10,这里设置截图质量为30
ST.SNAPSHOT_QUALITY = 30
# 设置截图尺寸不超过600*600,如果不设置,默认为原图尺寸
ST.IMAGE_MAXSIZE = 600

touch(xx)  # touch语句保存的截图质量为30, 尺寸不超过600*600
snapshot(filename="test.png", msg="test", quality=90)  # 本条语句截图质量为90
snapshot(filename="test2.png", msg="test", quality=90, max_size=1200)  # 截图质量为90,尺寸不超过1200*1200
snapshot(msg="test12")  # 不设置的情况下,默认采用ST中的全局变量的数值

  1. playground/android_motionevents.py里面提供了一些Android自定义手势的示例代码,现在直接调用dev.touch_proxy.perform接口就可以传入写好的MoveEvent列表来进行自定义的滑动了(以前是调用dev.minitouch.perform,如果是安卓10就会不兼容)。

调用示例:

from airtest.core.android.touch_methods.base_touch import *
# tap with two fingers
multitouch_event = [
    DownEvent((100, 100), 0),
    DownEvent((200, 200), 1),  # second finger
    SleepEvent(1),
    UpEvent(0), UpEvent(1)]

device().touch_proxy.perform(multitouch_event)

更多示例请参见:https://github.com/AirtestProject/Airtest/blob/master/playground/android_motionevents.py


  1. (仅限安卓手机)在运行脚本时如果需要录制屏幕,可以传入--recording 录屏文件名.mp4来指定录屏文件
  • 如果只传了--recording,默认将会使用recording_手机序列号.mp4来命名录屏文件
  • 如果指定了文件名--recording test.mp4,且超过一台手机,就命名为 手机序列号_test.mp4
  • 如果指定了文件名--recording test.mp4,且只有一台手机,就命名为 test.mp4
  • 注意传入的文件名必须以mp4作为结尾

BUG修复

  1. iOS修复了上个版本stopapp失效的问题 https://github.com/AirtestProject/Airtest/commit/6bf146becc56b2737288941d0771b013d183bc96

  2. 回退了屏幕录制代码到1.0.27之前的版本,取消使用yosemite.apk来录屏,避免每次重装过yosemite.apk后必须要手工赋予录屏权限才能录屏的问题

  3. 在一些无法使用minicap的手机上,虽然指定了Javacap模式也能截屏,但是在调用get_display_info的时候依然调用到minicap.get_display_info,如果没有指定ori_methodadbori,会导致脚本无法运行成功。 因此修改为假如获取屏幕信息失败,自动调整为使用adbori模式来获取当前屏幕信息。 https://github.com/AirtestProject/Airtest/commit/9312f0d52a6dbf28a9b84ed51e338686d68ed875
    https://github.com/AirtestProject/Airtest/pull/802/commits/469fa829ca1c593b16e87ba60c8982c4c868cc14

  4. 在脚本中一旦对同一台手机运行了不止一次connect_device接口,并指定了不同的设备连接参数时,G.DEVICE不会更新到最新参数创建出来的设备对象,导致部分手机可能连接失败。现在改为每次更新设备对象时,也会自动更新一下G.DEVICE https://github.com/AirtestProject/Airtest/commit/c163a4f46b95c9ad758fa666cf113696bbe7ce6d

  5. 修复了在高版本Android手机上,get_ip_address()接口不能正确获取到手机IP的问题 https://github.com/AirtestProject/Airtest/pull/802/commits/e4d76254f17850b927288fe09a6d0356951a4f2a

  6. (暂未完全修复,请等待下个版本更新)修复了查找图片时,指定RGB属性没生效的问题: https://github.com/AirtestProject/Airtest/pull/802/commits/f2e84a06e90d1e97fc15cec0f2507198c79faf25

  7. 去掉了assert_exists接口使用特殊的ST.THRESHOLD_STRICT值作为找图阈值的设定。假如之前设置了ST.THRESHOLD_STRICT将会继续沿用该数值,但是如果没有设置的话,默认与其他图片一样都使用指定的threshold参数,或是全局的ST.THRESHOLD,这样能够方便统一设置和管理,也不容易造成误解。https://github.com/AirtestProject/Airtest/pull/802/commits/0045c9bcd074f19e2084f864428eb165d5e10c59


New features and interface changes

  1. Added support for Android 11

  2. The log() interface used to log logs in the script has been greatly changed, supporting 4 parameters: arg, timestamp=None, desc="", snapshot=False, deleted the original parameters.
    https://github.com/AirtestProject/Airtest/commit/777b5ffe51cfc41c7c05b3bcf289edc38f861774
    https://github.com/AirtestProject/Airtest/commit/77a4893be37bb7a3094171af27993fb6b593a0c1
    https://github.com/AirtestProject/Airtest/pull/802/commits/ced1201bbf1a3c244e7a5f5131b684b19b37b18a

  • Args can be a string or a traceback object, and now supports non-string input, and is compatible with py2. If the traceback object is passed in, it will be automatically marked as an error step in the report, otherwise the normal log content will be displayed
  • The timestamp parameter can customize the timestamp of the current log, and the default is the current time (when recording the log obtained in some long-term callbacks, the time written to this log was originally used by default, but it may need to be modified to The time when the log was generated, such as a few minutes ago)
  • desc customize a log title for better display in the report
  • snapshot Whether it is necessary to take a screenshot of the current screen image and display it in the report for easy viewing. (At the same time, because of the addition of this parameter, if the airtest script terminates due to a failure to execute the Poco statement and an error is reported, it can take an additional screenshot of the current screen to facilitate troubleshooting.)
  • Call example:
data = {"test": 123, "time": 123456}
log(data, timestamp=time.time(), desc="title", snapshot=True)
try:
    1/0
except Exception as e:
    log(e, snapshot=True)
log("中文")

  1. A new setting ST.IMAGE_MAXSIZE is added to specify the maximum size of the screenshot. If it is set to 1200, the height and width of the final saved screenshot will not exceed 1200, which is helpful to further reduce the screenshot image size. https://github.com/AirtestProject/Airtest/pull/802/commits/ffe7ebc5ad92dcb7139d0f91437658c8518da886

At the same time, it also supports customization for single screenshot accuracy and global screenshot accuracy https://github.com/AirtestProject/Airtest/commit/31e40122e723a36cc23e13716a48d336069a73ea:

  • snapshot interface supports passing in quality parameter to individually specify the image accuracy of this screenshot
  • Currently you can use ST.SNAPSHOT_QUALITY = xx to set the global screenshot accuracy. When running the script, the step screenshots of the report will also be compressed using this value

Example:

# Set the screenshot quality to 30
ST.SNAPSHOT_QUALITY = 30
# Set the screenshot size not to exceed 600*600, if not set, the default size is the original image size
ST.IMAGE_MAXSIZE = 600

touch(xx) # The quality of the screenshot saved by the touch statement is 30, and the size does not exceed 600*600
snapshot(filename="test.png", msg="test", quality=90) # The quality of the screenshot of this sentence is 90
snapshot(filename="test2.png", msg="test", quality=90, max_size=1200) # The quality of the screenshot is 90, and the size does not exceed 1200*1200
snapshot(msg="test12") # If not set, the value of the global variable in ST is used by default

  1. playground/android_motionevents.py provides some sample codes for Android custom gestures, now you can directly call the dev.touch_proxy.perform interface to pass in the written MoveEvent list for customization Sliding (previously it was called dev.minitouch.perform, if it is Android 10, it will not be compatible).

Call example:

from airtest.core.android.touch_methods.base_touch import *
# tap with two fingers
multitouch_event = [
    DownEvent((100, 100), 0),
    DownEvent((200, 200), 1), # second finger
    SleepEvent(1),
    UpEvent(0), UpEvent(1)]

device().touch_proxy.perform(multitouch_event)

For more examples, please see: https://github.com/AirtestProject/Airtest/blob/master/playground/android_motionevents.py


  1. (Android phones only) If you need to record the screen when running the script, you can pass in --recording filename.mp4 to specify the screen file
  • If only --recording is passed, serial_number.mp4 will be used by default to name the screen recording file
  • If the file name --recording test.mp4 is specified, and there is more than one mobile phone, it will be named as the serialnumber_test.mp4
  • If the file name --recording test.mp4 is specified and there is only one mobile phone, it will be named test.mp4
  • Note that the incoming file name must end with mp4

BUG repair

  1. iOS fixes the issue of the failure of the previous version of stopapp https://github.com/AirtestProject/Airtest/commit/6bf146becc56b2737288941d0771b013d183bc96

  2. The screen recording code was rolled back to the version before 1.0.27, and the use of yosemite.apk to record the screen was cancelled to avoid the problem that the screen recording permission must be manually granted every time yosemite.apk is reinstalled.

  3. On some mobile phones that cannot use minicap, although the Javacap mode can also be used to take screenshots, when calling get_display_info, minicap.get_display_info is still called. If ʻori_method is not specified as ʻadbori, it will cause The script could not run successfully. Therefore, it is modified to automatically adjust to use ʻadbori` mode to obtain current screen information if it fails to obtain screen information.
    https://github.com/AirtestProject/Airtest/commit/9312f0d52a6dbf28a9b84ed51e338686d68ed875
    https://github.com/AirtestProject/Airtest/pull/802/commits/469fa829ca1c593b16e87ba60c8982c4c868cc14

  4. Once the connect_device interface is run on the same mobile phone more than once in the script, and different device connection parameters are specified, G.DEVICE will not be updated to the device object created with the latest parameters, which may cause some mobile phones Connection failed. Now it’s changed to automatically update G.DEVICE every time the device object is updated https://github.com/AirtestProject/Airtest/commit/c163a4f46b95c9ad758fa666cf113696bbe7ce6d

  5. Fixed the issue that the get_ip_address() interface could not obtain the phone IP correctly on high version Android phones https://github.com/AirtestProject/Airtest/pull/802/commits/e4d76254f17850b927288fe09a6d0356951a4f2a

  6. Fixed the problem that the specified RGB attribute did not take effect when searching for pictures: https://github.com/AirtestProject/Airtest/pull/802/commits/f2e84a06e90d1e97fc15cec0f2507198c79faf25

  7. Removed the assert_exists interface and uses the special ST.THRESHOLD_STRICT value as the setting of the image finding threshold. If ST.THRESHOLD_STRICT is set before, this value will continue to be used, but if it is not set, the specified threshold parameter or the global ST.THRESHOLD will be used by default like other pictures, which is convenient for unification Setting and management are not easy to cause misunderstanding. https://github.com/AirtestProject/Airtest/pull/802/commits/0045c9bcd074f19e2084f864428eb165d5e10c59

Airtest - v1.1.4版本更新

Published by yimelia over 4 years ago

Android API修改:

  • Android部分点击接口修改:
    将Android的点击代码进行了一些维护,对于以前一部分需要调用到Android.minitouch才能运行的接口(主要是pinch, swipe_along, two_finger_swipe),现在统一直接在Android层面进行调用:
old:
dev = device()
dev.minitouch.pinch()
dev.minitouch.swipe_along([(100, 300), (300, 300), (100, 500), (300, 600)])
dev.minitouch.two_finger_swipe( (100, 100), (200, 200) )
->
new:
dev = device()
dev.pinch()  # 双指捏合或分开
dev.swipe_along([(100, 300), (300, 300), (100, 500), (300, 600)])  # 连续滑过一系列坐标
dev.two_finger_swipe( (100, 100), (200, 200) )  # 两个手指一起滑动

更多调用代码示例与参数示例,可以参考:tests/test_android.py

  • 如果使用了自定义点击DownEvent/UpEvent/SleepEvent,请将import语句修改成如下内容:
old:
from airtest.core.android.minitouch import *
->
new:
from airtest.core.android.touch_methods.base_touch import *
  • 修复了部分型号的小米手机(主要是MIUI11版本)在横屏时使用javacap截图,会导致图像被不正确压缩的情况。

    • 请卸载手机上已有的Yosemite.apk,重新连接手机即可重装新版本的Yosemite.apk修复此问题。
      注: 若手机更新到MIUI12版本,无需使用javacap模式就能直接获取到手机屏幕了,建议大家直接更新系统
  • 修复了MIUI11+android10下,is_screenon(手机是否亮屏)和is_locked(手机是否锁屏)接口无法使用的bug

iOS部分修改:

  • 修复iOS部分机型横屏异常及提高启动应用的速度
  • iOS-Tagent对xcode的支持更新到11.5版本,iOS版本支持到13.5(最新版本的xcode目前暂时还有一些问题需要兼容)

Android API modification:

  • Modification of some click interfaces of Android:
    Performed some maintenance on the Android click code. For the previous part of the interface that needs to be called to Android.minitouch to run (mainly pinch, swipe_along, two_finger_swipe), it is now called directly at the Android level. like this:
old:
dev.minitouch.pinch()
dev.minitouch.swipe_along([(100, 300), (300, 300), (100, 500), (300, 600)])
dev.minitouch.two_finger_swipe( (100, 100), (200, 200) )
->
new:
dev.pinch()  # pinch or separate with two fingers
dev.swipe_along([(100, 300), (300, 300), (100, 500), (300, 600)])  # continuously slide through a series of coordinates
dev.two_finger_swipe( (100, 100), (200, 200) )  # Two fingers slide together

For more call code examples, you can refer to tests/test_android.py

  • If you used DownEvent/UpEvent/SleepEvent, please modify the import statement to the following:
old:
from airtest.core.android.minitouch import *
->
new:
from airtest.core.android.touch_methods.base_touch import *
  • Fixed an issue where some models of Xiaomi phones (mainly the MIUI11 version) used javacap to take incorrect screenshots in landscape mode.
    • Please uninstall the existing Yosemite.apk on your phone and reconnect the phone to reinstall the new version of Yosemite.apk to fix this problem.
      Note: If the mobile phone is updated to the MIUI12 version, you can directly get the mobile phone screen without using javacap mode. It is recommended that you update the system directly
  • Fixed the bug that the interfaces of is_screenon (whether the phone is bright) and is_locked (whether the phone is locked) under MIUI11+android10 cannot be used

iOS modification:

  • Fixed the horizontal screen abnormality of some iOS models and increase the speed of starting the application
  • iOS-Tagent support for xcode is updated to version 11.5, iOS version is supported to 13.5 (the latest version of xcode currently has some problems that need to be compatible)