Modify the appium-uiautomator2-server source code to solve the problem of uncertain pop-up boxes in Android UI automation

1.Background

Since there are many uncertain pop-up boxes in the test application, it is very time-consuming to judge in the script, so the appium-uiautomator2-server source code is modified to add monitoring to solve this problem. Currently, configurable monitoring is implemented, and only text, resourceId, and textContains are currently supported. , search method in content-desc4, and only supports simple click operations, which can be expanded according to your own needs.

2. Download appium-uiautomator2-server

Download the corresponding uiautomator2server source code according to the apppium version you are using.

3. Use AndroidStudio to open the project

4. Add monitoring of pop-up boxes

Create a new WatcherUtils class under the utils package to read the content that needs to be monitored in the configuration document.

 WatcherUtils code is as follows:

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;
    }
}

 Call in the AndroidServer class to obtain the configuration file and add a listener

 code show as below:

/*
 * 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;
    }
}

Recompile, open cmd in the project root directory, and execute the command

gradlew.bat clean assembleServerDebug assembleServerDebugAndroidTest

After compilation is completed, 2 apks will be generated in the project\app\build\outputs\apk directory. These two apks will replace the apks in the appium\node_modules\appium-uiautomator2-server\apks directory.

5. Create configuration file

Create a watchers.txt file with the following content format:

Monitoring name#When monitoring is triggered By#The value when monitoring is triggered#The operation after triggering monitoring By#The operation value after triggering monitoring

 

 For example, the above monitoring is to click the target with resource-id close-button-icon when it is found that the resource-id is close-button-icon on the page.

6. Test

Push watches.txt to the phone\data\local\tmp directory, and uninstall io.appium.uiautomator2.server and io.appium.uiautomator2.server.test on the phone. After installing the two apks compiled and generated above, Execute the command to start the uiautomator2 service

adb shell am instrument -w io.appium.uiautomator2.server.test/androidx.test.runner.AndroidJUnitRunner

Then enter the page to add monitoring, you can see that the pop-up box will be turned off automatically.

 

 

Guess you like

Origin blog.csdn.net/y954227239/article/details/130239374