按下自定义 KeyboardView 按钮的 Espresso
Espresso with Custom KeyboardView button press
我正在我的应用程序中实现一个自定义的 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("0.00")).check(matches(isDisplayed()))
}
以及来自this post
的点击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 内的屏幕底部):
有谁知道为什么?感谢任何帮助。
确定灵活的解决方案后回答我自己的问题:
- 第一次尝试 - 获取根
View
的 DisplayMetrics
并减去任意数字以尝试命中 Keyboard.Key
- 这不起作用,因为 clickXY 函数使用视图的位置
- 这最终成为异常的原因,因为视图小于 DisplayMetrics 值并且添加到屏幕上的视图位置会给 x 和 y 一个非常高的数字。
所以我又试了一次,
- 第二次尝试 - 在
ViewMatcher
上使用 check
方法 检查 KeyBoardView
。
- 通过这样做,我能够访问
KeyboardView
的位置 x
- 然后我就能得到
KeyboardView
的宽度和高度
- 通过一些数学运算,我能够计算出 x 和 y 的目标索引
数学:
- 取
Keyboard.Key
的 widthPercent(在我的例子中是 33.3%)
- 获取 keyboard.xml 的行数(在我的例子中是 3)
- 使用 (viewWidth * widthPercent) / 4 得到 relativeButtonX
- 使用 (viewHeight / rowCount) / 2 得到 relativeButtonY
- 然后对于 targetY,我取了 viewHeight - relativeButtonY
- 最后,对于 targetX,我采用了 (viewPosX + viewWidth) - relativeButtonX
解释够多了,这是代码:
@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: .00")).check(matches(isDisplayed()))
onView(withText("Total: 0.00")).check(matches(isDisplayed()))
}
以及包含所有数学运算的辅助方法:
private fun getTargetXAndY(): Pair<Int, Double> {
var viewHeight = 0
var viewWidth = 0
var viewPosX = 0F
val viewMatcher = onView(withId(R.id.keyboardLayout))
viewMatcher.check { view, _ ->
viewWidth = view.width
viewHeight = view.height
viewPosX = view.x
}
val keyboardKeyWidthPercent = 0.333
val keyboardRowsCount = 3
val keyboardButtonWidthQuarter = (viewWidth * keyboardKeyWidthPercent) / 4
val keyboardButtonHeightHalf = (viewHeight / keyboardRowsCount) / 2
val viewTargetY = viewHeight - keyboardButtonHeightHalf
val viewTargetX = (viewPosX + viewWidth) - keyboardButtonWidthQuarter
return Pair(viewTargetY, viewTargetX)
}
现在,点击并没有完全居中,但它点击的按钮非常接近中心。
我希望这对其他人有帮助!祝你好运,编码愉快!
我正在我的应用程序中实现一个自定义的 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("0.00")).check(matches(isDisplayed()))
}
以及来自this post
的点击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 内的屏幕底部):
有谁知道为什么?感谢任何帮助。
确定灵活的解决方案后回答我自己的问题:
- 第一次尝试 - 获取根
View
的DisplayMetrics
并减去任意数字以尝试命中Keyboard.Key
- 这不起作用,因为 clickXY 函数使用视图的位置
- 这最终成为异常的原因,因为视图小于 DisplayMetrics 值并且添加到屏幕上的视图位置会给 x 和 y 一个非常高的数字。
所以我又试了一次,
- 第二次尝试 - 在
ViewMatcher
上使用check
方法 检查KeyBoardView
。- 通过这样做,我能够访问
KeyboardView
的位置 x - 然后我就能得到
KeyboardView
的宽度和高度 - 通过一些数学运算,我能够计算出 x 和 y 的目标索引
- 通过这样做,我能够访问
数学:
- 取
Keyboard.Key
的 widthPercent(在我的例子中是 33.3%) - 获取 keyboard.xml 的行数(在我的例子中是 3)
- 使用 (viewWidth * widthPercent) / 4 得到 relativeButtonX
- 使用 (viewHeight / rowCount) / 2 得到 relativeButtonY
- 然后对于 targetY,我取了 viewHeight - relativeButtonY
- 最后,对于 targetX,我采用了 (viewPosX + viewWidth) - relativeButtonX
解释够多了,这是代码:
@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: .00")).check(matches(isDisplayed()))
onView(withText("Total: 0.00")).check(matches(isDisplayed()))
}
以及包含所有数学运算的辅助方法:
private fun getTargetXAndY(): Pair<Int, Double> {
var viewHeight = 0
var viewWidth = 0
var viewPosX = 0F
val viewMatcher = onView(withId(R.id.keyboardLayout))
viewMatcher.check { view, _ ->
viewWidth = view.width
viewHeight = view.height
viewPosX = view.x
}
val keyboardKeyWidthPercent = 0.333
val keyboardRowsCount = 3
val keyboardButtonWidthQuarter = (viewWidth * keyboardKeyWidthPercent) / 4
val keyboardButtonHeightHalf = (viewHeight / keyboardRowsCount) / 2
val viewTargetY = viewHeight - keyboardButtonHeightHalf
val viewTargetX = (viewPosX + viewWidth) - keyboardButtonWidthQuarter
return Pair(viewTargetY, viewTargetX)
}
现在,点击并没有完全居中,但它点击的按钮非常接近中心。
我希望这对其他人有帮助!祝你好运,编码愉快!