Best Appium-espresso-driver code snippet using android.support.test.espresso.matcher.RootMatchers.isFocusable
StateFragmentTest.kt
Source:StateFragmentTest.kt
...28import androidx.test.espresso.matcher.ViewMatchers.hasChildCount29import androidx.test.espresso.matcher.ViewMatchers.isClickable30import androidx.test.espresso.matcher.ViewMatchers.isDisplayed31import androidx.test.espresso.matcher.ViewMatchers.isEnabled32import androidx.test.espresso.matcher.ViewMatchers.isFocusable33import androidx.test.espresso.matcher.ViewMatchers.isRoot34import androidx.test.espresso.matcher.ViewMatchers.withContentDescription35import androidx.test.espresso.matcher.ViewMatchers.withHint36import androidx.test.espresso.matcher.ViewMatchers.withId37import androidx.test.espresso.matcher.ViewMatchers.withText38import androidx.test.espresso.util.HumanReadables39import androidx.test.espresso.util.TreeIterables40import androidx.test.ext.junit.runners.AndroidJUnit441import com.bumptech.glide.Glide42import com.bumptech.glide.GlideBuilder43import com.bumptech.glide.load.engine.executor.MockGlideExecutor44import com.google.common.truth.Truth.assertThat45import dagger.BindsInstance46import dagger.Component47import dagger.Module48import dagger.Provides49import kotlinx.coroutines.CoroutineDispatcher50import org.hamcrest.BaseMatcher51import org.hamcrest.CoreMatchers.allOf52import org.hamcrest.CoreMatchers.containsString53import org.hamcrest.CoreMatchers.not54import org.hamcrest.Description55import org.hamcrest.Matcher56import org.hamcrest.TypeSafeMatcher57import org.junit.After58import org.junit.Before59import org.junit.Ignore60import org.junit.Rule61import org.junit.Test62import org.junit.runner.RunWith63import org.oppia.android.R64import org.oppia.android.app.activity.ActivityComponent65import org.oppia.android.app.application.ActivityComponentFactory66import org.oppia.android.app.application.ApplicationComponent67import org.oppia.android.app.application.ApplicationInjector68import org.oppia.android.app.application.ApplicationInjectorProvider69import org.oppia.android.app.application.ApplicationModule70import org.oppia.android.app.application.ApplicationStartupListenerModule71import org.oppia.android.app.devoptions.DeveloperOptionsModule72import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule73import org.oppia.android.app.player.state.hintsandsolution.HintsAndSolutionConfigFastShowTestModule74import org.oppia.android.app.player.state.itemviewmodel.StateItemViewModel75import org.oppia.android.app.player.state.itemviewmodel.StateItemViewModel.ViewType.CONTENT76import org.oppia.android.app.player.state.itemviewmodel.StateItemViewModel.ViewType.CONTINUE_INTERACTION77import org.oppia.android.app.player.state.itemviewmodel.StateItemViewModel.ViewType.CONTINUE_NAVIGATION_BUTTON78import org.oppia.android.app.player.state.itemviewmodel.StateItemViewModel.ViewType.DRAG_DROP_SORT_INTERACTION79import org.oppia.android.app.player.state.itemviewmodel.StateItemViewModel.ViewType.FEEDBACK80import org.oppia.android.app.player.state.itemviewmodel.StateItemViewModel.ViewType.FRACTION_INPUT_INTERACTION81import org.oppia.android.app.player.state.itemviewmodel.StateItemViewModel.ViewType.NEXT_NAVIGATION_BUTTON82import org.oppia.android.app.player.state.itemviewmodel.StateItemViewModel.ViewType.NUMERIC_INPUT_INTERACTION83import org.oppia.android.app.player.state.itemviewmodel.StateItemViewModel.ViewType.RATIO_EXPRESSION_INPUT_INTERACTION84import org.oppia.android.app.player.state.itemviewmodel.StateItemViewModel.ViewType.RETURN_TO_TOPIC_NAVIGATION_BUTTON85import org.oppia.android.app.player.state.itemviewmodel.StateItemViewModel.ViewType.SELECTION_INTERACTION86import org.oppia.android.app.player.state.itemviewmodel.StateItemViewModel.ViewType.SUBMITTED_ANSWER87import org.oppia.android.app.player.state.itemviewmodel.StateItemViewModel.ViewType.SUBMIT_ANSWER_BUTTON88import org.oppia.android.app.player.state.itemviewmodel.StateItemViewModel.ViewType.TEXT_INPUT_INTERACTION89import org.oppia.android.app.player.state.testing.StateFragmentTestActivity90import org.oppia.android.app.recyclerview.RecyclerViewMatcher.Companion.atPositionOnView91import org.oppia.android.app.shim.ViewBindingShimModule92import org.oppia.android.app.topic.PracticeTabModule93import org.oppia.android.app.utility.ChildViewCoordinatesProvider94import org.oppia.android.app.utility.CustomGeneralLocation95import org.oppia.android.app.utility.DragViewAction96import org.oppia.android.app.utility.OrientationChangeAction.Companion.orientationLandscape97import org.oppia.android.app.utility.RecyclerViewCoordinatesProvider98import org.oppia.android.app.utility.clickPoint99import org.oppia.android.domain.classify.InteractionsModule100import org.oppia.android.domain.classify.rules.continueinteraction.ContinueModule101import org.oppia.android.domain.classify.rules.dragAndDropSortInput.DragDropSortInputModule102import org.oppia.android.domain.classify.rules.fractioninput.FractionInputModule103import org.oppia.android.domain.classify.rules.imageClickInput.ImageClickInputModule104import org.oppia.android.domain.classify.rules.itemselectioninput.ItemSelectionInputModule105import org.oppia.android.domain.classify.rules.multiplechoiceinput.MultipleChoiceInputModule106import org.oppia.android.domain.classify.rules.numberwithunits.NumberWithUnitsRuleModule107import org.oppia.android.domain.classify.rules.numericinput.NumericInputRuleModule108import org.oppia.android.domain.classify.rules.ratioinput.RatioInputModule109import org.oppia.android.domain.classify.rules.textinput.TextInputRuleModule110import org.oppia.android.domain.exploration.lightweightcheckpointing.ExplorationStorageModule111import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule112import org.oppia.android.domain.oppialogger.LogStorageModule113import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule114import org.oppia.android.domain.oppialogger.loguploader.WorkManagerConfigurationModule115import org.oppia.android.domain.platformparameter.PlatformParameterModule116import org.oppia.android.domain.question.QuestionModule117import org.oppia.android.domain.topic.FRACTIONS_EXPLORATION_ID_1118import org.oppia.android.domain.topic.PrimeTopicAssetsControllerModule119import org.oppia.android.domain.topic.TEST_EXPLORATION_ID_2120import org.oppia.android.domain.topic.TEST_EXPLORATION_ID_4121import org.oppia.android.domain.topic.TEST_EXPLORATION_ID_5122import org.oppia.android.domain.topic.TEST_STORY_ID_0123import org.oppia.android.domain.topic.TEST_TOPIC_ID_0124import org.oppia.android.testing.AccessibilityTestRule125import org.oppia.android.testing.OppiaTestRule126import org.oppia.android.testing.RunOn127import org.oppia.android.testing.TestLogReportingModule128import org.oppia.android.testing.TestPlatform129import org.oppia.android.testing.environment.TestEnvironmentConfig130import org.oppia.android.testing.espresso.EditTextInputAction131import org.oppia.android.testing.profile.ProfileTestHelper132import org.oppia.android.testing.robolectric.IsOnRobolectric133import org.oppia.android.testing.robolectric.RobolectricModule134import org.oppia.android.testing.threading.CoroutineExecutorService135import org.oppia.android.testing.threading.TestCoroutineDispatchers136import org.oppia.android.testing.threading.TestDispatcherModule137import org.oppia.android.testing.time.FakeOppiaClockModule138import org.oppia.android.util.accessibility.AccessibilityTestModule139import org.oppia.android.util.caching.CacheAssetsLocally140import org.oppia.android.util.caching.LoadImagesFromAssets141import org.oppia.android.util.caching.LoadLessonProtosFromAssets142import org.oppia.android.util.caching.TopicListToCache143import org.oppia.android.util.gcsresource.GcsResourceModule144import org.oppia.android.util.logging.LoggerModule145import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule146import org.oppia.android.util.parser.html.HtmlParserEntityTypeModule147import org.oppia.android.util.parser.image.GlideImageLoaderModule148import org.oppia.android.util.parser.image.ImageParsingModule149import org.oppia.android.util.threading.BackgroundDispatcher150import org.robolectric.annotation.Config151import org.robolectric.annotation.LooperMode152import java.io.IOException153import java.util.concurrent.TimeoutException154import javax.inject.Inject155import javax.inject.Singleton156/** Tests for [StateFragment]. */157@RunWith(AndroidJUnit4::class)158@Config(application = StateFragmentTest.TestApplication::class, qualifiers = "port-xxhdpi")159@LooperMode(LooperMode.Mode.PAUSED)160class StateFragmentTest {161 @get:Rule162 val accessibilityTestRule = AccessibilityTestRule()163 @get:Rule164 val oppiaTestRule = OppiaTestRule()165 @Inject166 lateinit var profileTestHelper: ProfileTestHelper167 @Inject168 lateinit var context: Context169 @Inject170 lateinit var testCoroutineDispatchers: TestCoroutineDispatchers171 @Inject172 lateinit var editTextInputAction: EditTextInputAction173 @Inject174 @field:BackgroundDispatcher175 lateinit var backgroundCoroutineDispatcher: CoroutineDispatcher176 private val internalProfileId: Int = 1177 @Before178 fun setUp() {179 Intents.init()180 setUpTestApplicationComponent()181 testCoroutineDispatchers.registerIdlingResource()182 profileTestHelper.initializeProfiles()183 // Initialize Glide such that all of its executors use the same shared dispatcher pool as the184 // rest of Oppia so that thread execution can be synchronized via Oppia's test coroutine185 // dispatchers.186 val executorService = MockGlideExecutor.newTestExecutor(187 CoroutineExecutorService(backgroundCoroutineDispatcher)188 )189 Glide.init(190 context,191 GlideBuilder().setDiskCacheExecutor(executorService)192 .setAnimationExecutor(executorService)193 .setSourceExecutor(executorService)194 )195 // Only initialize the Robolectric shadows when running on Robolectric (and use reflection since196 // Espresso can't load Robolectric into its classpath).197 if (isOnRobolectric()) {198 val dataSource = createAudioDataSource(199 explorationId = FRACTIONS_EXPLORATION_ID_1, audioFileName = "content-en-ouqm7j21vt8.mp3"200 )201 addShadowMediaPlayerException(dataSource, IOException("Test does not have networking"))202 }203 }204 @After205 fun tearDown() {206 testCoroutineDispatchers.unregisterIdlingResource()207 Intents.release()208 }209 // TODO(#388): Add more test-cases210 // 1. Actually going through each of the exploration states with typing text/clicking the correct211 // answers for each of the interactions.212 // 2. Verifying the button visibility state based on whether text is missing, then213 // present/missing for text input or numeric input.214 // 3. Testing providing the wrong answer and showing feedback and the same question again.215 // 4. Configuration change with typed text (e.g. for numeric or text input) retains that216 // temporary217 // text and you can continue with the exploration after rotating.218 // 5. Configuration change after submitting the wrong answer to show that the old answer & re-ask219 // of the question stay the same.220 // 6. Backward/forward navigation along with configuration changes to verify that you stay on the221 // navigated state.222 // 7. Verifying that old answers were present when navigation backward/forward.223 // 8. Testing providing the wrong answer and showing hints.224 // 9. Testing all possible invalid/error input cases for each interaction.225 // 10. Testing interactions with custom Oppia tags (including images) render correctly (when226 // manually inspected) and are correctly functional.227 // 11. Add tests for hints & solutions.228 // 13. Add tests for audio states, including: audio playing & having an error, or no-network229 // connectivity scenarios. See the PR introducing this comment & #1340 / #1341 for context.230 // 14. Add tests to check the placeholder in FractionInput, TextInput and NumericInput.231 // TODO(#56): Add support for testing that previous/next button states are properly retained on232 // config changes.233 @Test234 fun testStateFragment_loadExp_explorationLoads() {235 launchForExploration(TEST_EXPLORATION_ID_2).use {236 startPlayingExploration()237 // Due to the exploration activity loading, the play button should no longer be visible.238 onView(withId(R.id.play_test_exploration_button)).check(matches(not(isDisplayed())))239 }240 }241 @Test242 fun testStateFragment_loadExp_explorationLoads_changeConfiguration_buttonIsNotVisible() {243 launchForExploration(TEST_EXPLORATION_ID_2).use {244 startPlayingExploration()245 rotateToLandscape()246 // Due to the exploration activity loading, the play button should no longer be visible.247 onView(withId(R.id.play_test_exploration_button)).check(matches(not(isDisplayed())))248 }249 }250 @Test251 fun testStateFragment_loadExp_explorationHasContinueButton() {252 launchForExploration(TEST_EXPLORATION_ID_2).use {253 startPlayingExploration()254 scrollToViewType(CONTINUE_INTERACTION)255 onView(withId(R.id.continue_button)).check(matches(isDisplayed()))256 }257 }258 @Test259 fun testStateFragment_loadExp_changeConfiguration_explorationHasContinueButton() {260 launchForExploration(TEST_EXPLORATION_ID_2).use {261 startPlayingExploration()262 rotateToLandscape()263 scrollToViewType(CONTINUE_INTERACTION)264 onView(withId(R.id.continue_button)).check(matches(isDisplayed()))265 }266 }267 @Test268 fun testStateFragment_loadExp_secondState_hasSubmitButton() {269 launchForExploration(TEST_EXPLORATION_ID_2).use {270 startPlayingExploration()271 clickContinueInteractionButton()272 scrollToViewType(SUBMIT_ANSWER_BUTTON)273 onView(withId(R.id.submit_answer_button)).check(274 matches(withText(R.string.state_submit_button))275 )276 onView(withId(R.id.submit_answer_button)).check(matches(not(isEnabled())))277 }278 }279 @Test280 fun testStateFragment_loadExp_changeConfiguration_secondState_hasSubmitButton() {281 launchForExploration(TEST_EXPLORATION_ID_2).use {282 startPlayingExploration()283 rotateToLandscape()284 clickContinueInteractionButton()285 scrollToViewType(SUBMIT_ANSWER_BUTTON)286 onView(withId(R.id.submit_answer_button)).check(287 matches(withText(R.string.state_submit_button))288 )289 }290 }291 @Test292 fun testStateFragment_loadExp_secondState_submitAnswer_submitButtonIsEnabled() {293 launchForExploration(TEST_EXPLORATION_ID_2).use {294 startPlayingExploration()295 clickContinueInteractionButton()296 typeFractionText("1/2")297 scrollToViewType(SUBMIT_ANSWER_BUTTON)298 onView(withId(R.id.submit_answer_button)).check(matches(isEnabled()))299 }300 }301 @Test302 fun testStateFragment_loadExp_secondState_submitAnswer_clickSubmit_continueButtonIsVisible() {303 launchForExploration(TEST_EXPLORATION_ID_2).use {304 startPlayingExploration()305 clickContinueInteractionButton()306 typeFractionText("1/2")307 clickSubmitAnswerButton()308 scrollToViewType(CONTINUE_NAVIGATION_BUTTON)309 onView(withId(R.id.continue_navigation_button)).check(310 matches(withText(R.string.state_continue_button))311 )312 }313 }314 @Test315 fun testStateFragment_loadExp_landscape_secondState_submitAnswer_submitButtonIsEnabled() {316 launchForExploration(TEST_EXPLORATION_ID_2).use {317 startPlayingExploration()318 rotateToLandscape()319 clickContinueInteractionButton()320 typeFractionText("1/2")321 scrollToViewType(SUBMIT_ANSWER_BUTTON)322 onView(withId(R.id.submit_answer_button)).check(matches(isEnabled()))323 }324 }325 @Test326 fun testStateFragment_loadExp_land_secondState_submitAnswer_clickSubmit_continueIsVisible() {327 launchForExploration(TEST_EXPLORATION_ID_2).use {328 startPlayingExploration()329 rotateToLandscape()330 clickContinueInteractionButton()331 typeFractionText("1/2")332 clickSubmitAnswerButton()333 scrollToViewType(CONTINUE_NAVIGATION_BUTTON)334 onView(withId(R.id.continue_navigation_button)).check(335 matches(withText(R.string.state_continue_button))336 )337 }338 }339 @Test340 fun testStateFragment_loadExp_secondState_submitInvalidAnswer_disablesSubmitAndShowsError() {341 launchForExploration(TEST_EXPLORATION_ID_2).use {342 startPlayingExploration()343 clickContinueInteractionButton()344 // Attempt to submit an invalid answer.345 typeFractionText("1/")346 clickSubmitAnswerButton()347 // The submission button should now be disabled and there should be an error.348 scrollToViewType(SUBMIT_ANSWER_BUTTON)349 onView(withId(R.id.submit_answer_button)).check(matches(not(isEnabled())))350 onView(withId(R.id.fraction_input_error)).check(matches(isDisplayed()))351 }352 }353 @Test354 fun testStateFragment_loadExp_land_secondState_submitInvalidAnswer_disablesSubmitAndShowsError() {355 launchForExploration(TEST_EXPLORATION_ID_2).use {356 startPlayingExploration()357 rotateToLandscape()358 clickContinueInteractionButton()359 // Attempt to submit an invalid answer.360 typeFractionText("1/")361 clickSubmitAnswerButton()362 // The submission button should now be disabled and there should be an error.363 scrollToViewType(SUBMIT_ANSWER_BUTTON)364 onView(withId(R.id.submit_answer_button)).check(matches(not(isEnabled())))365 onView(withId(R.id.fraction_input_error)).check(matches(isDisplayed()))366 }367 }368 @Test369 fun testStateFragment_loadExp_secondState_invalidAnswer_submitAnswerIsNotEnabled() {370 launchForExploration(TEST_EXPLORATION_ID_2).use {371 startPlayingExploration()372 clickContinueInteractionButton()373 typeFractionText("1/")374 clickSubmitAnswerButton()375 scrollToViewType(SUBMIT_ANSWER_BUTTON)376 onView(withId(R.id.submit_answer_button)).check(matches(not(isEnabled())))377 }378 }379 @Test380 fun testStateFragment_loadExp_secondState_invalidAnswer_updated_submitAnswerIsEnabled() {381 launchForExploration(TEST_EXPLORATION_ID_2).use {382 startPlayingExploration()383 clickContinueInteractionButton()384 typeFractionText("1/")385 clickSubmitAnswerButton()386 // Add another '2' to change the pending input text.387 typeFractionText("2")388 // The submit button should be re-enabled since the text view changed.389 scrollToViewType(SUBMIT_ANSWER_BUTTON)390 onView(withId(R.id.submit_answer_button)).check(matches(isEnabled()))391 }392 }393 @Test394 fun testStateFragment_loadExp_land_secondState_invalidAnswer_submitAnswerIsNotEnabled() {395 launchForExploration(TEST_EXPLORATION_ID_2).use {396 startPlayingExploration()397 rotateToLandscape()398 clickContinueInteractionButton()399 typeFractionText("1/")400 clickSubmitAnswerButton()401 scrollToViewType(SUBMIT_ANSWER_BUTTON)402 onView(withId(R.id.submit_answer_button)).check(matches(not(isEnabled())))403 }404 }405 @Test406 fun testStateFragment_loadExp_land_secondState_invalidAnswer_updated_submitAnswerIsEnabled() {407 launchForExploration(TEST_EXPLORATION_ID_2).use {408 startPlayingExploration()409 rotateToLandscape()410 clickContinueInteractionButton()411 typeFractionText("1/")412 clickSubmitAnswerButton()413 // Add another '2' to change the pending input text.414 typeFractionText("2")415 // The submit button should be re-enabled since the text view changed.416 scrollToViewType(SUBMIT_ANSWER_BUTTON)417 onView(withId(R.id.submit_answer_button)).check(matches(isEnabled()))418 }419 }420 @Test421 fun testStateFragment_loadExp_secondState_submitWrongAnswer_contentDescriptionIsCorrect() {422 launchForExploration(TEST_EXPLORATION_ID_2).use {423 startPlayingExploration()424 clickContinueInteractionButton()425 // Attempt to submit an wrong answer.426 typeFractionText("1/4")427 clickSubmitAnswerButton()428 scrollToViewType(SUBMITTED_ANSWER)429 onView(withId(R.id.submitted_answer_text_view)).check(430 matches(431 withContentDescription(432 "Incorrect submitted answer: 1/4"433 )434 )435 )436 }437 }438 @Test439 fun testStateFragment_loadExp_secondState_submitCorrectAnswer_contentDescriptionIsCorrect() {440 launchForExploration(TEST_EXPLORATION_ID_2).use {441 startPlayingExploration()442 clickContinueInteractionButton()443 // Attempt to submit an wrong answer.444 typeFractionText("1/2")445 clickSubmitAnswerButton()446 scrollToViewType(SUBMITTED_ANSWER)447 onView(withId(R.id.submitted_answer_text_view)).check(448 matches(449 withContentDescription(450 "Correct submitted answer: 1/2"451 )452 )453 )454 }455 }456 @Test457 fun testStateFragment_loadExp_firstState_previousAndNextButtonIsNotDisplayed() {458 launchForExploration(TEST_EXPLORATION_ID_2).use {459 startPlayingExploration()460 onView(withId(R.id.previous_state_navigation_button)).check(matches(not(isDisplayed())))461 onView(withId(R.id.next_state_navigation_button)).check(doesNotExist())462 }463 }464 @Test465 fun testStateFragment_loadDragDropExp_mergeFirstTwoItems_worksCorrectly() {466 launchForExploration(TEST_EXPLORATION_ID_4).use {467 startPlayingExploration()468 mergeDragAndDropItems(position = 0)469 scrollToViewType(DRAG_DROP_SORT_INTERACTION)470 onView(471 atPositionOnView(472 recyclerViewId = R.id.drag_drop_interaction_recycler_view,473 position = 0,474 targetViewId = R.id.drag_drop_item_recyclerview475 )476 ).check(matches(hasChildCount(2)))477 }478 }479 @Test480 fun testStateFragment_loadDragDropExp_mergeFirstTwoItems_invalidAnswer_correctItemCount() {481 launchForExploration(TEST_EXPLORATION_ID_4).use {482 startPlayingExploration()483 mergeDragAndDropItems(position = 0)484 clickSubmitAnswerButton()485 scrollToViewType(SUBMITTED_ANSWER)486 onView(withId(R.id.submitted_answer_recycler_view)).check(matches(hasChildCount(3)))487 onView(488 atPositionOnView(489 recyclerViewId = R.id.submitted_answer_recycler_view,490 position = 0,491 targetViewId = R.id.submitted_html_answer_recycler_view492 )493 ).check(matches(hasChildCount(2)))494 }495 }496 @Test497 fun testStateFragment_loadDragDropExp_wrongAnswer_contentDescriptionIsCorrect() {498 launchForExploration(TEST_EXPLORATION_ID_4).use {499 startPlayingExploration()500 mergeDragAndDropItems(position = 0)501 clickSubmitAnswerButton()502 scrollToViewType(SUBMITTED_ANSWER)503 onView(withId(R.id.submitted_answer_recycler_view_container)).check(504 matches(505 withContentDescription(506 context.getString(R.string.incorrect_submitted_answer)507 )508 )509 )510 }511 }512 @Test513 fun testStateFragment_loadDragDropExp_correctAnswer_contentDescriptionIsCorrect() {514 launchForExploration(TEST_EXPLORATION_ID_2).use {515 startPlayingExploration()516 playThroughPrototypeState1()517 playThroughPrototypeState2()518 playThroughPrototypeState3()519 playThroughPrototypeState4()520 playThroughPrototypeState5()521 playThroughPrototypeState6()522 playThroughPrototypeState7()523 playThroughPrototypeState8()524 // Drag and drop interaction without grouping.525 // Ninth state: Drag Drop Sort. Correct answer: Move 1st item to 4th position.526 dragAndDropItem(fromPosition = 0, toPosition = 3)527 clickSubmitAnswerButton()528 scrollToViewType(SUBMITTED_ANSWER)529 onView(withId(R.id.submitted_answer_recycler_view_container)).check(530 matches(531 withContentDescription(532 context.getString(R.string.correct_submitted_answer)533 )534 )535 )536 }537 }538 @Test539 @RunOn(TestPlatform.ESPRESSO) // TODO(#1612): Enable for Robolectric.540 fun testStateFragment_loadDragDropExp_mergeFirstTwoItems_dragItem_worksCorrectly() {541 // Note to self: current setup allows the user to drag the view without issues (now that542 // event interception isn't a problem), however the view is going partly offscreen which543 // is triggering an infinite animation loop in ItemTouchHelper).544 launchForExploration(TEST_EXPLORATION_ID_4).use {545 startPlayingExploration()546 mergeDragAndDropItems(position = 0)547 dragAndDropItem(fromPosition = 0, toPosition = 2)548 scrollToViewType(DRAG_DROP_SORT_INTERACTION)549 onView(550 atPositionOnView(551 recyclerViewId = R.id.drag_drop_interaction_recycler_view,552 position = 2,553 targetViewId = R.id.drag_drop_content_text_view554 )555 ).check(matches(withText("a camera at the store")))556 }557 }558 @Test559 fun testStateFragment_loadDragDropExp_mergeFirstTwoItems_unlinkFirstItem_worksCorrectly() {560 launchForExploration(TEST_EXPLORATION_ID_4).use {561 startPlayingExploration()562 mergeDragAndDropItems(position = 0)563 unlinkDragAndDropItems(position = 0)564 scrollToViewType(DRAG_DROP_SORT_INTERACTION)565 onView(566 atPositionOnView(567 recyclerViewId = R.id.drag_drop_interaction_recycler_view,568 position = 0,569 targetViewId = R.id.drag_drop_item_recyclerview570 )571 ).check(matches(hasChildCount(1)))572 }573 }574 @Test575 @RunOn(TestPlatform.ESPRESSO) // TODO(#1611): Enable for Robolectric.576 @Ignore("Flaky test") // TODO(#3171): Fix ImageRegion failing test cases.577 fun testStateFragment_loadImageRegion_clickRegion6_submitButtonEnabled() {578 launchForExploration(TEST_EXPLORATION_ID_5).use {579 startPlayingExploration()580 waitForImageViewInteractionToFullyLoad()581 clickImageRegion(pointX = 0.5f, pointY = 0.5f)582 scrollToViewType(SUBMIT_ANSWER_BUTTON)583 onView(withId(R.id.submit_answer_button)).check(matches(isEnabled()))584 }585 }586 @Test587 @RunOn(TestPlatform.ESPRESSO) // TODO(#1611): Enable for Robolectric.588 @Ignore("Flaky test") // TODO(#3171): Fix ImageRegion failing test cases.589 fun testStateFragment_loadImageRegion_clickRegion6_clickSubmit_receivesCorrectFeedback() {590 launchForExploration(TEST_EXPLORATION_ID_5).use {591 startPlayingExploration()592 waitForImageViewInteractionToFullyLoad()593 clickImageRegion(pointX = 0.5f, pointY = 0.5f)594 clickSubmitAnswerButton()595 scrollToViewType(FEEDBACK)596 onView(withId(R.id.feedback_text_view)).check(597 matches(598 withText(containsString("Saturn"))599 )600 )601 }602 }603 @Test604 @RunOn(TestPlatform.ESPRESSO) // TODO(#1611): Enable for Robolectric.605 @Ignore("Flaky test") // TODO(#3171): Fix ImageRegion failing test cases.606 fun testStateFragment_loadImageRegion_submitButtonDisabled() {607 launchForExploration(TEST_EXPLORATION_ID_5).use {608 startPlayingExploration()609 waitForImageViewInteractionToFullyLoad()610 scrollToViewType(SUBMIT_ANSWER_BUTTON)611 onView(withId(R.id.submit_answer_button)).check(matches(not(isEnabled())))612 }613 }614 @Test615 @RunOn(TestPlatform.ESPRESSO) // TODO(#1611): Enable for Robolectric.616 @Ignore("Flaky test") // TODO(#3171): Fix ImageRegion failing test cases.617 fun testStateFragment_loadImageRegion_defaultRegionClick_defRegionClicked_submitButtonDisabled() {618 launchForExploration(TEST_EXPLORATION_ID_5).use {619 startPlayingExploration()620 waitForImageViewInteractionToFullyLoad()621 clickImageRegion(pointX = 0.1f, pointY = 0.5f)622 scrollToViewType(SUBMIT_ANSWER_BUTTON)623 onView(withId(R.id.submit_answer_button)).check(matches(not(isEnabled())))624 }625 }626 @Test627 @RunOn(TestPlatform.ESPRESSO) // TODO(#1611): Enable for Robolectric.628 @Ignore("Flaky test") // TODO(#3171): Fix ImageRegion failing test cases.629 fun testStateFragment_loadImageRegion_clickedRegion6_region6Clicked_submitButtonEnabled() {630 launchForExploration(TEST_EXPLORATION_ID_5).use {631 startPlayingExploration()632 waitForImageViewInteractionToFullyLoad()633 clickImageRegion(pointX = 0.5f, pointY = 0.5f)634 scrollToViewType(SUBMIT_ANSWER_BUTTON)635 onView(withId(R.id.submit_answer_button)).check(matches(isEnabled()))636 }637 }638 @Test639 @RunOn(TestPlatform.ESPRESSO) // TODO(#1611): Enable for Robolectric.640 @Ignore("Flaky test") // TODO(#3171): Fix ImageRegion failing test cases.641 fun testStateFragment_loadImageRegion_clickedRegion6_region6Clicked_correctFeedback() {642 launchForExploration(TEST_EXPLORATION_ID_5).use {643 startPlayingExploration()644 waitForImageViewInteractionToFullyLoad()645 clickImageRegion(pointX = 0.5f, pointY = 0.5f)646 clickSubmitAnswerButton()647 scrollToViewType(FEEDBACK)648 onView(withId(R.id.feedback_text_view)).check(649 matches(650 withText(containsString("Saturn"))651 )652 )653 }654 }655 @Test656 @RunOn(TestPlatform.ESPRESSO) // TODO(#1611): Enable for Robolectric.657 @Ignore("Flaky test") // TODO(#3171): Fix ImageRegion failing test cases.658 fun testStateFragment_loadImageRegion_clickedRegion6_region6Clicked_correctAnswer() {659 launchForExploration(TEST_EXPLORATION_ID_5).use {660 startPlayingExploration()661 waitForImageViewInteractionToFullyLoad()662 clickImageRegion(pointX = 0.5f, pointY = 0.5f)663 clickSubmitAnswerButton()664 scrollToViewType(SUBMITTED_ANSWER)665 onView(withId(R.id.submitted_answer_text_view)).check(666 matches(667 withText("Clicks on Saturn")668 )669 )670 }671 }672 @Test673 @RunOn(TestPlatform.ESPRESSO) // TODO(#1611): Enable for Robolectric.674 @Ignore("Flaky test") // TODO(#3171): Fix ImageRegion failing test cases.675 fun testStateFragment_loadImageRegion_clickedRegion6_region6Clicked_continueButtonIsDisplayed() {676 launchForExploration(TEST_EXPLORATION_ID_5).use {677 startPlayingExploration()678 waitForImageViewInteractionToFullyLoad()679 clickImageRegion(pointX = 0.5f, pointY = 0.5f)680 clickSubmitAnswerButton()681 scrollToViewType(CONTINUE_NAVIGATION_BUTTON)682 onView(withId(R.id.continue_navigation_button)).check(matches(isDisplayed()))683 }684 }685 @Test686 @RunOn(TestPlatform.ESPRESSO) // TODO(#1611): Enable for Robolectric.687 @Ignore("Flaky test") // TODO(#3171): Fix ImageRegion failing test cases.688 fun testStateFragment_loadImageRegion_clickRegion6_clickedRegion5_clickRegion5_correctFeedback() {689 launchForExploration(TEST_EXPLORATION_ID_5).use {690 startPlayingExploration()691 waitForImageViewInteractionToFullyLoad()692 clickImageRegion(pointX = 0.5f, pointY = 0.5f)693 clickImageRegion(pointX = 0.2f, pointY = 0.5f)694 clickSubmitAnswerButton()695 scrollToViewType(FEEDBACK)696 onView(withId(R.id.feedback_text_view)).check(697 matches(698 withText(containsString("Jupiter"))699 )700 )701 }702 }703 @Test704 fun testStateFragment_loadExp_changeConfiguration_firstState_prevAndNextButtonIsNotDisplayed() {705 launchForExploration(TEST_EXPLORATION_ID_2).use {706 startPlayingExploration()707 rotateToLandscape()708 onView(withId(R.id.previous_state_navigation_button)).check(matches(not(isDisplayed())))709 onView(withId(R.id.next_state_navigation_button)).check(doesNotExist())710 }711 }712 @Test713 fun testStateFragment_loadExp_submitAnswer_clickContinueButton_previousButtonIsDisplayed() {714 launchForExploration(TEST_EXPLORATION_ID_2).use {715 startPlayingExploration()716 clickContinueInteractionButton()717 onView(withId(R.id.previous_state_navigation_button)).check(matches(isDisplayed()))718 }719 }720 @Test721 fun testStateFragment_loadExp_changeConfig_submitAnswer_clickContinue_prevButtonIsDisplayed() {722 launchForExploration(TEST_EXPLORATION_ID_2).use {723 startPlayingExploration()724 rotateToLandscape()725 clickContinueInteractionButton()726 onView(withId(R.id.previous_state_navigation_button)).check(matches(isDisplayed()))727 }728 }729 @Test730 fun testStateFragment_loadExp_submitAnswer_clickContinueThenPrevious_onlyNextButtonIsShown() {731 launchForExploration(TEST_EXPLORATION_ID_2).use {732 startPlayingExploration()733 clickContinueInteractionButton()734 clickPreviousNavigationButton()735 // Since we navigated back to the first state, only the next navigation button is visible.736 scrollToViewType(NEXT_NAVIGATION_BUTTON)737 onView(withId(R.id.previous_state_navigation_button)).check(matches(not(isDisplayed())))738 onView(withId(R.id.next_state_navigation_button)).check(matches(isDisplayed()))739 }740 }741 @Test742 fun testStateFragment_loadExp_changeConfig_submit_clickContinueThenPrev_onlyNextButtonShown() {743 launchForExploration(TEST_EXPLORATION_ID_2).use {744 startPlayingExploration()745 rotateToLandscape()746 clickContinueInteractionButton()747 clickPreviousNavigationButton()748 // Since we navigated back to the first state, only the next navigation button is visible.749 scrollToViewType(NEXT_NAVIGATION_BUTTON)750 onView(withId(R.id.previous_state_navigation_button)).check(matches(not(isDisplayed())))751 onView(withId(R.id.next_state_navigation_button)).check(matches(isDisplayed()))752 }753 }754 @Test755 fun testStateFragment_loadExp_submitAnswer_clickContinueThenPrevThenNext_prevAndSubmitShown() {756 launchForExploration(TEST_EXPLORATION_ID_2).use {757 startPlayingExploration()758 clickContinueInteractionButton()759 clickPreviousNavigationButton()760 clickNextNavigationButton()761 // Navigating back to the second state should show the previous & submit buttons, but not the762 // next button.763 scrollToViewType(SUBMIT_ANSWER_BUTTON)764 onView(withId(R.id.previous_state_navigation_button)).check(matches(isDisplayed()))765 onView(withId(R.id.submit_answer_button)).check(matches(isDisplayed()))766 onView(withId(R.id.next_state_navigation_button)).check(doesNotExist())767 }768 }769 @Test770 fun testStateFragment_loadExp_land_submit_clickContinueThenPrevThenNext_prevAndSubmitShown() {771 launchForExploration(TEST_EXPLORATION_ID_2).use {772 startPlayingExploration()773 rotateToLandscape()774 clickContinueInteractionButton()775 clickPreviousNavigationButton()776 clickNextNavigationButton()777 // Navigating back to the second state should show the previous & submit buttons, but not the778 // next button.779 scrollToViewType(SUBMIT_ANSWER_BUTTON)780 onView(withId(R.id.previous_state_navigation_button)).check(matches(isDisplayed()))781 onView(withId(R.id.submit_answer_button)).check(matches(isDisplayed()))782 onView(withId(R.id.next_state_navigation_button)).check(doesNotExist())783 }784 }785 @Test786 @RunOn(TestPlatform.ESPRESSO) // TODO(#1612): Enable for Robolectric.787 fun testStateFragment_loadExp_continueToEndExploration_hasReturnToTopicButton() {788 launchForExploration(TEST_EXPLORATION_ID_2).use {789 startPlayingExploration()790 playThroughPrototypeExploration()791 // Ninth state: end exploration.792 scrollToViewType(RETURN_TO_TOPIC_NAVIGATION_BUTTON)793 onView(withId(R.id.return_to_topic_button)).check(794 matches(withText(R.string.state_end_exploration_button))795 )796 }797 }798 @Test799 @RunOn(TestPlatform.ESPRESSO) // TODO(#1612): Enable for Robolectric.800 fun testStateFragment_loadExp_changeConfiguration_continueToEnd_hasReturnToTopicButton() {801 launchForExploration(TEST_EXPLORATION_ID_2).use {802 startPlayingExploration()803 rotateToLandscape()804 playThroughPrototypeExploration()805 // Ninth state: end exploration.806 scrollToViewType(RETURN_TO_TOPIC_NAVIGATION_BUTTON)807 onView(withId(R.id.return_to_topic_button)).check(808 matches(withText(R.string.state_end_exploration_button))809 )810 }811 }812 @Test813 @RunOn(TestPlatform.ESPRESSO) // TODO(#1612): Enable for Robolectric.814 fun testStateFragment_loadExp_continueToEndExploration_clickReturnToTopic_destroysActivity() {815 launchForExploration(TEST_EXPLORATION_ID_2).use {816 startPlayingExploration()817 playThroughPrototypeExploration()818 clickReturnToTopicButton()819 // Due to the exploration activity finishing, the play button should be visible again.820 onView(withId(R.id.play_test_exploration_button)).check(matches(isDisplayed()))821 }822 }823 @Test824 @RunOn(TestPlatform.ESPRESSO) // TODO(#1612): Enable for Robolectric.825 fun testStateFragment_loadExp_changeConfig_continueToEnd_clickReturnToTopic_destroysActivity() {826 launchForExploration(TEST_EXPLORATION_ID_2).use {827 startPlayingExploration()828 rotateToLandscape()829 playThroughPrototypeExploration()830 clickReturnToTopicButton()831 // Due to the exploration activity finishing, the play button should be visible again.832 onView(withId(R.id.play_test_exploration_button)).check(matches(isDisplayed()))833 }834 }835 @Test836 fun testContentCard_forPrototypeExploration_withCustomOppiaTags_displaysParsedHtml() {837 launchForExploration(TEST_EXPLORATION_ID_2).use {838 startPlayingExploration()839 scrollToViewType(CONTENT)840 verifyContentContains("Test exploration with interactions.")841 }842 }843 @Test844 fun testContentCard_forPrototypeExploration_changeConfig_withCustomTags_displaysParsedHtml() {845 launchForExploration(TEST_EXPLORATION_ID_2).use {846 startPlayingExploration()847 scrollToViewType(CONTENT)848 verifyContentContains("Test exploration with interactions.")849 }850 }851 @Test852 fun testStateFragment_inputRatio_correctAnswerSubmitted_correctAnswerIsDisplayed() {853 launchForExploration(TEST_EXPLORATION_ID_2).use {854 startPlayingExploration()855 playThroughPrototypeState1()856 playThroughPrototypeState2()857 playThroughPrototypeState3()858 playThroughPrototypeState4()859 playThroughPrototypeState5()860 playThroughPrototypeState6()861 typeRatioExpression("4:5")862 clickSubmitAnswerButton()863 onView(withId(R.id.submitted_answer_text_view))864 .check(matches(withContentDescription("Correct submitted answer: 4 to 5")))865 }866 }867 @Test868 fun testStateFragment_forHintsAndSolution_incorrectInputTwice_hintBulbContainerIsVisible() {869 launchForExploration(FRACTIONS_EXPLORATION_ID_1).use {870 startPlayingExploration()871 selectMultipleChoiceOption(872 optionPosition = 3,873 expectedOptionText = "No, because, in a fraction, the pieces must be the same size."874 )875 clickContinueNavigationButton()876 // Entering incorrect answer twice.877 typeFractionText("1/2")878 clickSubmitAnswerButton()879 scrollToViewType(FRACTION_INPUT_INTERACTION)880 typeFractionText("1/2")881 clickSubmitAnswerButton()882 onView(withId(R.id.hints_and_solution_fragment_container)).check(matches(isDisplayed()))883 }884 }885 @Test886 fun testStateFragment_showHintsAndSolutionBulb_dotHasCorrectContentDescription() {887 launchForExploration(FRACTIONS_EXPLORATION_ID_1).use {888 startPlayingExploration()889 selectMultipleChoiceOption(890 optionPosition = 3,891 expectedOptionText = "No, because, in a fraction, the pieces must be the same size."892 )893 clickContinueNavigationButton()894 // Entering incorrect answer twice.895 typeFractionText("1/2")896 clickSubmitAnswerButton()897 scrollToViewType(FRACTION_INPUT_INTERACTION)898 typeFractionText("1/2")899 clickSubmitAnswerButton()900 onView(withId(R.id.dot_hint)).check(901 matches(902 withContentDescription(R.string.new_hint_available)903 )904 )905 }906 }907 @Test908 fun testStateFragment_showHintsAndSolutionBulb_bulbHasCorrectContentDescription() {909 launchForExploration(FRACTIONS_EXPLORATION_ID_1).use {910 startPlayingExploration()911 selectMultipleChoiceOption(912 optionPosition = 3,913 expectedOptionText = "No, because, in a fraction, the pieces must be the same size."914 )915 clickContinueNavigationButton()916 // Entering incorrect answer twice.917 typeFractionText("1/2")918 clickSubmitAnswerButton()919 scrollToViewType(FRACTION_INPUT_INTERACTION)920 typeFractionText("1/2")921 clickSubmitAnswerButton()922 onView(withId(R.id.hint_bulb)).check(923 matches(924 withContentDescription(R.string.show_hints_and_solution)925 )926 )927 }928 }929 @Test930 fun testStateFragment_forMisconception_showsLinkTextForConceptCard() {931 launchForExploration(FRACTIONS_EXPLORATION_ID_1).use {932 startPlayingExploration()933 selectMultipleChoiceOption(934 optionPosition = 3,935 expectedOptionText = "No, because, in a fraction, the pieces must be the same size."936 )937 clickContinueNavigationButton()938 // This answer is incorrect and a detected misconception.939 typeFractionText("3/2")940 clickSubmitAnswerButton()941 scrollToViewType(FEEDBACK)942 onView(withId(R.id.feedback_text_view)).check(943 matches(944 withText(containsString("Take a look at the short refresher lesson"))945 )946 )947 }948 }949 @Test950 fun testStateFragment_landscape_forMisconception_showsLinkTextForConceptCard() {951 launchForExploration(FRACTIONS_EXPLORATION_ID_1).use {952 rotateToLandscape()953 startPlayingExploration()954 selectMultipleChoiceOption(955 optionPosition = 3,956 expectedOptionText = "No, because, in a fraction, the pieces must be the same size."957 )958 clickContinueNavigationButton()959 // This answer is incorrect and a detected misconception.960 typeFractionText("3/2")961 clickSubmitAnswerButton()962 scrollToViewType(FEEDBACK)963 onView(withId(R.id.feedback_text_view)).check(964 matches(965 withText(containsString("Take a look at the short refresher lesson"))966 )967 )968 }969 }970 @Test971 fun testStateFragment_forMisconception_clickLinkText_opensConceptCard() {972 launchForExploration(FRACTIONS_EXPLORATION_ID_1).use {973 startPlayingExploration()974 selectMultipleChoiceOption(975 optionPosition = 3,976 expectedOptionText = "No, because, in a fraction, the pieces must be the same size."977 )978 clickContinueNavigationButton()979 typeFractionText("3/2") // Misconception.980 clickSubmitAnswerButton()981 onView(withId(R.id.feedback_text_view)).perform(openClickableSpan("refresher lesson"))982 testCoroutineDispatchers.runCurrent()983 onView(withText("Concept Card")).inRoot(isDialog()).check(matches(isDisplayed()))984 onView(withId(R.id.concept_card_heading_text))985 .inRoot(isDialog())986 .check(matches(withText(containsString("Identify the numerator and denominator"))))987 }988 }989 @Test990 fun testStateFragment_landscape_forMisconception_clickLinkText_opensConceptCard() {991 launchForExploration(FRACTIONS_EXPLORATION_ID_1).use {992 rotateToLandscape()993 startPlayingExploration()994 selectMultipleChoiceOption(995 optionPosition = 3,996 expectedOptionText = "No, because, in a fraction, the pieces must be the same size."997 )998 clickContinueNavigationButton()999 typeFractionText("3/2") // Misconception.1000 clickSubmitAnswerButton()1001 onView(withId(R.id.feedback_text_view)).perform(openClickableSpan("refresher lesson"))1002 testCoroutineDispatchers.runCurrent()1003 onView(withText("Concept Card")).inRoot(isDialog()).check(matches(isDisplayed()))1004 onView(withId(R.id.concept_card_heading_text))1005 .inRoot(isDialog())1006 .check(matches(withText(containsString("Identify the numerator and denominator"))))1007 }1008 }1009 @Test1010 fun testStateFragment_interactions_initialStateIsContinueInteraction() {1011 launchForExploration(TEST_EXPLORATION_ID_2).use {1012 startPlayingExploration()1013 // Verify that the initial state is the continue interaction.1014 verifyViewTypeIsPresent(CONTINUE_INTERACTION)1015 verifyContentContains("Test exploration with interactions")1016 }1017 }1018 @Test1019 fun testStateFragment_interactions_continueInteraction_canSuccessfullySubmitAnswer() {1020 launchForExploration(TEST_EXPLORATION_ID_2).use {1021 startPlayingExploration()1022 // Continue interaction.1023 playThroughPrototypeState1()1024 // Verify that the user is now on the second state.1025 verifyViewTypeIsPresent(FRACTION_INPUT_INTERACTION)1026 verifyContentContains("What fraction represents half of something?")1027 }1028 }1029 @Test1030 fun testStateFragment_interactions_fractionInteraction_canSuccessfullySubmitAnswer() {1031 launchForExploration(TEST_EXPLORATION_ID_2).use {1032 startPlayingExploration()1033 playThroughPrototypeState1()1034 // Fraction interaction.1035 playThroughPrototypeState2()1036 // Verify that the user is now on the third state.1037 verifyViewTypeIsPresent(SELECTION_INTERACTION)1038 verifyContentContains("Which bird can sustain flight for long periods of time?")1039 }1040 }1041 @Test1042 fun testStateFragment_interactions_multipleChoiceInteraction_canSuccessfullySubmitAnswer() {1043 launchForExploration(TEST_EXPLORATION_ID_2).use {1044 startPlayingExploration()1045 playThroughPrototypeState1()1046 playThroughPrototypeState2()1047 // Multiple choice interaction.1048 playThroughPrototypeState3()1049 // Verify that the user is now on the fourth state.1050 verifyViewTypeIsPresent(SELECTION_INTERACTION)1051 verifyContentContains("What color does the 'G' in 'RGB' correspond to?")1052 }1053 }1054 @Test1055 fun testStateFragment_interactions_radioItemSelection_hasCorrectAccessibilityAttributes() {1056 launchForExploration(TEST_EXPLORATION_ID_2).use {1057 startPlayingExploration()1058 playThroughPrototypeState1()1059 playThroughPrototypeState2()1060 // Verify that the attributes required for correct accessibility support are present.1061 verifyViewTypeIsPresent(SELECTION_INTERACTION)1062 verifyAccessibilityForItemSelection(1063 position = 0,1064 targetViewId = R.id.multiple_choice_radio_button1065 )1066 }1067 }1068 @Test1069 fun testStateFragment_interactions_radioItemSelection_canSuccessfullySubmitAnswer() {1070 launchForExploration(TEST_EXPLORATION_ID_2).use {1071 startPlayingExploration()1072 playThroughPrototypeState1()1073 playThroughPrototypeState2()1074 playThroughPrototypeState3()1075 // Single selection item selection.1076 playThroughPrototypeState4()1077 // Verify that the user is now on the fifth state.1078 verifyViewTypeIsPresent(SELECTION_INTERACTION)1079 verifyContentContains("What are the primary colors of light?")1080 }1081 }1082 @Test1083 fun testStateFragment_interactions_checkboxItemSelection_hasCorrectAccessibilityAttributes() {1084 launchForExploration(TEST_EXPLORATION_ID_2).use {1085 startPlayingExploration()1086 playThroughPrototypeState1()1087 playThroughPrototypeState2()1088 playThroughPrototypeState3()1089 playThroughPrototypeState4()1090 // Verify that the attributes required for correct accessibility support are present.1091 verifyViewTypeIsPresent(SELECTION_INTERACTION)1092 verifyAccessibilityForItemSelection(position = 1, targetViewId = R.id.item_selection_checkbox)1093 }1094 }1095 @Test1096 fun testStateFragment_interactions_checkboxItemSelection_canSuccessfullySubmitAnswer() {1097 launchForExploration(TEST_EXPLORATION_ID_2).use {1098 startPlayingExploration()1099 playThroughPrototypeState1()1100 playThroughPrototypeState2()1101 playThroughPrototypeState3()1102 playThroughPrototypeState4()1103 // Multi-selection item selection.1104 playThroughPrototypeState5()1105 // Verify that the user is now on the sixth state.1106 verifyViewTypeIsPresent(NUMERIC_INPUT_INTERACTION)1107 verifyContentContains("What is 11 times 11?")1108 }1109 }1110 @Test1111 fun testStateFragment_interactions_numericInputInteraction_canSuccessfullySubmitAnswer() {1112 launchForExploration(TEST_EXPLORATION_ID_2).use {1113 startPlayingExploration()1114 playThroughPrototypeState1()1115 playThroughPrototypeState2()1116 playThroughPrototypeState3()1117 playThroughPrototypeState4()1118 playThroughPrototypeState5()1119 // Numeric input interaction.1120 playThroughPrototypeState6()1121 // Verify that the user is now on the seventh state.1122 verifyViewTypeIsPresent(RATIO_EXPRESSION_INPUT_INTERACTION)1123 verifyContentContains("The ratio of the two numbers is:")1124 }1125 }1126 @Test1127 fun testStateFragment_interactions_numericInputInteraction_hasCorrectHint() {1128 launchForExploration(TEST_EXPLORATION_ID_2).use {1129 startPlayingExploration()1130 playThroughPrototypeState1()1131 playThroughPrototypeState2()1132 playThroughPrototypeState3()1133 playThroughPrototypeState4()1134 // Multi-selection item selection.1135 playThroughPrototypeState5()1136 // Verify that the user is now on the sixth state.1137 verifyViewTypeIsPresent(NUMERIC_INPUT_INTERACTION)1138 verifyHint(context.resources.getString(R.string.numeric_input_hint))1139 }1140 }1141 @Test1142 fun testStateFragment_interactions_ratioInputInteraction_canSuccessfullySubmitAnswer() {1143 launchForExploration(TEST_EXPLORATION_ID_2).use {1144 startPlayingExploration()1145 playThroughPrototypeState1()1146 playThroughPrototypeState2()1147 playThroughPrototypeState3()1148 playThroughPrototypeState4()1149 playThroughPrototypeState5()1150 playThroughPrototypeState6()1151 // Ratio input interaction.1152 playThroughPrototypeState7()1153 // Verify that the user is now on the eighth state.1154 verifyViewTypeIsPresent(TEXT_INPUT_INTERACTION)1155 verifyContentContains("In which language does Oppia mean 'to learn'?")1156 }1157 }1158 @Test1159 fun testStateFragment_interactions_textInputInteraction_canSuccessfullySubmitAnswer() {1160 launchForExploration(TEST_EXPLORATION_ID_2).use {1161 startPlayingExploration()1162 playThroughPrototypeState1()1163 playThroughPrototypeState2()1164 playThroughPrototypeState3()1165 playThroughPrototypeState4()1166 playThroughPrototypeState5()1167 playThroughPrototypeState6()1168 playThroughPrototypeState7()1169 // Text input interaction.1170 playThroughPrototypeState8()1171 // Verify that the user is now on the ninth state.1172 verifyViewTypeIsPresent(DRAG_DROP_SORT_INTERACTION)1173 verifyContentContains("Sort the following in descending order.")1174 }1175 }1176 @Test1177 @RunOn(TestPlatform.ESPRESSO) // TODO(#1612): Enable for Robolectric.1178 fun testStateFragment_interactions_dragAndDropNoGrouping_canSuccessfullySubmitAnswer() {1179 launchForExploration(TEST_EXPLORATION_ID_2).use {1180 startPlayingExploration()1181 playThroughPrototypeState1()1182 playThroughPrototypeState2()1183 playThroughPrototypeState3()1184 playThroughPrototypeState4()1185 playThroughPrototypeState5()1186 playThroughPrototypeState6()1187 playThroughPrototypeState7()1188 playThroughPrototypeState8()1189 // Drag and drop interaction without grouping.1190 playThroughPrototypeState9()1191 // Verify that the user is now on the tenth state.1192 verifyViewTypeIsPresent(DRAG_DROP_SORT_INTERACTION)1193 verifyContentContains("putting equal items in the same position")1194 }1195 }1196 @Test1197 @RunOn(TestPlatform.ESPRESSO) // TODO(#1612): Enable for Robolectric.1198 fun testStateFragment_interactions_dragAndDropWithGrouping_canSuccessfullySubmitAnswer() {1199 launchForExploration(TEST_EXPLORATION_ID_2).use {1200 startPlayingExploration()1201 playThroughPrototypeState1()1202 playThroughPrototypeState2()1203 playThroughPrototypeState3()1204 playThroughPrototypeState4()1205 playThroughPrototypeState5()1206 playThroughPrototypeState6()1207 playThroughPrototypeState7()1208 playThroughPrototypeState8()1209 playThroughPrototypeState9()1210 // Drag and drop interaction with grouping.1211 playThroughPrototypeState10()1212 // Verify that the user is now on the eleventh and final state.1213 verifyViewTypeIsPresent(RETURN_TO_TOPIC_NAVIGATION_BUTTON)1214 }1215 }1216 @Test1217 fun testStateFragment_fractionInput_textViewHasTextInputType() {1218 launchForExploration(TEST_EXPLORATION_ID_2).use { scenario ->1219 startPlayingExploration()1220 // Play to state 2 to access the fraction input interaction.1221 playThroughPrototypeState1()1222 // Verify that fraction input uses the standard text software keyboard.1223 scenario.onActivity { activity ->1224 val textView: TextView = activity.findViewById(R.id.fraction_input_interaction_view)1225 assertThat(textView.inputType).isEqualTo(InputType.TYPE_CLASS_TEXT)1226 }1227 }1228 }1229 @Test1230 fun testStateFragment_ratioInput_textViewHasTextInputType() {1231 launchForExploration(TEST_EXPLORATION_ID_2).use { scenario ->1232 startPlayingExploration()1233 playThroughPrototypeState1()1234 playThroughPrototypeState2()1235 playThroughPrototypeState3()1236 playThroughPrototypeState4()1237 playThroughPrototypeState5()1238 // Play to state 7 to access the ratio input interaction.1239 playThroughPrototypeState6()1240 // Verify that ratio input uses the standard text software keyboard.1241 scenario.onActivity { activity ->1242 val textView: TextView = activity.findViewById(R.id.ratio_input_interaction_view)1243 assertThat(textView.inputType).isEqualTo(InputType.TYPE_CLASS_TEXT)1244 }1245 }1246 }1247 private fun addShadowMediaPlayerException(dataSource: Any, exception: Exception) {1248 val classLoader = StateFragmentTest::class.java.classLoader!!1249 val shadowMediaPlayerClass = classLoader.loadClass("org.robolectric.shadows.ShadowMediaPlayer")1250 val addException =1251 shadowMediaPlayerClass.getDeclaredMethod(1252 "addException", dataSource.javaClass, IOException::class.java1253 )1254 addException.invoke(/* obj= */ null, dataSource, exception)1255 }1256 @Suppress("SameParameterValue")1257 private fun createAudioDataSource(explorationId: String, audioFileName: String): Any {1258 val audioUrl = createAudioUrl(explorationId, audioFileName)1259 val classLoader = StateFragmentTest::class.java.classLoader!!1260 val dataSourceClass = classLoader.loadClass("org.robolectric.shadows.util.DataSource")1261 val toDataSource =1262 dataSourceClass.getDeclaredMethod(1263 "toDataSource", String::class.java, Map::class.java1264 )1265 return toDataSource.invoke(/* obj= */ null, audioUrl, /* headers= */ null)1266 }1267 private fun createAudioUrl(explorationId: String, audioFileName: String): String {1268 return "https://storage.googleapis.com/oppiaserver-resources/" +1269 "exploration/$explorationId/assets/audio/$audioFileName"1270 }1271 private fun launchForExploration(1272 explorationId: String1273 ): ActivityScenario<StateFragmentTestActivity> {1274 return launch(1275 StateFragmentTestActivity.createTestActivityIntent(1276 context,1277 internalProfileId,1278 TEST_TOPIC_ID_0,1279 TEST_STORY_ID_0,1280 explorationId1281 )1282 )1283 }1284 private fun startPlayingExploration() {1285 onView(withId(R.id.play_test_exploration_button)).perform(click())1286 testCoroutineDispatchers.runCurrent()1287 }1288 private fun playThroughPrototypeState1() {1289 // First state: Continue interaction.1290 clickContinueInteractionButton()1291 }1292 private fun playThroughPrototypeState2() {1293 // Second state: Fraction input. Correct answer: 1/2.1294 typeFractionText("1/2")1295 clickSubmitAnswerButton()1296 clickContinueNavigationButton()1297 }1298 private fun playThroughPrototypeState3() {1299 // Third state: Multiple choice. Correct answer: Eagle.1300 selectMultipleChoiceOption(optionPosition = 2, expectedOptionText = "Eagle")1301 clickContinueNavigationButton()1302 }1303 private fun playThroughPrototypeState4() {1304 // Fourth state: Item selection (radio buttons). Correct answer: Green.1305 selectMultipleChoiceOption(optionPosition = 0, expectedOptionText = "Green")1306 clickContinueNavigationButton()1307 }1308 private fun playThroughPrototypeState5() {1309 // Fifth state: Item selection (checkboxes). Correct answer: {Red, Green, Blue}.1310 selectItemSelectionCheckbox(optionPosition = 0, expectedOptionText = "Red")1311 selectItemSelectionCheckbox(optionPosition = 2, expectedOptionText = "Green")1312 selectItemSelectionCheckbox(optionPosition = 3, expectedOptionText = "Blue")1313 clickSubmitAnswerButton()1314 clickContinueNavigationButton()1315 }1316 private fun playThroughPrototypeState6() {1317 // Sixth state: Numeric input. Correct answer: 121.1318 typeNumericInput("121")1319 clickSubmitAnswerButton()1320 clickContinueNavigationButton()1321 }1322 private fun playThroughPrototypeState7() {1323 // Seventh state: Ratio input. Correct answer: 4:5.1324 typeRatioExpression("4:5")1325 clickSubmitAnswerButton()1326 clickContinueNavigationButton()1327 }1328 private fun playThroughPrototypeState8() {1329 // Eighth state: Text input. Correct answer: finnish.1330 typeTextInput("finnish")1331 clickSubmitAnswerButton()1332 clickContinueNavigationButton()1333 }1334 private fun playThroughPrototypeState9() {1335 // Ninth state: Drag Drop Sort. Correct answer: Move 1st item to 4th position.1336 dragAndDropItem(fromPosition = 0, toPosition = 3)1337 clickSubmitAnswerButton()1338 onView(1339 atPositionOnView(1340 recyclerViewId = R.id.submitted_answer_recycler_view,1341 position = 0,1342 targetViewId = R.id.submitted_answer_content_text_view1343 )1344 ).check(matches(withText("3/5")))1345 clickContinueNavigationButton()1346 }1347 private fun playThroughPrototypeState10() {1348 // Tenth state: Drag Drop Sort with grouping. Correct answer: Merge First Two and after merging1349 // move 2nd item to 3rd position.1350 mergeDragAndDropItems(position = 1)1351 unlinkDragAndDropItems(position = 1)1352 mergeDragAndDropItems(position = 0)1353 dragAndDropItem(fromPosition = 1, toPosition = 2)1354 clickSubmitAnswerButton()1355 onView(1356 atPositionOnView(1357 recyclerViewId = R.id.submitted_answer_recycler_view,1358 position = 0,1359 targetViewId = R.id.submitted_answer_content_text_view1360 )1361 ).check(matches(withText("0.6")))1362 clickContinueNavigationButton()1363 }1364 private fun playThroughPrototypeExploration() {1365 playThroughPrototypeState1()1366 playThroughPrototypeState2()1367 playThroughPrototypeState3()1368 playThroughPrototypeState4()1369 playThroughPrototypeState5()1370 playThroughPrototypeState6()1371 playThroughPrototypeState7()1372 playThroughPrototypeState8()1373 playThroughPrototypeState9()1374 playThroughPrototypeState10()1375 }1376 private fun rotateToLandscape() {1377 onView(isRoot()).perform(orientationLandscape())1378 testCoroutineDispatchers.runCurrent()1379 }1380 private fun clickContinueInteractionButton() {1381 scrollToViewType(CONTINUE_INTERACTION)1382 onView(withId(R.id.continue_button)).perform(click())1383 testCoroutineDispatchers.runCurrent()1384 }1385 private fun typeFractionText(text: String) {1386 scrollToViewType(FRACTION_INPUT_INTERACTION)1387 typeTextIntoInteraction(text, interactionViewId = R.id.fraction_input_interaction_view)1388 }1389 @Suppress("SameParameterValue")1390 private fun typeNumericInput(text: String) {1391 scrollToViewType(NUMERIC_INPUT_INTERACTION)1392 typeTextIntoInteraction(text, interactionViewId = R.id.numeric_input_interaction_view)1393 }1394 @Suppress("SameParameterValue")1395 private fun typeTextInput(text: String) {1396 scrollToViewType(TEXT_INPUT_INTERACTION)1397 typeTextIntoInteraction(text, interactionViewId = R.id.text_input_interaction_view)1398 }1399 @Suppress("SameParameterValue")1400 private fun typeRatioExpression(text: String) {1401 scrollToViewType(RATIO_EXPRESSION_INPUT_INTERACTION)1402 typeTextIntoInteraction(text, interactionViewId = R.id.ratio_input_interaction_view)1403 }1404 private fun selectMultipleChoiceOption(optionPosition: Int, expectedOptionText: String) {1405 clickSelection(1406 optionPosition,1407 targetClickViewId = R.id.multiple_choice_radio_button,1408 expectedText = expectedOptionText,1409 targetTextViewId = R.id.multiple_choice_content_text_view1410 )1411 }1412 private fun selectItemSelectionCheckbox(optionPosition: Int, expectedOptionText: String) {1413 clickSelection(1414 optionPosition,1415 targetClickViewId = R.id.item_selection_checkbox,1416 expectedText = expectedOptionText,1417 targetTextViewId = R.id.item_selection_contents_text_view1418 )1419 }1420 private fun dragAndDropItem(fromPosition: Int, toPosition: Int) {1421 scrollToViewType(DRAG_DROP_SORT_INTERACTION)1422 onView(withId(R.id.drag_drop_interaction_recycler_view)).perform(1423 DragViewAction(1424 RecyclerViewCoordinatesProvider(1425 fromPosition,1426 ChildViewCoordinatesProvider(1427 R.id.drag_drop_item_container,1428 GeneralLocation.CENTER1429 )1430 ),1431 RecyclerViewCoordinatesProvider(toPosition, CustomGeneralLocation.UNDER_RIGHT),1432 Press.FINGER1433 )1434 )1435 testCoroutineDispatchers.runCurrent()1436 }1437 private fun mergeDragAndDropItems(position: Int) {1438 clickDragAndDropOption(position, targetViewId = R.id.drag_drop_content_group_item)1439 }1440 private fun unlinkDragAndDropItems(position: Int) {1441 clickDragAndDropOption(position, targetViewId = R.id.drag_drop_content_unlink_items)1442 }1443 @Suppress("SameParameterValue")1444 private fun clickImageRegion(pointX: Float, pointY: Float) {1445 onView(withId(R.id.image_click_interaction_image_view)).perform(1446 clickPoint(pointX, pointY)1447 )1448 testCoroutineDispatchers.runCurrent()1449 }1450 private fun clickSubmitAnswerButton() {1451 scrollToViewType(SUBMIT_ANSWER_BUTTON)1452 onView(withId(R.id.submit_answer_button)).perform(click())1453 testCoroutineDispatchers.runCurrent()1454 }1455 private fun clickContinueNavigationButton() {1456 scrollToViewType(CONTINUE_NAVIGATION_BUTTON)1457 onView(withId(R.id.continue_navigation_button)).perform(click())1458 testCoroutineDispatchers.runCurrent()1459 }1460 private fun clickReturnToTopicButton() {1461 scrollToViewType(RETURN_TO_TOPIC_NAVIGATION_BUTTON)1462 onView(withId(R.id.return_to_topic_button)).perform(click())1463 testCoroutineDispatchers.runCurrent()1464 }1465 private fun clickPreviousNavigationButton() {1466 onView(withId(R.id.previous_state_navigation_button)).perform(click())1467 testCoroutineDispatchers.runCurrent()1468 }1469 private fun clickNextNavigationButton() {1470 scrollToViewType(NEXT_NAVIGATION_BUTTON)1471 onView(withId(R.id.next_state_navigation_button)).perform(click())1472 testCoroutineDispatchers.runCurrent()1473 }1474 private fun waitForImageViewInteractionToFullyLoad() {1475 // TODO(#669): Remove explicit delay - https://github.com/oppia/oppia-android/issues/15231476 waitForTheView(1477 allOf(1478 withId(R.id.image_click_interaction_image_view),1479 WithNonZeroDimensionsMatcher()1480 )1481 )1482 }1483 private fun typeTextIntoInteraction(text: String, interactionViewId: Int) {1484 onView(withId(interactionViewId)).perform(1485 editTextInputAction.appendText(text),1486 closeSoftKeyboard()1487 )1488 testCoroutineDispatchers.runCurrent()1489 }1490 private fun clickSelection(1491 optionPosition: Int,1492 targetClickViewId: Int,1493 expectedText: String,1494 targetTextViewId: Int1495 ) {1496 scrollToViewType(SELECTION_INTERACTION)1497 onView(1498 atPositionOnView(1499 recyclerViewId = R.id.selection_interaction_recyclerview,1500 position = optionPosition,1501 targetViewId = targetTextViewId1502 )1503 ).check(matches(withText(containsString(expectedText))))1504 // Then, click on it.1505 onView(1506 atPositionOnView(1507 recyclerViewId = R.id.selection_interaction_recyclerview,1508 position = optionPosition,1509 targetViewId = targetClickViewId1510 )1511 ).perform(click())1512 testCoroutineDispatchers.runCurrent()1513 }1514 private fun clickDragAndDropOption(position: Int, targetViewId: Int) {1515 scrollToViewType(DRAG_DROP_SORT_INTERACTION)1516 onView(1517 atPositionOnView(1518 recyclerViewId = R.id.drag_drop_interaction_recycler_view,1519 position = position,1520 targetViewId = targetViewId1521 )1522 ).perform(click())1523 testCoroutineDispatchers.runCurrent()1524 }1525 private fun scrollToViewType(viewType: StateItemViewModel.ViewType) {1526 onView(withId(R.id.state_recycler_view)).perform(1527 scrollToHolder(StateViewHolderTypeMatcher(viewType))1528 )1529 testCoroutineDispatchers.runCurrent()1530 }1531 private fun verifyContentContains(expectedHtml: String) {1532 scrollToViewType(CONTENT)1533 onView(1534 atPositionOnView(1535 recyclerViewId = R.id.state_recycler_view,1536 position = 0,1537 targetViewId = R.id.content_text_view1538 )1539 ).check(matches(withText(containsString(expectedHtml))))1540 }1541 private fun verifyHint(hint: String) {1542 scrollToViewType(NUMERIC_INPUT_INTERACTION)1543 onView(1544 atPositionOnView(1545 recyclerViewId = R.id.state_recycler_view,1546 position = 1,1547 targetViewId = R.id.numeric_input_interaction_view1548 )1549 ).check(matches(withHint(containsString(hint))))1550 }1551 private fun verifyViewTypeIsPresent(viewType: StateItemViewModel.ViewType) {1552 // Attempting to scroll to the specified view type is sufficient to verify that it's present.1553 scrollToViewType(viewType)1554 }1555 private fun verifyAccessibilityForItemSelection(position: Int, targetViewId: Int) {1556 onView(1557 atPositionOnView(1558 recyclerViewId = R.id.selection_interaction_recyclerview,1559 position = position,1560 targetViewId = targetViewId1561 )1562 ).check(matches(not(isClickable())))1563 onView(1564 atPositionOnView(1565 recyclerViewId = R.id.selection_interaction_recyclerview,1566 position = position,1567 targetViewId = targetViewId1568 )1569 ).check(matches(not(isFocusable())))1570 testCoroutineDispatchers.runCurrent()1571 }1572 private fun waitForTheView(viewMatcher: Matcher<View>): ViewInteraction {1573 return onView(isRoot()).perform(waitForMatch(viewMatcher, 30000L))1574 }1575 private fun setUpTestApplicationComponent() {1576 ApplicationProvider.getApplicationContext<TestApplication>().inject(this)1577 }1578 private fun isOnRobolectric(): Boolean {1579 return ApplicationProvider.getApplicationContext<TestApplication>().isOnRobolectric()1580 }1581 // TODO(#59): Remove these waits once we can ensure that the production executors are not depended on in tests.1582 // Sleeping is really bad practice in Espresso tests, and can lead to test flakiness. It shouldn't be necessary if we1583 // use a test executor service with a counting idle resource, but right now Gradle mixes dependencies such that both...
Builders.kt
Source:Builders.kt
...299 }300 /**301 * Matches root that is focusable302 */303 fun isFocusable() {304 rootMatchers.add(RootMatchers.isFocusable())305 }306 /**307 * Matches root that is not focusable308 */309 fun isNotFocusable() {310 rootMatchers.add(Matchers.not(RootMatchers.isFocusable()))311 }312 /**313 * Matches root that is platform popup314 */315 fun isPlatformPopup() {316 rootMatchers.add(RootMatchers.isPlatformPopup())317 }318 /**319 * Matches root that is not platform popup320 */321 fun isNotPlatformPopup() {322 rootMatchers.add(Matchers.not(RootMatchers.isPlatformPopup()))323 }324 /**...
MyTaxi.kt
Source:MyTaxi.kt
...52 // Expecting to see error message displaying on screen53 @Test54 fun B_OneEmptyField() {55 onView(withId(R.id.edt_username))56 .check(matches(isFocusable()))57 onView(withId(R.id.edt_username))58 .perform(ViewActions.replaceText(username))59 onView(withId(R.id.btn_login))60 .perform(click())61 onView(withId(R.id.edt_username))62 .perform(ViewActions.clearText())63 onView(withId(R.id.edt_password))64 .perform(ViewActions.replaceText(password))65 onView(withId(R.id.btn_login))66 .perform(click())67 onView(withId(R.id.snackbar_text))68 .check(matches(withText(R.string.message_login_fail)))69 }70 // Clicking on Login button with empty username and password after....
ViewMatchersTest.kt
Source:ViewMatchersTest.kt
...25import android.support.test.espresso.matcher.ViewMatchers.isChecked26import android.support.test.espresso.matcher.ViewMatchers.isDescendantOfA27import android.support.test.espresso.matcher.ViewMatchers.isDisplayed28import android.support.test.espresso.matcher.ViewMatchers.isEnabled29import android.support.test.espresso.matcher.ViewMatchers.isFocusable30import android.support.test.espresso.matcher.ViewMatchers.isSelected31import android.support.test.espresso.matcher.ViewMatchers.supportsInputMethods32import android.support.test.espresso.matcher.ViewMatchers.withChild33import android.support.test.espresso.matcher.ViewMatchers.withClassName34import android.support.test.espresso.matcher.ViewMatchers.withContentDescription35import android.support.test.espresso.matcher.ViewMatchers.withHint36import android.support.test.espresso.matcher.ViewMatchers.withId37import android.support.test.espresso.matcher.ViewMatchers.withParent38import android.support.test.espresso.matcher.ViewMatchers.withText39import org.hamcrest.CoreMatchers.allOf40import org.hamcrest.CoreMatchers.`is`41import org.hamcrest.CoreMatchers.not42/**43 * Lists all ViewMatchers. ViewMatchers here are without functional load.44 * This is done for demonstration purposes.45 */46@RunWith(AndroidJUnit4::class)47class ViewMatchersTest {48 @Test49 fun userProperties() {50 onView(withId(R.id.fab_add_task))51 onView(withText("All TO-DOs"))52 onView(withContentDescription(R.string.menu_filter))53 onView(hasContentDescription())54 onView(withHint(R.string.name_hint))55 }56 @Test57 fun uiProperties() {58 onView(isDisplayed())59 onView(isEnabled())60 onView(isChecked())61 onView(isSelected())62 }63 @Test64 fun objectMatcher() {65 onView(not<View>(isChecked()))66 onView(allOf<View>(withText("item 1"), isChecked()))67 }68 @Test69 fun hierarchy() {70 onView(withParent(withId(R.id.todo_item)))71 onView(withChild(withText("item 2")))72 onView(isDescendantOfA(withId(R.id.todo_item)))73 onView(hasDescendant(isChecked()))74 .check(matches(isDisplayed()))75 .check(matches(isFocusable()))76 onView(hasSibling(withContentDescription(R.string.menu_filter)))77 }78 @Test79 fun input() {80 onView(supportsInputMethods())81 onView(hasImeAction(EditorInfo.IME_ACTION_SEND))82 }83 @Test84 fun classMatchers() {85 onView(isAssignableFrom(CheckBox::class.java))86 onView(withClassName(`is`(FloatingActionButton::class.java.canonicalName)))87 }88 @Test89 fun rootMatchers() {90 onView(isFocusable())91 onView(withText(R.string.name_hint)).inRoot(isTouchable())92 onView(withText(R.string.name_hint)).inRoot(isDialog())93 onView(withText(R.string.name_hint)).inRoot(isPlatformPopup())94 }95 @Test96 fun preferenceMatchers() {97 onData(withSummaryText("3 days"))98 onData(withTitle(R.string.pref_title_send_notifications))99 onData(withKey("example_switch"))100 onView(isEnabled())101 }102 @Test103 fun layoutMatchers() {104 onView(hasEllipsizedText())...
isFocusable
Using AI Code Generation
1import static android.support.test.espresso.matcher.RootMatchers.withDecorView;2import static android.support.test.espresso.matcher.ViewMatchers.withText;3import static org.hamcrest.Matchers.is;4import static org.hamcrest.Matchers.not;5import static android.support.test.espresso.Espresso.onView;6import static android.support.test.espresso.assertion.ViewAssertions.matches;7import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;8import static android.support.test.espresso.matcher.ViewMatchers.withId;9import static android.support.test.espresso.action.ViewActions.click;10import static android.support.test.espresso.action.ViewActions.typeText;11import static android.support.test.espresso.action.ViewActions.closeSoftKeyboard;12import static android.support.test.espresso.action.ViewActions.pressImeActionButton;13import static android.support.test.espresso.action.ViewActions.replaceText;14import static android.support.test.espresso.matcher.ViewMatchers.withId;15import static android.support.test.espresso.matcher.ViewMatchers.withText;16import static android.support.test.espresso.matcher.ViewMatchers.withContentDescription;17import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;18import static android.support.test.espresso.matcher.ViewMatchers.isClickable;19import static android.support.test.espresso.matcher.ViewMatchers.isEnabled;20import static android.support.test.espresso.matcher.ViewMatchers.isSelected;21import static android.support.test.espresso.matcher.ViewMatchers.isFocusable;22import static android.support.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;23import static android.support.test.espresso.matcher.ViewMatchers.withParent;24import static android.support.test.espresso.matcher.ViewMatchers.withParentIndex;25import static android.support.test.espresso.matcher.ViewMatchers.withParentId;26import static android.support.test.espresso.matcher.ViewMatchers.withParentMatcher;27import static android.support.test.espresso.matcher.ViewMatchers.withTagKey;28import static android.support.test.espresso.matcher.ViewMatchers.withTagValue;29import static android.support.test.espresso.matcher.ViewMatchers.withClassName;30import static android.support.test.espresso.matcher.ViewMatchers.withContentDescription;31import static android.support.test.espresso.matcher.ViewMatchers.withHint;32import static android.support.test.espresso.matcher.ViewMatchers.withId;33import static android.support.test.espresso.matcher.ViewMatchers.withText;34import static android.support.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;35import static android.support.test.espresso.matcher.ViewMatchers.withParent;36import static android.support.test.espresso.matcher.ViewMatchers.withParentIndex;37import static android.support.test.espresso.matcher.ViewMatchers.withParentId;38import static android.support.test.espresso.matcher.ViewMatchers.withParentMatcher;39import static android.support.test.espresso.matcher.ViewMatchers.withTagKey;40import static android.support.test.espresso.matcher.ViewMatchers.withTagValue;41import static android.support.test.espresso.matcher.ViewMatchers.withClassName;42import
isFocusable
Using AI Code Generation
1import android.support.test.espresso.matcher.RootMatchers;2import android.support.test.espresso.matcher.ViewMatchers;3import android.support.test.rule.ActivityTestRule;4import android.support.test.runner.AndroidJUnit4;5import android.test.suitebuilder.annotation.LargeTest;6import android.view.WindowManager;7import org.hamcrest.Matcher;8import org.junit.Rule;9import org.junit.Test;10import org.junit.runner.RunWith;11import static android.support.test.espresso.Espresso.onView;12import static android.support.test.espresso.action.ViewActions.click;13import static android.support.test.espresso.assertion.ViewAssertions.matches;14import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;15import static android.support.test.espresso.matcher.ViewMatchers.withId;16import static android.support.test.espresso.matcher.ViewMatchers.withText;17@RunWith(AndroidJUnit4.class)18public class MainActivityTest {19 public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(20 MainActivity.class);21 public void checkToastMessage() {22 onView(withId(R.id.button))23 .perform(click());24 onView(withText("Hello toast!"))25 .inRoot(RootMatchers.isFocusable())26 .check(matches(isDisplayed()));27 }28}29import android.support.test.espresso.matcher.RootMatchers;30import android.support.test.espresso.matcher.ViewMatchers;31import android.support.test.rule.ActivityTestRule;32import android.support.test.runner.AndroidJUnit4;33import android.test.suitebuilder.annotation.LargeTest;34import android.view.WindowManager;35import org.hamcrest.Matcher;36import org.junit.Rule;37import org.junit.Test;38import org.junit.runner.RunWith;39import static android.support.test.espresso.Espresso.onView;40import static android.support.test.espresso.action.ViewActions.click;41import static android.support.test.espresso.assertion.ViewAssertions.matches;42import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;43import static android.support.test.espresso.matcher.ViewMatchers.withId;44import static android.support.test.espresso.matcher.ViewMatchers.withText;45@RunWith(AndroidJUnit4.class)46public class MainActivityTest {47 public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(48 MainActivity.class);49 public void checkToastMessage() {50 onView(withId(R.id.button))51 .perform(click());52 onView(withText("Hello toast!"))53 .inRoot(RootMatchers.isDialog())54 .check(matches(isDisplayed()));55 }56}
isFocusable
Using AI Code Generation
1ViewInteraction appCompatButton = onView( allOf( withId(R.id.button), withText("Click Me"), isDisplayed()));2appCompatButton.perform(click());3ViewInteraction appCompatButton2 = onView( allOf( withId(R.id.button), withText("Click Me"), isDisplayed()));4appCompatButton2.perform(click());5ViewInteraction appCompatButton3 = onView( allOf( withId(R.id.button), withText("Click Me"), isDisplayed()));6appCompatButton3.perform(click());7ViewInteraction appCompatButton4 = onView( allOf( withId(R.id.button), withText("Click Me"), isDisplayed()));8appCompatButton4.perform(click());9ViewInteraction appCompatButton5 = onView( allOf( withId(R.id.button), withText("Click Me"), isDisplayed()));10appCompatButton5.perform(click());11ViewInteraction appCompatButton6 = onView( allOf( withId(R.id.button), withText("Click Me"), isDisplayed()));12appCompatButton6.perform(click());13ViewInteraction appCompatButton7 = onView( allOf( withId(R.id.button), withText("Click Me"), isDisplayed()));14appCompatButton7.perform(click());15ViewInteraction appCompatButton8 = onView( allOf( withId(R.id.button), withText("Click Me"), isDisplayed()));16appCompatButton8.perform(click());17ViewInteraction appCompatButton9 = onView( allOf( withId(R.id.button), withText("Click Me"), isDisplayed()));18appCompatButton9.perform(click());19ViewInteraction appCompatButton10 = onView( allOf( withId(R.id.button), withText("Click Me"), isDisplayed()));20appCompatButton10.perform(click());21ViewInteraction appCompatButton11 = onView( allOf( withId(R.id.button), withText("Click Me"), isDisplayed()));22appCompatButton11.perform(click());23ViewInteraction appCompatButton12 = onView( allOf( withId(R.id.button), withText("Click Me"), isDisplayed()));24appCompatButton12.perform(click());25ViewInteraction appCompatButton13 = onView( allOf( withId(R.id.button), withText("Click Me"), isDisplayed()));26appCompatButton13.perform(click());27ViewInteraction appCompatButton14 = onView( allOf( withId(R.id.button), withText("Click Me"), isDisplayed()));28appCompatButton14.perform(click());29ViewInteraction appCompatButton15 = onView( allOf( withId(R.id.button), withText("Click Me"),
isFocusable
Using AI Code Generation
1@Rule public ActivityTestRule<MainActivity> activityTestRule = new ActivityTestRule<MainActivity>(MainActivity.class); @Test public void testIsFocusable() { onView(withText("Hello World!")).inRoot(isFocusable()).check(matches(isDisplayed())); }2@Rule public ActivityTestRule<MainActivity> activityTestRule = new ActivityTestRule<MainActivity>(MainActivity.class); @Test public void testIsDialog() { onView(withText("Hello World!")).inRoot(isDialog()).check(matches(isDisplayed())); }3@Rule public ActivityTestRule<MainActivity> activityTestRule = new ActivityTestRule<MainActivity>(MainActivity.class); @Test public void testIsPlatformPopup() { onView(withText("Hello World!")).inRoot(isPlatformPopup()).check(matches(isDisplayed())); }4@Rule public ActivityTestRule<MainActivity> activityTestRule = new ActivityTestRule<MainActivity>(MainActivity.class); @Test public void testWithDecorView() { onView(withText("Hello World!")).inRoot(withDecorView(not(activityTestRule.getActivity().getWindow().getDecorView()))).check(matches(isDisplayed())); }5@Rule public ActivityTestRule<MainActivity> activityTestRule = new ActivityTestRule<MainActivity>(MainActivity.class); @Test public void testWithDecorView() { onView(withText("Hello World!")).inRoot(withDecorView(not(activityTestRule.getActivity().getWindow().getDecorView()))).check(matches(isDisplayed())); }6@Rule public ActivityTestRule<MainActivity> activityTestRule = new ActivityTestRule<MainActivity>(MainActivity.class); @Test public void testWithDecorView() { onView(withText("Hello World!")).inRoot(withDecorView(not(activityTestRule.getActivity().getWindow().getDecorView()))).check(matches(isDisplayed())); }7@Rule public ActivityTestRule<MainActivity> activityTestRule = new ActivityTestRule<MainActivity>(MainActivity.class); @Test public void testWithDecorView() { onView(withText("Hello World
isFocusable
Using AI Code Generation
1ViewInteraction appCompatEditText6 = onView( allOf( withId(R.id.editText), isFocusable() ) ); appCompatEditText6.perform( replaceText("1"), closeSoftKeyboard() );2ViewInteraction appCompatEditText7 = onView( allOf( withId(R.id.editText), isFocusable() ) ); appCompatEditText7.perform( replaceText("1"), closeSoftKeyboard() );3ViewInteraction appCompatEditText8 = onView( allOf( withId(R.id.editText), isFocusableInTouchMode() ) ); appCompatEditText8.perform( replaceText("1"), closeSoftKeyboard() );4ViewInteraction appCompatEditText9 = onView( allOf( withId(R.id.editText), isFocused() ) ); appCompatEditText9.perform( replaceText("1"), closeSoftKeyboard() );5ViewInteraction appCompatEditText10 = onView( allOf( withId(R.id.editText), isGone() ) ); appCompatEditText10.perform( replaceText("1"), closeSoftKeyboard() );6ViewInteraction appCompatEditText11 = onView( allOf( withId(R.id.editText), isHardwareAccelerated() ) ); appCompatEditText11.perform( replaceText("1"), closeSoftKeyboard() );7ViewInteraction appCompatEditText12 = onView( allOf( withId(R.id.editText), isHorizontalScrollBarEnabled() ) ); appCompatEditText12.perform( replaceText("1"), closeSoftKeyboard() );8ViewInteraction appCompatEditText13 = onView( allOf( withId(R.id.editText), isJavascriptEnabled() ) ); appCompatEditText13.perform( replaceText("1"), closeSoftKeyboard() );9ViewInteraction appCompatEditText14 = onView( allOf( withId(R.id.edit
isFocusable
Using AI Code Generation
1@RunWith(AndroidJUnit4.class)2public class MainActivityTest {3 public ActivityTestRule<MainActivity> activityTestRule = new ActivityTestRule<>(MainActivity.class);4 public void test() {5 onView(withId(R.id.button)).perform(click());6 onView(withText("Hello World!")).inRoot(isFocusable()).check(matches(isDisplayed()));7 }8}
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!