带有自定义KeyboardView按钮的Espresso,按

时间:2018-07-25 22:41:54

标签: android android-espresso custom-keyboard

我正在我的应用程序中实现自定义KeyboardView,目前所有功能均正常运行,但是,当我尝试使用Espresso ViewAction按下键盘上的某个键时,出现了一个异常提示:

android.support.test.espresso.PerformException: 
Error performing 'single click - At Coordinates: 1070, 2809 and 
precision: 16, 16' on view 'with id: 
com.example.app.mvpdemo:id/keyboardLayout'.

引发异常的代码是:

@Test
fun enter100AsPriceShouldDisplay120ForA20PercentTip(){
    onView(withId(R.id.editTextCheckAmount))
            .perform(typeText("100"), closeSoftKeyboard())
    val appContext = InstrumentationRegistry.getTargetContext()
    val displayMetrics = appContext.resources.displayMetrics
    onView(withId(R.id.keyboardLayout)).perform(clickXY(displayMetrics.widthPixels - 10, displayMetrics.heightPixels - 10))
    onView(withText("$120.00")).check(matches(isDisplayed()))
}

和来自this post

的click XY函数
 private fun clickXY(x: Int, y: Int): ViewAction {
    return GeneralClickAction(
            Tap.SINGLE,
            CoordinatesProvider { view ->
                val screenPos = IntArray(2)
                view.getLocationOnScreen(screenPos)

                val screenX = (screenPos[0] + x).toFloat()
                val screenY = (screenPos[1] + y).toFloat()

                floatArrayOf(screenX, screenY)
            },
            Press.FINGER, 0, 0)
}

这是我的键盘布局(固定在ConstraintLayout内部的屏幕底部):

enter image description here

有人知道为什么吗?任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:0)

在确定灵活的解决方案后回答我自己的问题:

  1. 首次尝试-获得根DisplayMetrics的{​​{1}}并减去任意数字以尝试命中View
    • 这不起作用,因为clickXY函数使用视图的位置
    • 这最终是导致异常的原因,因为视图小于DisplayMetrics值,并将其添加到屏幕上的“视图”位置将为x和y提供非常高的数字。

所以我再试一次,

  1. 第二次尝试-在Keyboard.Key上使用check方法来检查 ViewMatcher
    • 这样做可以访问KeyBoardView的位置x
    • 然后我就能得到KeyboardView的宽度和高度
    • 通过一些数学运算,我能够找出x和y的目标索引

数学:

  • 获取KeyboardView的widthPercent(在我的情况下为33.3%)
  • 获取keyboard.xml的rowCount(在我的情况下为3)
  • 使用(viewWidth * widthPercent)/ 4获取relativeButtonX
  • 使用(viewHeight / rowCount)/ 2获得relativeButtonY
  • 然后对于targetY,我使用了viewHeight-relativeButtonY
  • 最后,对于targetX,我采用(viewPosX + viewWidth)-relativeButtonX

足够多的解释,下面是代码:

Keyboard.Key

以及所有数学方法的辅助方法:

@Test
fun enter100AsPriceShouldDisplay120ForA20PercentTip() {
    onView(withId(R.id.editTextCheckAmount))
            .perform(typeText("100"), closeSoftKeyboard())

    // call the function to get the targets
    val (viewTargetY, viewTargetX) = getTargetXAndY()

    // perform the action
    onView(withId(R.id.keyboardLayout)).perform(clickXY(viewTargetX.toInt(), viewTargetY))
    onView(withText("Tip: $20.00")).check(matches(isDisplayed()))
    onView(withText("Total: $120.00")).check(matches(isDisplayed()))
}

现在,单击并没有完全居中,但它单击的按钮非常靠近中心。

我希望这对其他人有帮助!祝您好运,编码愉快!