有没有办法使用 UIAutomator 输入西里尔字母?

Is there a way to use UIAutomator to enter cyrillic letters?

我正在尝试使用 UIAutomator 测试我公司浏览器的俄语自动建议功能,但遇到了障碍:

俄语字母没有 KeyEvent.KeyCode_* 代码,UiDevice.pressKeyCode(KeyEvent.KEYCODE_LANGUAGE_SWITCH) 似乎没有帮助。我在 KeyEvent class 中找到的文档似乎表明我只需要使用与英文字母相同的 KeyCodes,但神奇的是它们会被映射到其他语言的字母。然而,这似乎并没有真正发生,因为当我尝试这样做时,我仍然看到英文字母出现。

通常使用俄语我只使用 UiObject2.setText(...) 但该方法不会触发自动建议。

我已经尝试深入研究 UiDevice.pressKeyCode 正在做什么,并尝试了一些解决方法,例如:

KeyEvent eventsб2 = new KeyEvent(SystemClock.currentThreadTimeMillis(), "б", KeyCharacterMap.VIRTUAL_KEYBOARD, 0);
Instrumentation.sendKeySync(eventsб2);

KeyEvent[] eventsа = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD).getEvents(new char[] {'a'});
Instrumentation.sendKeySync(eventsа[0]);

但他们要么不输入字母,要么抛出关于需要 INJECT_EVENTS 权限的权限异常。总的来说,我感觉自己在黑暗中跌跌撞撞,希望得到一些关于如何继续的建议。

我试过了并且成功了。

/**
 * @@Test comment here@@
 *
 * @throws Exception
 */
@Test
public void culebraGeneratedTest_CyrillicKeyBoardAndSelectSuggestion() throws Exception {
    mDevice.pressHome();
    mDevice.findObject(By.res("com.android.quicksearchbox:id/search_widget_text").clazz("android.widget.TextView").text(Pattern.compile("")).pkg("com.android.quicksearchbox")).clickAndWait(Until.newWindow(), DEFAULT_TIMEOUT);
    mDevice.findObject(By.desc("й").clazz("com.android.inputmethod.keyboard.Key").text(Pattern.compile("")).pkg("com.android.inputmethod.latin")).clickAndWait(Until.newWindow(), DEFAULT_TIMEOUT);
    (new UiScrollable(new UiSelector().resourceId("com.android.quicksearchbox:id/suggestions").index(1).packageName("com.android.quicksearchbox"))).getChildByText(new UiSelector().className("android.widget.RelativeLayout").packageName("com.android.quicksearchbox"), "йемен", true).click();
}

我不得不承认我不懂俄语,也不懂我在西里尔键盘上输入的内容 select,请耐心等待。

为了生成此测试,我使用了 CulebraTester,因为它似乎是该工具的一个有趣用例。

步骤是:

  1. 开始录制测试(生成Java UiAutomator,还可以生成python等其他语言)
  2. 按主页
  3. select 快速搜索框
  4. 按键
  5. Select建议之一

您将能够在 python 中使用 AndroidViewClient/culebra 创建类似的测试,但由于此工具基于从 uiautomator dump 获得的信息,因此无法检测键盘上的字母,但您也可以使用 DIPs

触摸它们
vc.dump(window=-1)
vc.findViewByIdOrRaise("com.android.quicksearchbox:id/search_widget_text").touch()
vc.sleep(_s)
vc.dump(window=-1)
device.touchDip(15.33, 393.33, 0)

但这不像第一个解决方案那样独立于设备。

希望对您有所帮助。