পরীক্ষার ফোকাস নেভিগেশন

ফোকাস নেভিগেশন পরীক্ষা স্বয়ংক্রিয় করার মাধ্যমে আপনার অ্যাপ হার্ডওয়্যার কিবোর্ড, ডি-প্যাড এবং অ্যাক্সেসিবিলিটি টুল জুড়ে একটি সামঞ্জস্যপূর্ণ ও অনুমানযোগ্য ব্যবহারকারীর অভিজ্ঞতা প্রদান করে। কী-ইনপুট অনুকরণ করতে এবং ফোকাসের অবস্থা যাচাই করার জন্য কম্পোজে বিল্ট-ইন টেস্টিং এপিআই রয়েছে।

ফোকাস পরীক্ষা সেট আপ করুন

ফোকাস টেস্ট লেখার জন্য, Compose টেস্টিং লাইব্রেরি থেকে createComposeRule() ব্যবহার করুন:

@RunWith(AndroidJUnit4::class)
class FocusNavigationTest {
    @get:Rule
    val composeTestRule = createComposeRule()

ফোকাস লক্ষ্যগুলি যাচাই করুন

কোনো UI এলিমেন্ট ফোকাস পাবে কি না, তা আপনি ক্লিক করে বা ফোকাসের জন্য অনুরোধ করে এবং তারপর 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()
}

একমাত্রিক ফোকাস ট্র্যাভার্সাল পরীক্ষা করুন

UI-তে ফোকাস উপস্থিতির ক্রমানুসারে অগ্রসর হচ্ছে কিনা তা যাচাই করার জন্য performKeyInput ব্যবহার করে Tab এবং Shift+Tab কী-প্রেস অনুকরণ করুন। একটি উত্তম অনুশীলন হিসেবে, দ্বিমুখী ট্র্যাভার্সালের অখণ্ডতা নিশ্চিত করতে সম্মুখ নেভিগেশন ( 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()
}

দ্বিমাত্রিক দিকনির্দেশক অতিক্রমণ পরীক্ষা করুন

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()
}

পরীক্ষার টেক্সট ফিল্ড ফোকাস আচরণ

যাচাই করুন যে এক-লাইনের টেক্সট ফিল্ডে ট্যাব চাপলে ফোকাস স্থানান্তরিত হয়, অপরদিকে একাধিক-লাইনের টেক্সট ফিল্ডে ফোকাস অপরিবর্তিত থাকে:

@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()
}

{% হুবহু %} {% endverbatim %} {% হুবহু %} {% endverbatim %}