Автоматизация тестов навигации по фокусу гарантирует, что ваше приложение обеспечит согласованный и предсказуемый пользовательский опыт на аппаратных клавиатурах, D-pad и инструментах специальных возможностей. Compose предоставляет встроенные API для тестирования, позволяющие имитировать ввод с клавиш и проверять состояния фокуса.
Настройте фокус-тесты
Для написания тестов с фокусировкой используйте createComposeRule() из библиотеки тестирования Compose:
@RunWith(AndroidJUnit4::class) class FocusNavigationTest { @get:Rule val composeTestRule = createComposeRule()
Проверьте целевые объекты фокусировки.
Проверить, может ли элемент пользовательского интерфейса получить фокус, можно, выполнив щелчок или запросив фокус, а затем проверив его состояние с помощью assertIsFocused() и assertIsNotFocused() .
@Test fun interactiveElement_isFocusTarget() { composeTestRule.setContent { AppTheme { CardListScreen() } } val firstCard = composeTestRule.onNodeWithTag("card_1") val secondCard = composeTestRule.onNodeWithTag("card_2") // Focus the first element firstCard.performClick() firstCard.assertIsFocused() secondCard.assertIsNotFocused() }
Проверка одномерного перемещения фокуса
Имитируйте нажатия клавиш Tab и Shift+Tab с помощью performKeyInput , чтобы убедиться, что фокус перемещается по пользовательскому интерфейсу в порядке его появления. В качестве рекомендации, проверяйте как прямую навигацию ( Key.Tab ), так и обратную навигацию ( Key.Tab с удерживаемой Key.ShiftLeft ), чтобы обеспечить целостность двустороннего перемещения:
@Test fun tabKey_navigatesInAppearanceOrder() { composeTestRule.setContent { AppTheme { CardListScreen() } } val firstCard = composeTestRule.onNodeWithTag("card_1") val secondCard = composeTestRule.onNodeWithTag("card_2") val thirdCard = composeTestRule.onNodeWithTag("card_3") firstCard.performClick() firstCard.assertIsFocused() // Press Tab -> Moves to second card firstCard.performKeyInput { pressKey(Key.Tab) } secondCard.assertIsFocused() firstCard.assertIsNotFocused() // Press Tab -> Moves to third card secondCard.performKeyInput { pressKey(Key.Tab) } thirdCard.assertIsFocused() // Press Shift + Tab -> Moves backward to second card thirdCard.performKeyInput { withKeyDown(Key.ShiftLeft) { pressKey(Key.Tab) } } secondCard.assertIsFocused() }
Проверка двумерного направленного перемещения
Имитируйте клавиши со стрелками или клавиши управления D-pad с помощью Key.DirectionDown , Key.DirectionUp , Key.DirectionRight и Key.DirectionLeft .
@Test fun arrowKeys_moveFocusTwoDimensionallyWithoutWrap() { composeTestRule.setContent { AppTheme { GridLayoutScreen() } } val topLeftButton = composeTestRule.onNodeWithTag("btn_top_left") val bottomLeftButton = composeTestRule.onNodeWithTag("btn_bottom_left") topLeftButton.performClick() topLeftButton.assertIsFocused() // Down arrow moves focus downward to bottom-left button topLeftButton.performKeyInput { pressKey(Key.DirectionDown) } bottomLeftButton.assertIsFocused() // Directional keys do not wrap around: pressing Down on bottom element stays focused bottomLeftButton.performKeyInput { pressKey(Key.DirectionDown) } bottomLeftButton.assertIsFocused() }
Проверка поведения фокусировки текстового поля
Убедитесь, что в однострочных текстовых полях фокус автоматически переключается на клавишу Tab , а в многострочных текстовых полях фокус сохраняется:
@Test fun textField_handlesTabAccordingToLineLimits() { composeTestRule.setContent { AppTheme { FormScreen() } } val singleLineNode = composeTestRule.onNodeWithTag("single_line_field") val multiLineNode = composeTestRule.onNodeWithTag("multi_line_field") val submitButtonNode = composeTestRule.onNodeWithTag("submit_button") // Single-line field advances focus on Tab singleLineNode.performClick() singleLineNode.assertIsFocused() singleLineNode.performKeyInput { pressKey(Key.Tab) } multiLineNode.assertIsFocused() // Multi-line field keeps focus and inserts '\t' multiLineNode.performKeyInput { pressKey(Key.Tab) } multiLineNode.assertIsFocused() submitButtonNode.assertIsNotFocused() // Shift + Tab escapes multi-line field to previous target multiLineNode.performKeyInput { withKeyDown(Key.ShiftLeft) { pressKey(Key.Tab) } } singleLineNode.assertIsFocused() }
Рекомендуем вам
- Примечание: текст ссылки отображается, когда JavaScript отключен.
- Целевые показатели
- Порядок перемещения фокуса
- Фокусировка на текстовых полях
- Целевые показатели фокусировки группы