Эспрессо с настраиваемым нажатием кнопки KeyboardView

Я реализую настраиваемый 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()))
}

и функция щелчка 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):

Эспрессо с настраиваемым нажатием кнопки KeyboardView

Кто-нибудь знает почему? Любая помощь приветствуется.

0
0
637
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Отвечая на свой вопрос после определения гибкого решения:

  1. Первая попытка - получить DisplayMetrics из корневого View и вычесть произвольное число, чтобы попытаться попасть в Keyboard.Key.
    • это не сработало, потому что функция clickXY использует позицию представления
    • в конечном итоге это стало причиной исключения, поскольку представление меньше значений DisplayMetrics, и добавление к расположению представлений на экране дало бы очень большое число для x и y.

Итак, я попробовал еще раз,

  1. Вторая попытка - используйте метод check на ViewMatcher, чтобы проверять на KeyBoardView.
    • таким образом я смог получить доступ к позиции x KeyboardView.
    • тогда я смог получить ширину и высоту KeyboardView
    • выполнив некоторую математику, я смог вычислить целевой индекс для x и y

математика:

  • возьмите widthPercent для Keyboard.Key (в моем случае 33,3%)
  • возьмите rowCount из 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: $20.00")).check(matches(isDisplayed()))
    onView(withText("Total: $120.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)
}

Теперь щелчок не отцентрирован идеально, но он нажимает кнопку довольно близко к центру.

Надеюсь, это поможет кому-то другому! Удачи и удачного кодирования!

Другие вопросы по теме