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
コンパイルが完了すると、project\app\build\outputs\apk ディレクトリに 2 つの apk が生成されます。これら 2 つの apk は、appium\node_modules\appium-uiauTomator2-server\apks ディレクトリの apk を置き換えます。
5. 設定ファイルの作成
次のコンテンツ形式で watchers.txt ファイルを作成します。
監視名#監視開始時 By#監視開始時の値#監視開始後の動作 By#監視開始後の動作値
例えば、上記の監視は、ページ上でリソースIDが閉じるボタンアイコンであることが判明した場合に、リソースIDの閉じるボタンアイコンの対象をクリックするというものです。
6. テスト
watchs.txt をphone\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
次に、モニタリングを追加するページに移動すると、ポップアップ ボックスが自動的にオフになることがわかります。