最近弄 iOS 的自动化测试时发现 appium 和 macaca 均不能在数字键盘弹出时进行 clear 和 sendkeys 操作,想来应该是 WDA 的问题了。问题描述见https://github.com/appium/appium/issues/8004

该方法适用于 macaca 和 appium 以及其他使用 WDA 做底层驱动的测试框架(根据各框架的 API 进行改动即可😺)。

一、 分析数字键盘

规律如下,数字 1-9 对应的 xpath 为:
/XCUIElementTypeApplication/XCUIElementTypeWindow[4]/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther[2]/XCUIElementTypeButton[1-9]
数字 0 对应:
/XCUIElementTypeApplication/XCUIElementTypeWindow[4]/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther[2]/XCUIElementTypeButton[11]
Done/完成按钮对应:
/XCUIElementTypeApplication/XCUIElementTypeWindow[4]/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther[2]/XCUIElementTypeButton[10]
X 删除按钮对应:
/XCUIElementTypeApplication/XCUIElementTypeWindow[4]/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther[2]/XCUIElementTypeButton[12]

二、 分析全键盘


全键盘弹出时能正常识别,控件类型为 XCUIElementTypeKeyboard。

三、 封装

public void sendkeys(WebElement el, String str) {
    try {
        el.click();
        // 如弹出的是数字键盘,目前WDA无法识别,则使用点击数字按钮完成
        if (driver.findElementByXPath("XCUIElementTypeKeyboard") == null) {
            String xpath = "/XCUIElementTypeApplication/XCUIElementTypeWindow[4]/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther[2]";
            char[] keys = str.toCharArray();
            for (int i = 0; i < keys.length; i++) {
                String x = String.valueOf(keys[i]);
                if (!x.equals("0")) {
                    driver.findElementByXPath(xpath + "/XCUIElementTypeButton[" + x + "]").click();
                } else {
                    // 数字0为第11个Button
                    driver.findElementByXPath(xpath + "/XCUIElementTypeButton[11]").click();
                }
            }
            // 完成按钮为第10个Button
            driver.findElementByXPath(xpath + "/XCUIElementTypeButton[10]").click();
        } else {
            el.sendKeys(str);
        }
    } catch (Exception e) {
        TraceUtil.logTrace(e);
    }
}

四、 调用执行

@Test
public void test_case() throws Exception {
    driver.findElementByName("注册").click();
    WebElement phone = driver.findElementByXPath(
            "/XCUIElementTypeApplication/XCUIElementTypeWindow[1]/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther[2]/XCUIElementTypeTextField[1]");
    sendkeys(phone, "13312345678");
    driver.findElementByName("发送验证码").click();
    WebElement code = driver.findElementByXPath(
            "/XCUIElementTypeApplication/XCUIElementTypeWindow[1]/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther[2]/XCUIElementTypeTextField[2]");
    sendkeys(code, "123456");
}


↙↙↙阅读原文可查看相关链接,并与作者交流