由于测试应用不确定弹框较多,如果在脚本中判断很耗时间,因此修改 appium-uiautomator2-server 源码添加监听解决这个问题,目前实现了可配置式的监听,暂时只支持 text、resourceId、textContains、content-desc4 中查找方式,且只支持简单的点击操作,具体可以根据自己的需求进行扩展。
根据你所使用的 apppium 版本下载对应的 uiautomator2server 源码
在 utils 包下新建 WatcherUtils 类,用于读取配置文档中需要监听的内容
WatcherUtils 代码如下:
package io.appium.uiautomator2.utils;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
/**
* 监听工具类,用于读取配置文件中需要监听的内容
*/
public class WatcherUtils {
/**
* 读取配置文件
* @return
*/
public static List<String> readWatchers(){
List<String> watcherList = new ArrayList<>();
String encoding = "GBK";
File file = new File("/data/local/tmp/watchers.txt");
if (file.isFile() && file.exists()){
try {
InputStream is = new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(is, encoding);
BufferedReader br = new BufferedReader(isr);
String line = "";
while ((line = br.readLine()) != null){
watcherList.add(line);
}
br.close();
isr.close();
is.close();
}catch (Exception ex){
Logger.error("read watchers fail");
}
}
return watcherList;
}
}
在 AndroidServer 类中调用获取配置文件,并添加监听
代码如下:
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.appium.uiautomator2.server;
import static io.appium.uiautomator2.utils.Device.getUiDevice;
import androidx.test.uiautomator.By;
import androidx.test.uiautomator.BySelector;
import androidx.test.uiautomator.UiWatcher;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import io.appium.uiautomator2.http.HttpServer;
import io.appium.uiautomator2.utils.Logger;
import io.appium.uiautomator2.utils.WatcherUtils;
public class AndroidServer {
private final HttpServer webServer;
public AndroidServer(int port) {
webServer = new HttpServer(port);
init();
List<String> watcherList = WatcherUtils.readWatchers();
watcherHandler(watcherList);
Logger.info("AndroidServer created on port " + port);
}
private void init() {
webServer.addHandler(new AppiumServlet());
}
public void start() {
webServer.start();
}
public void stop() {
webServer.stop();
}
public int getPort() {
return webServer.getPort();
}
/**
* 注册监听
* @param watcherList
*/
private void watcherHandler(List<String> watcherList){
//将配置文件中的内容添加到监听
for (String watcher : watcherList){
String[] str = watcher.split("#");
getUiDevice().registerWatcher(str[0], new UiWatcher() {
@Override
public boolean checkForCondition() {
BySelector selector = findTarget(str[1], str[2]);
if (getUiDevice().hasObject(selector)){
if (getUiDevice().hasObject(findTarget(str[3], str[4]))){
getUiDevice().findObject(findTarget(str[3], str[4])).click();
}
return true;
}
return false;
}
});
}
//设置监听任务
TimerTask watcherTask = new TimerTask() {
@Override
public void run() {
try {
getUiDevice().runWatchers();
}catch (Exception ex){}
}
};
Timer timer = new Timer("WatcherTimer");
//每隔5s监听一次
timer.scheduleAtFixedRate(watcherTask, 1000, 5000);
}
private BySelector findTarget(String key, String value){
BySelector selector = null;
switch (key){
case "text":
selector = By.text(value);
break;
case "resourceId":
selector = By.res(value);
break;
case "textContains":
selector = By.textContains(value);
break;
case "content-desc":
selector = By.desc(value);
break;
default:
break;
}
return selector;
}
}
重新编译,在项目根目录下打开 cmd,执行命令
gradlew.bat clean assembleServerDebug assembleServerDebugAndroidTest
编译完成后会在项目\app\build\outputs\apk 目录下生成 2 个 apk,将将 2 个 apk 替换掉 appium\node_modules\appium-uiautomator2-server\apks 目录下的 apk
创建 watchers.txt 文件,内容格式如下:
监听名称 # 触发监听时 By# 触发监听时的值 # 触发监听后操作 By# 触发监听后操作值
例如上面的监听即为当发现页面存在 resource-id 为 close-button-icon 时,点击 resource-id 为 close-button-icon 的目标
将 watchers.txt push 到手机\data\local\tmp 目录下,并见手机中的 io.appium.uiautomator2.server、io.appium.uiautomator2.server.test 卸载,安装上面编译生成的 2 个 apk 后,执行命令启动 uiautomator2 服务
adb shell am instrument -w io.appium.uiautomator2.server.test/androidx.test.runner.AndroidJUnitRunner
然后进入添加监听的页面,可以看到会自动关掉弹框
后续只需要在 watchers.txt 中添加相应的配置并 push 到手机中即可