1.背景
由于测试应用不确定弹框较多,如果在脚本中判断很耗时间,因此修改appium-uiautomator2-server源码添加监听解决这个问题,目前实现了可配置式的监听,暂时只支持text、resourceId、textContains、content-desc4中查找方式,且只支持简单的点击操作,具体可以根据自己的需求进行扩展。
2.下载appium-uiautomator2-server
根据你所使用的apppium版本下载对应的uiautomator2server源码
3.使用AndroidStudio打开项目
4.添加对弹框的监听
在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
5.创建配置文件
创建watchers.txt文件,内容格式如下:
监听名称#触发监听时By#触发监听时的值#触发监听后操作By#触发监听后操作值
例如上面的监听即为当发现页面存在resource-id为close-button-icon时,点击resource-id为close-button-icon的目标
6.测试
将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
然后进入添加监听的页面,可以看到会自动关掉弹框