From b720222a627268675521a17f9868287965686b67 Mon Sep 17 00:00:00 2001 From: farees Date: Thu, 15 Jul 2021 13:08:31 +0530 Subject: [PATCH 01/63] Introducing UiAutomator --- .bazelrc | 23 ++++ BUILD.bazel | 2 + WORKSPACE | 14 +++ instrumentation/AndroidManifest.xml | 9 ++ instrumentation/BUILD.bazel | 49 ++++++++ .../android/instrumentation/ProfileTest.kt | 106 ++++++++++++++++++ third_party/maven_install.json | 34 +++++- third_party/versions.bzl | 1 + 8 files changed, 236 insertions(+), 2 deletions(-) create mode 100644 instrumentation/AndroidManifest.xml create mode 100644 instrumentation/BUILD.bazel create mode 100644 instrumentation/src/javatest/org/oppia/android/instrumentation/ProfileTest.kt diff --git a/.bazelrc b/.bazelrc index 71793d2ba7c..0f0f609a735 100644 --- a/.bazelrc +++ b/.bazelrc @@ -7,3 +7,26 @@ build --android_databinding_use_v3_4_args \ # Show all test output by default (for better debugging). test --test_output=all + +# Headless instrumentation tests +test:headless --test_arg=--enable_display=false + +# Graphical instrumentation tests. Ensure that $DISPLAY is set. +test:gui --test_env=DISPLAY +test:gui --test_arg=--enable_display=true + +# Testing with a local emulator or device. Ensure that `adb devices` lists the device. +# Run tests serially. +test:local_device --test_strategy=exclusive +# Use the local device broker type, as opposed to WRAPPED_EMULATOR. +test:local_device --test_arg=--device_broker_type=LOCAL_ADB_SERVER +# Uncomment and set $device_id if there is more than one connected device. +# test:local_device --test_arg=--device_serial_number=$device_id + +# test --flaky_test_attempts=3 + +# The unified launcher runs in Python 2 host configuration +# https://github.com/bazelbuild/bazel/issues/7899 +build --host_force_python=PY2 + + diff --git a/BUILD.bazel b/BUILD.bazel index 7e63e989b6e..1b5f86014be 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -51,6 +51,7 @@ android_binary( custom_package = "org.oppia.android", enable_data_binding = True, manifest = "//app:src/main/AndroidManifest.xml", + visibility = ["//visibility:public"], manifest_values = { "applicationId": "org.oppia.android", "minSdkVersion": "19", @@ -63,3 +64,4 @@ android_binary( "//app", ], ) + diff --git a/WORKSPACE b/WORKSPACE index ffe08b6e446..d0c9cbff421 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -141,6 +141,20 @@ http_archive( load("@rules_jvm_external//:defs.bzl", "maven_install") +ATS_TAG = "1edfdab3134a7f01b37afabd3eebfd2c5bb05151" +ATS_SHA256 = "dcd1ff76aef1a26329d77863972780c8fe1fc8ff625747342239f0489c2837ec" + +http_archive( + name = "android_test_support", + sha256 = ATS_SHA256, + strip_prefix = "android-test-%s" % ATS_TAG, + urls = ["https://github.com/android/android-test/archive/%s.tar.gz" % ATS_TAG], +) + +load("@android_test_support//:repo.bzl", "android_test_repositories") + +android_test_repositories() + # Note to developers: new dependencies should be added to //third_party:versions.bzl, not here. maven_install( artifacts = DAGGER_ARTIFACTS + get_maven_dependencies(), diff --git a/instrumentation/AndroidManifest.xml b/instrumentation/AndroidManifest.xml new file mode 100644 index 00000000000..88be080e5bc --- /dev/null +++ b/instrumentation/AndroidManifest.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/instrumentation/BUILD.bazel b/instrumentation/BUILD.bazel new file mode 100644 index 00000000000..32e7abdc5f0 --- /dev/null +++ b/instrumentation/BUILD.bazel @@ -0,0 +1,49 @@ +load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_android_library") + +android_library( + name="instrumentation_deps", + testonly = True, + visibility = ["//visibility:public"], + exports = [ + "//third_party:androidx_test_runner", + "//third_party:androidx_test_ext_junit", + "//third_party:com_google_truth_truth", + "//third_party:junit_junit", + "//third_party:androidx_test_uiautomator_uiautomator", + ], +) + +kt_android_library( + name="profile_test", + testonly = True, + srcs = [ + "src/javatest/org/oppia/android/instrumentation/ProfileTest.kt", + ], + visibility = ["//visibility:public"], + deps = [ + ":instrumentation_deps", + ], +) + +android_binary( + name = "ProfileTest", + testonly = True, + custom_package = "org.oppia.android", + visibility = ["//visibility:public"], + instruments = "//:oppia", + manifest="AndroidManifest.xml", + deps = [":profile_test"] +) +API_LEVELS = [ + "19_x86", + "21_x86", + "22_x86", + "23_x86", + "28_x86", +] + +android_instrumentation_test( + name = "OppiaTest", + target_device = "@android_test_support//tools/android/emulated_devices/pixel_3_xl:android_28_x86_qemu2", + test_app = ":ProfileTest", +) diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/ProfileTest.kt b/instrumentation/src/javatest/org/oppia/android/instrumentation/ProfileTest.kt new file mode 100644 index 00000000000..729392844dc --- /dev/null +++ b/instrumentation/src/javatest/org/oppia/android/instrumentation/ProfileTest.kt @@ -0,0 +1,106 @@ +package org.oppia.android.instrumentation + + +import android.content.Context +import android.content.Intent +import android.content.pm.PackageManager +import androidx.test.core.app.ApplicationProvider +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.uiautomator.By +import androidx.test.uiautomator.UiDevice +import androidx.test.uiautomator.Until + +import org.junit.Assert.assertNotNull +import org.junit.Assert.assertThat +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import androidx.test.ext.junit.runners.AndroidJUnit4 + + +@RunWith(AndroidJUnit4::class) +class ProfileTest { + + private val BASIC_SAMPLE_PACKAGE = "com.example.android.testing.uiautomator.BasicSample" + + private val OPPIA_PACKAGE = "org.oppia.android" + + private val LAUNCH_TIMEOUT = 5000 + + private val STRING_TO_BE_TYPED = "UiAutomator" + + private lateinit var mDevice: UiDevice + + @Before + fun startMainActivityFromHomeScreen() { + // Initialize UiDevice instance + mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) + + // Start from the home screen + mDevice.pressHome() + + // Wait for launcher + val launcherPackage = getLauncherPackageName() + assertNotNull(launcherPackage) + mDevice.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)), LAUNCH_TIMEOUT.toLong()) + + // Launch the blueprint app + val context = ApplicationProvider.getApplicationContext() + val intent = context.packageManager + .getLaunchIntentForPackage(OPPIA_PACKAGE) + intent!!.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) // Clear out any previous instances + context.startActivity(intent) + + // Wait for the app to appear + mDevice.wait(Until.hasObject(By.pkg(OPPIA_PACKAGE).depth(0)), LAUNCH_TIMEOUT.toLong()) + } + + @Test + fun checkPreconditions() { + assertNotNull(mDevice) + } + + @Test + fun exitOnBoarding() { + mDevice.findObject(By.res("org.oppia.android:id/skip_text_view")) + .click() + mDevice.findObject(By.res("org.oppia.android:id/get_started_button")) + .click() + } + + @Test + fun openOppia() { + // Start from the home screen + mDevice.pressHome() + // Wait for launcher + val launcherPackage = getLauncherPackageName() + assertNotNull(launcherPackage) + mDevice.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)), LAUNCH_TIMEOUT.toLong()) + + // Launch the blueprint app + val context = InstrumentationRegistry.getInstrumentation().context + val intent = context.packageManager + .getLaunchIntentForPackage(OPPIA_PACKAGE) + intent!!.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) // Clear out any previous instances + context.startActivity(intent) + + // Wait for the app to appear + mDevice.wait(Until.hasObject(By.pkg(BASIC_SAMPLE_PACKAGE).depth(0)), LAUNCH_TIMEOUT.toLong()) + } + + /** + * Uses package manager to find the package name of the device launcher. Usually this package + * is "com.android.launcher" but can be different at times. This is a generic solution which + * works on all platforms.` + */ + private fun getLauncherPackageName(): String { + // Create launcher Intent + val intent = Intent(Intent.ACTION_MAIN) + intent.addCategory(Intent.CATEGORY_HOME) + + // Use PackageManager to get the launcher package name + val pm = ApplicationProvider.getApplicationContext().packageManager + val resolveInfo = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) + return resolveInfo!!.activityInfo.packageName + } +} diff --git a/third_party/maven_install.json b/third_party/maven_install.json index 469a63ebf48..9dc96076218 100644 --- a/third_party/maven_install.json +++ b/third_party/maven_install.json @@ -1,8 +1,8 @@ { "dependency_tree": { "__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL", - "__INPUT_ARTIFACTS_HASH": -1412576931, - "__RESOLVED_ARTIFACTS_HASH": -1944714209, + "__INPUT_ARTIFACTS_HASH": -211174318, + "__RESOLVED_ARTIFACTS_HASH": 2137571045, "conflict_resolution": { "androidx.appcompat:appcompat:1.0.2": "androidx.appcompat:appcompat:1.2.0", "androidx.core:core:1.0.1": "androidx.core:core:1.3.0", @@ -3337,6 +3337,36 @@ "sha256": "e8abb0752a123d337be4cced50298067a8340135e64f0a24ff52345ed20cd292", "url": "https://maven.google.com/androidx/test/ext/junit/1.1.1/junit-1.1.1-sources.jar" }, + { + "coord": "androidx.test.uiautomator:uiautomator:2.2.0", + "dependencies": [], + "directDependencies": [], + "file": "v1/https/maven.google.com/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0.aar", + "mirror_urls": [ + "https://maven.google.com/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0.aar", + "https://repo1.maven.org/maven2/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0.aar", + "https://maven.fabric.io/public/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0.aar", + "https://maven.google.com/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0.aar", + "https://repo1.maven.org/maven2/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0.aar" + ], + "sha256": "2838e9d961dbffefbbd229a2bd4f6f82ac4fb2462975862a9e75e9ed325a3197", + "url": "https://maven.google.com/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0.aar" + }, + { + "coord": "androidx.test.uiautomator:uiautomator:jar:sources:2.2.0", + "dependencies": [], + "directDependencies": [], + "file": "v1/https/maven.google.com/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0-sources.jar", + "mirror_urls": [ + "https://maven.google.com/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0-sources.jar", + "https://maven.fabric.io/public/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0-sources.jar", + "https://maven.google.com/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0-sources.jar" + ], + "sha256": "e1f438106ac0d26b80ecf4fd6ffe6d36f60e12bdcd6316903f802ed24d00be99", + "url": "https://maven.google.com/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0-sources.jar" + }, { "coord": "androidx.test:core:1.2.0", "dependencies": [ diff --git a/third_party/versions.bzl b/third_party/versions.bzl index fa391f65998..8d6e0972e7b 100644 --- a/third_party/versions.bzl +++ b/third_party/versions.bzl @@ -38,6 +38,7 @@ MAVEN_PRODUCTION_DEPENDENCY_VERSIONS = { "androidx.navigation:navigation-ui-ktx": "2.0.0", "androidx.recyclerview:recyclerview": "1.0.0", "androidx.room:room-runtime": "2.2.5", + "androidx.test.uiautomator:uiautomator": "2.2.0", "androidx.viewpager2:viewpager2": "1.0.0", "androidx.viewpager:viewpager": "1.0.0", "androidx.work:work-runtime": "2.4.0", From f90cbfca446be4abd0f11e9caa6c0eb7d9188e9d Mon Sep 17 00:00:00 2001 From: farees Date: Thu, 15 Jul 2021 14:33:56 +0530 Subject: [PATCH 02/63] Using 23 api level --- instrumentation/BUILD.bazel | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/instrumentation/BUILD.bazel b/instrumentation/BUILD.bazel index 32e7abdc5f0..1f84c40aa87 100644 --- a/instrumentation/BUILD.bazel +++ b/instrumentation/BUILD.bazel @@ -34,16 +34,8 @@ android_binary( manifest="AndroidManifest.xml", deps = [":profile_test"] ) -API_LEVELS = [ - "19_x86", - "21_x86", - "22_x86", - "23_x86", - "28_x86", -] - android_instrumentation_test( name = "OppiaTest", - target_device = "@android_test_support//tools/android/emulated_devices/pixel_3_xl:android_28_x86_qemu2", + target_device = "@android_test_support//tools/android/emulated_devices/generic_phone:android_23_x86_qemu2", test_app = ":ProfileTest", ) From 930abe00fc1082fe389ad923bec79ea20defc922 Mon Sep 17 00:00:00 2001 From: farees Date: Fri, 16 Jul 2021 19:39:59 +0530 Subject: [PATCH 03/63] some local tweaks --- instrumentation/BUILD.bazel | 28 +- .../android/instrumentation/ProfileTest.kt | 50 ++- third_party/maven_install.json | 321 +++++++++--------- third_party/versions.bzl | 6 +- 4 files changed, 238 insertions(+), 167 deletions(-) diff --git a/instrumentation/BUILD.bazel b/instrumentation/BUILD.bazel index 1f84c40aa87..273eea6a026 100644 --- a/instrumentation/BUILD.bazel +++ b/instrumentation/BUILD.bazel @@ -25,6 +25,24 @@ kt_android_library( ], ) +android_device( + name = "android_26_x86", + visibility = ["//visibility:public"], + tags = ["requires-kvm"], + generator_name = "generic_phone", + generator_function = "make_device", + generator_location = "tools/android/emulated_devices/generic_phone/BUILD.bazel:43:12", + vertical_resolution = 2160, + horizontal_resolution = 1080, + ram = 2048, + screen_density = 240, + cache = 32, + vm_heap = 256, + system_image = "@android_test_support//tools/android/emulated_devices/generic_phone:android_26_x86_images", + default_properties = "@android_test_support//tools/android/emulated_devices/generic_phone:_android_26_x86_props", +) + + android_binary( name = "ProfileTest", testonly = True, @@ -34,8 +52,16 @@ android_binary( manifest="AndroidManifest.xml", deps = [":profile_test"] ) + android_instrumentation_test( name = "OppiaTest", - target_device = "@android_test_support//tools/android/emulated_devices/generic_phone:android_23_x86_qemu2", + target_device = "@android_test_support//tools/android/emulated_devices/generic_phone:android_26_x86_qemu2", + test_app = ":ProfileTest", +) + + +android_instrumentation_test( + name = "Instrument", + target_device = "@android_test_support//tools/android/emulated_devices/low_mem_phone:android_23_x86_qemu2", test_app = ":ProfileTest", ) diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/ProfileTest.kt b/instrumentation/src/javatest/org/oppia/android/instrumentation/ProfileTest.kt index 729392844dc..39ce3bcff3f 100644 --- a/instrumentation/src/javatest/org/oppia/android/instrumentation/ProfileTest.kt +++ b/instrumentation/src/javatest/org/oppia/android/instrumentation/ProfileTest.kt @@ -7,6 +7,7 @@ import android.content.pm.PackageManager import androidx.test.core.app.ApplicationProvider import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.By +import androidx.test.uiautomator.Direction import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.Until @@ -25,7 +26,7 @@ class ProfileTest { private val OPPIA_PACKAGE = "org.oppia.android" - private val LAUNCH_TIMEOUT = 5000 + private val LAUNCH_TIMEOUT = 1000 * 5 private val STRING_TO_BE_TYPED = "UiAutomator" @@ -55,15 +56,16 @@ class ProfileTest { mDevice.wait(Until.hasObject(By.pkg(OPPIA_PACKAGE).depth(0)), LAUNCH_TIMEOUT.toLong()) } - @Test - fun checkPreconditions() { - assertNotNull(mDevice) - } + // @Test + // fun checkPreconditions() { + // assertNotNull(mDevice) + // } @Test fun exitOnBoarding() { mDevice.findObject(By.res("org.oppia.android:id/skip_text_view")) .click() + mDevice.wait(Until.hasObject(By.res("org.oppia.android:id/get_started_button")), 1000L) mDevice.findObject(By.res("org.oppia.android:id/get_started_button")) .click() } @@ -104,3 +106,41 @@ class ProfileTest { return resolveInfo!!.activityInfo.packageName } } + +/* + +android_device( + name = "android_27_x86_qemu2", + visibility = ["//visibility:public"], + tags = ["requires-kvm"], + generator_name = "generic_phone", + generator_function = "make_device", + generator_location = "tools/android/emulated_devices/generic_phone/BUILD.bazel:43:12", + vertical_resolution = 2160, + horizontal_resolution = 1080, + ram = 2048, + screen_density = 240, + cache = 32, + vm_heap = 256, + system_image = "@android_test_support//tools/android/emulated_devices/generic_phone:android_27_x86_qemu2_images", + default_properties = "@android_test_support//tools/android/emulated_devices/generic_phone:_android_27_x86_qemu2_props", +) + +android_device( + name = "android_23_x86", + visibility = ["//visibility:public"], + tags = ["requires-kvm"], + generator_name = "generic_phone", + generator_function = "make_device", + generator_location = "tools/android/emulated_devices/generic_phone/BUILD.bazel:43:12", + vertical_resolution = 800, + horizontal_resolution = 480, + ram = 2048, + screen_density = 240, + cache = 32, + vm_heap = 256, + system_image = "@android_test_support//tools/android/emulated_devices/generic_phone:android_23_x86_images", + default_properties = "@android_test_support//tools/android/emulated_devices/generic_phone:_android_23_x86_props", +) + +* */ diff --git a/third_party/maven_install.json b/third_party/maven_install.json index 9dc96076218..c265e179362 100644 --- a/third_party/maven_install.json +++ b/third_party/maven_install.json @@ -1,13 +1,12 @@ { "dependency_tree": { "__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL", - "__INPUT_ARTIFACTS_HASH": -211174318, - "__RESOLVED_ARTIFACTS_HASH": 2137571045, + "__INPUT_ARTIFACTS_HASH": 221927950, + "__RESOLVED_ARTIFACTS_HASH": -1551118665, "conflict_resolution": { "androidx.appcompat:appcompat:1.0.2": "androidx.appcompat:appcompat:1.2.0", "androidx.core:core:1.0.1": "androidx.core:core:1.3.0", "androidx.recyclerview:recyclerview:1.0.0": "androidx.recyclerview:recyclerview:1.1.0", - "androidx.test:core:1.0.0": "androidx.test:core:1.2.0", "org.jetbrains.kotlin:kotlin-reflect:1.3.41": "org.jetbrains.kotlin:kotlin-reflect:1.4.10", "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.72": "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.10", "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.2": "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.4", @@ -3140,24 +3139,20 @@ { "coord": "androidx.test.espresso:espresso-core:3.2.0", "dependencies": [ - "androidx.annotation:annotation:1.1.0", "com.google.code.findbugs:jsr305:3.0.2", - "androidx.test:monitor:1.3.0-rc03", "org.hamcrest:hamcrest-library:1.3", - "androidx.test:runner:1.2.0", "org.hamcrest:hamcrest-integration:1.3", - "junit:junit:4.12", "org.hamcrest:hamcrest-core:1.3", + "androidx.test:runner:1.4.0", "androidx.test.espresso:espresso-idling-resource:3.2.0", "com.squareup:javawriter:2.1.1", - "javax.inject:javax.inject:1", - "net.sf.kxml:kxml2:2.3.0" + "javax.inject:javax.inject:1" ], "directDependencies": [ "com.google.code.findbugs:jsr305:3.0.2", "org.hamcrest:hamcrest-library:1.3", - "androidx.test:runner:1.2.0", "org.hamcrest:hamcrest-integration:1.3", + "androidx.test:runner:1.4.0", "androidx.test.espresso:espresso-idling-resource:3.2.0", "com.squareup:javawriter:2.1.1", "javax.inject:javax.inject:1" @@ -3178,16 +3173,12 @@ "dependencies": [ "com.google.code.findbugs:jsr305:jar:sources:3.0.2", "org.hamcrest:hamcrest-integration:jar:sources:1.3", - "androidx.test:monitor:jar:sources:1.3.0-rc03", "com.squareup:javawriter:jar:sources:2.1.1", "javax.inject:javax.inject:jar:sources:1", "org.hamcrest:hamcrest-core:jar:sources:1.3", "androidx.test.espresso:espresso-idling-resource:jar:sources:3.2.0", "org.hamcrest:hamcrest-library:jar:sources:1.3", - "androidx.annotation:annotation:jar:sources:1.1.0", - "androidx.test:runner:jar:sources:1.2.0", - "net.sf.kxml:kxml2:jar:sources:2.3.0", - "junit:junit:jar:sources:4.12" + "androidx.test:runner:jar:sources:1.4.0" ], "directDependencies": [ "com.google.code.findbugs:jsr305:jar:sources:3.0.2", @@ -3196,7 +3187,7 @@ "javax.inject:javax.inject:jar:sources:1", "androidx.test.espresso:espresso-idling-resource:jar:sources:3.2.0", "org.hamcrest:hamcrest-library:jar:sources:1.3", - "androidx.test:runner:jar:sources:1.2.0" + "androidx.test:runner:jar:sources:1.4.0" ], "file": "v1/https/maven.google.com/androidx/test/espresso/espresso-core/3.2.0/espresso-core-3.2.0-sources.jar", "mirror_urls": [ @@ -3244,7 +3235,7 @@ "dependencies": [ "androidx.test:rules:1.1.0", "androidx.test.espresso:espresso-core:3.2.0", - "androidx.test:runner:1.2.0" + "androidx.test:runner:1.4.0" ], "directDependencies": [ "androidx.test:rules:1.1.0", @@ -3264,8 +3255,8 @@ { "coord": "androidx.test.espresso:espresso-intents:jar:sources:3.1.0", "dependencies": [ + "androidx.test:runner:jar:sources:1.4.0", "androidx.test:rules:jar:sources:1.1.0", - "androidx.test:runner:jar:sources:1.2.0", "androidx.test.espresso:espresso-core:jar:sources:3.2.0" ], "directDependencies": [ @@ -3284,37 +3275,37 @@ "url": "https://maven.google.com/androidx/test/espresso/espresso-intents/3.1.0/espresso-intents-3.1.0-sources.jar" }, { - "coord": "androidx.test.ext:junit:1.1.1", + "coord": "androidx.test.ext:junit:1.1.3", "dependencies": [ "androidx.lifecycle:lifecycle-common:2.2.0", "androidx.annotation:annotation:1.1.0", - "androidx.test:monitor:1.3.0-rc03", + "androidx.test:monitor:1.4.0", "junit:junit:4.12", "org.hamcrest:hamcrest-core:1.3", - "androidx.test:core:1.2.0" + "androidx.test:core:1.4.0" ], "directDependencies": [ "androidx.annotation:annotation:1.1.0", - "androidx.test:core:1.2.0", - "androidx.test:monitor:1.3.0-rc03", + "androidx.test:core:1.4.0", + "androidx.test:monitor:1.4.0", "junit:junit:4.12" ], - "file": "v1/https/maven.google.com/androidx/test/ext/junit/1.1.1/junit-1.1.1.aar", + "file": "v1/https/maven.google.com/androidx/test/ext/junit/1.1.3/junit-1.1.3.aar", "mirror_urls": [ - "https://maven.google.com/androidx/test/ext/junit/1.1.1/junit-1.1.1.aar", - "https://repo1.maven.org/maven2/androidx/test/ext/junit/1.1.1/junit-1.1.1.aar", - "https://maven.fabric.io/public/androidx/test/ext/junit/1.1.1/junit-1.1.1.aar", - "https://maven.google.com/androidx/test/ext/junit/1.1.1/junit-1.1.1.aar", - "https://repo1.maven.org/maven2/androidx/test/ext/junit/1.1.1/junit-1.1.1.aar" + "https://maven.google.com/androidx/test/ext/junit/1.1.3/junit-1.1.3.aar", + "https://repo1.maven.org/maven2/androidx/test/ext/junit/1.1.3/junit-1.1.3.aar", + "https://maven.fabric.io/public/androidx/test/ext/junit/1.1.3/junit-1.1.3.aar", + "https://maven.google.com/androidx/test/ext/junit/1.1.3/junit-1.1.3.aar", + "https://repo1.maven.org/maven2/androidx/test/ext/junit/1.1.3/junit-1.1.3.aar" ], - "sha256": "449df418d2916a0f86fe7dafb1edb09480fafb6e995d5c751c7d0d1970d4ae72", - "url": "https://maven.google.com/androidx/test/ext/junit/1.1.1/junit-1.1.1.aar" + "sha256": "a97209d75a9a85815fa8934f5a4a320de1163ffe94e2f0b328c0c98a59660690", + "url": "https://maven.google.com/androidx/test/ext/junit/1.1.3/junit-1.1.3.aar" }, { - "coord": "androidx.test.ext:junit:jar:sources:1.1.1", + "coord": "androidx.test.ext:junit:jar:sources:1.1.3", "dependencies": [ - "androidx.test:core:jar:sources:1.2.0", - "androidx.test:monitor:jar:sources:1.3.0-rc03", + "androidx.test:monitor:jar:sources:1.4.0", + "androidx.test:core:jar:sources:1.4.0", "org.hamcrest:hamcrest-core:jar:sources:1.3", "androidx.annotation:annotation:jar:sources:1.1.0", "androidx.lifecycle:lifecycle-common:jar:sources:2.2.0", @@ -3322,20 +3313,62 @@ ], "directDependencies": [ "androidx.annotation:annotation:jar:sources:1.1.0", - "androidx.test:core:jar:sources:1.2.0", - "androidx.test:monitor:jar:sources:1.3.0-rc03", + "androidx.test:core:jar:sources:1.4.0", + "androidx.test:monitor:jar:sources:1.4.0", "junit:junit:jar:sources:4.12" ], - "file": "v1/https/maven.google.com/androidx/test/ext/junit/1.1.1/junit-1.1.1-sources.jar", + "file": "v1/https/maven.google.com/androidx/test/ext/junit/1.1.3/junit-1.1.3-sources.jar", + "mirror_urls": [ + "https://maven.google.com/androidx/test/ext/junit/1.1.3/junit-1.1.3-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/ext/junit/1.1.3/junit-1.1.3-sources.jar", + "https://maven.fabric.io/public/androidx/test/ext/junit/1.1.3/junit-1.1.3-sources.jar", + "https://maven.google.com/androidx/test/ext/junit/1.1.3/junit-1.1.3-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/ext/junit/1.1.3/junit-1.1.3-sources.jar" + ], + "sha256": "aefd25841285b641906dca12127cad26866caacd9aeefe8b38103ede35abc828", + "url": "https://maven.google.com/androidx/test/ext/junit/1.1.3/junit-1.1.3-sources.jar" + }, + { + "coord": "androidx.test.services:storage:1.4.0", + "dependencies": [ + "androidx.test:monitor:1.4.0", + "com.google.code.findbugs:jsr305:3.0.2" + ], + "directDependencies": [ + "androidx.test:monitor:1.4.0", + "com.google.code.findbugs:jsr305:3.0.2" + ], + "file": "v1/https/maven.google.com/androidx/test/services/storage/1.4.0/storage-1.4.0.aar", "mirror_urls": [ - "https://maven.google.com/androidx/test/ext/junit/1.1.1/junit-1.1.1-sources.jar", - "https://repo1.maven.org/maven2/androidx/test/ext/junit/1.1.1/junit-1.1.1-sources.jar", - "https://maven.fabric.io/public/androidx/test/ext/junit/1.1.1/junit-1.1.1-sources.jar", - "https://maven.google.com/androidx/test/ext/junit/1.1.1/junit-1.1.1-sources.jar", - "https://repo1.maven.org/maven2/androidx/test/ext/junit/1.1.1/junit-1.1.1-sources.jar" + "https://maven.google.com/androidx/test/services/storage/1.4.0/storage-1.4.0.aar", + "https://repo1.maven.org/maven2/androidx/test/services/storage/1.4.0/storage-1.4.0.aar", + "https://maven.fabric.io/public/androidx/test/services/storage/1.4.0/storage-1.4.0.aar", + "https://maven.google.com/androidx/test/services/storage/1.4.0/storage-1.4.0.aar", + "https://repo1.maven.org/maven2/androidx/test/services/storage/1.4.0/storage-1.4.0.aar" ], - "sha256": "e8abb0752a123d337be4cced50298067a8340135e64f0a24ff52345ed20cd292", - "url": "https://maven.google.com/androidx/test/ext/junit/1.1.1/junit-1.1.1-sources.jar" + "sha256": "35cfbf442abb83e5876cd5deb9de02ae047459f18f831097c5caa76d626bc38a", + "url": "https://maven.google.com/androidx/test/services/storage/1.4.0/storage-1.4.0.aar" + }, + { + "coord": "androidx.test.services:storage:jar:sources:1.4.0", + "dependencies": [ + "com.google.code.findbugs:jsr305:jar:sources:3.0.2", + "androidx.test:monitor:jar:sources:1.4.0" + ], + "directDependencies": [ + "androidx.test:monitor:jar:sources:1.4.0", + "com.google.code.findbugs:jsr305:jar:sources:3.0.2" + ], + "file": "v1/https/maven.google.com/androidx/test/services/storage/1.4.0/storage-1.4.0-sources.jar", + "mirror_urls": [ + "https://maven.google.com/androidx/test/services/storage/1.4.0/storage-1.4.0-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/services/storage/1.4.0/storage-1.4.0-sources.jar", + "https://maven.fabric.io/public/androidx/test/services/storage/1.4.0/storage-1.4.0-sources.jar", + "https://maven.google.com/androidx/test/services/storage/1.4.0/storage-1.4.0-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/services/storage/1.4.0/storage-1.4.0-sources.jar" + ], + "sha256": "f80c24f6564166dafd70ac169e8881eea4f9de6e71e714408bf34c214ecb8673", + "url": "https://maven.google.com/androidx/test/services/storage/1.4.0/storage-1.4.0-sources.jar" }, { "coord": "androidx.test.uiautomator:uiautomator:2.2.0", @@ -3368,95 +3401,95 @@ "url": "https://maven.google.com/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0-sources.jar" }, { - "coord": "androidx.test:core:1.2.0", + "coord": "androidx.test:core:1.4.0", "dependencies": [ "androidx.annotation:annotation:1.1.0", - "androidx.lifecycle:lifecycle-common:2.2.0", - "androidx.test:monitor:1.3.0-rc03" + "androidx.test:monitor:1.4.0", + "androidx.lifecycle:lifecycle-common:2.2.0" ], "directDependencies": [ "androidx.annotation:annotation:1.1.0", "androidx.lifecycle:lifecycle-common:2.2.0", - "androidx.test:monitor:1.3.0-rc03" + "androidx.test:monitor:1.4.0" ], - "file": "v1/https/maven.google.com/androidx/test/core/1.2.0/core-1.2.0.aar", + "file": "v1/https/maven.google.com/androidx/test/core/1.4.0/core-1.4.0.aar", "mirror_urls": [ - "https://maven.google.com/androidx/test/core/1.2.0/core-1.2.0.aar", - "https://repo1.maven.org/maven2/androidx/test/core/1.2.0/core-1.2.0.aar", - "https://maven.fabric.io/public/androidx/test/core/1.2.0/core-1.2.0.aar", - "https://maven.google.com/androidx/test/core/1.2.0/core-1.2.0.aar", - "https://repo1.maven.org/maven2/androidx/test/core/1.2.0/core-1.2.0.aar" + "https://maven.google.com/androidx/test/core/1.4.0/core-1.4.0.aar", + "https://repo1.maven.org/maven2/androidx/test/core/1.4.0/core-1.4.0.aar", + "https://maven.fabric.io/public/androidx/test/core/1.4.0/core-1.4.0.aar", + "https://maven.google.com/androidx/test/core/1.4.0/core-1.4.0.aar", + "https://repo1.maven.org/maven2/androidx/test/core/1.4.0/core-1.4.0.aar" ], - "sha256": "c88b739b1c499afb792374be19b9cf829e89567f26441a74f664c0cf8de158a4", - "url": "https://maven.google.com/androidx/test/core/1.2.0/core-1.2.0.aar" + "sha256": "671284e62e393f16ceae1a99a3a9a07bf1aacda29f8fe7b6b884355ef34c09cf", + "url": "https://maven.google.com/androidx/test/core/1.4.0/core-1.4.0.aar" }, { - "coord": "androidx.test:core:jar:sources:1.2.0", + "coord": "androidx.test:core:jar:sources:1.4.0", "dependencies": [ - "androidx.test:monitor:jar:sources:1.3.0-rc03", + "androidx.test:monitor:jar:sources:1.4.0", "androidx.lifecycle:lifecycle-common:jar:sources:2.2.0", "androidx.annotation:annotation:jar:sources:1.1.0" ], "directDependencies": [ "androidx.annotation:annotation:jar:sources:1.1.0", "androidx.lifecycle:lifecycle-common:jar:sources:2.2.0", - "androidx.test:monitor:jar:sources:1.3.0-rc03" + "androidx.test:monitor:jar:sources:1.4.0" ], - "file": "v1/https/maven.google.com/androidx/test/core/1.2.0/core-1.2.0-sources.jar", + "file": "v1/https/maven.google.com/androidx/test/core/1.4.0/core-1.4.0-sources.jar", "mirror_urls": [ - "https://maven.google.com/androidx/test/core/1.2.0/core-1.2.0-sources.jar", - "https://repo1.maven.org/maven2/androidx/test/core/1.2.0/core-1.2.0-sources.jar", - "https://maven.fabric.io/public/androidx/test/core/1.2.0/core-1.2.0-sources.jar", - "https://maven.google.com/androidx/test/core/1.2.0/core-1.2.0-sources.jar", - "https://repo1.maven.org/maven2/androidx/test/core/1.2.0/core-1.2.0-sources.jar" + "https://maven.google.com/androidx/test/core/1.4.0/core-1.4.0-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/core/1.4.0/core-1.4.0-sources.jar", + "https://maven.fabric.io/public/androidx/test/core/1.4.0/core-1.4.0-sources.jar", + "https://maven.google.com/androidx/test/core/1.4.0/core-1.4.0-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/core/1.4.0/core-1.4.0-sources.jar" ], - "sha256": "19d087a01ae8741a62b661c07929897eb475af64198a9bd7e89d97e7ee88a89a", - "url": "https://maven.google.com/androidx/test/core/1.2.0/core-1.2.0-sources.jar" + "sha256": "b3125d546acfea278b82250344c83826e872e3f461109daf0948806382603b30", + "url": "https://maven.google.com/androidx/test/core/1.4.0/core-1.4.0-sources.jar" }, { - "coord": "androidx.test:monitor:1.3.0-rc03", + "coord": "androidx.test:monitor:1.4.0", "dependencies": [ "androidx.annotation:annotation:1.1.0" ], "directDependencies": [ "androidx.annotation:annotation:1.1.0" ], - "file": "v1/https/maven.google.com/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03.aar", + "file": "v1/https/maven.google.com/androidx/test/monitor/1.4.0/monitor-1.4.0.aar", "mirror_urls": [ - "https://maven.google.com/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03.aar", - "https://repo1.maven.org/maven2/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03.aar", - "https://maven.fabric.io/public/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03.aar", - "https://maven.google.com/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03.aar", - "https://repo1.maven.org/maven2/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03.aar" + "https://maven.google.com/androidx/test/monitor/1.4.0/monitor-1.4.0.aar", + "https://repo1.maven.org/maven2/androidx/test/monitor/1.4.0/monitor-1.4.0.aar", + "https://maven.fabric.io/public/androidx/test/monitor/1.4.0/monitor-1.4.0.aar", + "https://maven.google.com/androidx/test/monitor/1.4.0/monitor-1.4.0.aar", + "https://repo1.maven.org/maven2/androidx/test/monitor/1.4.0/monitor-1.4.0.aar" ], - "sha256": "7c67b438deec7c14cf62ab54223ce19d5981f53477a15359347d7b59018419d0", - "url": "https://maven.google.com/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03.aar" + "sha256": "46a912a1e175f27a97521af3f50e5af87c22c49275dd2c57c043740012806325", + "url": "https://maven.google.com/androidx/test/monitor/1.4.0/monitor-1.4.0.aar" }, { - "coord": "androidx.test:monitor:aar:sources:1.3.0-rc03", + "coord": "androidx.test:monitor:aar:sources:1.4.0", "dependencies": [], "directDependencies": [], "exclusions": [ "*:*" ], - "file": "v1/https/maven.google.com/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03-sources.jar", + "file": "v1/https/maven.google.com/androidx/test/monitor/1.4.0/monitor-1.4.0-sources.jar", "mirror_urls": [ - "https://maven.google.com/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03-sources.jar", - "https://repo1.maven.org/maven2/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03-sources.jar", - "https://maven.fabric.io/public/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03-sources.jar", - "https://maven.google.com/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03-sources.jar", - "https://repo1.maven.org/maven2/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03-sources.jar" + "https://maven.google.com/androidx/test/monitor/1.4.0/monitor-1.4.0-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/monitor/1.4.0/monitor-1.4.0-sources.jar", + "https://maven.fabric.io/public/androidx/test/monitor/1.4.0/monitor-1.4.0-sources.jar", + "https://maven.google.com/androidx/test/monitor/1.4.0/monitor-1.4.0-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/monitor/1.4.0/monitor-1.4.0-sources.jar" ], - "sha256": "08da381299ef3ecc345bd2ce7db2006fe21e054e928026a38104e9eeb9121761", - "url": "https://maven.google.com/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03-sources.jar" + "sha256": "a03ea6019c1ee7cc285afdbee98137ec463b891e6fc9176c121c5a70ec727f48", + "url": "https://maven.google.com/androidx/test/monitor/1.4.0/monitor-1.4.0-sources.jar" }, { "coord": "androidx.test:rules:1.1.0", "dependencies": [ - "androidx.test:runner:1.2.0" + "androidx.test:runner:1.4.0" ], "directDependencies": [ - "androidx.test:runner:1.2.0" + "androidx.test:runner:1.4.0" ], "file": "v1/https/maven.google.com/androidx/test/rules/1.1.0/rules-1.1.0.aar", "mirror_urls": [ @@ -3472,10 +3505,10 @@ { "coord": "androidx.test:rules:jar:sources:1.1.0", "dependencies": [ - "androidx.test:runner:jar:sources:1.2.0" + "androidx.test:runner:jar:sources:1.4.0" ], "directDependencies": [ - "androidx.test:runner:jar:sources:1.2.0" + "androidx.test:runner:jar:sources:1.4.0" ], "file": "v1/https/maven.google.com/androidx/test/rules/1.1.0/rules-1.1.0-sources.jar", "mirror_urls": [ @@ -3489,56 +3522,58 @@ "url": "https://maven.google.com/androidx/test/rules/1.1.0/rules-1.1.0-sources.jar" }, { - "coord": "androidx.test:runner:1.2.0", + "coord": "androidx.test:runner:1.4.0", "dependencies": [ "androidx.annotation:annotation:1.1.0", - "androidx.test:monitor:1.3.0-rc03", + "androidx.test:monitor:1.4.0", + "com.google.code.findbugs:jsr305:3.0.2", + "androidx.test.services:storage:1.4.0", "junit:junit:4.12", - "org.hamcrest:hamcrest-core:1.3", - "net.sf.kxml:kxml2:2.3.0" + "org.hamcrest:hamcrest-core:1.3" ], "directDependencies": [ "androidx.annotation:annotation:1.1.0", - "androidx.test:monitor:1.3.0-rc03", - "junit:junit:4.12", - "net.sf.kxml:kxml2:2.3.0" + "androidx.test:monitor:1.4.0", + "androidx.test.services:storage:1.4.0", + "junit:junit:4.12" ], - "file": "v1/https/maven.google.com/androidx/test/runner/1.2.0/runner-1.2.0.aar", + "file": "v1/https/maven.google.com/androidx/test/runner/1.4.0/runner-1.4.0.aar", "mirror_urls": [ - "https://maven.google.com/androidx/test/runner/1.2.0/runner-1.2.0.aar", - "https://repo1.maven.org/maven2/androidx/test/runner/1.2.0/runner-1.2.0.aar", - "https://maven.fabric.io/public/androidx/test/runner/1.2.0/runner-1.2.0.aar", - "https://maven.google.com/androidx/test/runner/1.2.0/runner-1.2.0.aar", - "https://repo1.maven.org/maven2/androidx/test/runner/1.2.0/runner-1.2.0.aar" + "https://maven.google.com/androidx/test/runner/1.4.0/runner-1.4.0.aar", + "https://repo1.maven.org/maven2/androidx/test/runner/1.4.0/runner-1.4.0.aar", + "https://maven.fabric.io/public/androidx/test/runner/1.4.0/runner-1.4.0.aar", + "https://maven.google.com/androidx/test/runner/1.4.0/runner-1.4.0.aar", + "https://repo1.maven.org/maven2/androidx/test/runner/1.4.0/runner-1.4.0.aar" ], - "sha256": "5387e011167a3c8da08d99b5d59248c0e2da839317b48ebf202e31dc1f791ec1", - "url": "https://maven.google.com/androidx/test/runner/1.2.0/runner-1.2.0.aar" + "sha256": "e3f3d8b8d5d4a3edcacbdaa4a31bda2b0e41d3e704b02b3750466a06367ec5a0", + "url": "https://maven.google.com/androidx/test/runner/1.4.0/runner-1.4.0.aar" }, { - "coord": "androidx.test:runner:jar:sources:1.2.0", + "coord": "androidx.test:runner:jar:sources:1.4.0", "dependencies": [ - "androidx.test:monitor:jar:sources:1.3.0-rc03", + "com.google.code.findbugs:jsr305:jar:sources:3.0.2", + "androidx.test:monitor:jar:sources:1.4.0", "org.hamcrest:hamcrest-core:jar:sources:1.3", + "androidx.test.services:storage:jar:sources:1.4.0", "androidx.annotation:annotation:jar:sources:1.1.0", - "net.sf.kxml:kxml2:jar:sources:2.3.0", "junit:junit:jar:sources:4.12" ], "directDependencies": [ "androidx.annotation:annotation:jar:sources:1.1.0", - "androidx.test:monitor:jar:sources:1.3.0-rc03", - "junit:junit:jar:sources:4.12", - "net.sf.kxml:kxml2:jar:sources:2.3.0" + "androidx.test:monitor:jar:sources:1.4.0", + "androidx.test.services:storage:jar:sources:1.4.0", + "junit:junit:jar:sources:4.12" ], - "file": "v1/https/maven.google.com/androidx/test/runner/1.2.0/runner-1.2.0-sources.jar", + "file": "v1/https/maven.google.com/androidx/test/runner/1.4.0/runner-1.4.0-sources.jar", "mirror_urls": [ - "https://maven.google.com/androidx/test/runner/1.2.0/runner-1.2.0-sources.jar", - "https://repo1.maven.org/maven2/androidx/test/runner/1.2.0/runner-1.2.0-sources.jar", - "https://maven.fabric.io/public/androidx/test/runner/1.2.0/runner-1.2.0-sources.jar", - "https://maven.google.com/androidx/test/runner/1.2.0/runner-1.2.0-sources.jar", - "https://repo1.maven.org/maven2/androidx/test/runner/1.2.0/runner-1.2.0-sources.jar" + "https://maven.google.com/androidx/test/runner/1.4.0/runner-1.4.0-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/runner/1.4.0/runner-1.4.0-sources.jar", + "https://maven.fabric.io/public/androidx/test/runner/1.4.0/runner-1.4.0-sources.jar", + "https://maven.google.com/androidx/test/runner/1.4.0/runner-1.4.0-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/runner/1.4.0/runner-1.4.0-sources.jar" ], - "sha256": "ec71974ddd8245a85ca856577c70972fd4c484f715df0a26271f0c28f8a58739", - "url": "https://maven.google.com/androidx/test/runner/1.2.0/runner-1.2.0-sources.jar" + "sha256": "f70a31dc1fc33d68700b61bdc44687b333ba4e44956e3df4a1fadbc46872cb61", + "url": "https://maven.google.com/androidx/test/runner/1.4.0/runner-1.4.0-sources.jar" }, { "coord": "androidx.transition:transition:aar:1.2.0", @@ -7304,36 +7339,6 @@ "sha256": "e78a7277cb9ce4980fba22d809352821848581df0a6b545fa22aa7400a05db43", "url": "https://repo1.maven.org/maven2/net/ltgt/gradle/incap/incap/0.3/incap-0.3-sources.jar" }, - { - "coord": "net.sf.kxml:kxml2:2.3.0", - "dependencies": [], - "directDependencies": [], - "file": "v1/https/repo1.maven.org/maven2/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0.jar", - "mirror_urls": [ - "https://maven.google.com/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0.jar", - "https://repo1.maven.org/maven2/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0.jar", - "https://maven.fabric.io/public/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0.jar", - "https://maven.google.com/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0.jar", - "https://repo1.maven.org/maven2/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0.jar" - ], - "sha256": "f264dd9f79a1fde10ce5ecc53221eff24be4c9331c830b7d52f2f08a7b633de2", - "url": "https://repo1.maven.org/maven2/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0.jar" - }, - { - "coord": "net.sf.kxml:kxml2:jar:sources:2.3.0", - "dependencies": [], - "directDependencies": [], - "file": "v1/https/repo1.maven.org/maven2/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0-sources.jar", - "mirror_urls": [ - "https://maven.google.com/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0-sources.jar", - "https://repo1.maven.org/maven2/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0-sources.jar", - "https://maven.fabric.io/public/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0-sources.jar", - "https://maven.google.com/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0-sources.jar", - "https://repo1.maven.org/maven2/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0-sources.jar" - ], - "sha256": "85495366666158b58961e8911ced0f6f3bc92f1ebee865518b493fdb90760250", - "url": "https://repo1.maven.org/maven2/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0-sources.jar" - }, { "coord": "nl.dionsegijn:konfetti:1.2.5", "dependencies": [ @@ -8725,12 +8730,12 @@ "org.robolectric:resources:4.4", "androidx.annotation:annotation:1.1.0", "org.ow2.asm:asm:7.2", - "androidx.test:monitor:1.3.0-rc03", + "androidx.test:monitor:1.4.0", "org.robolectric:shadows-framework:4.4", "org.robolectric:sandbox:4.4", + "androidx.test:monitor:aar:1.4.0", "org.robolectric:pluginapi:4.4", "org.ow2.asm:asm-commons:7.2", - "androidx.test:monitor:aar:1.3.0-rc03", "org.ow2.asm:asm-analysis:7.2", "org.robolectric:plugins-maven-dependency-resolver:4.4", "org.bouncycastle:bcprov-jdk15on:1.65", @@ -8748,7 +8753,7 @@ "directDependencies": [ "org.robolectric:utils:4.4", "org.robolectric:resources:4.4", - "androidx.test:monitor:1.3.0-rc03", + "androidx.test:monitor:1.4.0", "org.robolectric:shadows-framework:4.4", "org.robolectric:sandbox:4.4", "org.robolectric:pluginapi:4.4", @@ -8776,11 +8781,11 @@ "dependencies": [ "org.ow2.asm:asm-commons:jar:sources:7.2", "org.robolectric:annotations:jar:sources:4.4", - "androidx.test:monitor:aar:sources:1.3.0-rc03", "org.ow2.asm:asm-analysis:jar:sources:7.2", + "androidx.test:monitor:jar:sources:1.4.0", "org.robolectric:junit:jar:sources:4.4", - "androidx.test:monitor:jar:sources:1.3.0-rc03", "org.ow2.asm:asm:jar:sources:7.2", + "androidx.test:monitor:aar:sources:1.4.0", "javax.inject:javax.inject:jar:sources:1", "com.almworks.sqlite4java:sqlite4java:jar:sources:0.282", "com.google.auto.value:auto-value-annotations:jar:sources:1.6.5", @@ -8802,8 +8807,8 @@ ], "directDependencies": [ "org.robolectric:annotations:jar:sources:4.4", + "androidx.test:monitor:jar:sources:1.4.0", "org.robolectric:junit:jar:sources:4.4", - "androidx.test:monitor:jar:sources:1.3.0-rc03", "javax.inject:javax.inject:jar:sources:1", "org.robolectric:utils:jar:sources:4.4", "org.robolectric:pluginapi:jar:sources:4.4", @@ -8951,9 +8956,9 @@ "org.robolectric:resources:4.4", "androidx.annotation:annotation:1.1.0", "org.ow2.asm:asm:7.2", + "androidx.test:monitor:aar:1.4.0", "org.robolectric:pluginapi:4.4", "org.ow2.asm:asm-commons:7.2", - "androidx.test:monitor:aar:1.3.0-rc03", "org.ow2.asm:asm-analysis:7.2", "org.ow2.asm:asm-util:7.2", "com.almworks.sqlite4java:sqlite4java:0.282", @@ -8970,8 +8975,8 @@ "com.google.auto.value:auto-value-annotations:1.6.5", "org.robolectric:resources:4.4", "androidx.annotation:annotation:1.1.0", + "androidx.test:monitor:aar:1.4.0", "org.robolectric:pluginapi:4.4", - "androidx.test:monitor:aar:1.3.0-rc03", "com.almworks.sqlite4java:sqlite4java:0.282", "org.robolectric:utils-reflector:4.4", "org.robolectric:shadowapi:4.4", @@ -8994,9 +8999,9 @@ "dependencies": [ "org.ow2.asm:asm-commons:jar:sources:7.2", "org.robolectric:annotations:jar:sources:4.4", - "androidx.test:monitor:aar:sources:1.3.0-rc03", "org.ow2.asm:asm-analysis:jar:sources:7.2", "org.ow2.asm:asm:jar:sources:7.2", + "androidx.test:monitor:aar:sources:1.4.0", "javax.inject:javax.inject:jar:sources:1", "com.almworks.sqlite4java:sqlite4java:jar:sources:0.282", "com.google.auto.value:auto-value-annotations:jar:sources:1.6.5", @@ -9014,7 +9019,7 @@ ], "directDependencies": [ "org.robolectric:annotations:jar:sources:4.4", - "androidx.test:monitor:aar:sources:1.3.0-rc03", + "androidx.test:monitor:aar:sources:1.4.0", "com.almworks.sqlite4java:sqlite4java:jar:sources:0.282", "com.google.auto.value:auto-value-annotations:jar:sources:1.6.5", "org.robolectric:utils:jar:sources:4.4", diff --git a/third_party/versions.bzl b/third_party/versions.bzl index 8d6e0972e7b..4ef0d3fafae 100644 --- a/third_party/versions.bzl +++ b/third_party/versions.bzl @@ -81,9 +81,9 @@ MAVEN_TEST_DEPENDENCY_VERSIONS = { "androidx.test.espresso:espresso-contrib": "3.1.0", "androidx.test.espresso:espresso-core": "3.2.0", "androidx.test.espresso:espresso-intents": "3.1.0", - "androidx.test.ext:junit": "1.1.1", - "androidx.test:core": "1.0.0", - "androidx.test:runner": "1.2.0", + "androidx.test.ext:junit": "1.1.3", + "androidx.test:core": "1.4.0", + "androidx.test:runner": "1.4.0", "androidx.work:work-testing": "2.4.0", "com.github.bumptech.glide:mocks": "4.11.0", "com.google.truth:truth": "0.43", From bb6f5bbe66b12cc3d26019f8868afcbdbff10c57 Mon Sep 17 00:00:00 2001 From: farees Date: Tue, 20 Jul 2021 21:17:45 +0530 Subject: [PATCH 04/63] Updated implementation based on adb commands --- instrumentation/AndroidManifest.xml | 15 +- instrumentation/BUILD.bazel | 68 ++------ .../oppia/android/instrumentation/BUILD.bazel | 35 +++++ .../oppia/android/instrumentation/BaseTest.kt | 83 ++++++++++ .../android/instrumentation/ProfileTest.kt | 146 ------------------ 5 files changed, 137 insertions(+), 210 deletions(-) create mode 100644 instrumentation/src/javatest/org/oppia/android/instrumentation/BUILD.bazel create mode 100644 instrumentation/src/javatest/org/oppia/android/instrumentation/BaseTest.kt delete mode 100644 instrumentation/src/javatest/org/oppia/android/instrumentation/ProfileTest.kt diff --git a/instrumentation/AndroidManifest.xml b/instrumentation/AndroidManifest.xml index 88be080e5bc..dbbbe364642 100644 --- a/instrumentation/AndroidManifest.xml +++ b/instrumentation/AndroidManifest.xml @@ -1,9 +1,12 @@ + - + - - + + diff --git a/instrumentation/BUILD.bazel b/instrumentation/BUILD.bazel index 273eea6a026..6c8b7434afd 100644 --- a/instrumentation/BUILD.bazel +++ b/instrumentation/BUILD.bazel @@ -1,67 +1,19 @@ -load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_android_library") - -android_library( - name="instrumentation_deps", - testonly = True, - visibility = ["//visibility:public"], - exports = [ - "//third_party:androidx_test_runner", - "//third_party:androidx_test_ext_junit", - "//third_party:com_google_truth_truth", - "//third_party:junit_junit", - "//third_party:androidx_test_uiautomator_uiautomator", - ], -) - -kt_android_library( - name="profile_test", - testonly = True, - srcs = [ - "src/javatest/org/oppia/android/instrumentation/ProfileTest.kt", - ], - visibility = ["//visibility:public"], - deps = [ - ":instrumentation_deps", - ], -) - -android_device( - name = "android_26_x86", - visibility = ["//visibility:public"], - tags = ["requires-kvm"], - generator_name = "generic_phone", - generator_function = "make_device", - generator_location = "tools/android/emulated_devices/generic_phone/BUILD.bazel:43:12", - vertical_resolution = 2160, - horizontal_resolution = 1080, - ram = 2048, - screen_density = 240, - cache = 32, - vm_heap = 256, - system_image = "@android_test_support//tools/android/emulated_devices/generic_phone:android_26_x86_images", - default_properties = "@android_test_support//tools/android/emulated_devices/generic_phone:_android_26_x86_props", -) +""" +This library contains all android_binary targets to each test suite in instrumentation module. +Note that: + - All the android_binaries are named similar to the respective class name of the test suite. +""" +load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_android_library") android_binary( - name = "ProfileTest", + name = "BaseTest", testonly = True, custom_package = "org.oppia.android", visibility = ["//visibility:public"], instruments = "//:oppia", manifest="AndroidManifest.xml", - deps = [":profile_test"] -) - -android_instrumentation_test( - name = "OppiaTest", - target_device = "@android_test_support//tools/android/emulated_devices/generic_phone:android_26_x86_qemu2", - test_app = ":ProfileTest", -) - - -android_instrumentation_test( - name = "Instrument", - target_device = "@android_test_support//tools/android/emulated_devices/low_mem_phone:android_23_x86_qemu2", - test_app = ":ProfileTest", + deps = [ + "//instrumentation/src/javatest/org/oppia/android/instrumentation:base_test_lib" + ], ) diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/BUILD.bazel b/instrumentation/src/javatest/org/oppia/android/instrumentation/BUILD.bazel new file mode 100644 index 00000000000..2bfdebaa700 --- /dev/null +++ b/instrumentation/src/javatest/org/oppia/android/instrumentation/BUILD.bazel @@ -0,0 +1,35 @@ +""" +This library contains the test suite source files of the instrumentation module. +Note that: + - Each source file has its own kt_android_library target + - Target name of each kt_android_library as to be in small letters, separated by a underscore + and ends with "_lib" +""" + +load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_android_library") + +# Common deps for each test suite. +android_library( + name="instrumentation_deps", + testonly = True, + visibility = ["//visibility:public"], + exports = [ + "//third_party:androidx_test_runner", + "//third_party:androidx_test_ext_junit", + "//third_party:com_google_truth_truth", + "//third_party:junit_junit", + "//third_party:androidx_test_uiautomator_uiautomator", + ], +) + +kt_android_library( + name="base_test_lib", + testonly = True, + srcs = [ + "BaseTest.kt", + ], + visibility = ["//visibility:public"], + deps = [ + ":instrumentation_deps", + ], +) diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/BaseTest.kt b/instrumentation/src/javatest/org/oppia/android/instrumentation/BaseTest.kt new file mode 100644 index 00000000000..fd5e6588558 --- /dev/null +++ b/instrumentation/src/javatest/org/oppia/android/instrumentation/BaseTest.kt @@ -0,0 +1,83 @@ +package org.oppia.android.instrumentation + +import android.content.Context +import android.content.Intent +import android.content.pm.PackageManager +import androidx.test.core.app.ApplicationProvider +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.uiautomator.By +import androidx.test.uiautomator.Direction +import androidx.test.uiautomator.UiDevice +import androidx.test.uiautomator.Until + +import org.junit.Assert.assertNotNull +import org.junit.Assert.assertThat +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import androidx.test.ext.junit.runners.AndroidJUnit4 + +/** Tests to load Oppia using UI Automator. */ +class BaseTest { + private val OPPIA_PACKAGE = "org.oppia.android" + private val LAUNCH_TIMEOUT = 5000 + private lateinit var device: UiDevice + + @Before + fun startOppiaFromHomeScreen() { + // Initialize UiDevice instance + device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) + + // Start from the home screen + device.pressHome() + + // Wait for launcher + val launcherPackage = getLauncherPackageName() + assertNotNull(launcherPackage) + device.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)), LAUNCH_TIMEOUT.toLong()) + + // Launch the blueprint app + val context = ApplicationProvider.getApplicationContext() + val intent = context.packageManager + .getLaunchIntentForPackage(OPPIA_PACKAGE) + intent!!.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) // Clear out any previous instances + context.startActivity(intent) + + // Wait for the app to appear + device.wait(Until.hasObject(By.pkg(OPPIA_PACKAGE).depth(0)), LAUNCH_TIMEOUT.toLong()) + } + + @Test + fun baseTest_uiDevice_isNotNull() { + assertNotNull(device) + } + + @Test + fun baseTest_openProfileDashboard_titleExists() { + val skip_button = device.findObject(By.res("$OPPIA_PACKAGE:id/skip_text_view")) + skip_button?.let { + it.click() + device.wait(Until.hasObject(By.res("$OPPIA_PACKAGE:id/get_started_button")), 1000L) + device.findObject(By.res("org.oppia.android:id/get_started_button")) + .click() + } + device.wait(Until.hasObject(By.res("$OPPIA_PACKAGE:id/profile_select_text")), 1000L) + assertNotNull(device.findObject(By.res("$OPPIA_PACKAGE:id/profile_select_text"))) + } + + /** + * Uses package manager to find the package name of the device launcher. Usually this package + * is "com.android.launcher" but can be different at times. This is a generic solution which + * works on all platforms.` + */ + private fun getLauncherPackageName(): String { + // Create launcher Intent + val intent = Intent(Intent.ACTION_MAIN) + intent.addCategory(Intent.CATEGORY_HOME) + + // Use PackageManager to get the launcher package name + val pm = ApplicationProvider.getApplicationContext().packageManager + val resolveInfo = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) + return resolveInfo!!.activityInfo.packageName + } +} diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/ProfileTest.kt b/instrumentation/src/javatest/org/oppia/android/instrumentation/ProfileTest.kt deleted file mode 100644 index 39ce3bcff3f..00000000000 --- a/instrumentation/src/javatest/org/oppia/android/instrumentation/ProfileTest.kt +++ /dev/null @@ -1,146 +0,0 @@ -package org.oppia.android.instrumentation - - -import android.content.Context -import android.content.Intent -import android.content.pm.PackageManager -import androidx.test.core.app.ApplicationProvider -import androidx.test.platform.app.InstrumentationRegistry -import androidx.test.uiautomator.By -import androidx.test.uiautomator.Direction -import androidx.test.uiautomator.UiDevice -import androidx.test.uiautomator.Until - -import org.junit.Assert.assertNotNull -import org.junit.Assert.assertThat -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith -import androidx.test.ext.junit.runners.AndroidJUnit4 - - -@RunWith(AndroidJUnit4::class) -class ProfileTest { - - private val BASIC_SAMPLE_PACKAGE = "com.example.android.testing.uiautomator.BasicSample" - - private val OPPIA_PACKAGE = "org.oppia.android" - - private val LAUNCH_TIMEOUT = 1000 * 5 - - private val STRING_TO_BE_TYPED = "UiAutomator" - - private lateinit var mDevice: UiDevice - - @Before - fun startMainActivityFromHomeScreen() { - // Initialize UiDevice instance - mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) - - // Start from the home screen - mDevice.pressHome() - - // Wait for launcher - val launcherPackage = getLauncherPackageName() - assertNotNull(launcherPackage) - mDevice.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)), LAUNCH_TIMEOUT.toLong()) - - // Launch the blueprint app - val context = ApplicationProvider.getApplicationContext() - val intent = context.packageManager - .getLaunchIntentForPackage(OPPIA_PACKAGE) - intent!!.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) // Clear out any previous instances - context.startActivity(intent) - - // Wait for the app to appear - mDevice.wait(Until.hasObject(By.pkg(OPPIA_PACKAGE).depth(0)), LAUNCH_TIMEOUT.toLong()) - } - - // @Test - // fun checkPreconditions() { - // assertNotNull(mDevice) - // } - - @Test - fun exitOnBoarding() { - mDevice.findObject(By.res("org.oppia.android:id/skip_text_view")) - .click() - mDevice.wait(Until.hasObject(By.res("org.oppia.android:id/get_started_button")), 1000L) - mDevice.findObject(By.res("org.oppia.android:id/get_started_button")) - .click() - } - - @Test - fun openOppia() { - // Start from the home screen - mDevice.pressHome() - // Wait for launcher - val launcherPackage = getLauncherPackageName() - assertNotNull(launcherPackage) - mDevice.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)), LAUNCH_TIMEOUT.toLong()) - - // Launch the blueprint app - val context = InstrumentationRegistry.getInstrumentation().context - val intent = context.packageManager - .getLaunchIntentForPackage(OPPIA_PACKAGE) - intent!!.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) // Clear out any previous instances - context.startActivity(intent) - - // Wait for the app to appear - mDevice.wait(Until.hasObject(By.pkg(BASIC_SAMPLE_PACKAGE).depth(0)), LAUNCH_TIMEOUT.toLong()) - } - - /** - * Uses package manager to find the package name of the device launcher. Usually this package - * is "com.android.launcher" but can be different at times. This is a generic solution which - * works on all platforms.` - */ - private fun getLauncherPackageName(): String { - // Create launcher Intent - val intent = Intent(Intent.ACTION_MAIN) - intent.addCategory(Intent.CATEGORY_HOME) - - // Use PackageManager to get the launcher package name - val pm = ApplicationProvider.getApplicationContext().packageManager - val resolveInfo = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) - return resolveInfo!!.activityInfo.packageName - } -} - -/* - -android_device( - name = "android_27_x86_qemu2", - visibility = ["//visibility:public"], - tags = ["requires-kvm"], - generator_name = "generic_phone", - generator_function = "make_device", - generator_location = "tools/android/emulated_devices/generic_phone/BUILD.bazel:43:12", - vertical_resolution = 2160, - horizontal_resolution = 1080, - ram = 2048, - screen_density = 240, - cache = 32, - vm_heap = 256, - system_image = "@android_test_support//tools/android/emulated_devices/generic_phone:android_27_x86_qemu2_images", - default_properties = "@android_test_support//tools/android/emulated_devices/generic_phone:_android_27_x86_qemu2_props", -) - -android_device( - name = "android_23_x86", - visibility = ["//visibility:public"], - tags = ["requires-kvm"], - generator_name = "generic_phone", - generator_function = "make_device", - generator_location = "tools/android/emulated_devices/generic_phone/BUILD.bazel:43:12", - vertical_resolution = 800, - horizontal_resolution = 480, - ram = 2048, - screen_density = 240, - cache = 32, - vm_heap = 256, - system_image = "@android_test_support//tools/android/emulated_devices/generic_phone:android_23_x86_images", - default_properties = "@android_test_support//tools/android/emulated_devices/generic_phone:_android_23_x86_props", -) - -* */ From 44f4003adc5c226cf2a8012b50d9b06b9c9d385b Mon Sep 17 00:00:00 2001 From: farees Date: Tue, 20 Jul 2021 22:40:46 +0530 Subject: [PATCH 05/63] Nit fixes --- .../oppia/android/instrumentation/BaseTest.kt | 15 +- scripts/ktlint_lint_check.sh | 4 +- third_party/maven_install.json | 351 ++++++++++-------- 3 files changed, 200 insertions(+), 170 deletions(-) diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/BaseTest.kt b/instrumentation/src/javatest/org/oppia/android/instrumentation/BaseTest.kt index fd5e6588558..816d3067e79 100644 --- a/instrumentation/src/javatest/org/oppia/android/instrumentation/BaseTest.kt +++ b/instrumentation/src/javatest/org/oppia/android/instrumentation/BaseTest.kt @@ -6,16 +6,11 @@ import android.content.pm.PackageManager import androidx.test.core.app.ApplicationProvider import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.By -import androidx.test.uiautomator.Direction import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.Until - import org.junit.Assert.assertNotNull -import org.junit.Assert.assertThat import org.junit.Before import org.junit.Test -import org.junit.runner.RunWith -import androidx.test.ext.junit.runners.AndroidJUnit4 /** Tests to load Oppia using UI Automator. */ class BaseTest { @@ -47,11 +42,11 @@ class BaseTest { device.wait(Until.hasObject(By.pkg(OPPIA_PACKAGE).depth(0)), LAUNCH_TIMEOUT.toLong()) } - @Test - fun baseTest_uiDevice_isNotNull() { - assertNotNull(device) - } - + @Test + fun baseTest_uiDevice_isNotNull() { + assertNotNull(device) + } + @Test fun baseTest_openProfileDashboard_titleExists() { val skip_button = device.findObject(By.res("$OPPIA_PACKAGE:id/skip_text_view")) diff --git a/scripts/ktlint_lint_check.sh b/scripts/ktlint_lint_check.sh index 5045c1fd3f9..2713b88d0e0 100755 --- a/scripts/ktlint_lint_check.sh +++ b/scripts/ktlint_lint_check.sh @@ -14,7 +14,7 @@ else jar_file_path="$github_actions_path/oppia-android-tools/ktlint" fi -java -jar $jar_file_path --android app/src/**/*.kt data/src/**/*.kt domain/src/**/*.kt testing/src/**/*.kt utility/src/**/*.kt scripts/src/**/*.kt +java -jar $jar_file_path --android app/src/**/*.kt data/src/**/*.kt domain/src/**/*.kt testing/src/**/*.kt utility/src/**/*.kt scripts/src/**/*.kt instrumentation/src/**/*.kt status=$? @@ -25,7 +25,7 @@ else echo "********************************" echo "Ktlint issue found." echo "Please fix the above issues. - You can also use the java -jar $jar_file_path -F --android domain/src/**/*.kt utility/src/**/*.kt data/src/**/*.kt app/src/**/*.kt testing/src/**/*.kt scripts/src/**/*.kt + You can also use the java -jar $jar_file_path -F --android domain/src/**/*.kt utility/src/**/*.kt data/src/**/*.kt app/src/**/*.kt testing/src/**/*.kt scripts/src/**/*.kt instrumentation/src/**/*.kt command to fix the most common issues." echo "Please note, there might be a possibility where the above command will not fix the issue. In that case, you will have to fix it yourself." diff --git a/third_party/maven_install.json b/third_party/maven_install.json index 3d6cf35c655..b2c163f2d75 100644 --- a/third_party/maven_install.json +++ b/third_party/maven_install.json @@ -1,13 +1,12 @@ { "dependency_tree": { "__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL", - "__INPUT_ARTIFACTS_HASH": 400706612, - "__RESOLVED_ARTIFACTS_HASH": -1263051889, + "__INPUT_ARTIFACTS_HASH": -1776077967, + "__RESOLVED_ARTIFACTS_HASH": -1881168025, "conflict_resolution": { "androidx.appcompat:appcompat:1.0.2": "androidx.appcompat:appcompat:1.2.0", "androidx.core:core:1.0.1": "androidx.core:core:1.3.0", "androidx.recyclerview:recyclerview:1.0.0": "androidx.recyclerview:recyclerview:1.1.0", - "androidx.test:core:1.0.0": "androidx.test:core:1.2.0", "org.jetbrains.kotlin:kotlin-reflect:1.3.41": "org.jetbrains.kotlin:kotlin-reflect:1.4.10", "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.72": "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.10", "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.2": "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.4", @@ -3141,24 +3140,20 @@ { "coord": "androidx.test.espresso:espresso-core:3.2.0", "dependencies": [ - "androidx.annotation:annotation:1.1.0", "com.google.code.findbugs:jsr305:3.0.2", - "androidx.test:monitor:1.3.0-rc03", "org.hamcrest:hamcrest-library:1.3", - "androidx.test:runner:1.2.0", "org.hamcrest:hamcrest-integration:1.3", - "junit:junit:4.12", "org.hamcrest:hamcrest-core:1.3", + "androidx.test:runner:1.4.0", "androidx.test.espresso:espresso-idling-resource:3.2.0", "com.squareup:javawriter:2.1.1", - "javax.inject:javax.inject:1", - "net.sf.kxml:kxml2:2.3.0" + "javax.inject:javax.inject:1" ], "directDependencies": [ "com.google.code.findbugs:jsr305:3.0.2", "org.hamcrest:hamcrest-library:1.3", - "androidx.test:runner:1.2.0", "org.hamcrest:hamcrest-integration:1.3", + "androidx.test:runner:1.4.0", "androidx.test.espresso:espresso-idling-resource:3.2.0", "com.squareup:javawriter:2.1.1", "javax.inject:javax.inject:1" @@ -3179,16 +3174,12 @@ "dependencies": [ "com.google.code.findbugs:jsr305:jar:sources:3.0.2", "org.hamcrest:hamcrest-integration:jar:sources:1.3", - "androidx.test:monitor:jar:sources:1.3.0-rc03", "com.squareup:javawriter:jar:sources:2.1.1", "javax.inject:javax.inject:jar:sources:1", "org.hamcrest:hamcrest-core:jar:sources:1.3", "androidx.test.espresso:espresso-idling-resource:jar:sources:3.2.0", "org.hamcrest:hamcrest-library:jar:sources:1.3", - "androidx.annotation:annotation:jar:sources:1.1.0", - "androidx.test:runner:jar:sources:1.2.0", - "net.sf.kxml:kxml2:jar:sources:2.3.0", - "junit:junit:jar:sources:4.12" + "androidx.test:runner:jar:sources:1.4.0" ], "directDependencies": [ "com.google.code.findbugs:jsr305:jar:sources:3.0.2", @@ -3197,7 +3188,7 @@ "javax.inject:javax.inject:jar:sources:1", "androidx.test.espresso:espresso-idling-resource:jar:sources:3.2.0", "org.hamcrest:hamcrest-library:jar:sources:1.3", - "androidx.test:runner:jar:sources:1.2.0" + "androidx.test:runner:jar:sources:1.4.0" ], "file": "v1/https/maven.google.com/androidx/test/espresso/espresso-core/3.2.0/espresso-core-3.2.0-sources.jar", "mirror_urls": [ @@ -3245,7 +3236,7 @@ "dependencies": [ "androidx.test:rules:1.1.0", "androidx.test.espresso:espresso-core:3.2.0", - "androidx.test:runner:1.2.0" + "androidx.test:runner:1.4.0" ], "directDependencies": [ "androidx.test:rules:1.1.0", @@ -3265,8 +3256,8 @@ { "coord": "androidx.test.espresso:espresso-intents:jar:sources:3.1.0", "dependencies": [ + "androidx.test:runner:jar:sources:1.4.0", "androidx.test:rules:jar:sources:1.1.0", - "androidx.test:runner:jar:sources:1.2.0", "androidx.test.espresso:espresso-core:jar:sources:3.2.0" ], "directDependencies": [ @@ -3285,37 +3276,37 @@ "url": "https://maven.google.com/androidx/test/espresso/espresso-intents/3.1.0/espresso-intents-3.1.0-sources.jar" }, { - "coord": "androidx.test.ext:junit:1.1.1", + "coord": "androidx.test.ext:junit:1.1.3", "dependencies": [ "androidx.lifecycle:lifecycle-common:2.2.0", "androidx.annotation:annotation:1.1.0", - "androidx.test:monitor:1.3.0-rc03", + "androidx.test:monitor:1.4.0", "junit:junit:4.12", "org.hamcrest:hamcrest-core:1.3", - "androidx.test:core:1.2.0" + "androidx.test:core:1.4.0" ], "directDependencies": [ "androidx.annotation:annotation:1.1.0", - "androidx.test:core:1.2.0", - "androidx.test:monitor:1.3.0-rc03", + "androidx.test:core:1.4.0", + "androidx.test:monitor:1.4.0", "junit:junit:4.12" ], - "file": "v1/https/maven.google.com/androidx/test/ext/junit/1.1.1/junit-1.1.1.aar", + "file": "v1/https/maven.google.com/androidx/test/ext/junit/1.1.3/junit-1.1.3.aar", "mirror_urls": [ - "https://maven.google.com/androidx/test/ext/junit/1.1.1/junit-1.1.1.aar", - "https://repo1.maven.org/maven2/androidx/test/ext/junit/1.1.1/junit-1.1.1.aar", - "https://maven.fabric.io/public/androidx/test/ext/junit/1.1.1/junit-1.1.1.aar", - "https://maven.google.com/androidx/test/ext/junit/1.1.1/junit-1.1.1.aar", - "https://repo1.maven.org/maven2/androidx/test/ext/junit/1.1.1/junit-1.1.1.aar" + "https://maven.google.com/androidx/test/ext/junit/1.1.3/junit-1.1.3.aar", + "https://repo1.maven.org/maven2/androidx/test/ext/junit/1.1.3/junit-1.1.3.aar", + "https://maven.fabric.io/public/androidx/test/ext/junit/1.1.3/junit-1.1.3.aar", + "https://maven.google.com/androidx/test/ext/junit/1.1.3/junit-1.1.3.aar", + "https://repo1.maven.org/maven2/androidx/test/ext/junit/1.1.3/junit-1.1.3.aar" ], - "sha256": "449df418d2916a0f86fe7dafb1edb09480fafb6e995d5c751c7d0d1970d4ae72", - "url": "https://maven.google.com/androidx/test/ext/junit/1.1.1/junit-1.1.1.aar" + "sha256": "a97209d75a9a85815fa8934f5a4a320de1163ffe94e2f0b328c0c98a59660690", + "url": "https://maven.google.com/androidx/test/ext/junit/1.1.3/junit-1.1.3.aar" }, { - "coord": "androidx.test.ext:junit:jar:sources:1.1.1", + "coord": "androidx.test.ext:junit:jar:sources:1.1.3", "dependencies": [ - "androidx.test:core:jar:sources:1.2.0", - "androidx.test:monitor:jar:sources:1.3.0-rc03", + "androidx.test:monitor:jar:sources:1.4.0", + "androidx.test:core:jar:sources:1.4.0", "org.hamcrest:hamcrest-core:jar:sources:1.3", "androidx.annotation:annotation:jar:sources:1.1.0", "androidx.lifecycle:lifecycle-common:jar:sources:2.2.0", @@ -3323,111 +3314,183 @@ ], "directDependencies": [ "androidx.annotation:annotation:jar:sources:1.1.0", - "androidx.test:core:jar:sources:1.2.0", - "androidx.test:monitor:jar:sources:1.3.0-rc03", + "androidx.test:core:jar:sources:1.4.0", + "androidx.test:monitor:jar:sources:1.4.0", "junit:junit:jar:sources:4.12" ], - "file": "v1/https/maven.google.com/androidx/test/ext/junit/1.1.1/junit-1.1.1-sources.jar", + "file": "v1/https/maven.google.com/androidx/test/ext/junit/1.1.3/junit-1.1.3-sources.jar", + "mirror_urls": [ + "https://maven.google.com/androidx/test/ext/junit/1.1.3/junit-1.1.3-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/ext/junit/1.1.3/junit-1.1.3-sources.jar", + "https://maven.fabric.io/public/androidx/test/ext/junit/1.1.3/junit-1.1.3-sources.jar", + "https://maven.google.com/androidx/test/ext/junit/1.1.3/junit-1.1.3-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/ext/junit/1.1.3/junit-1.1.3-sources.jar" + ], + "sha256": "aefd25841285b641906dca12127cad26866caacd9aeefe8b38103ede35abc828", + "url": "https://maven.google.com/androidx/test/ext/junit/1.1.3/junit-1.1.3-sources.jar" + }, + { + "coord": "androidx.test.services:storage:1.4.0", + "dependencies": [ + "androidx.test:monitor:1.4.0", + "com.google.code.findbugs:jsr305:3.0.2" + ], + "directDependencies": [ + "androidx.test:monitor:1.4.0", + "com.google.code.findbugs:jsr305:3.0.2" + ], + "file": "v1/https/maven.google.com/androidx/test/services/storage/1.4.0/storage-1.4.0.aar", "mirror_urls": [ - "https://maven.google.com/androidx/test/ext/junit/1.1.1/junit-1.1.1-sources.jar", - "https://repo1.maven.org/maven2/androidx/test/ext/junit/1.1.1/junit-1.1.1-sources.jar", - "https://maven.fabric.io/public/androidx/test/ext/junit/1.1.1/junit-1.1.1-sources.jar", - "https://maven.google.com/androidx/test/ext/junit/1.1.1/junit-1.1.1-sources.jar", - "https://repo1.maven.org/maven2/androidx/test/ext/junit/1.1.1/junit-1.1.1-sources.jar" + "https://maven.google.com/androidx/test/services/storage/1.4.0/storage-1.4.0.aar", + "https://repo1.maven.org/maven2/androidx/test/services/storage/1.4.0/storage-1.4.0.aar", + "https://maven.fabric.io/public/androidx/test/services/storage/1.4.0/storage-1.4.0.aar", + "https://maven.google.com/androidx/test/services/storage/1.4.0/storage-1.4.0.aar", + "https://repo1.maven.org/maven2/androidx/test/services/storage/1.4.0/storage-1.4.0.aar" ], - "sha256": "e8abb0752a123d337be4cced50298067a8340135e64f0a24ff52345ed20cd292", - "url": "https://maven.google.com/androidx/test/ext/junit/1.1.1/junit-1.1.1-sources.jar" + "sha256": "35cfbf442abb83e5876cd5deb9de02ae047459f18f831097c5caa76d626bc38a", + "url": "https://maven.google.com/androidx/test/services/storage/1.4.0/storage-1.4.0.aar" }, { - "coord": "androidx.test:core:1.2.0", + "coord": "androidx.test.services:storage:jar:sources:1.4.0", + "dependencies": [ + "com.google.code.findbugs:jsr305:jar:sources:3.0.2", + "androidx.test:monitor:jar:sources:1.4.0" + ], + "directDependencies": [ + "androidx.test:monitor:jar:sources:1.4.0", + "com.google.code.findbugs:jsr305:jar:sources:3.0.2" + ], + "file": "v1/https/maven.google.com/androidx/test/services/storage/1.4.0/storage-1.4.0-sources.jar", + "mirror_urls": [ + "https://maven.google.com/androidx/test/services/storage/1.4.0/storage-1.4.0-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/services/storage/1.4.0/storage-1.4.0-sources.jar", + "https://maven.fabric.io/public/androidx/test/services/storage/1.4.0/storage-1.4.0-sources.jar", + "https://maven.google.com/androidx/test/services/storage/1.4.0/storage-1.4.0-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/services/storage/1.4.0/storage-1.4.0-sources.jar" + ], + "sha256": "f80c24f6564166dafd70ac169e8881eea4f9de6e71e714408bf34c214ecb8673", + "url": "https://maven.google.com/androidx/test/services/storage/1.4.0/storage-1.4.0-sources.jar" + }, + { + "coord": "androidx.test.uiautomator:uiautomator:2.2.0", + "dependencies": [], + "directDependencies": [], + "file": "v1/https/maven.google.com/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0.aar", + "mirror_urls": [ + "https://maven.google.com/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0.aar", + "https://repo1.maven.org/maven2/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0.aar", + "https://maven.fabric.io/public/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0.aar", + "https://maven.google.com/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0.aar", + "https://repo1.maven.org/maven2/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0.aar" + ], + "sha256": "2838e9d961dbffefbbd229a2bd4f6f82ac4fb2462975862a9e75e9ed325a3197", + "url": "https://maven.google.com/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0.aar" + }, + { + "coord": "androidx.test.uiautomator:uiautomator:jar:sources:2.2.0", + "dependencies": [], + "directDependencies": [], + "file": "v1/https/maven.google.com/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0-sources.jar", + "mirror_urls": [ + "https://maven.google.com/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0-sources.jar", + "https://maven.fabric.io/public/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0-sources.jar", + "https://maven.google.com/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0-sources.jar" + ], + "sha256": "e1f438106ac0d26b80ecf4fd6ffe6d36f60e12bdcd6316903f802ed24d00be99", + "url": "https://maven.google.com/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0-sources.jar" + }, + { + "coord": "androidx.test:core:1.4.0", "dependencies": [ "androidx.annotation:annotation:1.1.0", - "androidx.lifecycle:lifecycle-common:2.2.0", - "androidx.test:monitor:1.3.0-rc03" + "androidx.test:monitor:1.4.0", + "androidx.lifecycle:lifecycle-common:2.2.0" ], "directDependencies": [ "androidx.annotation:annotation:1.1.0", "androidx.lifecycle:lifecycle-common:2.2.0", - "androidx.test:monitor:1.3.0-rc03" + "androidx.test:monitor:1.4.0" ], - "file": "v1/https/maven.google.com/androidx/test/core/1.2.0/core-1.2.0.aar", + "file": "v1/https/maven.google.com/androidx/test/core/1.4.0/core-1.4.0.aar", "mirror_urls": [ - "https://maven.google.com/androidx/test/core/1.2.0/core-1.2.0.aar", - "https://repo1.maven.org/maven2/androidx/test/core/1.2.0/core-1.2.0.aar", - "https://maven.fabric.io/public/androidx/test/core/1.2.0/core-1.2.0.aar", - "https://maven.google.com/androidx/test/core/1.2.0/core-1.2.0.aar", - "https://repo1.maven.org/maven2/androidx/test/core/1.2.0/core-1.2.0.aar" + "https://maven.google.com/androidx/test/core/1.4.0/core-1.4.0.aar", + "https://repo1.maven.org/maven2/androidx/test/core/1.4.0/core-1.4.0.aar", + "https://maven.fabric.io/public/androidx/test/core/1.4.0/core-1.4.0.aar", + "https://maven.google.com/androidx/test/core/1.4.0/core-1.4.0.aar", + "https://repo1.maven.org/maven2/androidx/test/core/1.4.0/core-1.4.0.aar" ], - "sha256": "c88b739b1c499afb792374be19b9cf829e89567f26441a74f664c0cf8de158a4", - "url": "https://maven.google.com/androidx/test/core/1.2.0/core-1.2.0.aar" + "sha256": "671284e62e393f16ceae1a99a3a9a07bf1aacda29f8fe7b6b884355ef34c09cf", + "url": "https://maven.google.com/androidx/test/core/1.4.0/core-1.4.0.aar" }, { - "coord": "androidx.test:core:jar:sources:1.2.0", + "coord": "androidx.test:core:jar:sources:1.4.0", "dependencies": [ - "androidx.test:monitor:jar:sources:1.3.0-rc03", + "androidx.test:monitor:jar:sources:1.4.0", "androidx.lifecycle:lifecycle-common:jar:sources:2.2.0", "androidx.annotation:annotation:jar:sources:1.1.0" ], "directDependencies": [ "androidx.annotation:annotation:jar:sources:1.1.0", "androidx.lifecycle:lifecycle-common:jar:sources:2.2.0", - "androidx.test:monitor:jar:sources:1.3.0-rc03" + "androidx.test:monitor:jar:sources:1.4.0" ], - "file": "v1/https/maven.google.com/androidx/test/core/1.2.0/core-1.2.0-sources.jar", + "file": "v1/https/maven.google.com/androidx/test/core/1.4.0/core-1.4.0-sources.jar", "mirror_urls": [ - "https://maven.google.com/androidx/test/core/1.2.0/core-1.2.0-sources.jar", - "https://repo1.maven.org/maven2/androidx/test/core/1.2.0/core-1.2.0-sources.jar", - "https://maven.fabric.io/public/androidx/test/core/1.2.0/core-1.2.0-sources.jar", - "https://maven.google.com/androidx/test/core/1.2.0/core-1.2.0-sources.jar", - "https://repo1.maven.org/maven2/androidx/test/core/1.2.0/core-1.2.0-sources.jar" + "https://maven.google.com/androidx/test/core/1.4.0/core-1.4.0-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/core/1.4.0/core-1.4.0-sources.jar", + "https://maven.fabric.io/public/androidx/test/core/1.4.0/core-1.4.0-sources.jar", + "https://maven.google.com/androidx/test/core/1.4.0/core-1.4.0-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/core/1.4.0/core-1.4.0-sources.jar" ], - "sha256": "19d087a01ae8741a62b661c07929897eb475af64198a9bd7e89d97e7ee88a89a", - "url": "https://maven.google.com/androidx/test/core/1.2.0/core-1.2.0-sources.jar" + "sha256": "b3125d546acfea278b82250344c83826e872e3f461109daf0948806382603b30", + "url": "https://maven.google.com/androidx/test/core/1.4.0/core-1.4.0-sources.jar" }, { - "coord": "androidx.test:monitor:1.3.0-rc03", + "coord": "androidx.test:monitor:1.4.0", "dependencies": [ "androidx.annotation:annotation:1.1.0" ], "directDependencies": [ "androidx.annotation:annotation:1.1.0" ], - "file": "v1/https/maven.google.com/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03.aar", + "file": "v1/https/maven.google.com/androidx/test/monitor/1.4.0/monitor-1.4.0.aar", "mirror_urls": [ - "https://maven.google.com/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03.aar", - "https://repo1.maven.org/maven2/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03.aar", - "https://maven.fabric.io/public/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03.aar", - "https://maven.google.com/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03.aar", - "https://repo1.maven.org/maven2/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03.aar" + "https://maven.google.com/androidx/test/monitor/1.4.0/monitor-1.4.0.aar", + "https://repo1.maven.org/maven2/androidx/test/monitor/1.4.0/monitor-1.4.0.aar", + "https://maven.fabric.io/public/androidx/test/monitor/1.4.0/monitor-1.4.0.aar", + "https://maven.google.com/androidx/test/monitor/1.4.0/monitor-1.4.0.aar", + "https://repo1.maven.org/maven2/androidx/test/monitor/1.4.0/monitor-1.4.0.aar" ], - "sha256": "7c67b438deec7c14cf62ab54223ce19d5981f53477a15359347d7b59018419d0", - "url": "https://maven.google.com/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03.aar" + "sha256": "46a912a1e175f27a97521af3f50e5af87c22c49275dd2c57c043740012806325", + "url": "https://maven.google.com/androidx/test/monitor/1.4.0/monitor-1.4.0.aar" }, { - "coord": "androidx.test:monitor:aar:sources:1.3.0-rc03", + "coord": "androidx.test:monitor:aar:sources:1.4.0", "dependencies": [], "directDependencies": [], "exclusions": [ "*:*" ], - "file": "v1/https/maven.google.com/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03-sources.jar", + "file": "v1/https/maven.google.com/androidx/test/monitor/1.4.0/monitor-1.4.0-sources.jar", "mirror_urls": [ - "https://maven.google.com/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03-sources.jar", - "https://repo1.maven.org/maven2/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03-sources.jar", - "https://maven.fabric.io/public/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03-sources.jar", - "https://maven.google.com/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03-sources.jar", - "https://repo1.maven.org/maven2/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03-sources.jar" + "https://maven.google.com/androidx/test/monitor/1.4.0/monitor-1.4.0-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/monitor/1.4.0/monitor-1.4.0-sources.jar", + "https://maven.fabric.io/public/androidx/test/monitor/1.4.0/monitor-1.4.0-sources.jar", + "https://maven.google.com/androidx/test/monitor/1.4.0/monitor-1.4.0-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/monitor/1.4.0/monitor-1.4.0-sources.jar" ], - "sha256": "08da381299ef3ecc345bd2ce7db2006fe21e054e928026a38104e9eeb9121761", - "url": "https://maven.google.com/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03-sources.jar" + "sha256": "a03ea6019c1ee7cc285afdbee98137ec463b891e6fc9176c121c5a70ec727f48", + "url": "https://maven.google.com/androidx/test/monitor/1.4.0/monitor-1.4.0-sources.jar" }, { "coord": "androidx.test:rules:1.1.0", "dependencies": [ - "androidx.test:runner:1.2.0" + "androidx.test:runner:1.4.0" ], "directDependencies": [ - "androidx.test:runner:1.2.0" + "androidx.test:runner:1.4.0" ], "file": "v1/https/maven.google.com/androidx/test/rules/1.1.0/rules-1.1.0.aar", "mirror_urls": [ @@ -3443,10 +3506,10 @@ { "coord": "androidx.test:rules:jar:sources:1.1.0", "dependencies": [ - "androidx.test:runner:jar:sources:1.2.0" + "androidx.test:runner:jar:sources:1.4.0" ], "directDependencies": [ - "androidx.test:runner:jar:sources:1.2.0" + "androidx.test:runner:jar:sources:1.4.0" ], "file": "v1/https/maven.google.com/androidx/test/rules/1.1.0/rules-1.1.0-sources.jar", "mirror_urls": [ @@ -3460,56 +3523,58 @@ "url": "https://maven.google.com/androidx/test/rules/1.1.0/rules-1.1.0-sources.jar" }, { - "coord": "androidx.test:runner:1.2.0", + "coord": "androidx.test:runner:1.4.0", "dependencies": [ "androidx.annotation:annotation:1.1.0", - "androidx.test:monitor:1.3.0-rc03", + "androidx.test:monitor:1.4.0", + "com.google.code.findbugs:jsr305:3.0.2", + "androidx.test.services:storage:1.4.0", "junit:junit:4.12", - "org.hamcrest:hamcrest-core:1.3", - "net.sf.kxml:kxml2:2.3.0" + "org.hamcrest:hamcrest-core:1.3" ], "directDependencies": [ "androidx.annotation:annotation:1.1.0", - "androidx.test:monitor:1.3.0-rc03", - "junit:junit:4.12", - "net.sf.kxml:kxml2:2.3.0" + "androidx.test:monitor:1.4.0", + "androidx.test.services:storage:1.4.0", + "junit:junit:4.12" ], - "file": "v1/https/maven.google.com/androidx/test/runner/1.2.0/runner-1.2.0.aar", + "file": "v1/https/maven.google.com/androidx/test/runner/1.4.0/runner-1.4.0.aar", "mirror_urls": [ - "https://maven.google.com/androidx/test/runner/1.2.0/runner-1.2.0.aar", - "https://repo1.maven.org/maven2/androidx/test/runner/1.2.0/runner-1.2.0.aar", - "https://maven.fabric.io/public/androidx/test/runner/1.2.0/runner-1.2.0.aar", - "https://maven.google.com/androidx/test/runner/1.2.0/runner-1.2.0.aar", - "https://repo1.maven.org/maven2/androidx/test/runner/1.2.0/runner-1.2.0.aar" + "https://maven.google.com/androidx/test/runner/1.4.0/runner-1.4.0.aar", + "https://repo1.maven.org/maven2/androidx/test/runner/1.4.0/runner-1.4.0.aar", + "https://maven.fabric.io/public/androidx/test/runner/1.4.0/runner-1.4.0.aar", + "https://maven.google.com/androidx/test/runner/1.4.0/runner-1.4.0.aar", + "https://repo1.maven.org/maven2/androidx/test/runner/1.4.0/runner-1.4.0.aar" ], - "sha256": "5387e011167a3c8da08d99b5d59248c0e2da839317b48ebf202e31dc1f791ec1", - "url": "https://maven.google.com/androidx/test/runner/1.2.0/runner-1.2.0.aar" + "sha256": "e3f3d8b8d5d4a3edcacbdaa4a31bda2b0e41d3e704b02b3750466a06367ec5a0", + "url": "https://maven.google.com/androidx/test/runner/1.4.0/runner-1.4.0.aar" }, { - "coord": "androidx.test:runner:jar:sources:1.2.0", + "coord": "androidx.test:runner:jar:sources:1.4.0", "dependencies": [ - "androidx.test:monitor:jar:sources:1.3.0-rc03", + "com.google.code.findbugs:jsr305:jar:sources:3.0.2", + "androidx.test:monitor:jar:sources:1.4.0", "org.hamcrest:hamcrest-core:jar:sources:1.3", + "androidx.test.services:storage:jar:sources:1.4.0", "androidx.annotation:annotation:jar:sources:1.1.0", - "net.sf.kxml:kxml2:jar:sources:2.3.0", "junit:junit:jar:sources:4.12" ], "directDependencies": [ "androidx.annotation:annotation:jar:sources:1.1.0", - "androidx.test:monitor:jar:sources:1.3.0-rc03", - "junit:junit:jar:sources:4.12", - "net.sf.kxml:kxml2:jar:sources:2.3.0" + "androidx.test:monitor:jar:sources:1.4.0", + "androidx.test.services:storage:jar:sources:1.4.0", + "junit:junit:jar:sources:4.12" ], - "file": "v1/https/maven.google.com/androidx/test/runner/1.2.0/runner-1.2.0-sources.jar", + "file": "v1/https/maven.google.com/androidx/test/runner/1.4.0/runner-1.4.0-sources.jar", "mirror_urls": [ - "https://maven.google.com/androidx/test/runner/1.2.0/runner-1.2.0-sources.jar", - "https://repo1.maven.org/maven2/androidx/test/runner/1.2.0/runner-1.2.0-sources.jar", - "https://maven.fabric.io/public/androidx/test/runner/1.2.0/runner-1.2.0-sources.jar", - "https://maven.google.com/androidx/test/runner/1.2.0/runner-1.2.0-sources.jar", - "https://repo1.maven.org/maven2/androidx/test/runner/1.2.0/runner-1.2.0-sources.jar" + "https://maven.google.com/androidx/test/runner/1.4.0/runner-1.4.0-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/runner/1.4.0/runner-1.4.0-sources.jar", + "https://maven.fabric.io/public/androidx/test/runner/1.4.0/runner-1.4.0-sources.jar", + "https://maven.google.com/androidx/test/runner/1.4.0/runner-1.4.0-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/runner/1.4.0/runner-1.4.0-sources.jar" ], - "sha256": "ec71974ddd8245a85ca856577c70972fd4c484f715df0a26271f0c28f8a58739", - "url": "https://maven.google.com/androidx/test/runner/1.2.0/runner-1.2.0-sources.jar" + "sha256": "f70a31dc1fc33d68700b61bdc44687b333ba4e44956e3df4a1fadbc46872cb61", + "url": "https://maven.google.com/androidx/test/runner/1.4.0/runner-1.4.0-sources.jar" }, { "coord": "androidx.transition:transition:aar:1.2.0", @@ -7305,36 +7370,6 @@ "sha256": "e78a7277cb9ce4980fba22d809352821848581df0a6b545fa22aa7400a05db43", "url": "https://repo1.maven.org/maven2/net/ltgt/gradle/incap/incap/0.3/incap-0.3-sources.jar" }, - { - "coord": "net.sf.kxml:kxml2:2.3.0", - "dependencies": [], - "directDependencies": [], - "file": "v1/https/repo1.maven.org/maven2/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0.jar", - "mirror_urls": [ - "https://maven.google.com/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0.jar", - "https://repo1.maven.org/maven2/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0.jar", - "https://maven.fabric.io/public/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0.jar", - "https://maven.google.com/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0.jar", - "https://repo1.maven.org/maven2/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0.jar" - ], - "sha256": "f264dd9f79a1fde10ce5ecc53221eff24be4c9331c830b7d52f2f08a7b633de2", - "url": "https://repo1.maven.org/maven2/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0.jar" - }, - { - "coord": "net.sf.kxml:kxml2:jar:sources:2.3.0", - "dependencies": [], - "directDependencies": [], - "file": "v1/https/repo1.maven.org/maven2/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0-sources.jar", - "mirror_urls": [ - "https://maven.google.com/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0-sources.jar", - "https://repo1.maven.org/maven2/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0-sources.jar", - "https://maven.fabric.io/public/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0-sources.jar", - "https://maven.google.com/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0-sources.jar", - "https://repo1.maven.org/maven2/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0-sources.jar" - ], - "sha256": "85495366666158b58961e8911ced0f6f3bc92f1ebee865518b493fdb90760250", - "url": "https://repo1.maven.org/maven2/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0-sources.jar" - }, { "coord": "nl.dionsegijn:konfetti:1.2.5", "dependencies": [ @@ -8770,12 +8805,12 @@ "org.robolectric:resources:4.4", "androidx.annotation:annotation:1.1.0", "org.ow2.asm:asm:7.2", - "androidx.test:monitor:1.3.0-rc03", + "androidx.test:monitor:1.4.0", "org.robolectric:shadows-framework:4.4", "org.robolectric:sandbox:4.4", + "androidx.test:monitor:aar:1.4.0", "org.robolectric:pluginapi:4.4", "org.ow2.asm:asm-commons:7.2", - "androidx.test:monitor:aar:1.3.0-rc03", "org.ow2.asm:asm-analysis:7.2", "org.robolectric:plugins-maven-dependency-resolver:4.4", "org.bouncycastle:bcprov-jdk15on:1.65", @@ -8793,7 +8828,7 @@ "directDependencies": [ "org.robolectric:utils:4.4", "org.robolectric:resources:4.4", - "androidx.test:monitor:1.3.0-rc03", + "androidx.test:monitor:1.4.0", "org.robolectric:shadows-framework:4.4", "org.robolectric:sandbox:4.4", "org.robolectric:pluginapi:4.4", @@ -8821,11 +8856,11 @@ "dependencies": [ "org.ow2.asm:asm-commons:jar:sources:7.2", "org.robolectric:annotations:jar:sources:4.4", - "androidx.test:monitor:aar:sources:1.3.0-rc03", "org.ow2.asm:asm-analysis:jar:sources:7.2", + "androidx.test:monitor:jar:sources:1.4.0", "org.robolectric:junit:jar:sources:4.4", - "androidx.test:monitor:jar:sources:1.3.0-rc03", "org.ow2.asm:asm:jar:sources:7.2", + "androidx.test:monitor:aar:sources:1.4.0", "javax.inject:javax.inject:jar:sources:1", "com.almworks.sqlite4java:sqlite4java:jar:sources:0.282", "com.google.auto.value:auto-value-annotations:jar:sources:1.6.5", @@ -8847,8 +8882,8 @@ ], "directDependencies": [ "org.robolectric:annotations:jar:sources:4.4", + "androidx.test:monitor:jar:sources:1.4.0", "org.robolectric:junit:jar:sources:4.4", - "androidx.test:monitor:jar:sources:1.3.0-rc03", "javax.inject:javax.inject:jar:sources:1", "org.robolectric:utils:jar:sources:4.4", "org.robolectric:pluginapi:jar:sources:4.4", @@ -8996,9 +9031,9 @@ "org.robolectric:resources:4.4", "androidx.annotation:annotation:1.1.0", "org.ow2.asm:asm:7.2", + "androidx.test:monitor:aar:1.4.0", "org.robolectric:pluginapi:4.4", "org.ow2.asm:asm-commons:7.2", - "androidx.test:monitor:aar:1.3.0-rc03", "org.ow2.asm:asm-analysis:7.2", "org.ow2.asm:asm-util:7.2", "com.almworks.sqlite4java:sqlite4java:0.282", @@ -9015,8 +9050,8 @@ "com.google.auto.value:auto-value-annotations:1.6.5", "org.robolectric:resources:4.4", "androidx.annotation:annotation:1.1.0", + "androidx.test:monitor:aar:1.4.0", "org.robolectric:pluginapi:4.4", - "androidx.test:monitor:aar:1.3.0-rc03", "com.almworks.sqlite4java:sqlite4java:0.282", "org.robolectric:utils-reflector:4.4", "org.robolectric:shadowapi:4.4", @@ -9039,9 +9074,9 @@ "dependencies": [ "org.ow2.asm:asm-commons:jar:sources:7.2", "org.robolectric:annotations:jar:sources:4.4", - "androidx.test:monitor:aar:sources:1.3.0-rc03", "org.ow2.asm:asm-analysis:jar:sources:7.2", "org.ow2.asm:asm:jar:sources:7.2", + "androidx.test:monitor:aar:sources:1.4.0", "javax.inject:javax.inject:jar:sources:1", "com.almworks.sqlite4java:sqlite4java:jar:sources:0.282", "com.google.auto.value:auto-value-annotations:jar:sources:1.6.5", @@ -9059,7 +9094,7 @@ ], "directDependencies": [ "org.robolectric:annotations:jar:sources:4.4", - "androidx.test:monitor:aar:sources:1.3.0-rc03", + "androidx.test:monitor:aar:sources:1.4.0", "com.almworks.sqlite4java:sqlite4java:jar:sources:0.282", "com.google.auto.value:auto-value-annotations:jar:sources:1.6.5", "org.robolectric:utils:jar:sources:4.4", From 72620a21a67fb3612ceb9f24779fb665c4fb69aa Mon Sep 17 00:00:00 2001 From: farees Date: Tue, 20 Jul 2021 22:54:47 +0530 Subject: [PATCH 06/63] Nit fixes --- .bazelrc | 23 ------------------- BUILD.bazel | 3 +-- WORKSPACE | 14 ----------- instrumentation/BUILD.bazel | 8 +++---- .../oppia/android/instrumentation/BUILD.bazel | 8 +++---- scripts/buildifier_lint_check.sh | 2 +- 6 files changed, 9 insertions(+), 49 deletions(-) diff --git a/.bazelrc b/.bazelrc index 0f0f609a735..71793d2ba7c 100644 --- a/.bazelrc +++ b/.bazelrc @@ -7,26 +7,3 @@ build --android_databinding_use_v3_4_args \ # Show all test output by default (for better debugging). test --test_output=all - -# Headless instrumentation tests -test:headless --test_arg=--enable_display=false - -# Graphical instrumentation tests. Ensure that $DISPLAY is set. -test:gui --test_env=DISPLAY -test:gui --test_arg=--enable_display=true - -# Testing with a local emulator or device. Ensure that `adb devices` lists the device. -# Run tests serially. -test:local_device --test_strategy=exclusive -# Use the local device broker type, as opposed to WRAPPED_EMULATOR. -test:local_device --test_arg=--device_broker_type=LOCAL_ADB_SERVER -# Uncomment and set $device_id if there is more than one connected device. -# test:local_device --test_arg=--device_serial_number=$device_id - -# test --flaky_test_attempts=3 - -# The unified launcher runs in Python 2 host configuration -# https://github.com/bazelbuild/bazel/issues/7899 -build --host_force_python=PY2 - - diff --git a/BUILD.bazel b/BUILD.bazel index 1b5f86014be..4273bf0c0b0 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -51,7 +51,6 @@ android_binary( custom_package = "org.oppia.android", enable_data_binding = True, manifest = "//app:src/main/AndroidManifest.xml", - visibility = ["//visibility:public"], manifest_values = { "applicationId": "org.oppia.android", "minSdkVersion": "19", @@ -60,8 +59,8 @@ android_binary( "versionName": "0.1-alpha", }, multidex = "native", # TODO(#1875): Re-enable legacy for optimized release builds. + visibility = ["//visibility:public"], deps = [ "//app", ], ) - diff --git a/WORKSPACE b/WORKSPACE index d0c9cbff421..ffe08b6e446 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -141,20 +141,6 @@ http_archive( load("@rules_jvm_external//:defs.bzl", "maven_install") -ATS_TAG = "1edfdab3134a7f01b37afabd3eebfd2c5bb05151" -ATS_SHA256 = "dcd1ff76aef1a26329d77863972780c8fe1fc8ff625747342239f0489c2837ec" - -http_archive( - name = "android_test_support", - sha256 = ATS_SHA256, - strip_prefix = "android-test-%s" % ATS_TAG, - urls = ["https://github.com/android/android-test/archive/%s.tar.gz" % ATS_TAG], -) - -load("@android_test_support//:repo.bzl", "android_test_repositories") - -android_test_repositories() - # Note to developers: new dependencies should be added to //third_party:versions.bzl, not here. maven_install( artifacts = DAGGER_ARTIFACTS + get_maven_dependencies(), diff --git a/instrumentation/BUILD.bazel b/instrumentation/BUILD.bazel index 6c8b7434afd..ff27f475425 100644 --- a/instrumentation/BUILD.bazel +++ b/instrumentation/BUILD.bazel @@ -4,16 +4,14 @@ Note that: - All the android_binaries are named similar to the respective class name of the test suite. """ -load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_android_library") - android_binary( name = "BaseTest", testonly = True, custom_package = "org.oppia.android", - visibility = ["//visibility:public"], instruments = "//:oppia", - manifest="AndroidManifest.xml", + manifest = "AndroidManifest.xml", + visibility = ["//visibility:public"], deps = [ - "//instrumentation/src/javatest/org/oppia/android/instrumentation:base_test_lib" + "//instrumentation/src/javatest/org/oppia/android/instrumentation:base_test_lib", ], ) diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/BUILD.bazel b/instrumentation/src/javatest/org/oppia/android/instrumentation/BUILD.bazel index 2bfdebaa700..ffd74dd44ae 100644 --- a/instrumentation/src/javatest/org/oppia/android/instrumentation/BUILD.bazel +++ b/instrumentation/src/javatest/org/oppia/android/instrumentation/BUILD.bazel @@ -10,20 +10,20 @@ load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_android_library") # Common deps for each test suite. android_library( - name="instrumentation_deps", + name = "instrumentation_deps", testonly = True, visibility = ["//visibility:public"], exports = [ - "//third_party:androidx_test_runner", "//third_party:androidx_test_ext_junit", + "//third_party:androidx_test_runner", + "//third_party:androidx_test_uiautomator_uiautomator", "//third_party:com_google_truth_truth", "//third_party:junit_junit", - "//third_party:androidx_test_uiautomator_uiautomator", ], ) kt_android_library( - name="base_test_lib", + name = "base_test_lib", testonly = True, srcs = [ "BaseTest.kt", diff --git a/scripts/buildifier_lint_check.sh b/scripts/buildifier_lint_check.sh index 47d0d91a248..52e0857468e 100644 --- a/scripts/buildifier_lint_check.sh +++ b/scripts/buildifier_lint_check.sh @@ -14,7 +14,7 @@ else buildifier_file_path="$github_actions_path/oppia-android-tools/buildifier" fi -$buildifier_file_path --lint=warn --mode=check --warnings=-native-android,+out-of-order-load,+unsorted-dict-items -r app data domain model testing utility third_party tools scripts BUILD.bazel WORKSPACE oppia_android_test.bzl +$buildifier_file_path --lint=warn --mode=check --warnings=-native-android,+out-of-order-load,+unsorted-dict-items -r app data domain instrumentation model testing utility third_party tools scripts BUILD.bazel WORKSPACE oppia_android_test.bzl status=$? From 8a641d735c9187b6ff466172c777d40e6a5775d7 Mon Sep 17 00:00:00 2001 From: farees Date: Fri, 23 Jul 2021 01:30:15 +0530 Subject: [PATCH 07/63] Requested changes --- BUILD.bazel | 23 +++++++- instrumentation/BUILD.bazel | 9 ++- instrumentation/{ => src}/AndroidManifest.xml | 0 .../oppia/android/instrumentation/BUILD.bazel | 7 +-- .../{BaseTest.kt => ExplorationPlayerTest.kt} | 56 ++++++++++++++----- third_party/versions.bzl | 6 +- 6 files changed, 75 insertions(+), 26 deletions(-) rename instrumentation/{ => src}/AndroidManifest.xml (100%) rename instrumentation/src/javatest/org/oppia/android/instrumentation/{BaseTest.kt => ExplorationPlayerTest.kt} (53%) diff --git a/BUILD.bazel b/BUILD.bazel index 4273bf0c0b0..7e0dee2a39e 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -30,6 +30,7 @@ package_group( "//app/...", "//data/...", "//domain/...", + "//instrumentation/...", "//testing/...", "//utility/...", ], @@ -59,7 +60,27 @@ android_binary( "versionName": "0.1-alpha", }, multidex = "native", # TODO(#1875): Re-enable legacy for optimized release builds. - visibility = ["//visibility:public"], + deps = [ + "//app", + ], +) + +# Used for end to end tests +android_binary( + name = "oppia_test", + testonly = True, + custom_package = "org.oppia.android", + enable_data_binding = True, + manifest = "//app:src/main/AndroidManifest.xml", + manifest_values = { + "applicationId": "org.oppia.android", + "minSdkVersion": "19", + "targetSdkVersion": "29", + "versionCode": "0", + "versionName": "0.1-alpha", + }, + multidex = "native", + visibility = ["//:oppia_testing_visibility"], deps = [ "//app", ], diff --git a/instrumentation/BUILD.bazel b/instrumentation/BUILD.bazel index ff27f475425..4f90136f1ec 100644 --- a/instrumentation/BUILD.bazel +++ b/instrumentation/BUILD.bazel @@ -5,13 +5,12 @@ Note that: """ android_binary( - name = "BaseTest", + name = "ExplorationPlayerTest", testonly = True, custom_package = "org.oppia.android", - instruments = "//:oppia", - manifest = "AndroidManifest.xml", - visibility = ["//visibility:public"], + instruments = "//:oppia_test", + manifest = "src/AndroidManifest.xml", deps = [ - "//instrumentation/src/javatest/org/oppia/android/instrumentation:base_test_lib", + "//instrumentation/src/javatest/org/oppia/android/instrumentation:exploration_player_test_lib", ], ) diff --git a/instrumentation/AndroidManifest.xml b/instrumentation/src/AndroidManifest.xml similarity index 100% rename from instrumentation/AndroidManifest.xml rename to instrumentation/src/AndroidManifest.xml diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/BUILD.bazel b/instrumentation/src/javatest/org/oppia/android/instrumentation/BUILD.bazel index ffd74dd44ae..1a7d55a539b 100644 --- a/instrumentation/src/javatest/org/oppia/android/instrumentation/BUILD.bazel +++ b/instrumentation/src/javatest/org/oppia/android/instrumentation/BUILD.bazel @@ -12,7 +12,6 @@ load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_android_library") android_library( name = "instrumentation_deps", testonly = True, - visibility = ["//visibility:public"], exports = [ "//third_party:androidx_test_ext_junit", "//third_party:androidx_test_runner", @@ -23,12 +22,12 @@ android_library( ) kt_android_library( - name = "base_test_lib", + name = "exploration_player_test_lib", testonly = True, srcs = [ - "BaseTest.kt", + "ExplorationPlayerTest.kt", ], - visibility = ["//visibility:public"], + visibility = ["//:oppia_testing_visibility"], deps = [ ":instrumentation_deps", ], diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/BaseTest.kt b/instrumentation/src/javatest/org/oppia/android/instrumentation/ExplorationPlayerTest.kt similarity index 53% rename from instrumentation/src/javatest/org/oppia/android/instrumentation/BaseTest.kt rename to instrumentation/src/javatest/org/oppia/android/instrumentation/ExplorationPlayerTest.kt index 816d3067e79..e3a4519fec1 100644 --- a/instrumentation/src/javatest/org/oppia/android/instrumentation/BaseTest.kt +++ b/instrumentation/src/javatest/org/oppia/android/instrumentation/ExplorationPlayerTest.kt @@ -6,16 +6,20 @@ import android.content.pm.PackageManager import androidx.test.core.app.ApplicationProvider import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.By +import androidx.test.uiautomator.UiCollection import androidx.test.uiautomator.UiDevice +import androidx.test.uiautomator.UiScrollable +import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.Until import org.junit.Assert.assertNotNull import org.junit.Before import org.junit.Test -/** Tests to load Oppia using UI Automator. */ -class BaseTest { +/** Tests for Explorations. */ +class ExxplorationPlayerTest { private val OPPIA_PACKAGE = "org.oppia.android" - private val LAUNCH_TIMEOUT = 5000 + private val LAUNCH_TIMEOUT = 30000L + private val TRANSITION_TIMEOUT = 5000L private lateinit var device: UiDevice @Before @@ -29,7 +33,7 @@ class BaseTest { // Wait for launcher val launcherPackage = getLauncherPackageName() assertNotNull(launcherPackage) - device.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)), LAUNCH_TIMEOUT.toLong()) + device.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)), LAUNCH_TIMEOUT) // Launch the blueprint app val context = ApplicationProvider.getApplicationContext() @@ -39,25 +43,51 @@ class BaseTest { context.startActivity(intent) // Wait for the app to appear - device.wait(Until.hasObject(By.pkg(OPPIA_PACKAGE).depth(0)), LAUNCH_TIMEOUT.toLong()) + device.wait(Until.hasObject(By.pkg(OPPIA_PACKAGE).depth(0)), LAUNCH_TIMEOUT) } @Test - fun baseTest_uiDevice_isNotNull() { - assertNotNull(device) + fun testExploration_prototypeExploration_toolbarTitle_isDisplayedSuccessfully() { + NavigateToPrototypeExploration() + device.wait( + Until.hasObject( + By.res("$OPPIA_PACKAGE:id/exploration_toolbar_title") + ), + TRANSITION_TIMEOUT + ) + assertNotNull(device.findObject(By.res("$OPPIA_PACKAGE:id/exploration_toolbar_title"))) } - @Test - fun baseTest_openProfileDashboard_titleExists() { + /** Navigates and opens the Prototype Exploration using the admin profile. */ + fun NavigateToPrototypeExploration() { val skip_button = device.findObject(By.res("$OPPIA_PACKAGE:id/skip_text_view")) skip_button?.let { it.click() - device.wait(Until.hasObject(By.res("$OPPIA_PACKAGE:id/get_started_button")), 1000L) - device.findObject(By.res("org.oppia.android:id/get_started_button")) + device.wait( + Until.hasObject(By.res("$OPPIA_PACKAGE:id/get_started_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/get_started_button")) .click() } - device.wait(Until.hasObject(By.res("$OPPIA_PACKAGE:id/profile_select_text")), 1000L) - assertNotNull(device.findObject(By.res("$OPPIA_PACKAGE:id/profile_select_text"))) + device.wait( + Until.hasObject(By.res("$OPPIA_PACKAGE:id/profile_select_text")), + TRANSITION_TIMEOUT + ) + val profiles = UiCollection(UiSelector().className("androidx.recyclerview.widget.RecyclerView")) + profiles.getChildByText(UiSelector().className("android.widget.LinearLayout"), "Admin").click() + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView("First Test Topic") + val firstTestTopicText = device.findObject(UiSelector().text("First Test Topic")) + firstTestTopicText.click() + device.findObject(UiSelector().text("First Test Topic")) + .click() + device.findObject(UiSelector().text("LESSONS")) + .click() + device.findObject(UiSelector().text("First Story")) + .click() + device.findObject(UiSelector().text("Chapter 1: Prototype Exploration")).click() } /** diff --git a/third_party/versions.bzl b/third_party/versions.bzl index 3835a92f08a..709b4c92dd6 100644 --- a/third_party/versions.bzl +++ b/third_party/versions.bzl @@ -81,9 +81,9 @@ MAVEN_TEST_DEPENDENCY_VERSIONS = { "androidx.test.espresso:espresso-contrib": "3.1.0", "androidx.test.espresso:espresso-core": "3.2.0", "androidx.test.espresso:espresso-intents": "3.1.0", - "androidx.test.ext:junit": "1.1.3", - "androidx.test:core": "1.4.0", - "androidx.test:runner": "1.4.0", + "androidx.test.ext:junit": "1.1.1", + "androidx.test:core": "1.0.0", + "androidx.test:runner": "1.2.0", "androidx.work:work-testing": "2.4.0", "com.github.bumptech.glide:mocks": "4.11.0", "com.google.protobuf:protobuf-java": "3.17.3", From c58b6f6849563229604e9b29c8e5ae4920de2ffc Mon Sep 17 00:00:00 2001 From: farees Date: Fri, 23 Jul 2021 01:32:04 +0530 Subject: [PATCH 08/63] fix class name --- .../org/oppia/android/instrumentation/ExplorationPlayerTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/ExplorationPlayerTest.kt b/instrumentation/src/javatest/org/oppia/android/instrumentation/ExplorationPlayerTest.kt index e3a4519fec1..12a320ee96c 100644 --- a/instrumentation/src/javatest/org/oppia/android/instrumentation/ExplorationPlayerTest.kt +++ b/instrumentation/src/javatest/org/oppia/android/instrumentation/ExplorationPlayerTest.kt @@ -16,7 +16,7 @@ import org.junit.Before import org.junit.Test /** Tests for Explorations. */ -class ExxplorationPlayerTest { +class ExplorationPlayerTest { private val OPPIA_PACKAGE = "org.oppia.android" private val LAUNCH_TIMEOUT = 30000L private val TRANSITION_TIMEOUT = 5000L From 09c419e1950c841d0e6d6cba960757f2dedf5d22 Mon Sep 17 00:00:00 2001 From: farees Date: Fri, 23 Jul 2021 04:25:42 +0530 Subject: [PATCH 09/63] update dependencies --- third_party/maven_install.json | 321 ++++++++++++++++----------------- 1 file changed, 158 insertions(+), 163 deletions(-) diff --git a/third_party/maven_install.json b/third_party/maven_install.json index b2c163f2d75..c39f4df7d3c 100644 --- a/third_party/maven_install.json +++ b/third_party/maven_install.json @@ -1,12 +1,13 @@ { "dependency_tree": { "__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL", - "__INPUT_ARTIFACTS_HASH": -1776077967, - "__RESOLVED_ARTIFACTS_HASH": -1881168025, + "__INPUT_ARTIFACTS_HASH": 1530415593, + "__RESOLVED_ARTIFACTS_HASH": 1501416789, "conflict_resolution": { "androidx.appcompat:appcompat:1.0.2": "androidx.appcompat:appcompat:1.2.0", "androidx.core:core:1.0.1": "androidx.core:core:1.3.0", "androidx.recyclerview:recyclerview:1.0.0": "androidx.recyclerview:recyclerview:1.1.0", + "androidx.test:core:1.0.0": "androidx.test:core:1.2.0", "org.jetbrains.kotlin:kotlin-reflect:1.3.41": "org.jetbrains.kotlin:kotlin-reflect:1.4.10", "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.72": "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.10", "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.2": "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.4", @@ -3140,20 +3141,24 @@ { "coord": "androidx.test.espresso:espresso-core:3.2.0", "dependencies": [ + "androidx.annotation:annotation:1.1.0", "com.google.code.findbugs:jsr305:3.0.2", + "androidx.test:monitor:1.3.0-rc03", "org.hamcrest:hamcrest-library:1.3", + "androidx.test:runner:1.2.0", "org.hamcrest:hamcrest-integration:1.3", + "junit:junit:4.12", "org.hamcrest:hamcrest-core:1.3", - "androidx.test:runner:1.4.0", "androidx.test.espresso:espresso-idling-resource:3.2.0", "com.squareup:javawriter:2.1.1", - "javax.inject:javax.inject:1" + "javax.inject:javax.inject:1", + "net.sf.kxml:kxml2:2.3.0" ], "directDependencies": [ "com.google.code.findbugs:jsr305:3.0.2", "org.hamcrest:hamcrest-library:1.3", + "androidx.test:runner:1.2.0", "org.hamcrest:hamcrest-integration:1.3", - "androidx.test:runner:1.4.0", "androidx.test.espresso:espresso-idling-resource:3.2.0", "com.squareup:javawriter:2.1.1", "javax.inject:javax.inject:1" @@ -3174,12 +3179,16 @@ "dependencies": [ "com.google.code.findbugs:jsr305:jar:sources:3.0.2", "org.hamcrest:hamcrest-integration:jar:sources:1.3", + "androidx.test:monitor:jar:sources:1.3.0-rc03", "com.squareup:javawriter:jar:sources:2.1.1", "javax.inject:javax.inject:jar:sources:1", "org.hamcrest:hamcrest-core:jar:sources:1.3", "androidx.test.espresso:espresso-idling-resource:jar:sources:3.2.0", "org.hamcrest:hamcrest-library:jar:sources:1.3", - "androidx.test:runner:jar:sources:1.4.0" + "androidx.annotation:annotation:jar:sources:1.1.0", + "androidx.test:runner:jar:sources:1.2.0", + "net.sf.kxml:kxml2:jar:sources:2.3.0", + "junit:junit:jar:sources:4.12" ], "directDependencies": [ "com.google.code.findbugs:jsr305:jar:sources:3.0.2", @@ -3188,7 +3197,7 @@ "javax.inject:javax.inject:jar:sources:1", "androidx.test.espresso:espresso-idling-resource:jar:sources:3.2.0", "org.hamcrest:hamcrest-library:jar:sources:1.3", - "androidx.test:runner:jar:sources:1.4.0" + "androidx.test:runner:jar:sources:1.2.0" ], "file": "v1/https/maven.google.com/androidx/test/espresso/espresso-core/3.2.0/espresso-core-3.2.0-sources.jar", "mirror_urls": [ @@ -3236,7 +3245,7 @@ "dependencies": [ "androidx.test:rules:1.1.0", "androidx.test.espresso:espresso-core:3.2.0", - "androidx.test:runner:1.4.0" + "androidx.test:runner:1.2.0" ], "directDependencies": [ "androidx.test:rules:1.1.0", @@ -3256,8 +3265,8 @@ { "coord": "androidx.test.espresso:espresso-intents:jar:sources:3.1.0", "dependencies": [ - "androidx.test:runner:jar:sources:1.4.0", "androidx.test:rules:jar:sources:1.1.0", + "androidx.test:runner:jar:sources:1.2.0", "androidx.test.espresso:espresso-core:jar:sources:3.2.0" ], "directDependencies": [ @@ -3276,37 +3285,37 @@ "url": "https://maven.google.com/androidx/test/espresso/espresso-intents/3.1.0/espresso-intents-3.1.0-sources.jar" }, { - "coord": "androidx.test.ext:junit:1.1.3", + "coord": "androidx.test.ext:junit:1.1.1", "dependencies": [ "androidx.lifecycle:lifecycle-common:2.2.0", "androidx.annotation:annotation:1.1.0", - "androidx.test:monitor:1.4.0", + "androidx.test:monitor:1.3.0-rc03", "junit:junit:4.12", "org.hamcrest:hamcrest-core:1.3", - "androidx.test:core:1.4.0" + "androidx.test:core:1.2.0" ], "directDependencies": [ "androidx.annotation:annotation:1.1.0", - "androidx.test:core:1.4.0", - "androidx.test:monitor:1.4.0", + "androidx.test:core:1.2.0", + "androidx.test:monitor:1.3.0-rc03", "junit:junit:4.12" ], - "file": "v1/https/maven.google.com/androidx/test/ext/junit/1.1.3/junit-1.1.3.aar", + "file": "v1/https/maven.google.com/androidx/test/ext/junit/1.1.1/junit-1.1.1.aar", "mirror_urls": [ - "https://maven.google.com/androidx/test/ext/junit/1.1.3/junit-1.1.3.aar", - "https://repo1.maven.org/maven2/androidx/test/ext/junit/1.1.3/junit-1.1.3.aar", - "https://maven.fabric.io/public/androidx/test/ext/junit/1.1.3/junit-1.1.3.aar", - "https://maven.google.com/androidx/test/ext/junit/1.1.3/junit-1.1.3.aar", - "https://repo1.maven.org/maven2/androidx/test/ext/junit/1.1.3/junit-1.1.3.aar" + "https://maven.google.com/androidx/test/ext/junit/1.1.1/junit-1.1.1.aar", + "https://repo1.maven.org/maven2/androidx/test/ext/junit/1.1.1/junit-1.1.1.aar", + "https://maven.fabric.io/public/androidx/test/ext/junit/1.1.1/junit-1.1.1.aar", + "https://maven.google.com/androidx/test/ext/junit/1.1.1/junit-1.1.1.aar", + "https://repo1.maven.org/maven2/androidx/test/ext/junit/1.1.1/junit-1.1.1.aar" ], - "sha256": "a97209d75a9a85815fa8934f5a4a320de1163ffe94e2f0b328c0c98a59660690", - "url": "https://maven.google.com/androidx/test/ext/junit/1.1.3/junit-1.1.3.aar" + "sha256": "449df418d2916a0f86fe7dafb1edb09480fafb6e995d5c751c7d0d1970d4ae72", + "url": "https://maven.google.com/androidx/test/ext/junit/1.1.1/junit-1.1.1.aar" }, { - "coord": "androidx.test.ext:junit:jar:sources:1.1.3", + "coord": "androidx.test.ext:junit:jar:sources:1.1.1", "dependencies": [ - "androidx.test:monitor:jar:sources:1.4.0", - "androidx.test:core:jar:sources:1.4.0", + "androidx.test:core:jar:sources:1.2.0", + "androidx.test:monitor:jar:sources:1.3.0-rc03", "org.hamcrest:hamcrest-core:jar:sources:1.3", "androidx.annotation:annotation:jar:sources:1.1.0", "androidx.lifecycle:lifecycle-common:jar:sources:2.2.0", @@ -3314,62 +3323,20 @@ ], "directDependencies": [ "androidx.annotation:annotation:jar:sources:1.1.0", - "androidx.test:core:jar:sources:1.4.0", - "androidx.test:monitor:jar:sources:1.4.0", + "androidx.test:core:jar:sources:1.2.0", + "androidx.test:monitor:jar:sources:1.3.0-rc03", "junit:junit:jar:sources:4.12" ], - "file": "v1/https/maven.google.com/androidx/test/ext/junit/1.1.3/junit-1.1.3-sources.jar", - "mirror_urls": [ - "https://maven.google.com/androidx/test/ext/junit/1.1.3/junit-1.1.3-sources.jar", - "https://repo1.maven.org/maven2/androidx/test/ext/junit/1.1.3/junit-1.1.3-sources.jar", - "https://maven.fabric.io/public/androidx/test/ext/junit/1.1.3/junit-1.1.3-sources.jar", - "https://maven.google.com/androidx/test/ext/junit/1.1.3/junit-1.1.3-sources.jar", - "https://repo1.maven.org/maven2/androidx/test/ext/junit/1.1.3/junit-1.1.3-sources.jar" - ], - "sha256": "aefd25841285b641906dca12127cad26866caacd9aeefe8b38103ede35abc828", - "url": "https://maven.google.com/androidx/test/ext/junit/1.1.3/junit-1.1.3-sources.jar" - }, - { - "coord": "androidx.test.services:storage:1.4.0", - "dependencies": [ - "androidx.test:monitor:1.4.0", - "com.google.code.findbugs:jsr305:3.0.2" - ], - "directDependencies": [ - "androidx.test:monitor:1.4.0", - "com.google.code.findbugs:jsr305:3.0.2" - ], - "file": "v1/https/maven.google.com/androidx/test/services/storage/1.4.0/storage-1.4.0.aar", + "file": "v1/https/maven.google.com/androidx/test/ext/junit/1.1.1/junit-1.1.1-sources.jar", "mirror_urls": [ - "https://maven.google.com/androidx/test/services/storage/1.4.0/storage-1.4.0.aar", - "https://repo1.maven.org/maven2/androidx/test/services/storage/1.4.0/storage-1.4.0.aar", - "https://maven.fabric.io/public/androidx/test/services/storage/1.4.0/storage-1.4.0.aar", - "https://maven.google.com/androidx/test/services/storage/1.4.0/storage-1.4.0.aar", - "https://repo1.maven.org/maven2/androidx/test/services/storage/1.4.0/storage-1.4.0.aar" + "https://maven.google.com/androidx/test/ext/junit/1.1.1/junit-1.1.1-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/ext/junit/1.1.1/junit-1.1.1-sources.jar", + "https://maven.fabric.io/public/androidx/test/ext/junit/1.1.1/junit-1.1.1-sources.jar", + "https://maven.google.com/androidx/test/ext/junit/1.1.1/junit-1.1.1-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/ext/junit/1.1.1/junit-1.1.1-sources.jar" ], - "sha256": "35cfbf442abb83e5876cd5deb9de02ae047459f18f831097c5caa76d626bc38a", - "url": "https://maven.google.com/androidx/test/services/storage/1.4.0/storage-1.4.0.aar" - }, - { - "coord": "androidx.test.services:storage:jar:sources:1.4.0", - "dependencies": [ - "com.google.code.findbugs:jsr305:jar:sources:3.0.2", - "androidx.test:monitor:jar:sources:1.4.0" - ], - "directDependencies": [ - "androidx.test:monitor:jar:sources:1.4.0", - "com.google.code.findbugs:jsr305:jar:sources:3.0.2" - ], - "file": "v1/https/maven.google.com/androidx/test/services/storage/1.4.0/storage-1.4.0-sources.jar", - "mirror_urls": [ - "https://maven.google.com/androidx/test/services/storage/1.4.0/storage-1.4.0-sources.jar", - "https://repo1.maven.org/maven2/androidx/test/services/storage/1.4.0/storage-1.4.0-sources.jar", - "https://maven.fabric.io/public/androidx/test/services/storage/1.4.0/storage-1.4.0-sources.jar", - "https://maven.google.com/androidx/test/services/storage/1.4.0/storage-1.4.0-sources.jar", - "https://repo1.maven.org/maven2/androidx/test/services/storage/1.4.0/storage-1.4.0-sources.jar" - ], - "sha256": "f80c24f6564166dafd70ac169e8881eea4f9de6e71e714408bf34c214ecb8673", - "url": "https://maven.google.com/androidx/test/services/storage/1.4.0/storage-1.4.0-sources.jar" + "sha256": "e8abb0752a123d337be4cced50298067a8340135e64f0a24ff52345ed20cd292", + "url": "https://maven.google.com/androidx/test/ext/junit/1.1.1/junit-1.1.1-sources.jar" }, { "coord": "androidx.test.uiautomator:uiautomator:2.2.0", @@ -3402,95 +3369,95 @@ "url": "https://maven.google.com/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0-sources.jar" }, { - "coord": "androidx.test:core:1.4.0", + "coord": "androidx.test:core:1.2.0", "dependencies": [ "androidx.annotation:annotation:1.1.0", - "androidx.test:monitor:1.4.0", - "androidx.lifecycle:lifecycle-common:2.2.0" + "androidx.lifecycle:lifecycle-common:2.2.0", + "androidx.test:monitor:1.3.0-rc03" ], "directDependencies": [ "androidx.annotation:annotation:1.1.0", "androidx.lifecycle:lifecycle-common:2.2.0", - "androidx.test:monitor:1.4.0" + "androidx.test:monitor:1.3.0-rc03" ], - "file": "v1/https/maven.google.com/androidx/test/core/1.4.0/core-1.4.0.aar", + "file": "v1/https/maven.google.com/androidx/test/core/1.2.0/core-1.2.0.aar", "mirror_urls": [ - "https://maven.google.com/androidx/test/core/1.4.0/core-1.4.0.aar", - "https://repo1.maven.org/maven2/androidx/test/core/1.4.0/core-1.4.0.aar", - "https://maven.fabric.io/public/androidx/test/core/1.4.0/core-1.4.0.aar", - "https://maven.google.com/androidx/test/core/1.4.0/core-1.4.0.aar", - "https://repo1.maven.org/maven2/androidx/test/core/1.4.0/core-1.4.0.aar" + "https://maven.google.com/androidx/test/core/1.2.0/core-1.2.0.aar", + "https://repo1.maven.org/maven2/androidx/test/core/1.2.0/core-1.2.0.aar", + "https://maven.fabric.io/public/androidx/test/core/1.2.0/core-1.2.0.aar", + "https://maven.google.com/androidx/test/core/1.2.0/core-1.2.0.aar", + "https://repo1.maven.org/maven2/androidx/test/core/1.2.0/core-1.2.0.aar" ], - "sha256": "671284e62e393f16ceae1a99a3a9a07bf1aacda29f8fe7b6b884355ef34c09cf", - "url": "https://maven.google.com/androidx/test/core/1.4.0/core-1.4.0.aar" + "sha256": "c88b739b1c499afb792374be19b9cf829e89567f26441a74f664c0cf8de158a4", + "url": "https://maven.google.com/androidx/test/core/1.2.0/core-1.2.0.aar" }, { - "coord": "androidx.test:core:jar:sources:1.4.0", + "coord": "androidx.test:core:jar:sources:1.2.0", "dependencies": [ - "androidx.test:monitor:jar:sources:1.4.0", + "androidx.test:monitor:jar:sources:1.3.0-rc03", "androidx.lifecycle:lifecycle-common:jar:sources:2.2.0", "androidx.annotation:annotation:jar:sources:1.1.0" ], "directDependencies": [ "androidx.annotation:annotation:jar:sources:1.1.0", "androidx.lifecycle:lifecycle-common:jar:sources:2.2.0", - "androidx.test:monitor:jar:sources:1.4.0" + "androidx.test:monitor:jar:sources:1.3.0-rc03" ], - "file": "v1/https/maven.google.com/androidx/test/core/1.4.0/core-1.4.0-sources.jar", + "file": "v1/https/maven.google.com/androidx/test/core/1.2.0/core-1.2.0-sources.jar", "mirror_urls": [ - "https://maven.google.com/androidx/test/core/1.4.0/core-1.4.0-sources.jar", - "https://repo1.maven.org/maven2/androidx/test/core/1.4.0/core-1.4.0-sources.jar", - "https://maven.fabric.io/public/androidx/test/core/1.4.0/core-1.4.0-sources.jar", - "https://maven.google.com/androidx/test/core/1.4.0/core-1.4.0-sources.jar", - "https://repo1.maven.org/maven2/androidx/test/core/1.4.0/core-1.4.0-sources.jar" + "https://maven.google.com/androidx/test/core/1.2.0/core-1.2.0-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/core/1.2.0/core-1.2.0-sources.jar", + "https://maven.fabric.io/public/androidx/test/core/1.2.0/core-1.2.0-sources.jar", + "https://maven.google.com/androidx/test/core/1.2.0/core-1.2.0-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/core/1.2.0/core-1.2.0-sources.jar" ], - "sha256": "b3125d546acfea278b82250344c83826e872e3f461109daf0948806382603b30", - "url": "https://maven.google.com/androidx/test/core/1.4.0/core-1.4.0-sources.jar" + "sha256": "19d087a01ae8741a62b661c07929897eb475af64198a9bd7e89d97e7ee88a89a", + "url": "https://maven.google.com/androidx/test/core/1.2.0/core-1.2.0-sources.jar" }, { - "coord": "androidx.test:monitor:1.4.0", + "coord": "androidx.test:monitor:1.3.0-rc03", "dependencies": [ "androidx.annotation:annotation:1.1.0" ], "directDependencies": [ "androidx.annotation:annotation:1.1.0" ], - "file": "v1/https/maven.google.com/androidx/test/monitor/1.4.0/monitor-1.4.0.aar", + "file": "v1/https/maven.google.com/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03.aar", "mirror_urls": [ - "https://maven.google.com/androidx/test/monitor/1.4.0/monitor-1.4.0.aar", - "https://repo1.maven.org/maven2/androidx/test/monitor/1.4.0/monitor-1.4.0.aar", - "https://maven.fabric.io/public/androidx/test/monitor/1.4.0/monitor-1.4.0.aar", - "https://maven.google.com/androidx/test/monitor/1.4.0/monitor-1.4.0.aar", - "https://repo1.maven.org/maven2/androidx/test/monitor/1.4.0/monitor-1.4.0.aar" + "https://maven.google.com/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03.aar", + "https://repo1.maven.org/maven2/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03.aar", + "https://maven.fabric.io/public/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03.aar", + "https://maven.google.com/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03.aar", + "https://repo1.maven.org/maven2/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03.aar" ], - "sha256": "46a912a1e175f27a97521af3f50e5af87c22c49275dd2c57c043740012806325", - "url": "https://maven.google.com/androidx/test/monitor/1.4.0/monitor-1.4.0.aar" + "sha256": "7c67b438deec7c14cf62ab54223ce19d5981f53477a15359347d7b59018419d0", + "url": "https://maven.google.com/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03.aar" }, { - "coord": "androidx.test:monitor:aar:sources:1.4.0", + "coord": "androidx.test:monitor:aar:sources:1.3.0-rc03", "dependencies": [], "directDependencies": [], "exclusions": [ "*:*" ], - "file": "v1/https/maven.google.com/androidx/test/monitor/1.4.0/monitor-1.4.0-sources.jar", + "file": "v1/https/maven.google.com/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03-sources.jar", "mirror_urls": [ - "https://maven.google.com/androidx/test/monitor/1.4.0/monitor-1.4.0-sources.jar", - "https://repo1.maven.org/maven2/androidx/test/monitor/1.4.0/monitor-1.4.0-sources.jar", - "https://maven.fabric.io/public/androidx/test/monitor/1.4.0/monitor-1.4.0-sources.jar", - "https://maven.google.com/androidx/test/monitor/1.4.0/monitor-1.4.0-sources.jar", - "https://repo1.maven.org/maven2/androidx/test/monitor/1.4.0/monitor-1.4.0-sources.jar" + "https://maven.google.com/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03-sources.jar", + "https://maven.fabric.io/public/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03-sources.jar", + "https://maven.google.com/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03-sources.jar" ], - "sha256": "a03ea6019c1ee7cc285afdbee98137ec463b891e6fc9176c121c5a70ec727f48", - "url": "https://maven.google.com/androidx/test/monitor/1.4.0/monitor-1.4.0-sources.jar" + "sha256": "08da381299ef3ecc345bd2ce7db2006fe21e054e928026a38104e9eeb9121761", + "url": "https://maven.google.com/androidx/test/monitor/1.3.0-rc03/monitor-1.3.0-rc03-sources.jar" }, { "coord": "androidx.test:rules:1.1.0", "dependencies": [ - "androidx.test:runner:1.4.0" + "androidx.test:runner:1.2.0" ], "directDependencies": [ - "androidx.test:runner:1.4.0" + "androidx.test:runner:1.2.0" ], "file": "v1/https/maven.google.com/androidx/test/rules/1.1.0/rules-1.1.0.aar", "mirror_urls": [ @@ -3506,10 +3473,10 @@ { "coord": "androidx.test:rules:jar:sources:1.1.0", "dependencies": [ - "androidx.test:runner:jar:sources:1.4.0" + "androidx.test:runner:jar:sources:1.2.0" ], "directDependencies": [ - "androidx.test:runner:jar:sources:1.4.0" + "androidx.test:runner:jar:sources:1.2.0" ], "file": "v1/https/maven.google.com/androidx/test/rules/1.1.0/rules-1.1.0-sources.jar", "mirror_urls": [ @@ -3523,58 +3490,56 @@ "url": "https://maven.google.com/androidx/test/rules/1.1.0/rules-1.1.0-sources.jar" }, { - "coord": "androidx.test:runner:1.4.0", + "coord": "androidx.test:runner:1.2.0", "dependencies": [ "androidx.annotation:annotation:1.1.0", - "androidx.test:monitor:1.4.0", - "com.google.code.findbugs:jsr305:3.0.2", - "androidx.test.services:storage:1.4.0", + "androidx.test:monitor:1.3.0-rc03", "junit:junit:4.12", - "org.hamcrest:hamcrest-core:1.3" + "org.hamcrest:hamcrest-core:1.3", + "net.sf.kxml:kxml2:2.3.0" ], "directDependencies": [ "androidx.annotation:annotation:1.1.0", - "androidx.test:monitor:1.4.0", - "androidx.test.services:storage:1.4.0", - "junit:junit:4.12" + "androidx.test:monitor:1.3.0-rc03", + "junit:junit:4.12", + "net.sf.kxml:kxml2:2.3.0" ], - "file": "v1/https/maven.google.com/androidx/test/runner/1.4.0/runner-1.4.0.aar", + "file": "v1/https/maven.google.com/androidx/test/runner/1.2.0/runner-1.2.0.aar", "mirror_urls": [ - "https://maven.google.com/androidx/test/runner/1.4.0/runner-1.4.0.aar", - "https://repo1.maven.org/maven2/androidx/test/runner/1.4.0/runner-1.4.0.aar", - "https://maven.fabric.io/public/androidx/test/runner/1.4.0/runner-1.4.0.aar", - "https://maven.google.com/androidx/test/runner/1.4.0/runner-1.4.0.aar", - "https://repo1.maven.org/maven2/androidx/test/runner/1.4.0/runner-1.4.0.aar" + "https://maven.google.com/androidx/test/runner/1.2.0/runner-1.2.0.aar", + "https://repo1.maven.org/maven2/androidx/test/runner/1.2.0/runner-1.2.0.aar", + "https://maven.fabric.io/public/androidx/test/runner/1.2.0/runner-1.2.0.aar", + "https://maven.google.com/androidx/test/runner/1.2.0/runner-1.2.0.aar", + "https://repo1.maven.org/maven2/androidx/test/runner/1.2.0/runner-1.2.0.aar" ], - "sha256": "e3f3d8b8d5d4a3edcacbdaa4a31bda2b0e41d3e704b02b3750466a06367ec5a0", - "url": "https://maven.google.com/androidx/test/runner/1.4.0/runner-1.4.0.aar" + "sha256": "5387e011167a3c8da08d99b5d59248c0e2da839317b48ebf202e31dc1f791ec1", + "url": "https://maven.google.com/androidx/test/runner/1.2.0/runner-1.2.0.aar" }, { - "coord": "androidx.test:runner:jar:sources:1.4.0", + "coord": "androidx.test:runner:jar:sources:1.2.0", "dependencies": [ - "com.google.code.findbugs:jsr305:jar:sources:3.0.2", - "androidx.test:monitor:jar:sources:1.4.0", + "androidx.test:monitor:jar:sources:1.3.0-rc03", "org.hamcrest:hamcrest-core:jar:sources:1.3", - "androidx.test.services:storage:jar:sources:1.4.0", "androidx.annotation:annotation:jar:sources:1.1.0", + "net.sf.kxml:kxml2:jar:sources:2.3.0", "junit:junit:jar:sources:4.12" ], "directDependencies": [ "androidx.annotation:annotation:jar:sources:1.1.0", - "androidx.test:monitor:jar:sources:1.4.0", - "androidx.test.services:storage:jar:sources:1.4.0", - "junit:junit:jar:sources:4.12" + "androidx.test:monitor:jar:sources:1.3.0-rc03", + "junit:junit:jar:sources:4.12", + "net.sf.kxml:kxml2:jar:sources:2.3.0" ], - "file": "v1/https/maven.google.com/androidx/test/runner/1.4.0/runner-1.4.0-sources.jar", + "file": "v1/https/maven.google.com/androidx/test/runner/1.2.0/runner-1.2.0-sources.jar", "mirror_urls": [ - "https://maven.google.com/androidx/test/runner/1.4.0/runner-1.4.0-sources.jar", - "https://repo1.maven.org/maven2/androidx/test/runner/1.4.0/runner-1.4.0-sources.jar", - "https://maven.fabric.io/public/androidx/test/runner/1.4.0/runner-1.4.0-sources.jar", - "https://maven.google.com/androidx/test/runner/1.4.0/runner-1.4.0-sources.jar", - "https://repo1.maven.org/maven2/androidx/test/runner/1.4.0/runner-1.4.0-sources.jar" + "https://maven.google.com/androidx/test/runner/1.2.0/runner-1.2.0-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/runner/1.2.0/runner-1.2.0-sources.jar", + "https://maven.fabric.io/public/androidx/test/runner/1.2.0/runner-1.2.0-sources.jar", + "https://maven.google.com/androidx/test/runner/1.2.0/runner-1.2.0-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/runner/1.2.0/runner-1.2.0-sources.jar" ], - "sha256": "f70a31dc1fc33d68700b61bdc44687b333ba4e44956e3df4a1fadbc46872cb61", - "url": "https://maven.google.com/androidx/test/runner/1.4.0/runner-1.4.0-sources.jar" + "sha256": "ec71974ddd8245a85ca856577c70972fd4c484f715df0a26271f0c28f8a58739", + "url": "https://maven.google.com/androidx/test/runner/1.2.0/runner-1.2.0-sources.jar" }, { "coord": "androidx.transition:transition:aar:1.2.0", @@ -7370,6 +7335,36 @@ "sha256": "e78a7277cb9ce4980fba22d809352821848581df0a6b545fa22aa7400a05db43", "url": "https://repo1.maven.org/maven2/net/ltgt/gradle/incap/incap/0.3/incap-0.3-sources.jar" }, + { + "coord": "net.sf.kxml:kxml2:2.3.0", + "dependencies": [], + "directDependencies": [], + "file": "v1/https/repo1.maven.org/maven2/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0.jar", + "mirror_urls": [ + "https://maven.google.com/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0.jar", + "https://repo1.maven.org/maven2/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0.jar", + "https://maven.fabric.io/public/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0.jar", + "https://maven.google.com/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0.jar", + "https://repo1.maven.org/maven2/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0.jar" + ], + "sha256": "f264dd9f79a1fde10ce5ecc53221eff24be4c9331c830b7d52f2f08a7b633de2", + "url": "https://repo1.maven.org/maven2/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0.jar" + }, + { + "coord": "net.sf.kxml:kxml2:jar:sources:2.3.0", + "dependencies": [], + "directDependencies": [], + "file": "v1/https/repo1.maven.org/maven2/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0-sources.jar", + "mirror_urls": [ + "https://maven.google.com/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0-sources.jar", + "https://repo1.maven.org/maven2/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0-sources.jar", + "https://maven.fabric.io/public/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0-sources.jar", + "https://maven.google.com/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0-sources.jar", + "https://repo1.maven.org/maven2/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0-sources.jar" + ], + "sha256": "85495366666158b58961e8911ced0f6f3bc92f1ebee865518b493fdb90760250", + "url": "https://repo1.maven.org/maven2/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0-sources.jar" + }, { "coord": "nl.dionsegijn:konfetti:1.2.5", "dependencies": [ @@ -8805,12 +8800,12 @@ "org.robolectric:resources:4.4", "androidx.annotation:annotation:1.1.0", "org.ow2.asm:asm:7.2", - "androidx.test:monitor:1.4.0", + "androidx.test:monitor:1.3.0-rc03", "org.robolectric:shadows-framework:4.4", "org.robolectric:sandbox:4.4", - "androidx.test:monitor:aar:1.4.0", "org.robolectric:pluginapi:4.4", "org.ow2.asm:asm-commons:7.2", + "androidx.test:monitor:aar:1.3.0-rc03", "org.ow2.asm:asm-analysis:7.2", "org.robolectric:plugins-maven-dependency-resolver:4.4", "org.bouncycastle:bcprov-jdk15on:1.65", @@ -8828,7 +8823,7 @@ "directDependencies": [ "org.robolectric:utils:4.4", "org.robolectric:resources:4.4", - "androidx.test:monitor:1.4.0", + "androidx.test:monitor:1.3.0-rc03", "org.robolectric:shadows-framework:4.4", "org.robolectric:sandbox:4.4", "org.robolectric:pluginapi:4.4", @@ -8856,11 +8851,11 @@ "dependencies": [ "org.ow2.asm:asm-commons:jar:sources:7.2", "org.robolectric:annotations:jar:sources:4.4", + "androidx.test:monitor:aar:sources:1.3.0-rc03", "org.ow2.asm:asm-analysis:jar:sources:7.2", - "androidx.test:monitor:jar:sources:1.4.0", "org.robolectric:junit:jar:sources:4.4", + "androidx.test:monitor:jar:sources:1.3.0-rc03", "org.ow2.asm:asm:jar:sources:7.2", - "androidx.test:monitor:aar:sources:1.4.0", "javax.inject:javax.inject:jar:sources:1", "com.almworks.sqlite4java:sqlite4java:jar:sources:0.282", "com.google.auto.value:auto-value-annotations:jar:sources:1.6.5", @@ -8882,8 +8877,8 @@ ], "directDependencies": [ "org.robolectric:annotations:jar:sources:4.4", - "androidx.test:monitor:jar:sources:1.4.0", "org.robolectric:junit:jar:sources:4.4", + "androidx.test:monitor:jar:sources:1.3.0-rc03", "javax.inject:javax.inject:jar:sources:1", "org.robolectric:utils:jar:sources:4.4", "org.robolectric:pluginapi:jar:sources:4.4", @@ -9031,9 +9026,9 @@ "org.robolectric:resources:4.4", "androidx.annotation:annotation:1.1.0", "org.ow2.asm:asm:7.2", - "androidx.test:monitor:aar:1.4.0", "org.robolectric:pluginapi:4.4", "org.ow2.asm:asm-commons:7.2", + "androidx.test:monitor:aar:1.3.0-rc03", "org.ow2.asm:asm-analysis:7.2", "org.ow2.asm:asm-util:7.2", "com.almworks.sqlite4java:sqlite4java:0.282", @@ -9050,8 +9045,8 @@ "com.google.auto.value:auto-value-annotations:1.6.5", "org.robolectric:resources:4.4", "androidx.annotation:annotation:1.1.0", - "androidx.test:monitor:aar:1.4.0", "org.robolectric:pluginapi:4.4", + "androidx.test:monitor:aar:1.3.0-rc03", "com.almworks.sqlite4java:sqlite4java:0.282", "org.robolectric:utils-reflector:4.4", "org.robolectric:shadowapi:4.4", @@ -9074,9 +9069,9 @@ "dependencies": [ "org.ow2.asm:asm-commons:jar:sources:7.2", "org.robolectric:annotations:jar:sources:4.4", + "androidx.test:monitor:aar:sources:1.3.0-rc03", "org.ow2.asm:asm-analysis:jar:sources:7.2", "org.ow2.asm:asm:jar:sources:7.2", - "androidx.test:monitor:aar:sources:1.4.0", "javax.inject:javax.inject:jar:sources:1", "com.almworks.sqlite4java:sqlite4java:jar:sources:0.282", "com.google.auto.value:auto-value-annotations:jar:sources:1.6.5", @@ -9094,7 +9089,7 @@ ], "directDependencies": [ "org.robolectric:annotations:jar:sources:4.4", - "androidx.test:monitor:aar:sources:1.4.0", + "androidx.test:monitor:aar:sources:1.3.0-rc03", "com.almworks.sqlite4java:sqlite4java:jar:sources:0.282", "com.google.auto.value:auto-value-annotations:jar:sources:1.6.5", "org.robolectric:utils:jar:sources:4.4", From 004e3a143b18f82121a83b7acf80a5d8de57cf1e Mon Sep 17 00:00:00 2001 From: farees Date: Sun, 25 Jul 2021 02:34:04 +0530 Subject: [PATCH 10/63] Nit fixes --- .../android/instrumentation/ExplorationPlayerTest.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/ExplorationPlayerTest.kt b/instrumentation/src/javatest/org/oppia/android/instrumentation/ExplorationPlayerTest.kt index 12a320ee96c..a2d5e0d73ca 100644 --- a/instrumentation/src/javatest/org/oppia/android/instrumentation/ExplorationPlayerTest.kt +++ b/instrumentation/src/javatest/org/oppia/android/instrumentation/ExplorationPlayerTest.kt @@ -10,7 +10,7 @@ import androidx.test.uiautomator.UiCollection import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.UiScrollable import androidx.test.uiautomator.UiSelector -import androidx.test.uiautomator.Until +import androidx.test.uiautomator.Until.hasObject import org.junit.Assert.assertNotNull import org.junit.Before import org.junit.Test @@ -33,7 +33,7 @@ class ExplorationPlayerTest { // Wait for launcher val launcherPackage = getLauncherPackageName() assertNotNull(launcherPackage) - device.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)), LAUNCH_TIMEOUT) + device.wait(hasObject(By.pkg(launcherPackage)), LAUNCH_TIMEOUT) // Launch the blueprint app val context = ApplicationProvider.getApplicationContext() @@ -43,14 +43,14 @@ class ExplorationPlayerTest { context.startActivity(intent) // Wait for the app to appear - device.wait(Until.hasObject(By.pkg(OPPIA_PACKAGE).depth(0)), LAUNCH_TIMEOUT) + device.wait(hasObject(By.pkg(OPPIA_PACKAGE).depth(0)), LAUNCH_TIMEOUT) } @Test fun testExploration_prototypeExploration_toolbarTitle_isDisplayedSuccessfully() { NavigateToPrototypeExploration() device.wait( - Until.hasObject( + hasObject( By.res("$OPPIA_PACKAGE:id/exploration_toolbar_title") ), TRANSITION_TIMEOUT @@ -64,14 +64,14 @@ class ExplorationPlayerTest { skip_button?.let { it.click() device.wait( - Until.hasObject(By.res("$OPPIA_PACKAGE:id/get_started_button")), + hasObject(By.res("$OPPIA_PACKAGE:id/get_started_button")), TRANSITION_TIMEOUT ) device.findObject(By.res("$OPPIA_PACKAGE:id/get_started_button")) .click() } device.wait( - Until.hasObject(By.res("$OPPIA_PACKAGE:id/profile_select_text")), + hasObject(By.res("$OPPIA_PACKAGE:id/profile_select_text")), TRANSITION_TIMEOUT ) val profiles = UiCollection(UiSelector().className("androidx.recyclerview.widget.RecyclerView")) From 7124642d34223c36993d2b56bf496913e709ee87 Mon Sep 17 00:00:00 2001 From: farees Date: Thu, 29 Jul 2021 05:52:15 +0530 Subject: [PATCH 11/63] Initial e2e tests --- .../instrumentation/ExplorationPlayerTest.kt | 4569 ++++++++++++++++- 1 file changed, 4546 insertions(+), 23 deletions(-) diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/ExplorationPlayerTest.kt b/instrumentation/src/javatest/org/oppia/android/instrumentation/ExplorationPlayerTest.kt index a2d5e0d73ca..818220dd66b 100644 --- a/instrumentation/src/javatest/org/oppia/android/instrumentation/ExplorationPlayerTest.kt +++ b/instrumentation/src/javatest/org/oppia/android/instrumentation/ExplorationPlayerTest.kt @@ -11,8 +11,13 @@ import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.UiScrollable import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.Until.hasObject +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse import org.junit.Assert.assertNotNull +import org.junit.Assert.assertNull +import org.junit.Assert.assertTrue import org.junit.Before +import org.junit.Ignore import org.junit.Test /** Tests for Explorations. */ @@ -20,46 +25,4297 @@ class ExplorationPlayerTest { private val OPPIA_PACKAGE = "org.oppia.android" private val LAUNCH_TIMEOUT = 30000L private val TRANSITION_TIMEOUT = 5000L + private val APP_STARTUP_TIMEOUT = 120000L private lateinit var device: UiDevice + private val PROTOTYPE_EXPLORATION_DESCRIPTION = "Test exploration with interactions. " + private val FRACTION_INTERACTION_CONTENT = "What fraction represents half of something?" + private val FRACTION_INTERACTION_VIEW_HINT = "Enter a fraction in the form x/x, or a mixed" + + " number in the form x x/x." + private val FRACTION_INTERACTION_INPUT_ERROR = "Please only use numerical digits, spaces or " + + "forward slashes (/)" + private val FRACTION_INTERACTION_INCOMPLETE_INPUT_ERROR = "Please enter a valid fraction " + + "(e.g., 5/3 or 1 2/3)" + private val FRACTION_INTERACTION_INCORRECT_ANSWER_FEEDBACK = "That answer isn't correct. Try " + + "again." + private val FRACTION_INTERACTION_CORRECT_ANSWER_FEEDBACK = "Correct!" + private val MULTIPLE_CHOICE_INTERACTION_1_CONTENT = "Which bird can sustain flight for long " + + "periods of time?" + private val MULTIPLE_CHOICE_INTERACTION_1_OPTION_1 = "Penguin" + private val MULTIPLE_CHOICE_INTERACTION_1_OPTION_2 = "Chicken" + private val MULTIPLE_CHOICE_INTERACTION_1_OPTION_3 = "Eagle" + private val MULTIPLE_CHOICE_INTERACTION_1_INCORRECT_ANS_FEEDBACK = "Try again." + private val MULTIPLE_CHOICE_INTERACTION_1_CORRECT_ANS_FEEDBACK = "Correct! Eagles can sustain " + + "flight." + private val MULTIPLE_CHOICE_INTERACTION_2_CONTENT = "What color does the 'G' in 'RGB' " + + "correspond to?" + private val MULTIPLE_CHOICE_INTERACTION_2_OPTION_1 = "Green" + private val MULTIPLE_CHOICE_INTERACTION_2_OPTION_2 = "Red" + private val MULTIPLE_CHOICE_INTERACTION_2_OPTION_3 = "Blue" + private val MULTIPLE_CHOICE_INTERACTION_2_INCORRECT_ANS_FEEDBACK = "Not quite. Try again." + private val MULTIPLE_CHOICE_INTERACTION_2_CORRECT_ANS_FEEDBACK = "Correct!" + private val ITEM_SELECTION_INTERACTION_CONTENT = "What are the primary colors of light?" + private val ITEM_SELECTION_INTERACTION_OPTION_1 = "Red" + private val ITEM_SELECTION_INTERACTION_OPTION_2 = "Yellow" + private val ITEM_SELECTION_INTERACTION_OPTION_3 = "Green" + private val ITEM_SELECTION_INTERACTION_OPTION_4 = "Blue" + private val ITEM_SELECTION_INTERACTION_OPTION_5 = "Orange" + private val ITEM_SELECTION_INTERACTION_OPTION_6 = "Purple" + private val ITEM_SELECTION_INTERACTION_INCORRECT_ANS_FEEDBACK = "That's not quite right. Try " + + "again." + private val ITEM_SELECTION_INTERACTION_INCORRECT_ANS_FEEDBACK_SUGGESTION = "'Yellow' is " + + "considered a primary color in the RYB color spectrum, but that doesn't correspond to light." + + " Try again!" + private val ITEM_SELECTION_INTERACTION_CORRECT_ANS_FEEDBACK = "Correct!" + private val NUMERIC_INPUT_INTERACTION_CONTENT = "What is 11 times 11?" + private val NUMERIC_INPUT_INTERACTION_VIEW_HINT = "Enter a number." + private val NUMERIC_INPUT_INTERACTION_LESSER_INPUT_FEEDBACK = "Not quite. It's actually larger " + + "than that. Try again." + private val NUMERIC_INPUT_INTERACTION_GREATER_INPUT_FEEDBACK = "Not quite. It's less than that." + private val NUMERIC_INPUT_INTERACTION_CORRECT_INPUT_FEEDBACK = "Correct!" + private val NUMERIC_INPUT_INTERACTION_INVALID_INPUT_ERROR = "Please enter a valid number." + private val NUMERIC_INPUT_INTERACTION_PERIOD_INPUT_ERROR = "Please begin your answer with a " + + "number (e.g.,”0” in 0.5)." + private val RATIO_INPUT_INTERACTION_CONTENT = "Two numbers are respectively 20% and 50% more " + + "than a third number. The ratio of the two numbers is:" + private val RATIO_INPUT_INTERACTION_VIEW_HINT = "Enter in format of x:y" + private val RATIO_INPUT_INTERACTION_INCOMPLETE_ANS_ERROR = "Please enter a valid ratio " + + "(e.g. 1:2 or 1:2:3)." + private val RATIO_INPUT_INTERACTION_INVALID_ANS_ERROR = "Please write a ratio that consists " + + "of digits separated by colons (e.g. 1:2 or 1:2:3)." + private val RATIO_INPUT_INTERACTION_DOUBLE_COLON_ERROR = "Your answer has two colons (:) next " + + "to each other." + private val RATIO_INPUT_INTERACTION_INCORRECT_ANS_FEEDBACK = "Not correct" + private val RATIO_INPUT_INTERACTION_CORRECT_ANS_FEEDBACK = "Correct" + private val TEXT_INPUT_INTERACTION_CONTENT = "In which language does Oppia mean 'to learn'?" + private val TEXT_INPUT_INTERACTION_VIEW_HINT = "Enter a language" + private val TEXT_INPUT_INTERACTION_INCORRECT_ANS_FEEDBACK = "Not quite. Try again (or maybe use" + + " a search engine)." + private val TEXT_INPUT_INTERACTION_CORRECT_ANS_FEEDBACK = "Correct!" + private val DRAG_AND_DROP_INTERACTION_CONTENT = "Sort the following in descending order." + private val DRAG_AND_DROP_INTERACTION_OPTION_1 = "0.35" + private val DRAG_AND_DROP_INTERACTION_OPTION_2 = "3/5" + private val DRAG_AND_DROP_INTERACTION_OPTION_3 = "0.5" + private val DRAG_AND_DROP_INTERACTION_OPTION_4 = "0.46" + private val DRAG_AND_DROP_INTERACTION_INCORRECT_FEEDBACK = "Not quite. Try again." + private val DRAG_AND_DROP_INTERACTION_CORRECT_FEEDBACK = "That's correct" + private val DRAG_DROP_MERGE_INTERACTION_CONTENT = "Sort the following in descending order," + + " putting equal items in the same position." + private val DRAG_DROP_MERGE_INTERACTION_OPTION_1 = "3/5" + private val DRAG_DROP_MERGE_INTERACTION_OPTION_2 = "0.6" + private val DRAG_DROP_MERGE_INTERACTION_OPTION_3 = "0.35" + private val DRAG_DROP_MERGE_INTERACTION_OPTION_4 = "0.46" + private val DRAG_DROP_MERGE_INTERACTION_INCORRECT_FEEDBACK = "Not quite. Try again." + private val DRAG_DROP_MERGE_INTERACTION_CORRECT_FEEDBACK = "That's correct" + private val PROTOTYPE_EXPLORATION_END_EXPLORATION_CONTENT = "Congratulations, you have finished!" + private val IMAGE_REGOIN_SELECTION_EXPLORATION_DESCRIPTION = "Our Solar System consists of nine" + + " planets orbiting around our sun: Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus," + + " Neptune and Pluto. They range from huge gas giants to small icy dwarf planets.\n" + + "\n" + + " \n" + + "\n" + + "Click on the planets below to find out more about each one!" + private val IMAGE_REGION_INTERACTION_JUPITER_FEEDBACK = "Jupiter, the fifth planet from the " + + "sun, is a huge planet that is 2.5 times heavier than all of the other planets in our Solar" + + " System combined. It is mostly formed out of thick gases around a solid core. One famous" + + " feature on it is the \"Great Red Spot\", which is a huge storm on its surface that has" + + " raged for at least 350 years, and is large enough to swallow three entire Earths." + private val IMAGE_REGION_INTERACTION_VENUS_FEEDBACK = "This is Venus, the second planet from" + + " the sun. It is the brightest planet in the Solar System, and can sometimes even be seen " + + "during the day. Though Mercury is nearer to the sun than Venus, Venus is the hottest planet" + + " in the Solar System, because its thick atmosphere of carbon dioxide traps heat on its" + + " surface." + private val IMAGE_REGION_INTERACTION_MERCURY_FEEDBACK = "This is Mercury, a small metallic" + + " planet closest to the sun. Since it is so near to the sun, it only takes 88 days for it" + + " to travel one entire orbit, so a year on Mercury would only be 88 days long." + private val IMAGE_REGION_INTERACTION_EARTH_FEEDBACK = "Earth! Our home planet is the third" + + " planet from the sun. Despite the vastness of the Solar System and the rest of space, it is" + + " the only place that we know life exists on. It is at just the right distance from the sun" + + " to ensure a comfortable temperature for us to exist in." + private val IMAGE_REGION_INTERACTION_MARS_FEEDBACK = "This doesn't seem like the correct" + + " choice.Try Again" + private val IMAGE_REGION_INTERACTION_URANUS_FEEDBACK = "Uranus is the seventh planet from " + + "the sun. It was the first planet that was discovered using a telescope, since it is normally" + + " too dim to be seen with the naked eye. It is the coldest planet, and is formed from layers" + + " of hydrogen gas enveloping a frigid core of rock and ice." + private val IMAGE_REGION_INTERACTION_NEPTUNE_FEEDBACK = "Neptune is the eighth planet from the" + + " sun. It is an \"ice giant\", like Uranus, with an outer layer of hydrogen, helium, and " + + "methane enveloping an icy core. The methane in its atmosphere absorbs red light, giving it a" + + " beautiful blue color. It was first predicted to exist from gravitational calculations, and" + + " was only discovered by telescope later." + private val IMAGE_REGION_INTERACTION_PLUTO_FEEDBACK = "Pluto was once considered the ninth" + + " planet from the sun, but has now been reclassified as a \"dwarf planet\". It is formed from" + + " ice and rock, and is even smaller than our moon. The first spacecraft to visit Pluto is due" + + " to reach in July 2015." + private val IMAGE_REGION_INTERACTION_SATURN_FEEDBACK = "Saturn, the sixth planet from the sun, " + + "is most well known for its beautiful rings of ice and dust orbiting around it. Like Jupiter," + + " it is a gas giant, mostly made of layers of hydrogen which get progressively denser towards" + + " its solid core. " + private val IMAGE_REGION_END_EXPLORATION_CONTENT = "This is the end " + @Before fun startOppiaFromHomeScreen() { // Initialize UiDevice instance device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) - // Start from the home screen - device.pressHome() + // Start from the home screen + device.pressHome() + + // Wait for launcher + val launcherPackage = getLauncherPackageName() + assertNotNull(launcherPackage) + device.wait(hasObject(By.pkg(launcherPackage)), LAUNCH_TIMEOUT) + + // Launch the blueprint app + val context = ApplicationProvider.getApplicationContext() + val intent = context.packageManager + .getLaunchIntentForPackage(OPPIA_PACKAGE) + intent!!.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) // Clear out any previous instances + context.startActivity(intent) + + // Wait for the app to appear + device.wait(hasObject(By.pkg(OPPIA_PACKAGE).depth(0)), LAUNCH_TIMEOUT) + } + + @Test + /** + * Test cases covered: + * PrototypeExploration - Description + * - [testprototypeExploration_checktoolbarTitle_isDisplayedSuccessfully] + * - [testprototypeExploration_checkExplorationDescription_isDisplayedSuccessfully] + * PrototypeExploration - FractionInputInteraction + * - [testprototypeExploration_checkFractionInteractionContent_isDisplayedSuccessfully] + * - [testprototypeExploration_fractionInputInvalidCharacter_errorIsDisplayedSuccessfully] + * - [testprototypeExploration_fractionInputInvalidCharacter_submitButtonIsDisabled] + * - [testprototypeExploration_fractionInputValidCharacter_submitButtonIsEnabled] + * - [testprototypeExploration_fractionSubmitIncorrectAnswer_incorrectFeedbackIsDisplayed] + * - [testprototypeExploration_fractionSubmitCorrectAnswer_correctFeedbackIsDisplayed] + * - [testprototypeExploration_fractionSubmitAndContinue_nextInteractionIsDisplayed] + * - [testprototypeExplorationLandscape_fractionEnterInvalidCharacter_errorIsDisplayed] + * - [testprototypeExplorationLandscape_fractionEnterInvalidCharacter_submitButtonIsDisabled] + * - [testPrototypeExplorationLandscape_fractionEnterValidCharacter_submitButtonIsEnabled] + * - [testPrototypeExplorationLandscape_fractionSubmitIncorrectAnswer_incorrectFeedbackIsDisplayed] + * - [testPrototypeExplorationLandscape_fractionSubmitCorrectAnswer_correctFeedbackIsDisplayed] + * - [testPrototypeExplorationLandscape_fractionSubmitAndContinue_nextInteractionIsDisplayed] + * - [testPrototypeExploration_fractionEnterACharacter_inputIsPreservedOnConfigChange] + * - [testPrototypeExploration_fractionEnterInvalidCharacter_errorIsPreservedOnConfigChange] + * - [testPrototypeExploration_fractionEnterInvalidCharacter_errorIsDisappearedOnEnteringValidCharacter] + * - [testPrototypeExplorationLandscape_fractionEnterInvalidCharacter_errorIsDisappearedOnEnteringValidCharacter] + * - [testprototypeExploration_fractionInputIncompleteFraction_incompleteErrorIsDisplayedSuccessfully] + * - [testprototypeExplorationLandscape_fractionInputIncompleteFraction_incompleteErrorIsDisplayedSuccessfully] + * PrototypeExploration - MultipleChoiceInput1 + * - [testPrototypeExploration_checkMultipleChoiceInput1_option1IsDisplayed] + * - [testPrototypeExploration_checkMultipleChoiceInput1_option2IsDisplayed] + * - [testPrototypeExploration_checkMultipleChoiceInput1_option3IsDisplayed] + * - [testPrototypeExploration_selectOption1MultipleChoiceInput1_incorrectFeedbackIsDisplayed] + * - [testPrototypeExploration_selectOption2MultipleChoiceInput1_incorrectFeedbackIsDisplayed] + * - [testPrototypeExploration_selectOption3MultipleChoiceInput1_correctFeedbackIsDisplayed] + * - [testPrototypeExploration_multipleChoiceInput1Continue_nextInteractionIsDisplayed] + * - [testPrototypeExpLandscape_selectOption1MultipleChoiceInput1_incorrectFeedbackIsDisplayed] + * - [testPrototypeExpLandscape_selectOption2MultipleChoiceInput1_incorrectFeedbackIsDisplayed] + * - [testPrototypeExpLandscape_selectOption3MultipleChoiceInput1_correctFeedbackIsDisplayed] + * - [testPrototypeExpLandscape_multipleChoiceInput1Continue_nextInteractionIsDisplayed] + * PrototypeExploration - MultipleChoiceInput2 + * - [testPrototypeExploration_checkMultipleChoiceInput2_option1IsDisplayed] + * - [testPrototypeExploration_checkMultipleChoiceInput2_option2IsDisplayed] + * - [testPrototypeExploration_checkMultipleChoiceInput2_option3IsDisplayed] + * - [testPrototypeExploration_selectOption1MultipleChoiceInput2_correctFeedbackIsDisplayed] + * - [testPrototypeExploration_selectOption2MultipleChoiceInput2_incorrectFeedbackIsDisplayed] + * - [testPrototypeExploration_selectOption3MultipleChoiceInput2_incorrectFeedbackIsDisplayed] + * - [testPrototypeExploration_multipleChoiceInput2Continue_nextInteractionIsDisplayed] + * - [testPrototypeExpLandscape_selectOption1MultipleChoiceInput2_correctFeedbackIsDisplayed] + * - [testPrototypeExpLandscape_selectOption2MultipleChoiceInput2_incorrectFeedbackIsDisplayed] + * - [testPrototypeExpLandscape_selectOption3MultipleChoiceInput2_incorrectFeedbackIsDisplayed] + * - [testPrototypeExpLandscape_multipleChoiceInput2Continue_nextInteractionIsDisplayed] + * PrototypeExploration - ItemSelectionInput + * - [testPrototypeExploration_checkItemSelection_option1IsDisplayed] + * - [testPrototypeExploration_checkItemSelection_option2IsDisplayed] + * - [testPrototypeExploration_checkItemSelection_option3IsDisplayed] + * - [testPrototypeExploration_checkItemSelection_option4IsDisplayed] + * - [testPrototypeExploration_checkItemSelection_option5IsDisplayed] + * - [testPrototypeExploration_checkItemSelection_option6IsDisplayed] + * - [testPrototypeExploration_checkItemSelection_submitButtonIsDisabled] + * - [testPrototypeExploration_itemSelectionCheckOneOption_submitButtonIsEnabled] + * - [testPrototypeExploration_itemSelectionSubmitIncorrectAns_incorrectFeedbackIsDisplayed] + * - [testPrototypeExploration_itemSelectionSubmitIncorrectAnsWithSuggestion_suggestionFeedbackIsDisplayed] + * - [testPrototypeExploration_itemSelectionSubmitCorrectAns_correctFeedbackIsDisplayed] + * - [testPrototypeExploration_itemSelectionContinue_nextInteractionIsDisplayed] + * - [testPrototypeExploration_itemSelectionSelect4Options_fourthOptionIsUnchecked] + * - [testPrototypeExploration_itemSelectionClickOnOptionText_checkBoxIsChecked] + * - [testPrototypeExplorationLandscape_checkItemSelection_submitButtonIsDisabled] + * - [testPrototypeExplorationLandscape_itemSelectionCheckOneOption_submitButtonIsEnabled] + * - [testPrototypeExplorationLandscape_itemSelectionSubmitIncorrectAns_incorrectFeedbackIsDisplayed] + * - [testPrototypeExplorationLandscape_itemSelectionSubmitIncorrectAnsWithSuggestion_suggestionFeedbackIsDisplayed] + * - [testPrototypeExplorationLandscape_itemSelectionSubmitCorrectAnsWithSuggestion_correctFeedbackIsDisplayed] + * - [testPrototypeExplorationLandscape_itemSelectionSelect4Options_fourthOptionIsUnchecked] + * - [testPrototypeExplorationLandscape_itemSelectionClickOnOptionText_checkBoxIsChecked] + * - [testPrototypeExplorationLandscape_itemSelectionContinue_nextInteractionIsDisplayed] + * - [testPrototypeExploration_itemSelectionSelectOption_selectedOptionPreservedOnConfigChange] + * - [testPrototypeExploration_itemSelectionSelectOption_submitButtonIsEnabled] + * PrototypeExploration - NumericInputInteraction + * - [testPrototypeExploration_checkNumericInput_inputHintIsDisplayed] + * - [testPrototypeExploration_numericInputEnterPeriod_inputErrorIsDisplayed] + * - [testPrototypeExploration_numericInputEnterMinus_inputErrorIsDisplayed] + * - [testPrototypeExploration_numericInputEnterLesserAns_lesserFeedbackIsDisplayed] + * - [testPrototypeExploration_numericInputEnterGreaterAns_greaterFeedbackIsDisplayed] + * - [testPrototypeExploration_numericInputEnterCorrectAns_correctFeedbackIsDisplayed] + * - [testPrototypeExploration_numericInputContinue_nextInteractionIsDisplayed] + * - [testPrototypeExplorationLandscape_numericInputEnterPeriod_inputErrorIsDisplayed] + * - [testPrototypeExplorationLandscape_numericInputEnterMinus_inputErrorIsDisplayed] + * - [testPrototypeExplorationLandscape_numericInputEnterLesserAns_lesserFeedbackIsDisplayed] + * - [testPrototypeExplorationLandscape_numericInputEnterGreaterAns_greaterFeedbackIsDisplayed] + * - [testPrototypeExplorationLandscape_numericInputEnterCorrectAns_correctFeedbackIsDisplayed] + * - [testPrototypeExplorationLandscape_numericInputContinue_nextInteractionIsDisplayed] + * - [testPrototypeExploration_checkNumericInput_submitButtonIsDisabled] + * - [testPrototypeExploration_numericInputEnterPeriod_submitButtonIsDisabled] + * - [testPrototypeExploration_numericInputEnterDigit_submitButtonIsEnabled] + * - [testPrototypeExplorationLandscape_checkNumericInput_submitButtonIsDisabled] + * - [testPrototypeExplorationLandscape_numericInputEnterPeriod_submitButtonIsDisabled] + * - [testPrototypeExplorationLandscape_numericInputEnterDigit_submitButtonIsEnabled] + * - [testPrototypeExploration_numericInputEnterDigit_inputIsPreservedOnConfigChange] + * - [testPrototypeExploration_numericInputEnterPeriod_errorIsPreservedOnConfigChange] + * - [testPrototypeExploration_numericInputEnterPeriod_errorIsDisappearedOnEnteringValidCharacter] + * PrototypeExploration - RatioInputInteraction + * - [testPrototypeExploration_checkRatioInput_hintIsDisplaed] + * - [testPrototypeExploration_checkRatioInputIncompleteRatio_incompleteErrorIsDisplayed] + * - [testPrototypeExploration_checkRatioInputInvalidCharacter_invalidErrorIsDisplayed] + * - [testPrototypeExploration_checkRatioInputDoubleColon_doubleColonErrorIsDisplayed] + * - [testPrototypeExploration_checkRatioInputSubmitIncorrectAns_incorrectFeedbackIsDisplayed] + * - [testPrototypeExploration_checkRatioInputSubmitCorrectAns_correctFeedbackIsDisplayed] + * - [testPrototypeExploration_checkRatioInputContinue_nextInteractionIsDisplayed] + * - [testPrototypeExploration_checkRatioInput_submitButtonIsDisabled] + * - [testPrototypeExploration_ratioInputValidNumber_submitButtonIsEnabled] + * - [testPrototypeExploration_ratioInputInvalidCharacter_submitButtonIsDisabled] + * - [testPrototypeExploration_ratioInputInvalidCharacter_errorDisabledOnValidCharacter] + * - [testPrototypeExplorationLandScape_checkRatioInputInvalidCharacter_invalidErrorIsDisplayed] + * - [testPrototypeExplorationLandscape_checkRatioInputDoubleColon_doubleColonErrorIsDisplayed] + * - [testPrototypeExplorationLandscape_checkRatioInputSubmitIncorrectAns_incorrectFeedbackIsDisplayed] + * - [testPrototypeExplorationLandscape_checkRatioInputSubmitCorrectAns_correctFeedbackIsDisplayed] + * - [testPrototypeExplorationLandscape_checkRatioInputContinue_nextInteractionIsDisplayed] + * - [testPrototypeExplorationLandscape_checkRatioInput_submitButtonIsDisabled] + * - [testPrototypeExplorationLandscape_ratioInputValidNumber_submitButtonIsEnabled] + * - [testPrototypeExplorationLandscape_ratioInputInvalidCharacter_submitButtonIsDisabled] + * - [testPrototypeExplorationLandscape_ratioInputInvalidCharacter_errorDisabledOnValidCharacter] + * - [testPrototypeExploration_ratioInputCharacter_characterIsPreservedOnConfigChange] + * - [testPrototypeExploration_ratioInputInvalidCharacter_invalidErrorIsPreservedOnConfigChange] + * - [testPrototypeExploration_ratioInputIncompleteRatio_incompleteErrorIsPreservedOnConfigChange] + * - [testPrototypeExploration_ratioInputDoubleColon_doubleColonErrorIsPreservedOnConfigChange] + * - [testPrototypeExploration_ratioInputACharacter_submitButtonIsPreservedOnConfigChange] + * PrototypeExploration - TextInputInteraction + * - [testPrototypeExploration_checkTextInput_hintIsDisplayed] + * - [testPrototypeExploration_checkTextInput_submitButtonIsDisabled] + * - [testPrototypeExploration_textInputCharacter_submitButtonIsEnabled] + * - [testPrototypeExploration_textInputSubmitIncorrectAns_incorrectFeedbackIsDislayed] + * - [testPrototypeExploration_textInputSubmitCorrectAns_correctFeedbackIsDislayed] + * - [testPrototypeExplorationLandscape_checkTextInput_hintIsDisplayed] + * - [testPrototypeExplorationLandscape_checkTextInput_submitButtonIsDisabled] + * - [testPrototypeExplorationLandScape_textInputCharacter_submitButtonIsEnabled] + * - [testPrototypeExplorationLandscape_textInputSubmitIncorrectAns_incorrectFeedbackIsDislayed] + * - [testPrototypeExplorationLandscape_textInputSubmitCorrectAns_correctFeedbackIsDislayed] + * - [testPrototypeExploration_textInputCharacter_inputIsPreservedOnConfigChange] + * - [testPrototypeExploration_textInputContinue_nextInteractionIsDisplayed] + * - [testPrototypeExplorationLandscape_textInputContinue_nextInteractionIsDisplayed] + * PrototypeExploration - DragAndDropInteraction + * - [testPrototypeExploration_checkDragAndDrop_option1IsDisplayed] + * - [testPrototypeExploration_checkDragAndDrop_option2IsDisplayed] + * - [testPrototypeExploration_checkDragAndDrop_option3IsDisplayed] + * - [testPrototypeExploration_checkDragAndDrop_option4IsDisplayed] + * - [testPrototypeExploration_checkDragAndDrop_firstItemMoveUpButtonIsDisabled] + * - [testPrototypeExploration_checkDragAndDrop_lastItemMoveDownButtonIsDisabled] + * - [testPrototypeExploration_dragAndDropSubmitWrongArrangement_incorrectFeedbackIsDisplayed] + * - [testPrototypeExploration_dragAndDropSubmitCorrectArrangmentByDrag_correctFeedbackIsDisplayed] + * - [testPrototypeExploration_dragAndDropSubmitCorrectArrangmentByButtons_correctFeedbackIsDisplayed] + * - [testPrototypeExplorationLandscape_checkDragAndDrop_firstItemMoveUpButtonIsDisabled] + * - [testPrototypeExplorationLandscape_checkDragAndDrop_lastItemMoveDownButtonIsDisabled] + * - [testPrototypeExplorationLandscape_dragAndDropSubmitWrongArrangement_incorrectFeedbackIsDisplayed] + * - [testPrototypeExplorationLandscape_dragAndDropSubmitCorrectArrangmentByDrag_correctFeedbackIsDisplayed] + * - [testPrototypeExplorationLandscape_dragAndDropSubmitCorrectArrangmentByButtons_correctFeedbackIsDisplayed] + * - [testPrototypeExploration_dragAndDropChangeArrangment_arrangementIsPreservedOnConfigChange] + * - [testPrototypeExploration_dragAndDropContine_nextInteractionIsDisplayed] + * - [testPrototypeExplorationLandscape_dragAndDropContine_nextInteractionIsDisplayed] + * PrototypeExploration - DragDropMergeInteraction + * - [testPrototypeExploration_checkDragDropMerge_option1IsDisplayed] + * - [testPrototypeExploration_checkDragDropMerge_option2IsDisplayed] + * - [testPrototypeExploration_checkDragDropMerge_option3IsDisplayed] + * - [testPrototypeExploration_checkDragDropMerge_option4IsDisplayed] + * - [testPrototypeExploration_checkDragDropMerge_firstItemMoveUpButtonIsDisabled] + * - [testPrototypeExploration_checkDragDropMerge_lastItemMoveDownButtonIsDisabled] + * - [testPrototypeExploration_checkDragDropMerge_lastItemMergeButtonIsDisabled] + * - [testPrototypeExploration_dragDropMergeSubmitWrongArrangement_incorrectFeedbackIsDisplayed] + * - [testPrototypeExploration_dragDropMergeSubmitCorrectArrangmentByDrag_correctFeedbackIsDisplayed] + * - [testPrototypeExploration_dragDropMergeSubmitCorrectArrangmentByButtons_correctFeedbackIsDisplayed] + * - [testPrototypeExplorationLandscape_checkDragDropMerge_firstItemMoveUpButtonIsDisabled] + * - [testPrototypeExplorationLandscape_checkDragDropMerge_lastItemMoveDownButtonIsDisabled] + * - [testPrototypeExplorationLandscape_checkDragDropMerge_lastItemMergeButtonIsDisabled] + * - [testPrototypeExplorationLandscape_dragDropMergeSubmitWrongArrangement_incorrectFeedbackIsDisplayed] + * - [testPrototypeExplorationLandscape_dragDropMergeSubmitCorrectArrangmentByDrag_correctFeedbackIsDisplayed] + * - [testPrototypeExplorationLandscape_dragDropMergeSubmitCorrectArrangmentByButtons_correctFeedbackIsDisplayed] + * - [testPrototypeExploration_dragDropMergeChangeArrangement_arrangementIsPreservedOnConfigChange] + * - [testPrototypeExploration_dragDropMergeContinue_nextInteractionIsDisplayed] + * - [testPrototypeExplorationLandscape_dragDropMergeContinue_nextInteractionIsDisplayed] + * PrototypeExploration - EndExploration + * - [testPrototypeExploration_endExplorationClickReturnToTopic_storyTitleIsDisplayed] + * - [testPrototypeExplorationLandscape_endExplorationClickReturnToTopic_topicTitleIsDisplayed] + * ImageRegionSelectionExploration - ImageRegionSelectionInteraction + * - [testImageRegionExp_checkExplorationDescription_isDisplayed] + * - [testImageRegionExp_imageRegionClickJupiter_jupiterFeedbackIsDisplayed] + * - [testImageRegionExp_imageRegionClickSaturn_saturnFeedbackIsDisplayed] + * - [testImageRegionExp_imageRegionClickUranus_uranusFeedbackIsDisplayed] + * - [testImageRegionExp_imageRegionClickNeptune_neptuneFeedbackIsDisplayed] + * - [testImageRegionExp_imageRegionClickEarth_earthFeedbackIsDisplayed] + * - [testImageRegionExp_imageRegionClickVenus_venusFeedbackIsDisplayed] + * - [testImageRegionExp_imageRegionClickMars_marsFeedbackIsDisplayed] + * - [testImageRegionExp_imageRegionClickPluto_plutoFeedbackIsDisplayed] + * - [testImageRegionExp_imageRegionClickMercury_mercuryFeedbackIsDisplayed] + * - [testImageRegionExp_imageRegionContinue_nextIntearctionIsDisplayed] + * - [testImageRegionExpLandscape_imageRegionClickJupiter_jupiterFeedbackIsDisplayed] + * - [testImageRegionExpLandscape_imageRegionClickSaturn_saturnFeedbackIsDisplayed] + * - [testImageRegionExpLandscape_imageRegionClickUranus_uranusFeedbackIsDisplayed] + * - [testImageRegionExpLandscape_imageRegionClickNeptune_neptuneFeedbackIsDisplayed] + * - [testImageRegionExpLandscape_imageRegionClickEarth_earthFeedbackIsDisplayed] + * - [testImageRegionExpLandscape_imageRegionClickVenus_venusFeedbackIsDisplayed] + * - [testImageRegionExpLandscape_imageRegionClickMars_marsFeedbackIsDisplayed] + * - [testImageRegionExpLandscape_imageRegionClickPluto_plutoFeedbackIsDisplayed] + * - [testImageRegionExpLandscape_imageRegionClickMercury_mercuryFeedbackIsDisplayed] + * - [testImageRegionExpLandscape_imageRegionContinue_nextIntearctionIsDisplayed] + * ImageRegionSelectionExploration - EndExploration + * - [testImageRegionExp_endExplorationClickReturnToTopic_storyTitleIsDisplayed] + * - [testImageRegionExpLandscape_endExplorationClickReturnToTopic_storyTitleIsDisplayed] + * */ + fun testprototypeExploration_checktoolbarTitle_isDisplayedSuccessfully() { + NavigateToPrototypeExploration() + assertNotNull(device.findObject(By.res("$OPPIA_PACKAGE:id/exploration_toolbar_title"))) + } + + @Test + fun testprototypeExploration_checkExplorationDescription_isDisplayedSuccessfully() { + NavigateToPrototypeExploration() + val expDescription = device.findObject(By.res("$OPPIA_PACKAGE:id/content_text_view")) + assertEquals(PROTOTYPE_EXPLORATION_DESCRIPTION, expDescription.text) + } + + @Test + fun testprototypeExploration_checkFractionInteractionContent_isDisplayedSuccessfully() { + NavigateToPrototypeExploration() + device.findObject(UiSelector().text("CONTINUE")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/fraction_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val fractionInteractionView = device.findObject(By.res("$OPPIA_PACKAGE:id/content_text_view")) + assertEquals(FRACTION_INTERACTION_CONTENT, fractionInteractionView.text) + } + + @Test + fun testprototypeExploration_fractionInputInvalidCharacter_errorIsDisplayedSuccessfully() { + NavigateToPrototypeExploration() + device.findObject(UiSelector().text("CONTINUE")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/fraction_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val fractionInteractionView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/fraction_input_interaction_view" + ) + ) + fractionInteractionView.text = "o" + val inputError = device.findObject(By.res("$OPPIA_PACKAGE:id/fraction_input_error")) + assertEquals(FRACTION_INTERACTION_INPUT_ERROR, inputError.text) + } + + @Test + fun testprototypeExploration_fractionInputInvalidCharacter_submitButtonIsDisabled() { + NavigateToPrototypeExploration() + device.findObject(UiSelector().text("CONTINUE")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/fraction_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val fractionInteractionView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/fraction_input_interaction_view" + ) + ) + fractionInteractionView.text = "o" + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + assertFalse(submitButton.isEnabled) + } + + @Test + fun testprototypeExploration_fractionInputValidCharacter_submitButtonIsEnabled() { + NavigateToPrototypeExploration() + device.findObject(UiSelector().text("CONTINUE")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/fraction_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val fractionInteractionView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/fraction_input_interaction_view" + ) + ) + fractionInteractionView.text = "1" + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + assertTrue(submitButton.isEnabled) + } + + @Test + fun testprototypeExploration_fractionSubmitIncorrectAnswer_incorrectFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + device.findObject(UiSelector().text("CONTINUE")).click() + device.wait( + hasObject( + By.res( + "$OPPIA_PACKAGE:id/fraction_input_interaction_view" + ) + ), + TRANSITION_TIMEOUT + ) + val fractionInteractionView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/fraction_input_interaction_view" + ) + ) + fractionInteractionView.text = "1" + device.findObject(By.res("org.oppia.android:id/submit_answer_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(FRACTION_INTERACTION_INCORRECT_ANSWER_FEEDBACK, feedback.text) + } + + @Test + fun testprototypeExploration_fractionSubmitCorrectAnswer_correctFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + device.findObject(UiSelector().text("CONTINUE")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/fraction_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val fractionInteractionView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/fraction_input_interaction_view" + ) + ) + fractionInteractionView.text = "1/2" + device.findObject(By.res("org.oppia.android:id/submit_answer_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(FRACTION_INTERACTION_CORRECT_ANSWER_FEEDBACK, feedback.text) + } + + @Test + fun testprototypeExploration_fractionSubmitAndContinue_nextInteractionIsDisplayed() { + NavigateToPrototypeExploration() + device.findObject(UiSelector().text("CONTINUE")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/fraction_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val fractionInteractionView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/fraction_input_interaction_view" + ) + ) + fractionInteractionView.text = "1/2" + device.findObject(By.res("$OPPIA_PACKAGE:id/submit_answer_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")), + TRANSITION_TIMEOUT + ) + val radioGroupContent = device.findObject(By.res("$OPPIA_PACKAGE:id/content_text_view")) + assertEquals(MULTIPLE_CHOICE_INTERACTION_1_CONTENT, radioGroupContent.text) + } + + @Test + fun testprototypeExplorationLandscape_fractionEnterInvalidCharacter_errorIsDisplayed() { + NavigateToPrototypeExploration() + device.findObject(UiSelector().text("CONTINUE")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/fraction_input_interaction_view")), + TRANSITION_TIMEOUT + ) + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/fraction_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val fractionInteractionView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/fraction_input_interaction_view" + ) + ) + fractionInteractionView.text = "o" + val inputError = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/fraction_input_error" + ) + ) + assertEquals(FRACTION_INTERACTION_INPUT_ERROR, inputError.text) + } + + @Test + fun testprototypeExplorationLandscape_fractionEnterInvalidCharacter_submitButtonIsDisabled() { + NavigateToPrototypeExploration() + device.findObject(UiSelector().text("CONTINUE")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/fraction_input_interaction_view")), + TRANSITION_TIMEOUT + ) + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/fraction_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val fractionInteractionView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/fraction_input_interaction_view" + ) + ) + fractionInteractionView.text = "o" + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + assertFalse(submitButton.isEnabled) + } + + @Test + fun testPrototypeExplorationLandscape_fractionEnterValidCharacter_submitButtonIsEnabled() { + NavigateToPrototypeExploration() + device.findObject(UiSelector().text("CONTINUE")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/fraction_input_interaction_view")), + TRANSITION_TIMEOUT + ) + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/fraction_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val fractionInteractionView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/fraction_input_interaction_view" + ) + ) + fractionInteractionView.text = "1" + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + assertTrue(submitButton.isEnabled) + } + + @Test + fun testPrototypeExpLandscape_fractionSubmitIncorrectAnswer_incorrectFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + device.findObject(UiSelector().text("CONTINUE")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/fraction_input_interaction_view")), + TRANSITION_TIMEOUT + ) + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/fraction_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val fractionInteractionView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/fraction_input_interaction_view" + ) + ) + fractionInteractionView.text = "1" + device.findObject(By.res("org.oppia.android:id/submit_answer_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(FRACTION_INTERACTION_INCORRECT_ANSWER_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExplorationLandscape_fractionSubmitCorrectAnswer_correctFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + device.findObject(UiSelector().text("CONTINUE")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/fraction_input_interaction_view")), + TRANSITION_TIMEOUT + ) + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/fraction_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val fractionInteractionView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/fraction_input_interaction_view" + ) + ) + fractionInteractionView.text = "1/2" + device.findObject(By.res("org.oppia.android:id/submit_answer_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(FRACTION_INTERACTION_CORRECT_ANSWER_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExplorationLandscape_fractionSubmitAndContinue_nextInteractionIsDisplayed() { + NavigateToPrototypeExploration() + device.findObject(UiSelector().text("CONTINUE")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/fraction_input_interaction_view")), + TRANSITION_TIMEOUT + ) + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/fraction_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val fractionInteractionView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/fraction_input_interaction_view" + ) + ) + fractionInteractionView.text = "1/2" + device.findObject(By.res("$OPPIA_PACKAGE:id/submit_answer_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")), + TRANSITION_TIMEOUT + ) + val radioGroupContent = device.findObject(By.res("$OPPIA_PACKAGE:id/content_text_view")) + assertEquals(MULTIPLE_CHOICE_INTERACTION_1_CONTENT, radioGroupContent.text) + } + + // TODO(#1737): Singleton class in domain to manage configuration changes + @Test + @Ignore("InputIntractions are not preserved on configuration change") + fun testPrototypeExploration_fractionEnterACharacter_inputIsPreservedOnConfigChange() { + NavigateToPrototypeExploration() + device.findObject(UiSelector().text("CONTINUE")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/fraction_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val fractionInteractionView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/fraction_input_interaction_view" + ) + ) + fractionInteractionView.text = "1" + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/fraction_input_interaction_view")), + TRANSITION_TIMEOUT + ) + assertEquals("1", fractionInteractionView.text) + } + + // TODO(#1737): Singleton class in domain to manage configuration changes + @Test + @Ignore("InputIntractions are not preserved on configuration change") + fun testPrototypeExploration_fractionEnterInvalidCharacter_errorIsPreservedOnConfigChange() { + NavigateToPrototypeExploration() + device.findObject(UiSelector().text("CONTINUE")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/fraction_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val fractionInteractionView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/fraction_input_interaction_view" + ) + ) + fractionInteractionView.text = "o" + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/fraction_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val inputError = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/fraction_input_error" + ) + ) + assertEquals(FRACTION_INTERACTION_INPUT_ERROR, inputError.text) + } + + @Test + fun testPrototypeExp_fractionEnterInvalidCharacter_errorIsDisappearedOnEnteringValidCharacter() { + NavigateToPrototypeExploration() + device.findObject(UiSelector().text("CONTINUE")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/fraction_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val fractionInteractionView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/fraction_input_interaction_view" + ) + ) + fractionInteractionView.text = "o" + val inputError = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/fraction_input_error" + ) + ) + assertEquals(FRACTION_INTERACTION_INPUT_ERROR, inputError.text) + fractionInteractionView.text = "" + fractionInteractionView.text = "1" + assertNull(device.findObject(By.res("$OPPIA_PACKAGE:id/fraction_input_error"))) + } + + @Test + fun testPrototypeExpLandscape_fractionEnterInvalidChar_errorIsDisappearedOnValidCharacter() { + NavigateToPrototypeExploration() + device.findObject(UiSelector().text("CONTINUE")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/fraction_input_interaction_view")), + TRANSITION_TIMEOUT + ) + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/fraction_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val fractionInteractionView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/fraction_input_interaction_view" + ) + ) + fractionInteractionView.text = "o" + val inputError = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/fraction_input_error" + ) + ) + assertEquals(FRACTION_INTERACTION_INPUT_ERROR, inputError.text) + fractionInteractionView.text = "" + fractionInteractionView.text = "1" + assertNull(device.findObject(By.res("$OPPIA_PACKAGE:id/fraction_input_error"))) + } + + @Test + fun testprototypeExp_fractionInputIncompleteFraction_incompleteErrorIsDisplayedSuccessfully() { + NavigateToPrototypeExploration() + device.findObject(UiSelector().text("CONTINUE")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/fraction_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val fractionInteractionView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/fraction_input_interaction_view" + ) + ) + fractionInteractionView.text = "1/" + device.findObject(UiSelector().text("SUBMIT")).click() + val inputError = device.findObject(By.res("$OPPIA_PACKAGE:id/fraction_input_error")) + assertEquals(FRACTION_INTERACTION_INCOMPLETE_INPUT_ERROR, inputError.text) + } + + @Test + fun testprototypeExpLand_fractionInputIncompleteFraction_incompleteErrorIsDisplayedSuccessfully() { // ktlint-disable max-line-length + NavigateToPrototypeExploration() + device.findObject(UiSelector().text("CONTINUE")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/fraction_input_interaction_view")), + TRANSITION_TIMEOUT + ) + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/fraction_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val fractionInteractionView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/fraction_input_interaction_view" + ) + ) + fractionInteractionView.text = "1/" + device.findObject(UiSelector().text("SUBMIT")).click() + val inputError = device.findObject(By.res("$OPPIA_PACKAGE:id/fraction_input_error")) + assertEquals(FRACTION_INTERACTION_INCOMPLETE_INPUT_ERROR, inputError.text) + } + + @Test + fun testPrototypeExploration_checkMultipleChoiceInput1_option1IsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteFractionInteraction() + val radioGroup = device.findObject( + By.res( + "org.oppia.android:id/selection_interaction_recyclerview" + ) + ) + val firstOption = radioGroup.children[0].children[1] + assertEquals(MULTIPLE_CHOICE_INTERACTION_1_OPTION_1, firstOption.text) + } + + @Test + fun testPrototypeExploration_checkMultipleChoiceInput1_option2IsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteFractionInteraction() + val radioGroup = device.findObject( + By.res( + "org.oppia.android:id/selection_interaction_recyclerview" + ) + ) + val secondOption = radioGroup.children[1].children[1] + assertEquals(MULTIPLE_CHOICE_INTERACTION_1_OPTION_2, secondOption.text) + } + + @Test + fun testPrototypeExploration_checkMultipleChoiceInput1_option3IsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteFractionInteraction() + val radioGroup = device.findObject( + By.res( + "org.oppia.android:id/selection_interaction_recyclerview" + ) + ) + val thirdOption = radioGroup.children[2].children[1] + assertEquals(MULTIPLE_CHOICE_INTERACTION_1_OPTION_3, thirdOption.text) + } + + @Test + fun testPrototypeExploration_selectOption1MultipleChoiceInput1_incorrectFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteFractionInteraction() + device.findObject(UiSelector().text(MULTIPLE_CHOICE_INTERACTION_1_OPTION_1)).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(MULTIPLE_CHOICE_INTERACTION_1_INCORRECT_ANS_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExploration_selectOption2MultipleChoiceInput1_incorrectFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteFractionInteraction() + device.findObject(UiSelector().text(MULTIPLE_CHOICE_INTERACTION_1_OPTION_2)).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(MULTIPLE_CHOICE_INTERACTION_1_INCORRECT_ANS_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExploration_selectOption3MultipleChoiceInput1_correctFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteFractionInteraction() + device.findObject(UiSelector().text(MULTIPLE_CHOICE_INTERACTION_1_OPTION_3)).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(MULTIPLE_CHOICE_INTERACTION_1_CORRECT_ANS_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExploration_multipleChoiceInput1Continue_nextInteractionIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteFractionInteraction() + device.findObject(UiSelector().text(MULTIPLE_CHOICE_INTERACTION_1_OPTION_3)).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")) + .click() + val radioGroupContent = device.findObject(By.res("$OPPIA_PACKAGE:id/content_text_view")) + assertEquals(MULTIPLE_CHOICE_INTERACTION_2_CONTENT, radioGroupContent.text) + } + + @Test + fun testPrototypeExpLandscape_selectOption1MultipleChoiceInput1_incorrectFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteFractionInteraction() + device.setOrientationRight() + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView(MULTIPLE_CHOICE_INTERACTION_1_OPTION_1) + device.findObject(UiSelector().text(MULTIPLE_CHOICE_INTERACTION_1_OPTION_1)).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(MULTIPLE_CHOICE_INTERACTION_1_INCORRECT_ANS_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExpLandscape_selectOption2MultipleChoiceInput1_incorrectFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteFractionInteraction() + device.setOrientationRight() + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView(MULTIPLE_CHOICE_INTERACTION_1_OPTION_2) + device.findObject(UiSelector().text(MULTIPLE_CHOICE_INTERACTION_1_OPTION_2)).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(MULTIPLE_CHOICE_INTERACTION_1_INCORRECT_ANS_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExpLandscape_selectOption3MultipleChoiceInput1_correctFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteFractionInteraction() + device.setOrientationRight() + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView(MULTIPLE_CHOICE_INTERACTION_1_OPTION_3) + device.findObject(UiSelector().text(MULTIPLE_CHOICE_INTERACTION_1_OPTION_3)).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(MULTIPLE_CHOICE_INTERACTION_1_CORRECT_ANS_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExpLandscape_multipleChoiceInput1Continue_nextInteractionIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteFractionInteraction() + device.setOrientationRight() + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView(MULTIPLE_CHOICE_INTERACTION_1_OPTION_3) + device.findObject(UiSelector().text(MULTIPLE_CHOICE_INTERACTION_1_OPTION_3)).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")) + .click() + val radioGroupContent = device.findObject(By.res("$OPPIA_PACKAGE:id/content_text_view")) + assertEquals(MULTIPLE_CHOICE_INTERACTION_2_CONTENT, radioGroupContent.text) + } + + @Test + fun testPrototypeExploration_checkMultipleChoiceInput2_option1IsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice1() + val radioGroup = device.findObject( + By.res( + "org.oppia.android:id/selection_interaction_recyclerview" + ) + ) + val firstOption = radioGroup.children[0].children[1] + assertEquals(MULTIPLE_CHOICE_INTERACTION_2_OPTION_1, firstOption.text) + } + + @Test + fun testPrototypeExploration_checkMultipleChoiceInput2_option2IsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice1() + val radioGroup = device.findObject( + By.res( + "org.oppia.android:id/selection_interaction_recyclerview" + ) + ) + val secondOption = radioGroup.children[1].children[1] + assertEquals(MULTIPLE_CHOICE_INTERACTION_2_OPTION_2, secondOption.text) + } + + @Test + fun testPrototypeExploration_checkMultipleChoiceInput2_option3IsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice1() + val radioGroup = device.findObject( + By.res( + "org.oppia.android:id/selection_interaction_recyclerview" + ) + ) + val thirdOption = radioGroup.children[2].children[1] + assertEquals(MULTIPLE_CHOICE_INTERACTION_2_OPTION_3, thirdOption.text) + } + + @Test + fun testPrototypeExploration_selectOption1MultipleChoiceInput2_correctFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice1() + device.findObject(UiSelector().text(MULTIPLE_CHOICE_INTERACTION_2_OPTION_1)).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(MULTIPLE_CHOICE_INTERACTION_2_CORRECT_ANS_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExploration_selectOption2MultipleChoiceInput2_incorrectFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice1() + device.findObject(UiSelector().text(MULTIPLE_CHOICE_INTERACTION_2_OPTION_2)).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(MULTIPLE_CHOICE_INTERACTION_2_INCORRECT_ANS_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExploration_selectOption3MultipleChoiceInput2_incorrectFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice1() + device.findObject(UiSelector().text(MULTIPLE_CHOICE_INTERACTION_2_OPTION_3)).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(MULTIPLE_CHOICE_INTERACTION_2_INCORRECT_ANS_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExploration_multipleChoiceInput2Continue_nextInteractionIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice1() + device.findObject(UiSelector().text(MULTIPLE_CHOICE_INTERACTION_2_OPTION_1)).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")) + .click() + val radioGroupContent = device.findObject(By.res("$OPPIA_PACKAGE:id/content_text_view")) + assertEquals(ITEM_SELECTION_INTERACTION_CONTENT, radioGroupContent.text) + } + + @Test + fun testPrototypeExpLandscape_selectOption1MultipleChoiceInput2_correctFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice1() + device.setOrientationRight() + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView(MULTIPLE_CHOICE_INTERACTION_2_OPTION_1) + device.findObject(UiSelector().text(MULTIPLE_CHOICE_INTERACTION_2_OPTION_1)).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(MULTIPLE_CHOICE_INTERACTION_2_CORRECT_ANS_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExpLandscape_selectOption2MultipleChoiceInput2_incorrectFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice1() + device.setOrientationRight() + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView(MULTIPLE_CHOICE_INTERACTION_2_OPTION_2) + device.findObject(UiSelector().text(MULTIPLE_CHOICE_INTERACTION_2_OPTION_2)).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(MULTIPLE_CHOICE_INTERACTION_2_INCORRECT_ANS_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExpLandscape_selectOption3MultipleChoiceInput2_incorrectFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice1() + device.setOrientationRight() + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView(MULTIPLE_CHOICE_INTERACTION_2_OPTION_3) + device.findObject(UiSelector().text(MULTIPLE_CHOICE_INTERACTION_2_OPTION_3)).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(MULTIPLE_CHOICE_INTERACTION_2_INCORRECT_ANS_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExpLandscape_multipleChoiceInput2Continue_nextInteractionIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice1() + device.setOrientationRight() + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView(MULTIPLE_CHOICE_INTERACTION_2_OPTION_1) + device.findObject(UiSelector().text(MULTIPLE_CHOICE_INTERACTION_2_OPTION_1)).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")) + .click() + val radioGroupContent = device.findObject(By.res("$OPPIA_PACKAGE:id/content_text_view")) + assertEquals(ITEM_SELECTION_INTERACTION_CONTENT, radioGroupContent.text) + } + + @Test + fun testPrototypeExploration_checkItemSelection_option1IsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice2() + val checkBoxGroup = device.findObject( + By.res( + "org.oppia.android:id/selection_interaction_recyclerview" + ) + ) + val firstOption = checkBoxGroup.children[0].children[1] + assertEquals(ITEM_SELECTION_INTERACTION_OPTION_1, firstOption.text) + } + + @Test + fun testPrototypeExploration_checkItemSelection_option2IsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice2() + val checkBoxGroup = device.findObject( + By.res( + "org.oppia.android:id/selection_interaction_recyclerview" + ) + ) + val secondOption = checkBoxGroup.children[1].children[1] + assertEquals(ITEM_SELECTION_INTERACTION_OPTION_2, secondOption.text) + } + + @Test + fun testPrototypeExploration_checkItemSelection_option3IsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice2() + val checkBoxGroup = device.findObject( + By.res( + "org.oppia.android:id/selection_interaction_recyclerview" + ) + ) + val thirdOption = checkBoxGroup.children[2].children[1] + assertEquals(ITEM_SELECTION_INTERACTION_OPTION_3, thirdOption.text) + } + + @Test + fun testPrototypeExploration_checkItemSelection_option4IsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice2() + val checkBoxGroup = device.findObject( + By.res( + "org.oppia.android:id/selection_interaction_recyclerview" + ) + ) + val fourthOption = checkBoxGroup.children[3].children[1] + assertEquals(ITEM_SELECTION_INTERACTION_OPTION_4, fourthOption.text) + } + + @Test + fun testPrototypeExploration_checkItemSelection_option5IsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice2() + val checkBoxGroup = device.findObject( + By.res( + "org.oppia.android:id/selection_interaction_recyclerview" + ) + ) + val fifthOption = checkBoxGroup.children[4].children[1] + assertEquals(ITEM_SELECTION_INTERACTION_OPTION_5, fifthOption.text) + } + + @Test + fun testPrototypeExploration_checkItemSelection_option6IsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice2() + val checkBoxGroup = device.findObject( + By.res( + "org.oppia.android:id/selection_interaction_recyclerview" + ) + ) + val sixthOption = checkBoxGroup.children[5].children[1] + assertEquals(ITEM_SELECTION_INTERACTION_OPTION_6, sixthOption.text) + } + + @Test + fun testPrototypeExploration_checkItemSelection_submitButtonIsDisabled() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice2() + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + assertFalse(submitButton.isEnabled) + } + + @Test + fun testPrototypeExploration_itemSelectionCheckOneOption_submitButtonIsEnabled() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice2() + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_1)).click() + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + assertTrue(submitButton.isEnabled) + } + + @Test + fun testPrototypeExploration_itemSelectionSubmitIncorrectAns_incorrectFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice2() + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_1)).click() + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + submitButton.click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(ITEM_SELECTION_INTERACTION_INCORRECT_ANS_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExp_itemSelectionSubmitIncorrectAnsWithSuggestion_suggestionFeedbackIsDisplayed() { // ktlint-disable max-line-length + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice2() + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_1)).click() + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_2)).click() + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + submitButton.click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(ITEM_SELECTION_INTERACTION_INCORRECT_ANS_FEEDBACK_SUGGESTION, feedback.text) + } + + @Test + fun testPrototypeExploration_itemSelectionSubmitCorrectAns_correctFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice2() + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_1)).click() + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_3)).click() + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_4)).click() + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + submitButton.click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(ITEM_SELECTION_INTERACTION_CORRECT_ANS_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExploration_itemSelectionContinue_nextInteractionIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice2() + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_1)).click() + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_3)).click() + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_4)).click() + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + submitButton.click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/numeric_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val numericInputContent = device.findObject(By.res("$OPPIA_PACKAGE:id/content_text_view")) + assertEquals(NUMERIC_INPUT_INTERACTION_CONTENT, numericInputContent.text) + } + + @Test + fun testPrototypeExploration_itemSelectionSelect4Options_fourthOptionIsUnchecked() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice2() + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_1)).click() + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_2)).click() + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_3)).click() + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_4)).click() + val checkBoxGroup = device.findObject( + By.res( + "org.oppia.android:id/selection_interaction_recyclerview" + ) + ) + val fourthOptionCheckBox = checkBoxGroup.children[3].children[0] + assertFalse(fourthOptionCheckBox.isChecked) + } + + @Test + fun testPrototypeExploration_itemSelectionClickOnOptionText_checkBoxIsChecked() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice2() + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_1)).click() + val checkBoxGroup = device.findObject( + By.res( + "org.oppia.android:id/selection_interaction_recyclerview" + ) + ) + val firstOptionCheckBox = checkBoxGroup.children[0].children[0] + assertTrue(firstOptionCheckBox.isChecked) + } + + @Test + fun testPrototypeExplorationLandscape_checkItemSelection_submitButtonIsDisabled() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice2() + device.setOrientationRight() + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView("SUBMIT") + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + assertFalse(submitButton.isEnabled) + } + + @Test + fun testPrototypeExplorationLandscape_itemSelectionCheckOneOption_submitButtonIsEnabled() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice2() + device.setOrientationRight() + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView(ITEM_SELECTION_INTERACTION_OPTION_1) + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_1)).click() + recyclerview.scrollTextIntoView("SUBMIT") + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + assertTrue(submitButton.isEnabled) + } + + @Test + fun testPrototypeExpLandscape_itemSelectionSubmitIncorrectAns_incorrectFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice2() + device.setOrientationRight() + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView(ITEM_SELECTION_INTERACTION_OPTION_1) + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_1)).click() + recyclerview.scrollTextIntoView("SUBMIT") + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + submitButton.click() + recyclerview.scrollTextIntoView(ITEM_SELECTION_INTERACTION_INCORRECT_ANS_FEEDBACK) + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(ITEM_SELECTION_INTERACTION_INCORRECT_ANS_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExpLand_itemSelectionSubmitIncorrectAnsWithSuggestion_suggestionFeedbackIsDisplayed() { // ktlint-disable max-line-length + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice2() + device.setOrientationRight() + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView(ITEM_SELECTION_INTERACTION_OPTION_1) + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_1)).click() + recyclerview.scrollTextIntoView(ITEM_SELECTION_INTERACTION_OPTION_2) + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_2)).click() + recyclerview.scrollTextIntoView("SUBMIT") + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + submitButton.click() + recyclerview.scrollTextIntoView(ITEM_SELECTION_INTERACTION_INCORRECT_ANS_FEEDBACK_SUGGESTION) + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(ITEM_SELECTION_INTERACTION_INCORRECT_ANS_FEEDBACK_SUGGESTION, feedback.text) + } + + @Test + fun testPrototypeExpLand_itemSelectionSubmitCorrectAnsWithSuggestion_correctFeedbackIsDisplayed() { // ktlint-disable max-line-length + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice2() + device.setOrientationRight() + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView(ITEM_SELECTION_INTERACTION_OPTION_1) + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_1)).click() + recyclerview.scrollTextIntoView(ITEM_SELECTION_INTERACTION_OPTION_3) + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_3)).click() + recyclerview.scrollTextIntoView(ITEM_SELECTION_INTERACTION_OPTION_4) + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_4)).click() + recyclerview.scrollTextIntoView("SUBMIT") + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + submitButton.click() + recyclerview.scrollTextIntoView(ITEM_SELECTION_INTERACTION_CORRECT_ANS_FEEDBACK) + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(ITEM_SELECTION_INTERACTION_CORRECT_ANS_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExplorationLandscape_itemSelectionSelect4Options_fourthOptionIsUnchecked() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice2() + device.setOrientationRight() + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView(ITEM_SELECTION_INTERACTION_OPTION_1) + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_1)).click() + recyclerview.scrollTextIntoView(ITEM_SELECTION_INTERACTION_OPTION_2) + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_2)).click() + recyclerview.scrollTextIntoView(ITEM_SELECTION_INTERACTION_OPTION_3) + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_3)).click() + recyclerview.scrollTextIntoView(ITEM_SELECTION_INTERACTION_OPTION_4) + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_4)).click() + val checkBoxGroup = device.findObject( + By.res( + "org.oppia.android:id/selection_interaction_recyclerview" + ) + ) + val fourthOptionCheckBox = checkBoxGroup.children[3].children[0] + assertFalse(fourthOptionCheckBox.isChecked) + } + + @Test + fun testPrototypeExplorationLandscape_itemSelectionClickOnOptionText_checkBoxIsChecked() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice2() + device.setOrientationRight() + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView(ITEM_SELECTION_INTERACTION_OPTION_1) + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_1)).click() + val checkBoxGroup = device.findObject( + By.res( + "org.oppia.android:id/selection_interaction_recyclerview" + ) + ) + val firstOptionCheckBox = checkBoxGroup.children[0].children[0] + assertTrue(firstOptionCheckBox.isChecked) + } + + @Test + fun testPrototypeExplorationLandscape_itemSelectionContinue_nextInteractionIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice2() + device.setOrientationRight() + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView(ITEM_SELECTION_INTERACTION_OPTION_1) + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_1)).click() + recyclerview.scrollTextIntoView(ITEM_SELECTION_INTERACTION_OPTION_3) + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_3)).click() + recyclerview.scrollTextIntoView(ITEM_SELECTION_INTERACTION_OPTION_4) + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_4)).click() + recyclerview.scrollTextIntoView("SUBMIT") + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + submitButton.click() + recyclerview.scrollTextIntoView("CONTINUE") + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/numeric_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val numericInputContent = device.findObject(By.res("$OPPIA_PACKAGE:id/content_text_view")) + assertEquals(NUMERIC_INPUT_INTERACTION_CONTENT, numericInputContent.text) + } + + // TODO(#1737): Singleton class in domain to manage configuration changes + @Test + @Ignore("InputIntractions are not preserved on configuration change") + fun testPrototypeExploration_itemSelectionSelectOption_selectedOptionPreservedOnConfigChange() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice2() + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_1)).click() + device.setOrientationRight() + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView(ITEM_SELECTION_INTERACTION_OPTION_1) + val checkBoxGroup = device.findObject( + By.res( + "org.oppia.android:id/selection_interaction_recyclerview" + ) + ) + val firstOptionCheckBox = checkBoxGroup.children[0].children[0] + assertTrue(firstOptionCheckBox.isChecked) + } + + // TODO(#3598): ItemSelectionInput submit button is enabled after config change + @Test + @Ignore("Submit button is enabled when no option is selected") + fun testPrototypeExploration_itemSelectionSelectOption_submitButtonIsEnabled() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteMultipleChoice2() + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_1)).click() + device.setOrientationRight() + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView("SUBMIT") + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + assertTrue(submitButton.isEnabled) + } + + @Test + fun testPrototypeExploration_checkNumericInput_inputHintIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteItemSelection() + val numericInputView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/numeric_input_interaction_view" + ) + ) + assertEquals(NUMERIC_INPUT_INTERACTION_VIEW_HINT, numericInputView.text) + } + + @Test + fun testPrototypeExploration_numericInputEnterPeriod_inputErrorIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteItemSelection() + val numericInputView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/numeric_input_interaction_view" + ) + ) + numericInputView.text = "." + val stateFragment = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/state_recycler_view" + ) + ) + val inputErrorView = stateFragment.children[1].children[1] + assertEquals(NUMERIC_INPUT_INTERACTION_PERIOD_INPUT_ERROR, inputErrorView.text) + } + + @Test + fun testPrototypeExploration_numericInputEnterMinus_inputErrorIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteItemSelection() + val numericInputView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/numeric_input_interaction_view" + ) + ) + numericInputView.text = "-" + device.findObject(UiSelector().text("SUBMIT")).click() + val stateFragment = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/state_recycler_view" + ) + ) + val inputErrorView = stateFragment.children[1].children[1] + assertEquals(NUMERIC_INPUT_INTERACTION_INVALID_INPUT_ERROR, inputErrorView.text) + } + + @Test + fun testPrototypeExploration_numericInputEnterLesserAns_lesserFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteItemSelection() + val numericInputView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/numeric_input_interaction_view" + ) + ) + numericInputView.text = "120" + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(NUMERIC_INPUT_INTERACTION_LESSER_INPUT_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExploration_numericInputEnterGreaterAns_greaterFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteItemSelection() + val numericInputView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/numeric_input_interaction_view" + ) + ) + numericInputView.text = "122" + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(NUMERIC_INPUT_INTERACTION_GREATER_INPUT_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExploration_numericInputEnterCorrectAns_correctFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteItemSelection() + val numericInputView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/numeric_input_interaction_view" + ) + ) + numericInputView.text = "121" + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(NUMERIC_INPUT_INTERACTION_CORRECT_INPUT_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExploration_numericInputContinue_nextInteractionIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteItemSelection() + val numericInputView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/numeric_input_interaction_view" + ) + ) + numericInputView.text = "121" + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/ratio_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val ratioInputContent = device.findObject(By.res("$OPPIA_PACKAGE:id/content_text_view")) + assertEquals(RATIO_INPUT_INTERACTION_CONTENT, ratioInputContent.text) + } + + @Test + fun testPrototypeExplorationLandscape_numericInputEnterPeriod_inputErrorIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteItemSelection() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/numeric_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val numericInputView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/numeric_input_interaction_view" + ) + ) + numericInputView.text = "." + val stateFragment = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/state_recycler_view" + ) + ) + val inputErrorView = stateFragment.children[1].children[1] + assertEquals(NUMERIC_INPUT_INTERACTION_PERIOD_INPUT_ERROR, inputErrorView.text) + } + + @Test + fun testPrototypeExplorationLandscape_numericInputEnterMinus_inputErrorIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteItemSelection() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/numeric_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val numericInputView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/numeric_input_interaction_view" + ) + ) + numericInputView.text = "-" + device.findObject(UiSelector().text("SUBMIT")).click() + val stateFragment = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/state_recycler_view" + ) + ) + val inputErrorView = stateFragment.children[1].children[1] + assertEquals(NUMERIC_INPUT_INTERACTION_INVALID_INPUT_ERROR, inputErrorView.text) + } + + @Test + fun testPrototypeExplorationLandscape_numericInputEnterLesserAns_lesserFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteItemSelection() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/numeric_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val numericInputView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/numeric_input_interaction_view" + ) + ) + numericInputView.text = "120" + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(NUMERIC_INPUT_INTERACTION_LESSER_INPUT_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExplorationLandscape_numericInputEnterGreaterAns_greaterFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteItemSelection() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/numeric_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val numericInputView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/numeric_input_interaction_view" + ) + ) + numericInputView.text = "122" + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(NUMERIC_INPUT_INTERACTION_GREATER_INPUT_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExplorationLandscape_numericInputEnterCorrectAns_correctFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteItemSelection() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/numeric_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val numericInputView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/numeric_input_interaction_view" + ) + ) + numericInputView.text = "121" + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(NUMERIC_INPUT_INTERACTION_CORRECT_INPUT_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExplorationLandscape_numericInputContinue_nextInteractionIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteItemSelection() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/numeric_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val numericInputView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/numeric_input_interaction_view" + ) + ) + numericInputView.text = "121" + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/ratio_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val ratioInputContent = device.findObject(By.res("$OPPIA_PACKAGE:id/content_text_view")) + assertEquals(RATIO_INPUT_INTERACTION_CONTENT, ratioInputContent.text) + } + + @Test + fun testPrototypeExploration_checkNumericInput_submitButtonIsDisabled() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteItemSelection() + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + assertFalse(submitButton.isEnabled) + } + + @Test + fun testPrototypeExploration_numericInputEnterPeriod_submitButtonIsDisabled() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteItemSelection() + val numericInputView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/numeric_input_interaction_view" + ) + ) + numericInputView.text = "." + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + assertFalse(submitButton.isEnabled) + } + + @Test + fun testPrototypeExploration_numericInputEnterDigit_submitButtonIsEnabled() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteItemSelection() + val numericInputView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/numeric_input_interaction_view" + ) + ) + numericInputView.text = "1" + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + assertTrue(submitButton.isEnabled) + } + + @Test + fun testPrototypeExplorationLandscape_checkNumericInput_submitButtonIsDisabled() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteItemSelection() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/numeric_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + assertFalse(submitButton.isEnabled) + } + + @Test + fun testPrototypeExplorationLandscape_numericInputEnterPeriod_submitButtonIsDisabled() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteItemSelection() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/numeric_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val numericInputView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/numeric_input_interaction_view" + ) + ) + numericInputView.text = "." + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + assertFalse(submitButton.isEnabled) + } + + @Test + fun testPrototypeExplorationLandscape_numericInputEnterDigit_submitButtonIsEnabled() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteItemSelection() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/numeric_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val numericInputView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/numeric_input_interaction_view" + ) + ) + numericInputView.text = "1" + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + assertTrue(submitButton.isEnabled) + } + + // TODO(#1737): Singleton class in domain to manage configuration changes + @Test + @Ignore("InputIntractions are not preserved on configuration change") + fun testPrototypeExploration_numericInputEnterDigit_inputIsPreservedOnConfigChange() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteItemSelection() + val numericInputView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/numeric_input_interaction_view" + ) + ) + numericInputView.text = "1" + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/numeric_input_interaction_view")), + TRANSITION_TIMEOUT + ) + assertEquals("1", numericInputView.text) + } + + // TODO(#1737): Singleton class in domain to manage configuration changes + @Test + @Ignore("InputIntractions are not preserved on configuration change") + fun testPrototypeExploration_numericInputEnterPeriod_errorIsPreservedOnConfigChange() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteItemSelection() + val numericInputView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/numeric_input_interaction_view" + ) + ) + numericInputView.text = "." + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/numeric_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val stateFragment = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/state_recycler_view" + ) + ) + val inputErrorView = stateFragment.children[1].children[1] + assertEquals(NUMERIC_INPUT_INTERACTION_PERIOD_INPUT_ERROR, inputErrorView.text) + } + + @Test + fun testPrototypeExp_numericInputEnterPeriod_errorIsDisappearedOnEnteringValidCharacter() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteItemSelection() + val numericInputView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/numeric_input_interaction_view" + ) + ) + numericInputView.text = "." + numericInputView.text = "" + numericInputView.text = "1" + val stateFragment = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/state_recycler_view" + ) + ) + assertEquals(1, stateFragment.children[1].childCount) + } + + @Test + fun testPrototypeExploration_checkRatioInput_hintIsDisplaed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteNumericInputInteraction() + val ratioInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_interaction_view" + ) + ) + assertEquals(RATIO_INPUT_INTERACTION_VIEW_HINT, ratioInputInteraction.text) + } + + @Test + fun testPrototypeExploration_checkRatioInputIncompleteRatio_incompleteErrorIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteNumericInputInteraction() + val ratioInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_interaction_view" + ) + ) + ratioInputInteraction.text = "4:" + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/ratio_input_error")), + TRANSITION_TIMEOUT + ) + val inputError = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_error" + ) + ) + assertEquals(RATIO_INPUT_INTERACTION_INCOMPLETE_ANS_ERROR, inputError.text) + } + + @Test + fun testPrototypeExploration_checkRatioInputInvalidCharacter_invalidErrorIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteNumericInputInteraction() + val ratioInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_interaction_view" + ) + ) + ratioInputInteraction.text = "o" + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/ratio_input_error")), + TRANSITION_TIMEOUT + ) + val inputError = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_error" + ) + ) + assertEquals(RATIO_INPUT_INTERACTION_INVALID_ANS_ERROR, inputError.text) + } + + @Test + fun testPrototypeExploration_checkRatioInputDoubleColon_doubleColonErrorIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteNumericInputInteraction() + val ratioInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_interaction_view" + ) + ) + ratioInputInteraction.text = "1::" + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/ratio_input_error")), + TRANSITION_TIMEOUT + ) + val inputError = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_error" + ) + ) + assertEquals(RATIO_INPUT_INTERACTION_DOUBLE_COLON_ERROR, inputError.text) + } + + @Test + fun testPrototypeExploration_checkRatioInputSubmitIncorrectAns_incorrectFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteNumericInputInteraction() + val ratioInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_interaction_view" + ) + ) + ratioInputInteraction.text = "4:6" + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(RATIO_INPUT_INTERACTION_INCORRECT_ANS_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExploration_checkRatioInputSubmitCorrectAns_correctFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteNumericInputInteraction() + val ratioInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_interaction_view" + ) + ) + ratioInputInteraction.text = "4:5" + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(RATIO_INPUT_INTERACTION_CORRECT_ANS_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExploration_checkRatioInputContinue_nextInteractionIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteNumericInputInteraction() + val ratioInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_interaction_view" + ) + ) + ratioInputInteraction.text = "4:5" + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/text_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val ratioInputContent = device.findObject(By.res("$OPPIA_PACKAGE:id/content_text_view")) + assertEquals(TEXT_INPUT_INTERACTION_CONTENT, ratioInputContent.text) + } + + @Test + fun testPrototypeExploration_checkRatioInput_submitButtonIsDisabled() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteNumericInputInteraction() + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + assertFalse(submitButton.isEnabled) + } + + @Test + fun testPrototypeExploration_ratioInputValidNumber_submitButtonIsEnabled() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteNumericInputInteraction() + val ratioInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_interaction_view" + ) + ) + ratioInputInteraction.text = "1:3" + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + assertTrue(submitButton.isEnabled) + } + + @Test + fun testPrototypeExploration_ratioInputInvalidCharacter_submitButtonIsDisabled() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteNumericInputInteraction() + val ratioInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_interaction_view" + ) + ) + ratioInputInteraction.text = "o" + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + assertFalse(submitButton.isEnabled) + } + + @Test + fun testPrototypeExploration_ratioInputInvalidCharacter_errorDisabledOnValidCharacter() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteNumericInputInteraction() + val ratioInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_interaction_view" + ) + ) + ratioInputInteraction.text = "o" + ratioInputInteraction.text = "" + ratioInputInteraction.text = "1" + val inputError = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_error" + ) + ) + assertNull(inputError) + } + + @Test + fun testPrototypeExplorationLandScape_checkRatioInputInvalidCharacter_invalidErrorIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteNumericInputInteraction() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/ratio_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val ratioInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_interaction_view" + ) + ) + ratioInputInteraction.text = "o" + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/ratio_input_error")), + TRANSITION_TIMEOUT + ) + val inputError = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_error" + ) + ) + assertEquals(RATIO_INPUT_INTERACTION_INVALID_ANS_ERROR, inputError.text) + } + + @Test + fun testPrototypeExplorationLandscape_checkRatioInputDoubleColon_doubleColonErrorIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteNumericInputInteraction() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/ratio_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val ratioInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_interaction_view" + ) + ) + ratioInputInteraction.text = "1::" + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/ratio_input_error")), + TRANSITION_TIMEOUT + ) + val inputError = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_error" + ) + ) + assertEquals(RATIO_INPUT_INTERACTION_DOUBLE_COLON_ERROR, inputError.text) + } + + @Test + fun testPrototypeExpLandscape_checkRatioInputSubmitIncorrectAns_incorrectFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteNumericInputInteraction() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/ratio_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val ratioInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_interaction_view" + ) + ) + ratioInputInteraction.text = "4:6" + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(RATIO_INPUT_INTERACTION_INCORRECT_ANS_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExpLandscape_checkRatioInputSubmitCorrectAns_correctFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteNumericInputInteraction() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/ratio_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val ratioInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_interaction_view" + ) + ) + ratioInputInteraction.text = "4:5" + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(RATIO_INPUT_INTERACTION_CORRECT_ANS_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExplorationLandscape_checkRatioInputContinue_nextInteractionIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteNumericInputInteraction() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/ratio_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val ratioInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_interaction_view" + ) + ) + ratioInputInteraction.text = "4:5" + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/text_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val ratioInputContent = device.findObject(By.res("$OPPIA_PACKAGE:id/content_text_view")) + assertEquals(TEXT_INPUT_INTERACTION_CONTENT, ratioInputContent.text) + } + + @Test + fun testPrototypeExplorationLandscape_checkRatioInput_submitButtonIsDisabled() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteNumericInputInteraction() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/ratio_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + assertFalse(submitButton.isEnabled) + } + + @Test + fun testPrototypeExplorationLandscape_ratioInputValidNumber_submitButtonIsEnabled() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteNumericInputInteraction() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/ratio_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val ratioInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_interaction_view" + ) + ) + ratioInputInteraction.text = "1:3" + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + assertTrue(submitButton.isEnabled) + } + + @Test + fun testPrototypeExplorationLandscape_ratioInputInvalidCharacter_submitButtonIsDisabled() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteNumericInputInteraction() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/ratio_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val ratioInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_interaction_view" + ) + ) + ratioInputInteraction.text = "o" + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + assertFalse(submitButton.isEnabled) + } + + @Test + fun testPrototypeExplorationLandscape_ratioInputInvalidCharacter_errorDisabledOnValidCharacter() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteNumericInputInteraction() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/ratio_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val ratioInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_interaction_view" + ) + ) + ratioInputInteraction.text = "o" + ratioInputInteraction.text = "" + ratioInputInteraction.text = "1" + val inputError = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_error" + ) + ) + assertNull(inputError) + } + + // TODO(#1737): Singleton class in domain to manage configuration changes + @Test + @Ignore("InputIntractions are not preserved on configuration change") + fun testPrototypeExploration_ratioInputCharacter_characterIsPreservedOnConfigChange() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteNumericInputInteraction() + val ratioInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_interaction_view" + ) + ) + ratioInputInteraction.text = "1" + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/ratio_input_interaction_view")), + TRANSITION_TIMEOUT + ) + assertEquals("1", ratioInputInteraction.text) + } + + // TODO(#1737): Singleton class in domain to manage configuration changes + @Test + @Ignore("InputIntractions are not preserved on configuration change") + fun testPrototypeExploration_ratioInputInvalidCharacter_invalidErrorIsPreservedOnConfigChange() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteNumericInputInteraction() + val ratioInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_interaction_view" + ) + ) + ratioInputInteraction.text = "*" + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/ratio_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val inputError = device.findObject(By.res("$OPPIA_PACKAGE:id/ratio_input_error")) + assertEquals(RATIO_INPUT_INTERACTION_INVALID_ANS_ERROR, inputError.text) + } + + @Test + fun testPrototypeExp_ratioInputIncompleteRatio_incompleteErrorIsPreservedOnConfigChange() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteNumericInputInteraction() + val ratioInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_interaction_view" + ) + ) + ratioInputInteraction.text = "1:" + device.findObject(UiSelector().text("SUBMIT")).click() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/ratio_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val inputError = device.findObject(By.res("$OPPIA_PACKAGE:id/ratio_input_error")) + assertEquals(RATIO_INPUT_INTERACTION_INCOMPLETE_ANS_ERROR, inputError.text) + } + + // TODO(#1737): Singleton class in domain to manage configuration changes + @Test + @Ignore("InputIntractions are not preserved on configuration change") + fun testPrototypeExploration_ratioInputDoubleColon_doubleColonErrorIsPreservedOnConfigChange() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteNumericInputInteraction() + val ratioInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_interaction_view" + ) + ) + ratioInputInteraction.text = "*" + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/ratio_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val inputError = device.findObject(By.res("$OPPIA_PACKAGE:id/ratio_input_error")) + assertEquals(RATIO_INPUT_INTERACTION_DOUBLE_COLON_ERROR, inputError.text) + } + + // TODO(#1737): Singleton class in domain to manage configuration changes + @Test + @Ignore("InputIntractions are not preserved on configuration change") + fun testPrototypeExploration_ratioInputACharacter_submitButtonIsPreservedOnConfigChange() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteNumericInputInteraction() + val ratioInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_interaction_view" + ) + ) + ratioInputInteraction.text = "1" + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/ratio_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + assertTrue(submitButton.isEnabled) + } + + @Test + fun testPrototypeExploration_checkTextInput_hintIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteRatioInputInteraction() + val textInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/text_input_interaction_view" + ) + ) + assertEquals(TEXT_INPUT_INTERACTION_VIEW_HINT, textInputInteraction.text) + } + + @Test + fun testPrototypeExploration_checkTextInput_submitButtonIsDisabled() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteRatioInputInteraction() + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + assertFalse(submitButton.isEnabled) + } + + @Test + fun testPrototypeExploration_textInputCharacter_submitButtonIsEnabled() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteRatioInputInteraction() + val textInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/text_input_interaction_view" + ) + ) + textInputInteraction.text = "o" + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + assertTrue(submitButton.isEnabled) + } + + @Test + fun testPrototypeExploration_textInputSubmitIncorrectAns_incorrectFeedbackIsDislayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteRatioInputInteraction() + val textInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/text_input_interaction_view" + ) + ) + textInputInteraction.text = "o" + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(TEXT_INPUT_INTERACTION_INCORRECT_ANS_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExploration_textInputSubmitCorrectAns_correctFeedbackIsDislayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteRatioInputInteraction() + val textInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/text_input_interaction_view" + ) + ) + textInputInteraction.text = "finnish" + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(TEXT_INPUT_INTERACTION_CORRECT_ANS_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExplorationLandscape_checkTextInput_hintIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteRatioInputInteraction() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/text_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val textInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/text_input_interaction_view" + ) + ) + assertEquals(TEXT_INPUT_INTERACTION_VIEW_HINT, textInputInteraction.text) + } + + @Test + fun testPrototypeExplorationLandscape_checkTextInput_submitButtonIsDisabled() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteRatioInputInteraction() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/text_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + assertFalse(submitButton.isEnabled) + } + + @Test + fun testPrototypeExplorationLandScape_textInputCharacter_submitButtonIsEnabled() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteRatioInputInteraction() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/text_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val textInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/text_input_interaction_view" + ) + ) + textInputInteraction.text = "o" + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + assertTrue(submitButton.isEnabled) + } + + @Test + fun testPrototypeExplorationLandscape_textInputSubmitIncorrectAns_incorrectFeedbackIsDislayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteRatioInputInteraction() + val textInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/text_input_interaction_view" + ) + ) + textInputInteraction.text = "o" + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(TEXT_INPUT_INTERACTION_INCORRECT_ANS_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExplorationLandscape_textInputSubmitCorrectAns_correctFeedbackIsDislayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteRatioInputInteraction() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/text_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val textInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/text_input_interaction_view" + ) + ) + textInputInteraction.text = "finnish" + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(TEXT_INPUT_INTERACTION_CORRECT_ANS_FEEDBACK, feedback.text) + } + + // TODO(#1737): Singleton class in domain to manage configuration changes + @Test + @Ignore("InputIntractions are not preserved on configuration change") + fun testPrototypeExploration_textInputCharacter_inputIsPreservedOnConfigChange() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteRatioInputInteraction() + val textInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/text_input_interaction_view" + ) + ) + textInputInteraction.text = "o" + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/text_input_interaction_view")), + TRANSITION_TIMEOUT + ) + assertEquals("0", textInputInteraction.text) + } + + @Test + fun testPrototypeExploration_textInputContinue_nextInteractionIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteRatioInputInteraction() + val textInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/text_input_interaction_view" + ) + ) + textInputInteraction.text = "finnish" + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view")), + TRANSITION_TIMEOUT + ) + val dragAndDropContent = device.findObject(By.res("$OPPIA_PACKAGE:id/content_text_view")) + assertEquals(DRAG_AND_DROP_INTERACTION_CONTENT, dragAndDropContent.text) + } + + @Test + fun testPrototypeExplorationLandscape_textInputContinue_nextInteractionIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteRatioInputInteraction() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/text_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val textInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/text_input_interaction_view" + ) + ) + textInputInteraction.text = "finnish" + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view")), + TRANSITION_TIMEOUT + ) + val dragAndDropContent = device.findObject(By.res("$OPPIA_PACKAGE:id/content_text_view")) + assertEquals(DRAG_AND_DROP_INTERACTION_CONTENT, dragAndDropContent.text) + } + + @Test + fun testPrototypeExploration_checkDragAndDrop_option1IsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteTextInputInteraction() + val dragAndDropContainer = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view" + ) + ) + val firstItem = dragAndDropContainer.children[0] + val firstItemTextView = firstItem.children[0].children[1].children[0] + assertEquals(DRAG_AND_DROP_INTERACTION_OPTION_1, firstItemTextView.text) + } + + @Test + fun testPrototypeExploration_checkDragAndDrop_option2IsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteTextInputInteraction() + val dragAndDropContainer = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view" + ) + ) + val secondItem = dragAndDropContainer.children[1] + val secondItemTextView = secondItem.children[0].children[1].children[0] + assertEquals(DRAG_AND_DROP_INTERACTION_OPTION_2, secondItemTextView.text) + } + + @Test + fun testPrototypeExploration_checkDragAndDrop_option3IsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteTextInputInteraction() + val dragAndDropContainer = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view" + ) + ) + val thirdItem = dragAndDropContainer.children[2] + val thirdItemTextView = thirdItem.children[0].children[1].children[0] + assertEquals(DRAG_AND_DROP_INTERACTION_OPTION_3, thirdItemTextView.text) + } + + @Test + fun testPrototypeExploration_checkDragAndDrop_option4IsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteTextInputInteraction() + val dragAndDropContainer = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view" + ) + ) + val fourthItem = dragAndDropContainer.children[3] + val fourthItemTextView = fourthItem.children[0].children[1].children[0] + assertEquals(DRAG_AND_DROP_INTERACTION_OPTION_4, fourthItemTextView.text) + } + + @Test + fun testPrototypeExploration_checkDragAndDrop_firstItemMoveUpButtonIsDisabled() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteTextInputInteraction() + val dragAndDropContainer = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view" + ) + ) + val firstItem = dragAndDropContainer.children[0] + val firstItemMoveUpButton = firstItem.children[0].children[0].children[0] + assertFalse(firstItemMoveUpButton.isEnabled) + } + + @Test + fun testPrototypeExploration_checkDragAndDrop_lastItemMoveDownButtonIsDisabled() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteTextInputInteraction() + val dragAndDropContainer = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view" + ) + ) + val lastItem = dragAndDropContainer.children[3] + val lastItemMoveUpButton = lastItem.children[0].children[0].children[1] + assertFalse(lastItemMoveUpButton.isEnabled) + } + + @Test + fun testPrototypeExploration_dragAndDropSubmitWrongArrangement_incorrectFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteTextInputInteraction() + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(DRAG_AND_DROP_INTERACTION_INCORRECT_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExp_dragAndDropSubmitCorrectArrangmentByDrag_correctFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteTextInputInteraction() + val init_position = + device.findObject(UiSelector().text(DRAG_AND_DROP_INTERACTION_OPTION_1)) + val des_position = + device.findObject(UiSelector().text("SUBMIT")) + init_position.dragTo(des_position, 300) + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(DRAG_AND_DROP_INTERACTION_CORRECT_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExp_dragAndDropSubmitCorrectArrangmentByButtons_correctFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteTextInputInteraction() + device.findObject(UiSelector().description("Move item down to 2")).click() + device.findObject(UiSelector().description("Move item down to 3")).click() + device.findObject(UiSelector().description("Move item down to 4")).click() + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(DRAG_AND_DROP_INTERACTION_CORRECT_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExplorationLandscape_checkDragAndDrop_firstItemMoveUpButtonIsDisabled() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteTextInputInteraction() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view")), + TRANSITION_TIMEOUT + ) + val dragAndDropContainer = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view" + ) + ) + val firstItem = dragAndDropContainer.children[0] + val firstItemMoveUpButton = firstItem.children[0].children[0].children[0] + assertFalse(firstItemMoveUpButton.isEnabled) + } + + @Test + fun testPrototypeExplorationLandscape_checkDragAndDrop_lastItemMoveDownButtonIsDisabled() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteTextInputInteraction() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view")), + TRANSITION_TIMEOUT + ) + val dragAndDropContainer = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view" + ) + ) + val lastItem = dragAndDropContainer.children[3] + val lastItemMoveUpButton = lastItem.children[0].children[0].children[1] + assertFalse(lastItemMoveUpButton.isEnabled) + } + + @Test + fun testPrototypeExpLand_dragAndDropSubmitWrongArrangement_incorrectFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteTextInputInteraction() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view")), + TRANSITION_TIMEOUT + ) + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView("SUBMIT") + device.findObject(UiSelector().text("SUBMIT")).click() + recyclerview.scrollBackward(100) + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(DRAG_AND_DROP_INTERACTION_INCORRECT_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExpLand_dragAndDropSubmitCorrectArrangmentByDrag_correctFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteTextInputInteraction() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view")), + TRANSITION_TIMEOUT + ) + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + val init_position = + device.findObject(UiSelector().text(DRAG_AND_DROP_INTERACTION_OPTION_1)) + val dest_position1 = + device.findObject(UiSelector().text(DRAG_AND_DROP_INTERACTION_OPTION_4)) + init_position.dragTo(dest_position1, 300) + recyclerview.scrollTextIntoView("SUBMIT") + val dest_position2 = + device.findObject(UiSelector().text("SUBMIT")) + init_position.dragTo(dest_position2, 300) + device.findObject(UiSelector().text("SUBMIT")).click() + recyclerview.scrollBackward(100) + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(DRAG_AND_DROP_INTERACTION_CORRECT_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExpLand_dragAndDropSubmitCorrectArrangmentByButtons_correctFeedbackIsDisplayed() { // ktlint-disable max-line-length + NavigateToPrototypeExploration() + PrototypeExplorationCompleteTextInputInteraction() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view")), + TRANSITION_TIMEOUT + ) + device.findObject(UiSelector().description("Move item down to 2")).click() + device.findObject(UiSelector().description("Move item down to 3")).click() + device.findObject(UiSelector().description("Move item down to 4")).click() + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView("SUBMIT") + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(DRAG_AND_DROP_INTERACTION_CORRECT_FEEDBACK, feedback.text) + } + + // TODO(#1737): Singleton class in domain to manage configuration changes + @Test + @Ignore("InputIntractions are not preserved on configuration change") + fun testPrototypeExploration_dragAndDropChangeArrangment_arrangementIsPreservedOnConfigChange() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteTextInputInteraction() + device.findObject(UiSelector().description("Move item down to 2")).click() + device.findObject(UiSelector().description("Move item down to 3")).click() + device.findObject(UiSelector().description("Move item down to 4")).click() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view")), + TRANSITION_TIMEOUT + ) + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollIntoView( + UiSelector().resourceId( + "$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view" + ) + ) + val dragAndDropContainer = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view" + ) + ) + val firstItem = dragAndDropContainer.children[0] + val firstItemTextView = firstItem.children[0].children[1].children[0] + assertEquals(DRAG_AND_DROP_INTERACTION_OPTION_2, firstItemTextView.text) + } + + @Test + fun testPrototypeExploration_dragAndDropContine_nextInteractionIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteTextInputInteraction() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view")), + TRANSITION_TIMEOUT + ) + device.findObject(UiSelector().description("Move item down to 2")).click() + device.findObject(UiSelector().description("Move item down to 3")).click() + device.findObject(UiSelector().description("Move item down to 4")).click() + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView("SUBMIT") + device.findObject(UiSelector().text("SUBMIT")).click() + recyclerview.scrollToEnd(2) + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view")), + TRANSITION_TIMEOUT + ) + val dragDropMergeContent = device.findObject(By.res("$OPPIA_PACKAGE:id/content_text_view")) + assertEquals(DRAG_DROP_MERGE_INTERACTION_CONTENT, dragDropMergeContent.text) + } + + @Test + fun testPrototypeExplorationLandscape_dragAndDropContine_nextInteractionIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteTextInputInteraction() + device.findObject(UiSelector().description("Move item down to 2")).click() + device.findObject(UiSelector().description("Move item down to 3")).click() + device.findObject(UiSelector().description("Move item down to 4")).click() + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view")), + TRANSITION_TIMEOUT + ) + val dragDropMergeContent = device.findObject(By.res("$OPPIA_PACKAGE:id/content_text_view")) + assertEquals(DRAG_DROP_MERGE_INTERACTION_CONTENT, dragDropMergeContent.text) + } + + @Test + fun testPrototypeExploration_checkDragDropMerge_option1IsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteDragAndDropInteraction() + val dragDropMergeContainer = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view" + ) + ) + val firstItem = dragDropMergeContainer.children[0] + val firstItemTextView = firstItem.children[0].children[1].children[0] + assertEquals(DRAG_DROP_MERGE_INTERACTION_OPTION_1, firstItemTextView.text) + } + + @Test + fun testPrototypeExploration_checkDragDropMerge_option2IsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteDragAndDropInteraction() + val dragDropMergeContainer = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view" + ) + ) + val secondItem = dragDropMergeContainer.children[1] + val secondItemTextView = secondItem.children[0].children[1].children[0] + assertEquals(DRAG_DROP_MERGE_INTERACTION_OPTION_2, secondItemTextView.text) + } + + @Test + fun testPrototypeExploration_checkDragDropMerge_option3IsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteDragAndDropInteraction() + val dragDropMergeContainer = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view" + ) + ) + val thirdItem = dragDropMergeContainer.children[2] + val thirdItemTextView = thirdItem.children[0].children[1].children[0] + assertEquals(DRAG_DROP_MERGE_INTERACTION_OPTION_3, thirdItemTextView.text) + } + + @Test + fun testPrototypeExploration_checkDragDropMerge_option4IsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteDragAndDropInteraction() + val dragDropMergeContainer = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view" + ) + ) + val fourthItem = dragDropMergeContainer.children[3] + val fourthItemTextView = fourthItem.children[0].children[1].children[0] + assertEquals(DRAG_DROP_MERGE_INTERACTION_OPTION_4, fourthItemTextView.text) + } + + @Test + fun testPrototypeExploration_checkDragDropMerge_firstItemMoveUpButtonIsDisabled() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteDragAndDropInteraction() + val dragDropMergeContainer = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view" + ) + ) + val firstItem = dragDropMergeContainer.children[0] + val firstItemMoveUpButton = firstItem.children[0].children[0].children[0] + assertFalse(firstItemMoveUpButton.isEnabled) + } + + @Test + fun testPrototypeExploration_checkDragDropMerge_lastItemMoveDownButtonIsDisabled() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteDragAndDropInteraction() + val dragDropMergeContainer = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view" + ) + ) + val lastItem = dragDropMergeContainer.children[3] + val lastItemMoveUpButton = lastItem.children[0].children[0].children[0] + assertFalse(lastItemMoveUpButton.isEnabled) + } + + @Test + fun testPrototypeExploration_checkDragDropMerge_lastItemMergeButtonIsDisabled() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteDragAndDropInteraction() + val dragDropMergeContainer = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view" + ) + ) + val lastItem = dragDropMergeContainer.children[3] + val lastItemMergeButton = lastItem.children[1] + assertFalse(lastItemMergeButton.isEnabled) + } + + @Test + fun testPrototypeExploration_dragDropMergeSubmitWrongArrangement_incorrectFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteDragAndDropInteraction() + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(DRAG_DROP_MERGE_INTERACTION_INCORRECT_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExp_dragDropMergeSubmitCorrectArrangmentByDrag_correctFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteDragAndDropInteraction() + val dragDropMergeContainer = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view" + ) + ) + val firstItem = dragDropMergeContainer.children[0] + val firstItemMergeButton = firstItem.children[1] + firstItemMergeButton.click() + val init_position = + device.findObject(UiSelector().text(DRAG_DROP_MERGE_INTERACTION_OPTION_3)) + val des_position = + device.findObject(UiSelector().text("SUBMIT")) + init_position.dragTo(des_position, 300) + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(DRAG_DROP_MERGE_INTERACTION_CORRECT_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExpl_dragDropMergeSubmitCorrectArrangmentByButtons_correctFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteDragAndDropInteraction() + val dragDropMergeContainer = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view" + ) + ) + val firstItem = dragDropMergeContainer.children[0] + val firstItemMergeButton = firstItem.children[1] + firstItemMergeButton.click() + device.findObject(UiSelector().description("Move item down to 3")).click() + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(DRAG_DROP_MERGE_INTERACTION_CORRECT_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExplorationLandscape_checkDragDropMerge_firstItemMoveUpButtonIsDisabled() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteDragAndDropInteraction() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view")), + TRANSITION_TIMEOUT + ) + val dragDropMergeContainer = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view" + ) + ) + val firstItem = dragDropMergeContainer.children[0] + val firstItemMoveUpButton = firstItem.children[0].children[0].children[0] + assertFalse(firstItemMoveUpButton.isEnabled) + } + + @Test + fun testPrototypeExplorationLandscape_checkDragDropMerge_lastItemMoveDownButtonIsDisabled() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteDragAndDropInteraction() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view")), + TRANSITION_TIMEOUT + ) + val dragDropMergeContainer = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view" + ) + ) + val lastItem = dragDropMergeContainer.children[3] + val lastItemMoveUpButton = lastItem.children[0].children[0].children[1] + assertFalse(lastItemMoveUpButton.isEnabled) + } + + @Test + fun testPrototypeExplorationLandscape_checkDragDropMerge_lastItemMergeButtonIsDisabled() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteDragAndDropInteraction() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view")), + TRANSITION_TIMEOUT + ) + val dragDropMergeContainer = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view" + ) + ) + val lastItem = dragDropMergeContainer.children[3] + val lastItemMergeButton = lastItem.children[1] + assertFalse(lastItemMergeButton.isEnabled) + } + + @Test + fun testPrototypeExpLandscape_dragDropMergeSubmitWrongArrangement_incorrectFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteDragAndDropInteraction() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view")), + TRANSITION_TIMEOUT + ) + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView("SUBMIT") + device.findObject(UiSelector().text("SUBMIT")).click() + recyclerview.scrollBackward(100) + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(DRAG_DROP_MERGE_INTERACTION_INCORRECT_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExpLand_dragDropMergeSubmitCorrectArrangmentByDrag_correctFeedbackIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteDragAndDropInteraction() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view")), + TRANSITION_TIMEOUT + ) + val dragDropMergeContainer = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view" + ) + ) + val firstItem = dragDropMergeContainer.children[0] + val firstItemMergeButton = firstItem.children[1] + firstItemMergeButton.click() + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView("SUBMIT") + val init_position = + device.findObject(UiSelector().text(DRAG_DROP_MERGE_INTERACTION_OPTION_3)) + val des_position = + device.findObject(UiSelector().text("SUBMIT")) + init_position.dragTo(des_position, 300) + device.findObject(UiSelector().text("SUBMIT")).click() + recyclerview.scrollBackward(100) + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(DRAG_DROP_MERGE_INTERACTION_CORRECT_FEEDBACK, feedback.text) + } + + @Test + fun testPrototypeExpLand_dragDropMergeSubmitCorrectArrangmentByButtons_correctFeedbackIsDisplayed() { // ktlint-disable max-line-length + NavigateToPrototypeExploration() + PrototypeExplorationCompleteDragAndDropInteraction() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view")), + TRANSITION_TIMEOUT + ) + val dragDropMergeContainer = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view" + ) + ) + val firstItem = dragDropMergeContainer.children[0] + val firstItemMergeButton = firstItem.children[1] + firstItemMergeButton.click() + device.findObject(UiSelector().description("Move item down to 3")).click() + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView("SUBMIT") + device.findObject(UiSelector().text("SUBMIT")).click() + recyclerview.scrollBackward(100) + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(DRAG_DROP_MERGE_INTERACTION_CORRECT_FEEDBACK, feedback.text) + } + + // TODO(#1737): Singleton class in domain to manage configuration changes + @Test + @Ignore("InputIntractions are not preserved on configuration change") + fun testPrototypeExp_dragDropMergeChangeArrangement_arrangementIsPreservedOnConfigChange() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteDragAndDropInteraction() + val dragDropMergeContainer = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view" + ) + ) + val firstItem = dragDropMergeContainer.children[0] + val firstItemMergeButton = firstItem.children[1] + firstItemMergeButton.click() + device.findObject(UiSelector().description("Move item down to 3")).click() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view")), + TRANSITION_TIMEOUT + ) + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView("SUBMIT") + val thirdItem = dragDropMergeContainer.children[2] + val thirdItemTextView = thirdItem.children[0].children[1].children[0] + assertEquals(DRAG_DROP_MERGE_INTERACTION_OPTION_4, thirdItemTextView.text) + } + + @Test + fun testPrototypeExploration_dragDropMergeContinue_nextInteractionIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteDragAndDropInteraction() + val dragDropMergeContainer = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view" + ) + ) + val firstItem = dragDropMergeContainer.children[0] + val firstItemMergeButton = firstItem.children[1] + firstItemMergeButton.click() + device.findObject(UiSelector().description("Move item down to 3")).click() + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/return_to_topic_button")), + TRANSITION_TIMEOUT + ) + val endExplorationContent = device.findObject(By.res("$OPPIA_PACKAGE:id/content_text_view")) + assertEquals(PROTOTYPE_EXPLORATION_END_EXPLORATION_CONTENT, endExplorationContent.text) + } + + @Test + fun testPrototypeExplorationLandscape_dragDropMergeContinue_nextInteractionIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteDragAndDropInteraction() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view")), + TRANSITION_TIMEOUT + ) + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + val dragDropMergeContainer = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view" + ) + ) + val firstItem = dragDropMergeContainer.children[0] + val firstItemMergeButton = firstItem.children[1] + firstItemMergeButton.click() + recyclerview.scrollTextIntoView("SUBMIT") + device.findObject(UiSelector().description("Move item down to 3")).click() + device.findObject(UiSelector().text("SUBMIT")).click() + recyclerview.scrollTextIntoView("CONTINUE") + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/return_to_topic_button")), + TRANSITION_TIMEOUT + ) + val endExplorationContent = device.findObject(By.res("$OPPIA_PACKAGE:id/content_text_view")) + assertEquals(PROTOTYPE_EXPLORATION_END_EXPLORATION_CONTENT, endExplorationContent.text) + } + + @Test + fun testPrototypeExploration_endExplorationClickReturnToTopic_storyTitleIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteDragDropMergeInteraction() + device.findObject(By.res("$OPPIA_PACKAGE:id/return_to_topic_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/story_toolbar_title")), + TRANSITION_TIMEOUT + ) + val storyToolbarTitle = device.findObject(By.res("$OPPIA_PACKAGE:id/story_toolbar_title")) + assertEquals("First Story", storyToolbarTitle.text) + } + + @Test + fun testPrototypeExplorationLandscape_endExplorationClickReturnToTopic_topicTitleIsDisplayed() { + NavigateToPrototypeExploration() + PrototypeExplorationCompleteDragDropMergeInteraction() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/return_to_topic_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/return_to_topic_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/story_toolbar_title")), + TRANSITION_TIMEOUT + ) + val storyToolbarTitle = device.findObject(By.res("$OPPIA_PACKAGE:id/story_toolbar_title")) + assertEquals("First Story", storyToolbarTitle.text) + } + + @Test + fun testImageRegionExp_checkExplorationDescription_isDisplayed() { + NavigateToImageRegionSelectionExploration() + val expDescription = device.findObject(By.res("$OPPIA_PACKAGE:id/content_text_view")) + assertEquals(IMAGE_REGOIN_SELECTION_EXPLORATION_DESCRIPTION, expDescription.text) + } + + @Test + fun testImageRegionExp_imageRegionClickJupiter_jupiterFeedbackIsDisplayed() { + NavigateToImageRegionSelectionExploration() + val imageSelectionView = device.findObject( + By.res( + "org.oppia.android:id/interaction_container_frame_layout" + ) + ) + val jupiter = imageSelectionView.children[1] + device.click(jupiter.visibleBounds.centerX() - 50, jupiter.visibleBounds.centerY() - 50) + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + submitButton.click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(IMAGE_REGION_INTERACTION_JUPITER_FEEDBACK, feedback.text) + } + + @Test + fun testImageRegionExp_imageRegionClickSaturn_saturnFeedbackIsDisplayed() { + NavigateToImageRegionSelectionExploration() + val imageSelectionView = device.findObject( + By.res( + "org.oppia.android:id/interaction_container_frame_layout" + ) + ) + val saturn = imageSelectionView.children[2] + saturn.click() + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + submitButton.click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(IMAGE_REGION_INTERACTION_SATURN_FEEDBACK, feedback.text) + } + + @Test + fun testImageRegionExp_imageRegionClickUranus_uranusFeedbackIsDisplayed() { + NavigateToImageRegionSelectionExploration() + val imageSelectionView = device.findObject( + By.res( + "org.oppia.android:id/interaction_container_frame_layout" + ) + ) + val uranus = imageSelectionView.children[3] + uranus.click() + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + submitButton.click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(IMAGE_REGION_INTERACTION_URANUS_FEEDBACK, feedback.text) + } + + @Test + fun testImageRegionExp_imageRegionClickNeptune_neptuneFeedbackIsDisplayed() { + NavigateToImageRegionSelectionExploration() + val imageSelectionView = device.findObject( + By.res( + "org.oppia.android:id/interaction_container_frame_layout" + ) + ) + val neptune = imageSelectionView.children[4] + neptune.click() + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + submitButton.click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(IMAGE_REGION_INTERACTION_NEPTUNE_FEEDBACK, feedback.text) + } + + @Test + fun testImageRegionExp_imageRegionClickEarth_earthFeedbackIsDisplayed() { + NavigateToImageRegionSelectionExploration() + val imageSelectionView = device.findObject( + By.res( + "org.oppia.android:id/interaction_container_frame_layout" + ) + ) + val earth = imageSelectionView.children[5] + earth.click() + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + submitButton.click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(IMAGE_REGION_INTERACTION_EARTH_FEEDBACK, feedback.text) + } + + @Test + fun testImageRegionExp_imageRegionClickVenus_venusFeedbackIsDisplayed() { + NavigateToImageRegionSelectionExploration() + val imageSelectionView = device.findObject( + By.res( + "org.oppia.android:id/interaction_container_frame_layout" + ) + ) + val venus = imageSelectionView.children[6] + venus.click() + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + submitButton.click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(IMAGE_REGION_INTERACTION_VENUS_FEEDBACK, feedback.text) + } + + @Test + fun testImageRegionExp_imageRegionClickMars_marsFeedbackIsDisplayed() { + NavigateToImageRegionSelectionExploration() + val imageSelectionView = device.findObject( + By.res( + "org.oppia.android:id/interaction_container_frame_layout" + ) + ) + val mars = imageSelectionView.children[7] + mars.click() + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + submitButton.click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(IMAGE_REGION_INTERACTION_MARS_FEEDBACK, feedback.text) + } + + @Test + fun testImageRegionExp_imageRegionClickPluto_plutoFeedbackIsDisplayed() { + NavigateToImageRegionSelectionExploration() + val imageSelectionView = device.findObject( + By.res( + "org.oppia.android:id/interaction_container_frame_layout" + ) + ) + val pluto = imageSelectionView.children[8] + pluto.click() + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + submitButton.click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(IMAGE_REGION_INTERACTION_PLUTO_FEEDBACK, feedback.text) + } + + @Test + fun testImageRegionExp_imageRegionClickMercury_mercuryFeedbackIsDisplayed() { + NavigateToImageRegionSelectionExploration() + val imageSelectionView = device.findObject( + By.res( + "org.oppia.android:id/interaction_container_frame_layout" + ) + ) + val mercury = imageSelectionView.children[9] + mercury.click() + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + submitButton.click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(IMAGE_REGION_INTERACTION_MERCURY_FEEDBACK, feedback.text) + } + + @Test + fun testImageRegionExp_imageRegionContinue_nextIntearctionIsDisplayed() { + NavigateToImageRegionSelectionExploration() + val imageSelectionView = device.findObject( + By.res( + "org.oppia.android:id/interaction_container_frame_layout" + ) + ) + val saturn = imageSelectionView.children[2] + saturn.click() + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + submitButton.click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/return_to_topic_button")), + TRANSITION_TIMEOUT + ) + val endExplorationContent = device.findObject(By.res("$OPPIA_PACKAGE:id/content_text_view")) + assertEquals(IMAGE_REGION_END_EXPLORATION_CONTENT, endExplorationContent.text) + } + + @Test + fun testImageRegionExpLandscape_imageRegionClickJupiter_jupiterFeedbackIsDisplayed() { + NavigateToImageRegionSelectionExploration() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/interaction_container_frame_layout")), + TRANSITION_TIMEOUT + ) + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView("SUBMIT") + recyclerview.scrollIntoView( + UiSelector().resourceId( + "org.oppia.android:id/interaction_container_frame_layout" + ).index(1) + ) + val imageSelectionView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/interaction_container_frame_layout" + ) + ) + val jupiter = imageSelectionView.children[1] + device.click(jupiter.visibleBounds.centerX() - 50, jupiter.visibleBounds.centerY() - 50) + recyclerview.scrollTextIntoView("SUBMIT") + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + submitButton.click() + recyclerview.scrollIntoView(UiSelector().resourceId("$OPPIA_PACKAGE:id/feedback_text_view")) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(IMAGE_REGION_INTERACTION_JUPITER_FEEDBACK, feedback.text) + } + + @Test + fun testImageRegionExpLandscape_imageRegionClickSaturn_saturnFeedbackIsDisplayed() { + NavigateToImageRegionSelectionExploration() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/interaction_container_frame_layout")), + TRANSITION_TIMEOUT + ) + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView("SUBMIT") + recyclerview.scrollIntoView( + UiSelector().resourceId( + "org.oppia.android:id/interaction_container_frame_layout" + ).index(2) + ) + val imageSelectionView = device.findObject( + By.res( + "org.oppia.android:id/interaction_container_frame_layout" + ) + ) + val saturn = imageSelectionView.children[2] + saturn.click() + recyclerview.scrollTextIntoView("SUBMIT") + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + submitButton.click() + recyclerview.scrollIntoView(UiSelector().resourceId("$OPPIA_PACKAGE:id/feedback_text_view")) + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(IMAGE_REGION_INTERACTION_SATURN_FEEDBACK, feedback.text) + } + + @Test + fun testImageRegionExpLandscape_imageRegionClickUranus_uranusFeedbackIsDisplayed() { + NavigateToImageRegionSelectionExploration() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/interaction_container_frame_layout")), + TRANSITION_TIMEOUT + ) + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView("SUBMIT") + recyclerview.scrollIntoView( + UiSelector().resourceId( + "org.oppia.android:id/interaction_container_frame_layout" + ).index(3) + ) + val imageSelectionView = device.findObject( + By.res( + "org.oppia.android:id/interaction_container_frame_layout" + ) + ) + val uranus = imageSelectionView.children[3] + uranus.click() + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + submitButton.click() + recyclerview.scrollIntoView(UiSelector().resourceId("$OPPIA_PACKAGE:id/feedback_text_view")) + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(IMAGE_REGION_INTERACTION_URANUS_FEEDBACK, feedback.text) + } + + @Test + fun testImageRegionExpLandscape_imageRegionClickNeptune_neptuneFeedbackIsDisplayed() { + NavigateToImageRegionSelectionExploration() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/interaction_container_frame_layout")), + TRANSITION_TIMEOUT + ) + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView("SUBMIT") + recyclerview.scrollIntoView( + UiSelector().resourceId( + "org.oppia.android:id/interaction_container_frame_layout" + ).index(4) + ) + val imageSelectionView = device.findObject( + By.res( + "org.oppia.android:id/interaction_container_frame_layout" + ) + ) + val neptune = imageSelectionView.children[4] + neptune.click() + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + submitButton.click() + recyclerview.scrollIntoView(UiSelector().resourceId("$OPPIA_PACKAGE:id/feedback_text_view")) + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(IMAGE_REGION_INTERACTION_NEPTUNE_FEEDBACK, feedback.text) + } + + @Test + fun testImageRegionExpLandscape_imageRegionClickEarth_earthFeedbackIsDisplayed() { + NavigateToImageRegionSelectionExploration() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/interaction_container_frame_layout")), + TRANSITION_TIMEOUT + ) + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView("SUBMIT") + recyclerview.scrollIntoView( + UiSelector().resourceId( + "org.oppia.android:id/interaction_container_frame_layout" + ).index(5) + ) + val imageSelectionView = device.findObject( + By.res( + "org.oppia.android:id/interaction_container_frame_layout" + ) + ) + val earth = imageSelectionView.children[5] + earth.click() + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + submitButton.click() + recyclerview.scrollIntoView(UiSelector().resourceId("$OPPIA_PACKAGE:id/feedback_text_view")) + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(IMAGE_REGION_INTERACTION_EARTH_FEEDBACK, feedback.text) + } + + @Test + fun testImageRegionExpLandscape_imageRegionClickVenus_venusFeedbackIsDisplayed() { + NavigateToImageRegionSelectionExploration() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/interaction_container_frame_layout")), + TRANSITION_TIMEOUT + ) + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView("SUBMIT") + recyclerview.scrollIntoView( + UiSelector().resourceId( + "org.oppia.android:id/interaction_container_frame_layout" + ).index(6) + ) + val imageSelectionView = device.findObject( + By.res( + "org.oppia.android:id/interaction_container_frame_layout" + ) + ) + val venus = imageSelectionView.children[6] + venus.click() + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + submitButton.click() + recyclerview.scrollIntoView(UiSelector().resourceId("$OPPIA_PACKAGE:id/feedback_text_view")) + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(IMAGE_REGION_INTERACTION_VENUS_FEEDBACK, feedback.text) + } - // Wait for launcher - val launcherPackage = getLauncherPackageName() - assertNotNull(launcherPackage) - device.wait(hasObject(By.pkg(launcherPackage)), LAUNCH_TIMEOUT) + @Test + fun testImageRegionExpLandscape_imageRegionClickMars_marsFeedbackIsDisplayed() { + NavigateToImageRegionSelectionExploration() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/interaction_container_frame_layout")), + TRANSITION_TIMEOUT + ) + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView("SUBMIT") + recyclerview.scrollIntoView( + UiSelector().resourceId( + "org.oppia.android:id/interaction_container_frame_layout" + ).index(7) + ) + val imageSelectionView = device.findObject( + By.res( + "org.oppia.android:id/interaction_container_frame_layout" + ) + ) + val mars = imageSelectionView.children[7] + mars.click() + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + submitButton.click() + recyclerview.scrollIntoView(UiSelector().resourceId("$OPPIA_PACKAGE:id/feedback_text_view")) + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(IMAGE_REGION_INTERACTION_MARS_FEEDBACK, feedback.text) + } - // Launch the blueprint app - val context = ApplicationProvider.getApplicationContext() - val intent = context.packageManager - .getLaunchIntentForPackage(OPPIA_PACKAGE) - intent!!.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) // Clear out any previous instances - context.startActivity(intent) + @Test + fun testImageRegionExpLandscape_imageRegionClickPluto_plutoFeedbackIsDisplayed() { + NavigateToImageRegionSelectionExploration() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/interaction_container_frame_layout")), + TRANSITION_TIMEOUT + ) + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView("SUBMIT") + recyclerview.scrollIntoView( + UiSelector().resourceId( + "org.oppia.android:id/interaction_container_frame_layout" + ).index(8) + ) + val imageSelectionView = device.findObject( + By.res( + "org.oppia.android:id/interaction_container_frame_layout" + ) + ) + val pluto = imageSelectionView.children[8] + pluto.click() + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + submitButton.click() + recyclerview.scrollIntoView(UiSelector().resourceId("$OPPIA_PACKAGE:id/feedback_text_view")) + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(IMAGE_REGION_INTERACTION_PLUTO_FEEDBACK, feedback.text) + } - // Wait for the app to appear - device.wait(hasObject(By.pkg(OPPIA_PACKAGE).depth(0)), LAUNCH_TIMEOUT) + @Test + fun testImageRegionExpLandscape_imageRegionClickMercury_mercuryFeedbackIsDisplayed() { + NavigateToImageRegionSelectionExploration() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/interaction_container_frame_layout")), + TRANSITION_TIMEOUT + ) + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView("SUBMIT") + recyclerview.scrollIntoView( + UiSelector().resourceId( + "org.oppia.android:id/interaction_container_frame_layout" + ).index(9) + ) + val imageSelectionView = device.findObject( + By.res( + "org.oppia.android:id/interaction_container_frame_layout" + ) + ) + val mercury = imageSelectionView.children[9] + mercury.click() + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + submitButton.click() + recyclerview.scrollIntoView(UiSelector().resourceId("$OPPIA_PACKAGE:id/feedback_text_view")) + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")), + TRANSITION_TIMEOUT + ) + val feedback = device.findObject(By.res("$OPPIA_PACKAGE:id/feedback_text_view")) + assertEquals(IMAGE_REGION_INTERACTION_MERCURY_FEEDBACK, feedback.text) } @Test - fun testExploration_prototypeExploration_toolbarTitle_isDisplayedSuccessfully() { - NavigateToPrototypeExploration() + fun testImageRegionExpLandscape_imageRegionContinue_nextIntearctionIsDisplayed() { + NavigateToImageRegionSelectionExploration() + device.setOrientationRight() device.wait( - hasObject( - By.res("$OPPIA_PACKAGE:id/exploration_toolbar_title") - ), + hasObject(By.res("$OPPIA_PACKAGE:id/interaction_container_frame_layout")), TRANSITION_TIMEOUT ) - assertNotNull(device.findObject(By.res("$OPPIA_PACKAGE:id/exploration_toolbar_title"))) + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView("SUBMIT") + recyclerview.scrollIntoView( + UiSelector().resourceId( + "org.oppia.android:id/interaction_container_frame_layout" + ).index(2) + ) + val imageSelectionView = device.findObject( + By.res( + "org.oppia.android:id/interaction_container_frame_layout" + ) + ) + val saturn = imageSelectionView.children[2] + saturn.click() + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + submitButton.click() + recyclerview.scrollIntoView(UiSelector().resourceId("$OPPIA_PACKAGE:id/feedback_text_view")) + recyclerview.scrollIntoView( + UiSelector().resourceId( + "$OPPIA_PACKAGE:id/continue_navigation_button" + ) + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/return_to_topic_button")), + TRANSITION_TIMEOUT + ) + val endExplorationContent = device.findObject(By.res("$OPPIA_PACKAGE:id/content_text_view")) + assertEquals(IMAGE_REGION_END_EXPLORATION_CONTENT, endExplorationContent.text) + } + + @Test + fun testImageRegionExp_endExplorationClickReturnToTopic_storyTitleIsDisplayed() { + NavigateToImageRegionSelectionExploration() + ImageRegionSelectionExplorationCompleteImageRegionSelectionInteraction() + device.findObject(By.res("$OPPIA_PACKAGE:id/return_to_topic_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/story_toolbar_title")), + TRANSITION_TIMEOUT + ) + val storyToolbarTitle = device.findObject(By.res("$OPPIA_PACKAGE:id/story_toolbar_title")) + assertEquals("First Story", storyToolbarTitle.text) + } + + @Test + fun testImageRegionExpLandscape_endExplorationClickReturnToTopic_storyTitleIsDisplayed() { + NavigateToImageRegionSelectionExploration() + ImageRegionSelectionExplorationCompleteImageRegionSelectionInteraction() + device.setOrientationRight() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/return_to_topic_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/return_to_topic_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/story_toolbar_title")), + TRANSITION_TIMEOUT + ) + val storyToolbarTitle = device.findObject(By.res("$OPPIA_PACKAGE:id/story_toolbar_title")) + assertEquals("First Story", storyToolbarTitle.text) } - /** Navigates and opens the Prototype Exploration using the admin profile. */ + /** Navigates to First Test Topic and opens the Prototype Exploration. */ fun NavigateToPrototypeExploration() { + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/skip_text_view")), + APP_STARTUP_TIMEOUT + ) val skip_button = device.findObject(By.res("$OPPIA_PACKAGE:id/skip_text_view")) skip_button?.let { it.click() @@ -71,8 +4327,8 @@ class ExplorationPlayerTest { .click() } device.wait( - hasObject(By.res("$OPPIA_PACKAGE:id/profile_select_text")), - TRANSITION_TIMEOUT + hasObject(By.res("$OPPIA_PACKAGE:id/profile_name_text")), + APP_STARTUP_TIMEOUT ) val profiles = UiCollection(UiSelector().className("androidx.recyclerview.widget.RecyclerView")) profiles.getChildByText(UiSelector().className("android.widget.LinearLayout"), "Admin").click() @@ -85,9 +4341,276 @@ class ExplorationPlayerTest { .click() device.findObject(UiSelector().text("LESSONS")) .click() + device.wait(hasObject(By.res("$OPPIA_PACKAGE:id/topic_play_text_view")), TRANSITION_TIMEOUT) device.findObject(UiSelector().text("First Story")) .click() + device.wait(hasObject(By.res("$OPPIA_PACKAGE:id/story_toolbar_title")), TRANSITION_TIMEOUT) device.findObject(UiSelector().text("Chapter 1: Prototype Exploration")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/exploration_toolbar_title")), + TRANSITION_TIMEOUT + ) + } + + fun PrototypeExplorationCompleteFractionInteraction() { + device.findObject(UiSelector().text("CONTINUE")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/fraction_input_interaction_view")), + TRANSITION_TIMEOUT + ) + val fractionInteractionView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/fraction_input_interaction_view" + ) + ) + fractionInteractionView.text = "1/2" + device.findObject(By.res("$OPPIA_PACKAGE:id/submit_answer_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/interaction_container_linear_layout")), + TRANSITION_TIMEOUT + ) + } + + fun PrototypeExplorationCompleteMultipleChoice1() { + PrototypeExplorationCompleteFractionInteraction() + device.findObject(UiSelector().text(MULTIPLE_CHOICE_INTERACTION_1_OPTION_3)).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/selection_interaction_recyclerview")), + TRANSITION_TIMEOUT + ) + } + + fun PrototypeExplorationCompleteMultipleChoice2() { + PrototypeExplorationCompleteMultipleChoice1() + device.findObject(UiSelector().text(MULTIPLE_CHOICE_INTERACTION_2_OPTION_1)).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/selection_interaction_recyclerview")), + TRANSITION_TIMEOUT + ) + } + + fun PrototypeExplorationCompleteItemSelection() { + PrototypeExplorationCompleteMultipleChoice2() + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_1)).click() + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_3)).click() + device.findObject(UiSelector().text(ITEM_SELECTION_INTERACTION_OPTION_4)).click() + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + submitButton.click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/numeric_input_interaction_view")), + TRANSITION_TIMEOUT + ) + } + + fun PrototypeExplorationCompleteNumericInputInteraction() { + PrototypeExplorationCompleteItemSelection() + val numericInputView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/numeric_input_interaction_view" + ) + ) + numericInputView.text = "121" + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/ratio_input_interaction_view")), + TRANSITION_TIMEOUT + ) + } + + fun PrototypeExplorationCompleteRatioInputInteraction() { + PrototypeExplorationCompleteNumericInputInteraction() + val ratioInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_interaction_view" + ) + ) + ratioInputInteraction.text = "4:5" + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/text_input_interaction_view")), + TRANSITION_TIMEOUT + ) + } + + fun PrototypeExplorationCompleteTextInputInteraction() { + PrototypeExplorationCompleteRatioInputInteraction() + val textInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/text_input_interaction_view" + ) + ) + textInputInteraction.text = "finnish" + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view")), + TRANSITION_TIMEOUT + ) + } + + fun PrototypeExplorationCompleteDragAndDropInteraction() { + PrototypeExplorationCompleteTextInputInteraction() + device.findObject(UiSelector().description("Move item down to 2")).click() + device.findObject(UiSelector().description("Move item down to 3")).click() + device.findObject(UiSelector().description("Move item down to 4")).click() + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view")), + TRANSITION_TIMEOUT + ) + } + + fun PrototypeExplorationCompleteDragDropMergeInteraction() { + PrototypeExplorationCompleteDragAndDropInteraction() + val dragDropMergeContainer = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view" + ) + ) + val firstItem = dragDropMergeContainer.children[0] + val firstItemMergeButton = firstItem.children[1] + firstItemMergeButton.click() + device.findObject(UiSelector().description("Move item down to 3")).click() + device.findObject(UiSelector().text("SUBMIT")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/return_to_topic_button")), + TRANSITION_TIMEOUT + ) + } + + fun PrototypeExplorationCompleteAllInteractions() { + PrototypeExplorationCompleteDragDropMergeInteraction() + device.findObject(By.res("$OPPIA_PACKAGE:id/return_to_topic_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/story_toolbar_title")), + TRANSITION_TIMEOUT + ) + } + /** Navigates to First Test Topic and opens the Image Region Selection Exploration. */ + fun NavigateToImageRegionSelectionExploration() { + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/skip_text_view")), + APP_STARTUP_TIMEOUT + ) + val skip_button = device.findObject(By.res("$OPPIA_PACKAGE:id/skip_text_view")) + skip_button?.let { + it.click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/get_started_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/get_started_button")) + .click() + } + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/profile_name_text")), + APP_STARTUP_TIMEOUT + ) + val profiles = UiCollection(UiSelector().className("androidx.recyclerview.widget.RecyclerView")) + profiles.getChildByText(UiSelector().className("android.widget.LinearLayout"), "Admin").click() + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView("First Test Topic") + val firstTestTopicText = device.findObject(UiSelector().text("First Test Topic")) + firstTestTopicText.click() + device.findObject(UiSelector().text("First Test Topic")) + .click() + device.findObject(UiSelector().text("LESSONS")) + .click() + device.wait(hasObject(By.res("$OPPIA_PACKAGE:id/topic_play_text_view")), TRANSITION_TIMEOUT) + device.findObject(UiSelector().text("First Story")) + .click() + + val chapters = UiCollection(UiSelector().className("androidx.recyclerview.widget.RecyclerView")) + val prototypeExplorationChapter = chapters.getChildByText( + UiSelector().className("android.widget.FrameLayout"), + "Chapter 1: Prototype Exploration" + ) + val tick = prototypeExplorationChapter.getChild( + UiSelector().resourceId( + "org.oppia.android:id/chapter_completed_tick" + ) + ) + if (!tick.exists()) { + recyclerview.scrollTextIntoView("Chapter 1: Prototype Exploration") + device.findObject(UiSelector().text("Chapter 1: Prototype Exploration")).click() + PrototypeExplorationCompleteAllInteractions() + } + recyclerview.scrollTextIntoView("Chapter 2: Image Region Selection Exploration") + device.findObject(UiSelector().text("Chapter 2: Image Region Selection Exploration")).click() + } + + fun ImageRegionSelectionExplorationCompleteImageRegionSelectionInteraction() { + val imageSelectionView = device.findObject( + By.res( + "org.oppia.android:id/interaction_container_frame_layout" + ) + ) + val saturn = imageSelectionView.children[2] + saturn.click() + val submitButton = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/submit_answer_button" + ) + ) + submitButton.click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/continue_navigation_button")).click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/return_to_topic_button")), + TRANSITION_TIMEOUT + ) } /** From 7a1221dd07b003a9ce84d70c2c9d048ce187ee13 Mon Sep 17 00:00:00 2001 From: farees Date: Fri, 30 Jul 2021 23:34:56 +0530 Subject: [PATCH 12/63] Requested changes --- BUILD.bazel | 4 +- WORKSPACE | 15 +++ instrumentation/BUILD.bazel | 15 +++ .../src/{ => javatest}/AndroidManifest.xml | 5 +- .../oppia/android/instrumentation/BUILD.bazel | 22 ++-- .../instrumentation/EndToEndTestHelper.kt | 36 ++++++ .../instrumentation/ExplorationPlayerTest.kt | 108 ------------------ .../player/ExplorationPlayerTest.kt | 69 +++++++++++ instrumentation/tests.bzl | 9 ++ 9 files changed, 162 insertions(+), 121 deletions(-) rename instrumentation/src/{ => javatest}/AndroidManifest.xml (80%) create mode 100644 instrumentation/src/javatest/org/oppia/android/instrumentation/EndToEndTestHelper.kt delete mode 100644 instrumentation/src/javatest/org/oppia/android/instrumentation/ExplorationPlayerTest.kt create mode 100644 instrumentation/src/javatest/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt create mode 100644 instrumentation/tests.bzl diff --git a/BUILD.bazel b/BUILD.bazel index 7e0dee2a39e..5055c14f5e2 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -65,7 +65,7 @@ android_binary( ], ) -# Used for end to end tests +# Used for end-to-end tests android_binary( name = "oppia_test", testonly = True, @@ -77,7 +77,7 @@ android_binary( "minSdkVersion": "19", "targetSdkVersion": "29", "versionCode": "0", - "versionName": "0.1-alpha", + "versionName": "0.1-test", }, multidex = "native", visibility = ["//:oppia_testing_visibility"], diff --git a/WORKSPACE b/WORKSPACE index ffe08b6e446..5cd142774ae 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -141,6 +141,21 @@ http_archive( load("@rules_jvm_external//:defs.bzl", "maven_install") +ATS_TAG = "1edfdab3134a7f01b37afabd3eebfd2c5bb05151" + +ATS_SHA256 = "dcd1ff76aef1a26329d77863972780c8fe1fc8ff625747342239f0489c2837ec" + +http_archive( + name = "android_test_support", + sha256 = ATS_SHA256, + strip_prefix = "android-test-%s" % ATS_TAG, + urls = ["https://github.com/android/android-test/archive/%s.tar.gz" % ATS_TAG], +) + +load("@android_test_support//:repo.bzl", "android_test_repositories") + +android_test_repositories() + # Note to developers: new dependencies should be added to //third_party:versions.bzl, not here. maven_install( artifacts = DAGGER_ARTIFACTS + get_maven_dependencies(), diff --git a/instrumentation/BUILD.bazel b/instrumentation/BUILD.bazel index 4f90136f1ec..a78a194fcac 100644 --- a/instrumentation/BUILD.bazel +++ b/instrumentation/BUILD.bazel @@ -4,6 +4,21 @@ Note that: - All the android_binaries are named similar to the respective class name of the test suite. """ +[android_binary( + name = testclass + "Binary", + testonly = True, + custom_package = "org.oppia.android", + instruments = "//:oppia_test", + manifest = "src/javatest/AndroidManifest.xml", + deps = [library], +) for testclass, library in END_TO_END_TEST_SUITES.items()] + +[android_instrumentation_test( + name = testclass, + target_device = "@android_test_support//tools/android/emulated_devices/generic_phone:android_23_x86_qemu2", + test_app = ":" + testclass + "Binary", +) for testclass, library in END_TO_END_TEST_SUITES.items()] + android_binary( name = "ExplorationPlayerTest", testonly = True, diff --git a/instrumentation/src/AndroidManifest.xml b/instrumentation/src/javatest/AndroidManifest.xml similarity index 80% rename from instrumentation/src/AndroidManifest.xml rename to instrumentation/src/javatest/AndroidManifest.xml index dbbbe364642..9d9d12857b2 100644 --- a/instrumentation/src/AndroidManifest.xml +++ b/instrumentation/src/javatest/AndroidManifest.xml @@ -3,10 +3,9 @@ package="org.oppia.android.app.instrumentation"> + android:targetSdkVersion="29" /> - + diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/BUILD.bazel b/instrumentation/src/javatest/org/oppia/android/instrumentation/BUILD.bazel index 1a7d55a539b..0e5baa10ace 100644 --- a/instrumentation/src/javatest/org/oppia/android/instrumentation/BUILD.bazel +++ b/instrumentation/src/javatest/org/oppia/android/instrumentation/BUILD.bazel @@ -8,15 +8,16 @@ Note that: load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_android_library") -# Common deps for each test suite. -android_library( - name = "instrumentation_deps", +kt_android_library( + name = "e2e_test_helper", testonly = True, - exports = [ + srcs = [ + "EndToEndTestHelper.kt", + ], + visibility = ["//:oppia_testing_visibility"], + deps = [ "//third_party:androidx_test_ext_junit", - "//third_party:androidx_test_runner", "//third_party:androidx_test_uiautomator_uiautomator", - "//third_party:com_google_truth_truth", "//third_party:junit_junit", ], ) @@ -25,10 +26,15 @@ kt_android_library( name = "exploration_player_test_lib", testonly = True, srcs = [ - "ExplorationPlayerTest.kt", + "player/ExplorationPlayerTest.kt", ], visibility = ["//:oppia_testing_visibility"], deps = [ - ":instrumentation_deps", + ":e2e_test_helper", + "//third_party:androidx_test_ext_junit", + "//third_party:androidx_test_runner", + "//third_party:androidx_test_uiautomator_uiautomator", + "//third_party:com_google_truth_truth", + "//third_party:junit_junit", ], ) diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/EndToEndTestHelper.kt b/instrumentation/src/javatest/org/oppia/android/instrumentation/EndToEndTestHelper.kt new file mode 100644 index 00000000000..b4ad4b9f9bc --- /dev/null +++ b/instrumentation/src/javatest/org/oppia/android/instrumentation/EndToEndTestHelper.kt @@ -0,0 +1,36 @@ +package org.oppia.android.instrumentation + +import android.content.Context +import android.content.Intent +import androidx.test.core.app.ApplicationProvider +import androidx.test.uiautomator.By +import androidx.test.uiautomator.UiDevice +import androidx.test.uiautomator.Until +import org.junit.Assert + +object EndToEndTestHelper { + + private val OPPIA_PACKAGE = "org.oppia.android" + private val LAUNCH_TIMEOUT = 30000L + + /** Starts oppia from HomeScreen. */ + fun UiDevice.startOppiaFromScratch() { + // Start from the home screen + this.pressHome() + + // Wait for launcher + val launcherPackage = launcherPackageName + Assert.assertNotNull(launcherPackage) + this.wait(Until.hasObject(By.pkg(launcherPackage).depth(1)), LAUNCH_TIMEOUT) + + // Launch the blueprint app + val context = ApplicationProvider.getApplicationContext() + val intent = context.packageManager + .getLaunchIntentForPackage(OPPIA_PACKAGE) + intent!!.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) // Clear out any previous instances + context.startActivity(intent) + + // Wait for the app to appear + this.wait(Until.hasObject(By.pkg(OPPIA_PACKAGE)), LAUNCH_TIMEOUT) + } +} diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/ExplorationPlayerTest.kt b/instrumentation/src/javatest/org/oppia/android/instrumentation/ExplorationPlayerTest.kt deleted file mode 100644 index a2d5e0d73ca..00000000000 --- a/instrumentation/src/javatest/org/oppia/android/instrumentation/ExplorationPlayerTest.kt +++ /dev/null @@ -1,108 +0,0 @@ -package org.oppia.android.instrumentation - -import android.content.Context -import android.content.Intent -import android.content.pm.PackageManager -import androidx.test.core.app.ApplicationProvider -import androidx.test.platform.app.InstrumentationRegistry -import androidx.test.uiautomator.By -import androidx.test.uiautomator.UiCollection -import androidx.test.uiautomator.UiDevice -import androidx.test.uiautomator.UiScrollable -import androidx.test.uiautomator.UiSelector -import androidx.test.uiautomator.Until.hasObject -import org.junit.Assert.assertNotNull -import org.junit.Before -import org.junit.Test - -/** Tests for Explorations. */ -class ExplorationPlayerTest { - private val OPPIA_PACKAGE = "org.oppia.android" - private val LAUNCH_TIMEOUT = 30000L - private val TRANSITION_TIMEOUT = 5000L - private lateinit var device: UiDevice - - @Before - fun startOppiaFromHomeScreen() { - // Initialize UiDevice instance - device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) - - // Start from the home screen - device.pressHome() - - // Wait for launcher - val launcherPackage = getLauncherPackageName() - assertNotNull(launcherPackage) - device.wait(hasObject(By.pkg(launcherPackage)), LAUNCH_TIMEOUT) - - // Launch the blueprint app - val context = ApplicationProvider.getApplicationContext() - val intent = context.packageManager - .getLaunchIntentForPackage(OPPIA_PACKAGE) - intent!!.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) // Clear out any previous instances - context.startActivity(intent) - - // Wait for the app to appear - device.wait(hasObject(By.pkg(OPPIA_PACKAGE).depth(0)), LAUNCH_TIMEOUT) - } - - @Test - fun testExploration_prototypeExploration_toolbarTitle_isDisplayedSuccessfully() { - NavigateToPrototypeExploration() - device.wait( - hasObject( - By.res("$OPPIA_PACKAGE:id/exploration_toolbar_title") - ), - TRANSITION_TIMEOUT - ) - assertNotNull(device.findObject(By.res("$OPPIA_PACKAGE:id/exploration_toolbar_title"))) - } - - /** Navigates and opens the Prototype Exploration using the admin profile. */ - fun NavigateToPrototypeExploration() { - val skip_button = device.findObject(By.res("$OPPIA_PACKAGE:id/skip_text_view")) - skip_button?.let { - it.click() - device.wait( - hasObject(By.res("$OPPIA_PACKAGE:id/get_started_button")), - TRANSITION_TIMEOUT - ) - device.findObject(By.res("$OPPIA_PACKAGE:id/get_started_button")) - .click() - } - device.wait( - hasObject(By.res("$OPPIA_PACKAGE:id/profile_select_text")), - TRANSITION_TIMEOUT - ) - val profiles = UiCollection(UiSelector().className("androidx.recyclerview.widget.RecyclerView")) - profiles.getChildByText(UiSelector().className("android.widget.LinearLayout"), "Admin").click() - val recyclerview = UiScrollable(UiSelector().scrollable(true)) - recyclerview.setAsVerticalList() - recyclerview.scrollTextIntoView("First Test Topic") - val firstTestTopicText = device.findObject(UiSelector().text("First Test Topic")) - firstTestTopicText.click() - device.findObject(UiSelector().text("First Test Topic")) - .click() - device.findObject(UiSelector().text("LESSONS")) - .click() - device.findObject(UiSelector().text("First Story")) - .click() - device.findObject(UiSelector().text("Chapter 1: Prototype Exploration")).click() - } - - /** - * Uses package manager to find the package name of the device launcher. Usually this package - * is "com.android.launcher" but can be different at times. This is a generic solution which - * works on all platforms.` - */ - private fun getLauncherPackageName(): String { - // Create launcher Intent - val intent = Intent(Intent.ACTION_MAIN) - intent.addCategory(Intent.CATEGORY_HOME) - - // Use PackageManager to get the launcher package name - val pm = ApplicationProvider.getApplicationContext().packageManager - val resolveInfo = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) - return resolveInfo!!.activityInfo.packageName - } -} diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt b/instrumentation/src/javatest/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt new file mode 100644 index 00000000000..d24754b439e --- /dev/null +++ b/instrumentation/src/javatest/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt @@ -0,0 +1,69 @@ +package org.oppia.android.instrumentation.player + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.uiautomator.By +import androidx.test.uiautomator.UiCollection +import androidx.test.uiautomator.UiDevice +import androidx.test.uiautomator.UiScrollable +import androidx.test.uiautomator.UiSelector +import androidx.test.uiautomator.Until.hasObject +import org.junit.Assert.assertEquals +import org.junit.Before +import org.junit.Test +import org.oppia.android.instrumentation.EndToEndTestHelper.startOppiaFromScratch + +/** Tests for Explorations. */ +class ExplorationPlayerTest { + private val OPPIA_PACKAGE = "org.oppia.android" + private val TRANSITION_TIMEOUT = 5000L + private lateinit var device: UiDevice + + @Before + fun setUp() { + // Initialize UiDevice instance + device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) + device.startOppiaFromScratch() + } + + @Test + fun testExploration_prototypeExploration_toolbarTitle_isDisplayedSuccessfully() { + navigateToPrototypeExploration() + device.wait( + hasObject( + By.res("$OPPIA_PACKAGE:id/exploration_toolbar_title") + ), + TRANSITION_TIMEOUT + ) + val explorationTitle = device.findObject(By.res("$OPPIA_PACKAGE:id/exploration_toolbar_title")) + assertEquals("Prototype Exploration", explorationTitle.text) + } + + /** Navigates and opens the Prototype Exploration using the admin profile. */ + private fun navigateToPrototypeExploration() { + val skip_button = device.findObject(By.res("$OPPIA_PACKAGE:id/skip_text_view")) + skip_button?.let { + it.click() + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/get_started_button")), + TRANSITION_TIMEOUT + ) + device.findObject(By.res("$OPPIA_PACKAGE:id/get_started_button")) + .click() + } + device.wait( + hasObject(By.res("$OPPIA_PACKAGE:id/profile_select_text")), + TRANSITION_TIMEOUT + ) + val profiles = UiCollection(UiSelector().className("androidx.recyclerview.widget.RecyclerView")) + profiles.getChildByText(UiSelector().className("android.widget.LinearLayout"), "Admin").click() + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + recyclerview.setAsVerticalList() + recyclerview.scrollTextIntoView("First Test Topic") + val firstTestTopicText = device.findObject(UiSelector().text("First Test Topic")) + firstTestTopicText.click() + device.findObject(UiSelector().text("First Test Topic")).click() + device.findObject(UiSelector().text("LESSONS")).click() + device.findObject(UiSelector().text("First Story")).click() + device.findObject(UiSelector().text("Chapter 1: Prototype Exploration")).click() + } +} diff --git a/instrumentation/tests.bzl b/instrumentation/tests.bzl new file mode 100644 index 00000000000..3a88f16363e --- /dev/null +++ b/instrumentation/tests.bzl @@ -0,0 +1,9 @@ +""" +Contains all the end-to-end test classes under the instrumentation directory. +""" + +# Note to developers: Please keep this dict sorted by key to make it easier to find dependencies. +# This list should contain classname and library target name of each test suite. +END_TO_END_TEST_SUITES = { + "ExplorationPlayerTest": "//instrumentation/src/javatest/org/oppia/android/instrumentation:exploration_player_test_lib", +} From 6e0996648e7cc41e4f81d8c65d67939b7cd37cad Mon Sep 17 00:00:00 2001 From: farees Date: Fri, 30 Jul 2021 23:41:39 +0530 Subject: [PATCH 13/63] updated maven_install --- third_party/maven_install.json | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/third_party/maven_install.json b/third_party/maven_install.json index 6dceaf6429a..03eef8ecc76 100644 --- a/third_party/maven_install.json +++ b/third_party/maven_install.json @@ -1,8 +1,8 @@ { "dependency_tree": { "__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL", - "__INPUT_ARTIFACTS_HASH": -690670428, - "__RESOLVED_ARTIFACTS_HASH": 764689860, + "__INPUT_ARTIFACTS_HASH": 171679321, + "__RESOLVED_ARTIFACTS_HASH": -2135931254, "conflict_resolution": { "androidx.appcompat:appcompat:1.0.2": "androidx.appcompat:appcompat:1.2.0", "androidx.core:core:1.0.1": "androidx.core:core:1.3.0", @@ -3338,6 +3338,36 @@ "sha256": "e8abb0752a123d337be4cced50298067a8340135e64f0a24ff52345ed20cd292", "url": "https://maven.google.com/androidx/test/ext/junit/1.1.1/junit-1.1.1-sources.jar" }, + { + "coord": "androidx.test.uiautomator:uiautomator:2.2.0", + "dependencies": [], + "directDependencies": [], + "file": "v1/https/maven.google.com/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0.aar", + "mirror_urls": [ + "https://maven.google.com/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0.aar", + "https://repo1.maven.org/maven2/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0.aar", + "https://maven.fabric.io/public/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0.aar", + "https://maven.google.com/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0.aar", + "https://repo1.maven.org/maven2/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0.aar" + ], + "sha256": "2838e9d961dbffefbbd229a2bd4f6f82ac4fb2462975862a9e75e9ed325a3197", + "url": "https://maven.google.com/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0.aar" + }, + { + "coord": "androidx.test.uiautomator:uiautomator:jar:sources:2.2.0", + "dependencies": [], + "directDependencies": [], + "file": "v1/https/maven.google.com/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0-sources.jar", + "mirror_urls": [ + "https://maven.google.com/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0-sources.jar", + "https://maven.fabric.io/public/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0-sources.jar", + "https://maven.google.com/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0-sources.jar", + "https://repo1.maven.org/maven2/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0-sources.jar" + ], + "sha256": "e1f438106ac0d26b80ecf4fd6ffe6d36f60e12bdcd6316903f802ed24d00be99", + "url": "https://maven.google.com/androidx/test/uiautomator/uiautomator/2.2.0/uiautomator-2.2.0-sources.jar" + }, { "coord": "androidx.test:core:1.2.0", "dependencies": [ From 44868828af9e716441dfad41c8ddcc87de6d68e3 Mon Sep 17 00:00:00 2001 From: farees Date: Sat, 31 Jul 2021 00:22:54 +0530 Subject: [PATCH 14/63] Nit fix --- instrumentation/BUILD.bazel | 2 ++ 1 file changed, 2 insertions(+) diff --git a/instrumentation/BUILD.bazel b/instrumentation/BUILD.bazel index a78a194fcac..5c3d3dc219c 100644 --- a/instrumentation/BUILD.bazel +++ b/instrumentation/BUILD.bazel @@ -4,6 +4,8 @@ Note that: - All the android_binaries are named similar to the respective class name of the test suite. """ +load(":test.bzl", "END_TO_END_TEST_SUITES") + [android_binary( name = testclass + "Binary", testonly = True, From f64d32c357d290e50e8ddc58526b89bb3b58e0a3 Mon Sep 17 00:00:00 2001 From: farees Date: Sat, 31 Jul 2021 00:27:17 +0530 Subject: [PATCH 15/63] Add CODEOWNERS --- .github/CODEOWNERS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 7c464fc0cfb..d497f1d13c8 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -195,6 +195,14 @@ NOTICE @BenHenning # Global model ownership. /model/ @vinitamurthi @BenHenning + +##################################################################################### +# instrumentation # +##################################################################################### + +# UiAutomator configuration files ownership. +/instrumentation/src/javatest/*.kt @anandwana001 @BenHenning + ##################################################################################### # global overrides # ##################################################################################### From dc66ba2f99fef214a6fa3de62cae047db7a6541a Mon Sep 17 00:00:00 2001 From: farees Date: Sat, 31 Jul 2021 00:36:55 +0530 Subject: [PATCH 16/63] Added KDoc --- .../org/oppia/android/instrumentation/EndToEndTestHelper.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/EndToEndTestHelper.kt b/instrumentation/src/javatest/org/oppia/android/instrumentation/EndToEndTestHelper.kt index b4ad4b9f9bc..f8a34b994a8 100644 --- a/instrumentation/src/javatest/org/oppia/android/instrumentation/EndToEndTestHelper.kt +++ b/instrumentation/src/javatest/org/oppia/android/instrumentation/EndToEndTestHelper.kt @@ -8,6 +8,7 @@ import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.Until import org.junit.Assert +/** This object contains common operations used for end-to-end tests */ object EndToEndTestHelper { private val OPPIA_PACKAGE = "org.oppia.android" From c233b71ca037cec364d94427969e5e1bbc63b783 Mon Sep 17 00:00:00 2001 From: farees Date: Sat, 31 Jul 2021 00:37:22 +0530 Subject: [PATCH 17/63] NIT --- .../org/oppia/android/instrumentation/EndToEndTestHelper.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/EndToEndTestHelper.kt b/instrumentation/src/javatest/org/oppia/android/instrumentation/EndToEndTestHelper.kt index f8a34b994a8..ee136884019 100644 --- a/instrumentation/src/javatest/org/oppia/android/instrumentation/EndToEndTestHelper.kt +++ b/instrumentation/src/javatest/org/oppia/android/instrumentation/EndToEndTestHelper.kt @@ -8,7 +8,7 @@ import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.Until import org.junit.Assert -/** This object contains common operations used for end-to-end tests */ +/** This object contains common operations used for end-to-end tests. */ object EndToEndTestHelper { private val OPPIA_PACKAGE = "org.oppia.android" From 20449796de94230a57022d56f64080e44c1dcb40 Mon Sep 17 00:00:00 2001 From: farees Date: Sat, 31 Jul 2021 01:09:26 +0530 Subject: [PATCH 18/63] Added comments --- instrumentation/BUILD.bazel | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/instrumentation/BUILD.bazel b/instrumentation/BUILD.bazel index 5c3d3dc219c..df30bbd7f5a 100644 --- a/instrumentation/BUILD.bazel +++ b/instrumentation/BUILD.bazel @@ -1,11 +1,14 @@ """ -This library contains all android_binary targets to each test suite in instrumentation module. +This library contains all android_binary and android_instrumentation_test targets to each +test suite in instrumentation module. Note that: - All the android_binaries are named similar to the respective class name of the test suite. """ load(":test.bzl", "END_TO_END_TEST_SUITES") +# android_binary wrapper for each test suite under instrumentation module. +# Note that: Target name is class name of the test suite ending with "Binary". [android_binary( name = testclass + "Binary", testonly = True, @@ -15,19 +18,12 @@ load(":test.bzl", "END_TO_END_TEST_SUITES") deps = [library], ) for testclass, library in END_TO_END_TEST_SUITES.items()] +# android_instrumentation_test wrapper for each test suite under instrumentation module. +# Note that: +# - Target name is the class name of the test suite. +# - The test doesn't run to completion #3617 for details. [android_instrumentation_test( name = testclass, target_device = "@android_test_support//tools/android/emulated_devices/generic_phone:android_23_x86_qemu2", test_app = ":" + testclass + "Binary", ) for testclass, library in END_TO_END_TEST_SUITES.items()] - -android_binary( - name = "ExplorationPlayerTest", - testonly = True, - custom_package = "org.oppia.android", - instruments = "//:oppia_test", - manifest = "src/AndroidManifest.xml", - deps = [ - "//instrumentation/src/javatest/org/oppia/android/instrumentation:exploration_player_test_lib", - ], -) From 7ac1ac59f812031b43f9e496e57d6d296da3a194 Mon Sep 17 00:00:00 2001 From: farees Date: Sat, 31 Jul 2021 14:49:23 +0530 Subject: [PATCH 19/63] Added oppia_instrumentation_test.bzl --- .github/CODEOWNERS | 2 +- instrumentation/BUILD.bazel | 41 ++++++++----------- .../oppia_instrumentation_test.bzl | 40 ++++++++++++++++++ .../oppia/android/instrumentation/BUILD.bazel | 19 +-------- 4 files changed, 61 insertions(+), 41 deletions(-) create mode 100644 instrumentation/oppia_instrumentation_test.bzl diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index d497f1d13c8..f2e18f1c07e 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -201,7 +201,7 @@ NOTICE @BenHenning ##################################################################################### # UiAutomator configuration files ownership. -/instrumentation/src/javatest/*.kt @anandwana001 @BenHenning +/instrumentation/src/javatest/**/*.kt @anandwana001 @BenHenning ##################################################################################### # global overrides # diff --git a/instrumentation/BUILD.bazel b/instrumentation/BUILD.bazel index df30bbd7f5a..6a8fa682d65 100644 --- a/instrumentation/BUILD.bazel +++ b/instrumentation/BUILD.bazel @@ -1,29 +1,24 @@ """ This library contains all android_binary and android_instrumentation_test targets to each -test suite in instrumentation module. +test suite in instrumentation module as a oppia_instrumentation_test wrapper. Note that: - - All the android_binaries are named similar to the respective class name of the test suite. + - All the oppia_instrumentation_test targets are named similar to the respective class name + of the test suite. """ -load(":test.bzl", "END_TO_END_TEST_SUITES") +load(":oppia_instrumentation_test.bzl", "oppia_instrumentation_test") -# android_binary wrapper for each test suite under instrumentation module. -# Note that: Target name is class name of the test suite ending with "Binary". -[android_binary( - name = testclass + "Binary", - testonly = True, - custom_package = "org.oppia.android", - instruments = "//:oppia_test", - manifest = "src/javatest/AndroidManifest.xml", - deps = [library], -) for testclass, library in END_TO_END_TEST_SUITES.items()] - -# android_instrumentation_test wrapper for each test suite under instrumentation module. -# Note that: -# - Target name is the class name of the test suite. -# - The test doesn't run to completion #3617 for details. -[android_instrumentation_test( - name = testclass, - target_device = "@android_test_support//tools/android/emulated_devices/generic_phone:android_23_x86_qemu2", - test_app = ":" + testclass + "Binary", -) for testclass, library in END_TO_END_TEST_SUITES.items()] +oppia_instrumentation_test( + name = "ExplorationPlayerTest", + srcs = [ + "//instrumentation/src/javatest/org/oppia/android/instrumentation:player/ExplorationPlayerTest.kt", + ], + deps = [ + "//instrumentation/src/javatest/org/oppia/android/instrumentation:e2e_test_helper", + "//third_party:androidx_test_ext_junit", + "//third_party:androidx_test_runner", + "//third_party:androidx_test_uiautomator_uiautomator", + "//third_party:com_google_truth_truth", + "//third_party:junit_junit", + ], +) diff --git a/instrumentation/oppia_instrumentation_test.bzl b/instrumentation/oppia_instrumentation_test.bzl new file mode 100644 index 00000000000..7341c7e78a9 --- /dev/null +++ b/instrumentation/oppia_instrumentation_test.bzl @@ -0,0 +1,40 @@ +""" +Instrumentation macros to setup up end-to-end tests. +""" + +load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_android_library") + +def oppia_instrumentation_test( + name, + srcs, + deps): + """ + Creates library, binary and a instrumentation test for each test suite. + + Args: + name: str. The class name of the Test suite or the test file. + srcs: list of str. List of test files under instrumentation module. + deps: list of str. The list of dependencies needed to build and run the library. + """ + kt_android_library( + name = name + "_lib", + testonly = True, + srcs = srcs, + visibility = ["//:oppia_testing_visibility"], + deps = deps, + ) + + native.android_binary( + name = name + "Binary", + testonly = True, + custom_package = "org.oppia.android", + instruments = "//:oppia_test", + manifest = "src/javatest/AndroidManifest.xml", + deps = [":" + name + "_lib"], + ) + + native.android_instrumentation_test( + name = name, + target_device = "@android_test_support//tools/android/emulated_devices/generic_phone:android_23_x86_qemu2", + test_app = ":" + name + "Binary", + ) diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/BUILD.bazel b/instrumentation/src/javatest/org/oppia/android/instrumentation/BUILD.bazel index 0e5baa10ace..393b0fc0f95 100644 --- a/instrumentation/src/javatest/org/oppia/android/instrumentation/BUILD.bazel +++ b/instrumentation/src/javatest/org/oppia/android/instrumentation/BUILD.bazel @@ -8,6 +8,8 @@ Note that: load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_android_library") +exports_files(["player/ExplorationPlayerTest.kt"]) + kt_android_library( name = "e2e_test_helper", testonly = True, @@ -21,20 +23,3 @@ kt_android_library( "//third_party:junit_junit", ], ) - -kt_android_library( - name = "exploration_player_test_lib", - testonly = True, - srcs = [ - "player/ExplorationPlayerTest.kt", - ], - visibility = ["//:oppia_testing_visibility"], - deps = [ - ":e2e_test_helper", - "//third_party:androidx_test_ext_junit", - "//third_party:androidx_test_runner", - "//third_party:androidx_test_uiautomator_uiautomator", - "//third_party:com_google_truth_truth", - "//third_party:junit_junit", - ], -) From 3bb5348570399a672e12b1e2962e8fe668109446 Mon Sep 17 00:00:00 2001 From: farees Date: Sat, 31 Jul 2021 16:44:00 +0530 Subject: [PATCH 20/63] added exempted_file_path --- scripts/assets/test_file_exemptions.textproto | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/assets/test_file_exemptions.textproto b/scripts/assets/test_file_exemptions.textproto index 04d0c64128d..bf1f2cb511f 100644 --- a/scripts/assets/test_file_exemptions.textproto +++ b/scripts/assets/test_file_exemptions.textproto @@ -556,6 +556,7 @@ exempted_file_path: "domain/src/main/java/org/oppia/android/domain/util/FloatExt exempted_file_path: "domain/src/main/java/org/oppia/android/domain/util/FractionExtensions.kt" exempted_file_path: "domain/src/main/java/org/oppia/android/domain/util/JsonAssetRetriever.kt" exempted_file_path: "domain/src/test/java/org/oppia/android/domain/classify/InteractionObjectTestBuilder.kt" +exempted_file_path: "instrumentation/src/javatest/org/oppia/android/instrumentation/EndToEndTestHelper.kt" exempted_file_path: "scripts/src/java/org/oppia/android/scripts/common/CommandExecutor.kt" exempted_file_path: "scripts/src/java/org/oppia/android/scripts/common/CommandResult.kt" exempted_file_path: "scripts/src/java/org/oppia/android/scripts/maven/data/MavenListDependency.kt" From 2e0440e98451bc76fa920246e3b6573132848608 Mon Sep 17 00:00:00 2001 From: farees Date: Sun, 1 Aug 2021 04:48:23 +0530 Subject: [PATCH 21/63] e2e tests for both explorations --- .../instrumentation/EndToEndTestHelper.kt | 34 ++- .../player/ExplorationPlayerTest.kt | 210 ++++++++++++++++-- 2 files changed, 221 insertions(+), 23 deletions(-) diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/EndToEndTestHelper.kt b/instrumentation/src/javatest/org/oppia/android/instrumentation/EndToEndTestHelper.kt index ee136884019..b4c97de6ac6 100644 --- a/instrumentation/src/javatest/org/oppia/android/instrumentation/EndToEndTestHelper.kt +++ b/instrumentation/src/javatest/org/oppia/android/instrumentation/EndToEndTestHelper.kt @@ -5,14 +5,17 @@ import android.content.Intent import androidx.test.core.app.ApplicationProvider import androidx.test.uiautomator.By import androidx.test.uiautomator.UiDevice +import androidx.test.uiautomator.UiScrollable +import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.Until -import org.junit.Assert +import org.junit.Assert.assertNotNull /** This object contains common operations used for end-to-end tests. */ object EndToEndTestHelper { private val OPPIA_PACKAGE = "org.oppia.android" private val LAUNCH_TIMEOUT = 30000L + private val TRANSITION_TIMEOUT = 5000L /** Starts oppia from HomeScreen. */ fun UiDevice.startOppiaFromScratch() { @@ -21,7 +24,7 @@ object EndToEndTestHelper { // Wait for launcher val launcherPackage = launcherPackageName - Assert.assertNotNull(launcherPackage) + assertNotNull(launcherPackage) this.wait(Until.hasObject(By.pkg(launcherPackage).depth(1)), LAUNCH_TIMEOUT) // Launch the blueprint app @@ -34,4 +37,31 @@ object EndToEndTestHelper { // Wait for the app to appear this.wait(Until.hasObject(By.pkg(OPPIA_PACKAGE)), LAUNCH_TIMEOUT) } + + /** Waits for the view with given resource name to appear. */ + fun UiDevice.waitForRes(resourceName: String, timeout: Long = TRANSITION_TIMEOUT) { + this.wait(Until.hasObject(By.res(resourceName)), timeout) + } + + /** Scrolls to the view with given text. */ + fun scrollToText(text: String, isVertical: Boolean = true) { + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + if (isVertical) { + recyclerview.setAsVerticalList() + } else { + recyclerview.setAsHorizontalList() + } + recyclerview.scrollTextIntoView(text) + } + + /** Scrolls to the view with given UiObject. */ + fun scrollToView(uiSelector: UiSelector, isVertical: Boolean = true) { + val recyclerview = UiScrollable(UiSelector().scrollable(true)) + if (isVertical) { + recyclerview.setAsVerticalList() + } else { + recyclerview.setAsHorizontalList() + } + recyclerview.scrollIntoView(uiSelector) + } } diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt b/instrumentation/src/javatest/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt index d24754b439e..6ddcc306bc6 100644 --- a/instrumentation/src/javatest/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt +++ b/instrumentation/src/javatest/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt @@ -4,13 +4,14 @@ import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.By import androidx.test.uiautomator.UiCollection import androidx.test.uiautomator.UiDevice -import androidx.test.uiautomator.UiScrollable import androidx.test.uiautomator.UiSelector -import androidx.test.uiautomator.Until.hasObject import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test +import org.oppia.android.instrumentation.EndToEndTestHelper.scrollToText import org.oppia.android.instrumentation.EndToEndTestHelper.startOppiaFromScratch +import org.oppia.android.instrumentation.EndToEndTestHelper.waitForRes /** Tests for Explorations. */ class ExplorationPlayerTest { @@ -28,42 +29,209 @@ class ExplorationPlayerTest { @Test fun testExploration_prototypeExploration_toolbarTitle_isDisplayedSuccessfully() { navigateToPrototypeExploration() - device.wait( - hasObject( - By.res("$OPPIA_PACKAGE:id/exploration_toolbar_title") - ), - TRANSITION_TIMEOUT - ) val explorationTitle = device.findObject(By.res("$OPPIA_PACKAGE:id/exploration_toolbar_title")) assertEquals("Prototype Exploration", explorationTitle.text) } + @Test + fun testProtoTypeExploration_answerAllInteractionsAndCompleteExploration() { + navigateToPrototypeExploration() + completePrototypeExploration() + + // Assert Topic Completed. + scrollToText("Chapter 1: Prototype Exploration") + val chapters = UiCollection(UiSelector().className("androidx.recyclerview.widget.RecyclerView")) + val prototypeExplorationChapter = chapters.getChildByText( + UiSelector().className("android.widget.FrameLayout"), + "Chapter 1: Prototype Exploration" + ) + val chapterCompletedTick = prototypeExplorationChapter.getChild( + UiSelector().resourceId( + "$OPPIA_PACKAGE:id/chapter_completed_tick" + ) + ) + assertTrue(chapterCompletedTick.exists()) + } + + @Test + fun testImageRegionSelectionInteraction_answerAllInteractionsAndCompleteExploration() { + navigateToImageRegionSelectionInteraction() + + // / Image Region Selection Interaction. + device.waitForRes("$OPPIA_PACKAGE:id/interaction_container_frame_layout") + val imageSelectionView = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/interaction_container_frame_layout" + ) + ) + imageSelectionView.children[2].click() + device.findObject(UiSelector().text("SUBMIT")).click() + clickContinueButton() + + // End Exploration. + device.waitForRes("$OPPIA_PACKAGE:id/return_to_topic_button") + device.findObject(UiSelector().text("RETURN TO TOPIC")).click() + + // Assert Topic Completed. + scrollToText("Chapter 2: Image Region Selection Exploration") + val chapters = UiCollection(UiSelector().className("androidx.recyclerview.widget.RecyclerView")) + val prototypeExplorationChapter = chapters.getChildByText( + UiSelector().className("android.widget.FrameLayout"), + "Chapter 2: Image Region Selection Exploration" + ) + val chapterCompletedTick = prototypeExplorationChapter.getChild( + UiSelector().resourceId( + "$OPPIA_PACKAGE:id/chapter_completed_tick" + ) + ) + assertTrue(chapterCompletedTick.exists()) + } + /** Navigates and opens the Prototype Exploration using the admin profile. */ private fun navigateToPrototypeExploration() { val skip_button = device.findObject(By.res("$OPPIA_PACKAGE:id/skip_text_view")) skip_button?.let { it.click() - device.wait( - hasObject(By.res("$OPPIA_PACKAGE:id/get_started_button")), - TRANSITION_TIMEOUT - ) + device.waitForRes("$OPPIA_PACKAGE:id/get_started_button") device.findObject(By.res("$OPPIA_PACKAGE:id/get_started_button")) .click() } - device.wait( - hasObject(By.res("$OPPIA_PACKAGE:id/profile_select_text")), - TRANSITION_TIMEOUT - ) + device.waitForRes("$OPPIA_PACKAGE:id/profile_select_text") val profiles = UiCollection(UiSelector().className("androidx.recyclerview.widget.RecyclerView")) profiles.getChildByText(UiSelector().className("android.widget.LinearLayout"), "Admin").click() - val recyclerview = UiScrollable(UiSelector().scrollable(true)) - recyclerview.setAsVerticalList() - recyclerview.scrollTextIntoView("First Test Topic") - val firstTestTopicText = device.findObject(UiSelector().text("First Test Topic")) - firstTestTopicText.click() + scrollToText("First Test Topic") device.findObject(UiSelector().text("First Test Topic")).click() device.findObject(UiSelector().text("LESSONS")).click() device.findObject(UiSelector().text("First Story")).click() + scrollToText("Chapter 1: Prototype Exploration") device.findObject(UiSelector().text("Chapter 1: Prototype Exploration")).click() + device.waitForRes("$OPPIA_PACKAGE:id/exploration_toolbar_title") + } + + /** Answers all the interactions and ends the exploration. */ + private fun completePrototypeExploration() { + // Exploration description. + device.findObject(UiSelector().text("CONTINUE")).click() + + // Fraction Input Interaction. + device.waitForRes("$OPPIA_PACKAGE:id/exploration_toolbar_title") + val fractionInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/fraction_input_interaction_view" + ) + ) + fractionInputInteraction.text = "1/2" + device.findObject(UiSelector().text("SUBMIT")).click() + clickContinueButton() + + // Multiple Choice Interaction - 1. + device.waitForRes("$OPPIA_PACKAGE:id/selection_interaction_recyclerview") + device.findObject(UiSelector().text("Eagle")).click() + clickContinueButton() + + // Multiple Choice Interaction - 2. + device.waitForRes("$OPPIA_PACKAGE:id/selection_interaction_recyclerview") + device.findObject(UiSelector().text("Green")).click() + clickContinueButton() + + // Item Selection Interaction. + device.waitForRes("$OPPIA_PACKAGE:id/selection_interaction_recyclerview") + device.findObject(UiSelector().text("Red")).click() + device.findObject(UiSelector().text("Green")).click() + device.findObject(UiSelector().text("Blue")).click() + device.findObject(UiSelector().text("SUBMIT")).click() + clickContinueButton() + + // Numeric Input Interaction. + device.waitForRes("$OPPIA_PACKAGE:id/numeric_input_interaction_view") + val numericInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/numeric_input_interaction_view" + ) + ) + numericInputInteraction.text = "121" + device.findObject(UiSelector().text("SUBMIT")).click() + clickContinueButton() + + // Ratio Input Interaction. + device.waitForRes("$OPPIA_PACKAGE:id/ratio_input_interaction_view") + val ratioInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/ratio_input_interaction_view" + ) + ) + ratioInputInteraction.text = "4:5" + device.findObject(UiSelector().text("SUBMIT")).click() + clickContinueButton() + + // Text Input Interaction. + device.waitForRes("$OPPIA_PACKAGE:id/text_input_interaction_view") + val textInputInteraction = device.findObject( + By.res( + "$OPPIA_PACKAGE:id/text_input_interaction_view" + ) + ) + textInputInteraction.text = "Finnish" + device.findObject(UiSelector().text("SUBMIT")).click() + clickContinueButton() + + // Drag And Drop Interaction. + device.waitForRes("$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view") + device.findObject(UiSelector().description("Move item down to 2")).click() + device.findObject(UiSelector().description("Move item down to 3")).click() + device.findObject(UiSelector().description("Move item down to 4")).click() + device.findObject(UiSelector().text("SUBMIT")).click() + clickContinueButton() + + // Drag Drop Merge Interaction. + device.waitForRes("$OPPIA_PACKAGE:id/drag_drop_interaction_recycler_view") + device.findObject(UiSelector().description("Link to item 2")).click() + device.findObject(UiSelector().description("Move item down to 3")).click() + device.findObject(UiSelector().text("SUBMIT")).click() + clickContinueButton() + + // End Exploration. + device.waitForRes("$OPPIA_PACKAGE:id/return_to_topic_button") + device.findObject(UiSelector().text("RETURN TO TOPIC")).click() + } + /** Navigates and opens the Image Region Selection Exploration using the admin profile. */ + private fun navigateToImageRegionSelectionInteraction() { + val skip_button = device.findObject(By.res("$OPPIA_PACKAGE:id/skip_text_view")) + skip_button?.let { + it.click() + device.waitForRes("$OPPIA_PACKAGE:id/get_started_button") + device.findObject(By.res("$OPPIA_PACKAGE:id/get_started_button")) + .click() + } + device.waitForRes("$OPPIA_PACKAGE:id/profile_select_text") + val profiles = UiCollection(UiSelector().className("androidx.recyclerview.widget.RecyclerView")) + profiles.getChildByText(UiSelector().className("android.widget.LinearLayout"), "Admin").click() + scrollToText("First Test Topic") + device.findObject(UiSelector().text("First Test Topic")).click() + device.findObject(UiSelector().text("LESSONS")).click() + device.findObject(UiSelector().text("First Story")).click() + scrollToText("Chapter 1: Prototype Exploration") + val chapters = UiCollection(UiSelector().className("androidx.recyclerview.widget.RecyclerView")) + val prototypeExplorationChapter = chapters.getChildByText( + UiSelector().className("android.widget.FrameLayout"), + "Chapter 1: Prototype Exploration" + ) + val chapterCompletedTick = prototypeExplorationChapter.getChild( + UiSelector().resourceId( + "$OPPIA_PACKAGE:id/chapter_completed_tick" + ) + ) + if (!chapterCompletedTick.exists()) { + device.findObject(UiSelector().text("Chapter 1: Prototype Exploration")).click() + device.waitForRes("$OPPIA_PACKAGE:id/exploration_toolbar_title") + completePrototypeExploration() + } + scrollToText("Chapter 2: Image Region Selection Exploration") + device.findObject(UiSelector().text("Chapter 2: Image Region Selection Exploration")).click() + } + + private fun clickContinueButton() { + device.waitForRes("$OPPIA_PACKAGE:id/continue_navigation_button") + device.findObject(UiSelector().text("CONTINUE")).click() } } From e5a6128c2bb67048877f829a3f6504731030ff54 Mon Sep 17 00:00:00 2001 From: farees Date: Wed, 4 Aug 2021 21:10:55 +0530 Subject: [PATCH 22/63] Helper utility shifted to testing module --- .github/CODEOWNERS | 2 +- BUILD.bazel | 21 ------- instrumentation/BUILD.bazel | 30 +++++---- .../oppia_instrumentation_test.bzl | 17 +++-- .../oppia/android/instrumentation/BUILD.bazel | 15 +++-- .../player/ExplorationPlayerTest.kt | 50 +++++---------- instrumentation/tests.bzl | 9 --- testing/build.gradle | 1 + .../android/testing/uiautomator/BUILD.bazel | 20 ++++++ .../testing/uiautomator/EndToEndTestHelper.kt | 63 +++++++++++++++++++ 10 files changed, 133 insertions(+), 95 deletions(-) delete mode 100644 instrumentation/tests.bzl create mode 100644 testing/src/main/java/org/oppia/android/testing/uiautomator/BUILD.bazel create mode 100644 testing/src/main/java/org/oppia/android/testing/uiautomator/EndToEndTestHelper.kt diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index f2e18f1c07e..4eb15b99c06 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -200,7 +200,7 @@ NOTICE @BenHenning # instrumentation # ##################################################################################### -# UiAutomator configuration files ownership. +# UiAutomator test suites ownership. /instrumentation/src/javatest/**/*.kt @anandwana001 @BenHenning ##################################################################################### diff --git a/BUILD.bazel b/BUILD.bazel index 5055c14f5e2..cd771f82244 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -64,24 +64,3 @@ android_binary( "//app", ], ) - -# Used for end-to-end tests -android_binary( - name = "oppia_test", - testonly = True, - custom_package = "org.oppia.android", - enable_data_binding = True, - manifest = "//app:src/main/AndroidManifest.xml", - manifest_values = { - "applicationId": "org.oppia.android", - "minSdkVersion": "19", - "targetSdkVersion": "29", - "versionCode": "0", - "versionName": "0.1-test", - }, - multidex = "native", - visibility = ["//:oppia_testing_visibility"], - deps = [ - "//app", - ], -) diff --git a/instrumentation/BUILD.bazel b/instrumentation/BUILD.bazel index 6a8fa682d65..660e52113a1 100644 --- a/instrumentation/BUILD.bazel +++ b/instrumentation/BUILD.bazel @@ -6,19 +6,23 @@ Note that: of the test suite. """ -load(":oppia_instrumentation_test.bzl", "oppia_instrumentation_test") - -oppia_instrumentation_test( - name = "ExplorationPlayerTest", - srcs = [ - "//instrumentation/src/javatest/org/oppia/android/instrumentation:player/ExplorationPlayerTest.kt", - ], +# Used for end-to-end tests +android_binary( + name = "oppia_test", + testonly = True, + custom_package = "org.oppia.android", + enable_data_binding = True, + manifest = "//app:src/main/AndroidManifest.xml", + manifest_values = { + "applicationId": "org.oppia.android", + "minSdkVersion": "19", + "targetSdkVersion": "29", + "versionCode": "0", + "versionName": "0.1-test", + }, + multidex = "native", + visibility = ["//:oppia_testing_visibility"], deps = [ - "//instrumentation/src/javatest/org/oppia/android/instrumentation:e2e_test_helper", - "//third_party:androidx_test_ext_junit", - "//third_party:androidx_test_runner", - "//third_party:androidx_test_uiautomator_uiautomator", - "//third_party:com_google_truth_truth", - "//third_party:junit_junit", + "//app", ], ) diff --git a/instrumentation/oppia_instrumentation_test.bzl b/instrumentation/oppia_instrumentation_test.bzl index 7341c7e78a9..b1c76a47b2b 100644 --- a/instrumentation/oppia_instrumentation_test.bzl +++ b/instrumentation/oppia_instrumentation_test.bzl @@ -1,5 +1,5 @@ """ -Instrumentation macros to setup up end-to-end tests. +Instrumentation macros to define up end-to-end tests. """ load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_android_library") @@ -9,28 +9,27 @@ def oppia_instrumentation_test( srcs, deps): """ - Creates library, binary and a instrumentation test for each test suite. + Creates library, binary, and instrumentation test for each test suite. Args: - name: str. The class name of the Test suite or the test file. - srcs: list of str. List of test files under instrumentation module. - deps: list of str. The list of dependencies needed to build and run the library. + name: str. The class name of the test suite. + srcs: list of str. List of test files corresponding to this test suite. + deps: list of str. The list of dependencies needed to build and run the test. """ kt_android_library( - name = name + "_lib", + name = "%s_lib" % name, testonly = True, srcs = srcs, - visibility = ["//:oppia_testing_visibility"], deps = deps, ) native.android_binary( - name = name + "Binary", + name = "%sBinary" % name, testonly = True, custom_package = "org.oppia.android", instruments = "//:oppia_test", manifest = "src/javatest/AndroidManifest.xml", - deps = [":" + name + "_lib"], + deps = [":%s_lib" % name], ) native.android_instrumentation_test( diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/BUILD.bazel b/instrumentation/src/javatest/org/oppia/android/instrumentation/BUILD.bazel index 393b0fc0f95..d1e2a994954 100644 --- a/instrumentation/src/javatest/org/oppia/android/instrumentation/BUILD.bazel +++ b/instrumentation/src/javatest/org/oppia/android/instrumentation/BUILD.bazel @@ -6,20 +6,19 @@ Note that: and ends with "_lib" """ -load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_android_library") +load("//instrumentation:oppia_instrumentation_test.bzl", "oppia_instrumentation_test") -exports_files(["player/ExplorationPlayerTest.kt"]) - -kt_android_library( - name = "e2e_test_helper", - testonly = True, +oppia_instrumentation_test( + name = "ExplorationPlayerTest", srcs = [ - "EndToEndTestHelper.kt", + "player/ExplorationPlayerTest.kt", ], - visibility = ["//:oppia_testing_visibility"], deps = [ + "//testing/src/main/java/org/oppia/android/testing/uiautomator:e2e_test_helper", "//third_party:androidx_test_ext_junit", + "//third_party:androidx_test_runner", "//third_party:androidx_test_uiautomator_uiautomator", + "//third_party:com_google_truth_truth", "//third_party:junit_junit", ], ) diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt b/instrumentation/src/javatest/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt index d24754b439e..b20b5240f9c 100644 --- a/instrumentation/src/javatest/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt +++ b/instrumentation/src/javatest/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt @@ -2,20 +2,17 @@ package org.oppia.android.instrumentation.player import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.By -import androidx.test.uiautomator.UiCollection import androidx.test.uiautomator.UiDevice -import androidx.test.uiautomator.UiScrollable import androidx.test.uiautomator.UiSelector -import androidx.test.uiautomator.Until.hasObject -import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Test -import org.oppia.android.instrumentation.EndToEndTestHelper.startOppiaFromScratch +import org.oppia.android.testing.uiautomator.EndToEndTestHelper.findObjectByRes +import org.oppia.android.testing.uiautomator.EndToEndTestHelper.scrollRecyclerViewTextIntoView +import org.oppia.android.testing.uiautomator.EndToEndTestHelper.startOppiaFromScratch +import org.oppia.android.testing.uiautomator.EndToEndTestHelper.waitForRes /** Tests for Explorations. */ class ExplorationPlayerTest { - private val OPPIA_PACKAGE = "org.oppia.android" - private val TRANSITION_TIMEOUT = 5000L private lateinit var device: UiDevice @Before @@ -28,14 +25,8 @@ class ExplorationPlayerTest { @Test fun testExploration_prototypeExploration_toolbarTitle_isDisplayedSuccessfully() { navigateToPrototypeExploration() - device.wait( - hasObject( - By.res("$OPPIA_PACKAGE:id/exploration_toolbar_title") - ), - TRANSITION_TIMEOUT - ) - val explorationTitle = device.findObject(By.res("$OPPIA_PACKAGE:id/exploration_toolbar_title")) - assertEquals("Prototype Exploration", explorationTitle.text) + val explorationTitle = device.findObjectByRes("exploration_toolbar_title") + assertThat(explorationTitle).isNotNull() } /** Navigates and opens the Prototype Exploration using the admin profile. */ @@ -43,27 +34,18 @@ class ExplorationPlayerTest { val skip_button = device.findObject(By.res("$OPPIA_PACKAGE:id/skip_text_view")) skip_button?.let { it.click() - device.wait( - hasObject(By.res("$OPPIA_PACKAGE:id/get_started_button")), - TRANSITION_TIMEOUT - ) - device.findObject(By.res("$OPPIA_PACKAGE:id/get_started_button")) - .click() + device.waitForRes("get_started_button") + device.findObjectByRes("get_started_button").click() } - device.wait( - hasObject(By.res("$OPPIA_PACKAGE:id/profile_select_text")), - TRANSITION_TIMEOUT - ) - val profiles = UiCollection(UiSelector().className("androidx.recyclerview.widget.RecyclerView")) - profiles.getChildByText(UiSelector().className("android.widget.LinearLayout"), "Admin").click() - val recyclerview = UiScrollable(UiSelector().scrollable(true)) - recyclerview.setAsVerticalList() - recyclerview.scrollTextIntoView("First Test Topic") + device.waitForRes("profile_select_text") + device.findObject(By.text("Admin")).click() + scrollRecyclerViewTextIntoView("First Test Topic") val firstTestTopicText = device.findObject(UiSelector().text("First Test Topic")) firstTestTopicText.click() - device.findObject(UiSelector().text("First Test Topic")).click() - device.findObject(UiSelector().text("LESSONS")).click() - device.findObject(UiSelector().text("First Story")).click() - device.findObject(UiSelector().text("Chapter 1: Prototype Exploration")).click() + device.findObject(By.text("First Test Topic")).click() + device.findObject(By.text("LESSONS")).click() + device.findObject(By.text("First Story")).click() + scrollRecyclerViewTextIntoView("Chapter 1: Prototype Exploration") + device.findObject(By.text("Chapter 1: Prototype Exploration")).click() } } diff --git a/instrumentation/tests.bzl b/instrumentation/tests.bzl deleted file mode 100644 index 3a88f16363e..00000000000 --- a/instrumentation/tests.bzl +++ /dev/null @@ -1,9 +0,0 @@ -""" -Contains all the end-to-end test classes under the instrumentation directory. -""" - -# Note to developers: Please keep this dict sorted by key to make it easier to find dependencies. -# This list should contain classname and library target name of each test suite. -END_TO_END_TEST_SUITES = { - "ExplorationPlayerTest": "//instrumentation/src/javatest/org/oppia/android/instrumentation:exploration_player_test_lib", -} diff --git a/testing/build.gradle b/testing/build.gradle index 44051cec11b..9ef4beeac20 100644 --- a/testing/build.gradle +++ b/testing/build.gradle @@ -56,6 +56,7 @@ dependencies { 'androidx.test.espresso:espresso-accessibility:3.1.0', 'androidx.test.espresso:espresso-core:3.2.0', 'androidx.test:runner:1.2.0', + 'androidx.test.uiautomator:uiautomator:2.2.0', 'com.google.dagger:dagger:2.24', 'com.google.truth:truth:0.43', 'nl.dionsegijn:konfetti:1.2.5', diff --git a/testing/src/main/java/org/oppia/android/testing/uiautomator/BUILD.bazel b/testing/src/main/java/org/oppia/android/testing/uiautomator/BUILD.bazel new file mode 100644 index 00000000000..ad8f0d36f3c --- /dev/null +++ b/testing/src/main/java/org/oppia/android/testing/uiautomator/BUILD.bazel @@ -0,0 +1,20 @@ +# TODO(#1532): Rename file to 'BUILD' post-Gradle. +""" +Package for Ui Automator utilities. +""" + +load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_android_library") + +kt_android_library( + name = "e2e_test_helper", + testonly = True, + srcs = [ + "EndToEndTestHelper.kt", + ], + visibility = ["//:oppia_testing_visibility"], + deps = [ + "//third_party:androidx_test_ext_junit", + "//third_party:androidx_test_uiautomator_uiautomator", + "//third_party:junit_junit", + ], +) diff --git a/testing/src/main/java/org/oppia/android/testing/uiautomator/EndToEndTestHelper.kt b/testing/src/main/java/org/oppia/android/testing/uiautomator/EndToEndTestHelper.kt new file mode 100644 index 00000000000..d97022d5cd0 --- /dev/null +++ b/testing/src/main/java/org/oppia/android/testing/uiautomator/EndToEndTestHelper.kt @@ -0,0 +1,63 @@ +package org.oppia.android.testing.uiautomator + +import android.content.Context +import android.content.Intent +import androidx.test.core.app.ApplicationProvider +import androidx.test.uiautomator.By +import androidx.test.uiautomator.UiDevice +import androidx.test.uiautomator.UiObject2 +import androidx.test.uiautomator.UiScrollable +import androidx.test.uiautomator.UiSelector +import androidx.test.uiautomator.Until +import org.junit.Assert.assertTrue + +/** This object contains common operations used for end-to-end tests. */ +object EndToEndTestHelper { + + private val OPPIA_PACKAGE = "org.oppia.android" + private val LAUNCH_TIMEOUT = 30000L + private val TRANSITION_TIMEOUT = 5000L + + /** Starts Oppia from the home screen. */ + fun UiDevice.startOppiaFromScratch() { + // Start from the home screen + pressHome() + + // Wait for launcher + val launcherPackage = findObject(UiSelector().packageName(launcherPackageName)) + launcherPackage.waitForExists(LAUNCH_TIMEOUT) + assertTrue(launcherPackage.exists()) + + // Launch the blueprint app + val context = ApplicationProvider.getApplicationContext() + val intent = context.packageManager.getLaunchIntentForPackage(OPPIA_PACKAGE) + intent!!.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) // Clear out any previous instances + context.startActivity(intent) + + // Wait for the app to appear + val oppiaPackage = findObject(UiSelector().packageName(OPPIA_PACKAGE)) + oppiaPackage.waitForExists(LAUNCH_TIMEOUT) + assertTrue(oppiaPackage.exists()) + } + + /** Waits for the view with given resourceId to appear. */ + fun UiDevice.waitForRes(resourceId: String, timeout: Long = TRANSITION_TIMEOUT) { + wait(Until.hasObject(By.res(resourceId)), timeout) + } + + /** Returns the UiObject for the given resourceId. */ + fun UiDevice.findObjectByRes(resourceId: String): UiObject2 { + return findObject(By.res("$OPPIA_PACKAGE:id/$resourceId")) + } + + /** Performs a scroll until the view with the give text is visible. */ + fun scrollRecyclerViewTextIntoView(text: String, isVertical: Boolean = true) { + val recyclerView = UiScrollable(UiSelector().scrollable(true)) + if (isVertical) { + recyclerView.setAsVerticalList() + } else { + recyclerView.setAsHorizontalList() + } + recyclerView.scrollTextIntoView(text) + } +} From 425ebfaf3a43ff053e893374259c05865ad137fa Mon Sep 17 00:00:00 2001 From: farees Date: Wed, 4 Aug 2021 21:58:11 +0530 Subject: [PATCH 23/63] NIT --- instrumentation/BUILD.bazel | 2 ++ .../oppia_instrumentation_test.bzl | 4 ++-- .../player/ExplorationPlayerTest.kt | 12 +++++------ .../android/testing/uiautomator/BUILD.bazel | 1 + .../testing/uiautomator/EndToEndTestHelper.kt | 20 +++++++++---------- 5 files changed, 20 insertions(+), 19 deletions(-) diff --git a/instrumentation/BUILD.bazel b/instrumentation/BUILD.bazel index 660e52113a1..de81c82bbbb 100644 --- a/instrumentation/BUILD.bazel +++ b/instrumentation/BUILD.bazel @@ -6,6 +6,8 @@ Note that: of the test suite. """ +exports_files(["src/javatest/AndroidManifest.xml"]) + # Used for end-to-end tests android_binary( name = "oppia_test", diff --git a/instrumentation/oppia_instrumentation_test.bzl b/instrumentation/oppia_instrumentation_test.bzl index b1c76a47b2b..5d935ebe833 100644 --- a/instrumentation/oppia_instrumentation_test.bzl +++ b/instrumentation/oppia_instrumentation_test.bzl @@ -27,8 +27,8 @@ def oppia_instrumentation_test( name = "%sBinary" % name, testonly = True, custom_package = "org.oppia.android", - instruments = "//:oppia_test", - manifest = "src/javatest/AndroidManifest.xml", + instruments = "//instrumentation:oppia_test", + manifest = "//instrumentation:src/javatest/AndroidManifest.xml", deps = [":%s_lib" % name], ) diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt b/instrumentation/src/javatest/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt index b20b5240f9c..20bbbf39771 100644 --- a/instrumentation/src/javatest/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt +++ b/instrumentation/src/javatest/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt @@ -3,7 +3,7 @@ package org.oppia.android.instrumentation.player import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.By import androidx.test.uiautomator.UiDevice -import androidx.test.uiautomator.UiSelector +import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test import org.oppia.android.testing.uiautomator.EndToEndTestHelper.findObjectByRes @@ -25,24 +25,22 @@ class ExplorationPlayerTest { @Test fun testExploration_prototypeExploration_toolbarTitle_isDisplayedSuccessfully() { navigateToPrototypeExploration() - val explorationTitle = device.findObjectByRes("exploration_toolbar_title") - assertThat(explorationTitle).isNotNull() + assertThat(device.findObjectByRes("exploration_toolbar_title")).isNotNull() } /** Navigates and opens the Prototype Exploration using the admin profile. */ private fun navigateToPrototypeExploration() { - val skip_button = device.findObject(By.res("$OPPIA_PACKAGE:id/skip_text_view")) + val skip_button = device.findObjectByRes("skip_text_view") skip_button?.let { it.click() device.waitForRes("get_started_button") - device.findObjectByRes("get_started_button").click() + device.findObjectByRes("get_started_button")?.click() } device.waitForRes("profile_select_text") device.findObject(By.text("Admin")).click() scrollRecyclerViewTextIntoView("First Test Topic") - val firstTestTopicText = device.findObject(UiSelector().text("First Test Topic")) - firstTestTopicText.click() device.findObject(By.text("First Test Topic")).click() + device.waitForRes("topic_toolbar_title") device.findObject(By.text("LESSONS")).click() device.findObject(By.text("First Story")).click() scrollRecyclerViewTextIntoView("Chapter 1: Prototype Exploration") diff --git a/testing/src/main/java/org/oppia/android/testing/uiautomator/BUILD.bazel b/testing/src/main/java/org/oppia/android/testing/uiautomator/BUILD.bazel index ad8f0d36f3c..3080489574e 100644 --- a/testing/src/main/java/org/oppia/android/testing/uiautomator/BUILD.bazel +++ b/testing/src/main/java/org/oppia/android/testing/uiautomator/BUILD.bazel @@ -15,6 +15,7 @@ kt_android_library( deps = [ "//third_party:androidx_test_ext_junit", "//third_party:androidx_test_uiautomator_uiautomator", + "//third_party:com_google_truth_truth", "//third_party:junit_junit", ], ) diff --git a/testing/src/main/java/org/oppia/android/testing/uiautomator/EndToEndTestHelper.kt b/testing/src/main/java/org/oppia/android/testing/uiautomator/EndToEndTestHelper.kt index d97022d5cd0..652f31ad7a0 100644 --- a/testing/src/main/java/org/oppia/android/testing/uiautomator/EndToEndTestHelper.kt +++ b/testing/src/main/java/org/oppia/android/testing/uiautomator/EndToEndTestHelper.kt @@ -9,7 +9,7 @@ import androidx.test.uiautomator.UiObject2 import androidx.test.uiautomator.UiScrollable import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.Until -import org.junit.Assert.assertTrue +import com.google.common.truth.Truth.assertThat /** This object contains common operations used for end-to-end tests. */ object EndToEndTestHelper { @@ -21,23 +21,22 @@ object EndToEndTestHelper { /** Starts Oppia from the home screen. */ fun UiDevice.startOppiaFromScratch() { // Start from the home screen - pressHome() + this.pressHome() // Wait for launcher - val launcherPackage = findObject(UiSelector().packageName(launcherPackageName)) - launcherPackage.waitForExists(LAUNCH_TIMEOUT) - assertTrue(launcherPackage.exists()) + val launcherPackage = launcherPackageName + assertThat(launcherPackage).isNotNull() + this.wait(Until.hasObject(By.pkg(launcherPackage).depth(1)), LAUNCH_TIMEOUT) // Launch the blueprint app val context = ApplicationProvider.getApplicationContext() - val intent = context.packageManager.getLaunchIntentForPackage(OPPIA_PACKAGE) + val intent = context.packageManager + .getLaunchIntentForPackage(OPPIA_PACKAGE) intent!!.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) // Clear out any previous instances context.startActivity(intent) // Wait for the app to appear - val oppiaPackage = findObject(UiSelector().packageName(OPPIA_PACKAGE)) - oppiaPackage.waitForExists(LAUNCH_TIMEOUT) - assertTrue(oppiaPackage.exists()) + this.wait(Until.hasObject(By.pkg(OPPIA_PACKAGE)), LAUNCH_TIMEOUT) } /** Waits for the view with given resourceId to appear. */ @@ -46,7 +45,8 @@ object EndToEndTestHelper { } /** Returns the UiObject for the given resourceId. */ - fun UiDevice.findObjectByRes(resourceId: String): UiObject2 { + fun UiDevice.findObjectByRes(resourceId: String): UiObject2? { + waitForRes(resourceId) return findObject(By.res("$OPPIA_PACKAGE:id/$resourceId")) } From 067537f703764ed5b3dd0317d80bcfc5e61d880a Mon Sep 17 00:00:00 2001 From: farees Date: Thu, 5 Aug 2021 02:43:41 +0530 Subject: [PATCH 24/63] NIT --- scripts/assets/test_file_exemptions.textproto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/assets/test_file_exemptions.textproto b/scripts/assets/test_file_exemptions.textproto index bf1f2cb511f..e54cba5ebae 100644 --- a/scripts/assets/test_file_exemptions.textproto +++ b/scripts/assets/test_file_exemptions.textproto @@ -556,7 +556,6 @@ exempted_file_path: "domain/src/main/java/org/oppia/android/domain/util/FloatExt exempted_file_path: "domain/src/main/java/org/oppia/android/domain/util/FractionExtensions.kt" exempted_file_path: "domain/src/main/java/org/oppia/android/domain/util/JsonAssetRetriever.kt" exempted_file_path: "domain/src/test/java/org/oppia/android/domain/classify/InteractionObjectTestBuilder.kt" -exempted_file_path: "instrumentation/src/javatest/org/oppia/android/instrumentation/EndToEndTestHelper.kt" exempted_file_path: "scripts/src/java/org/oppia/android/scripts/common/CommandExecutor.kt" exempted_file_path: "scripts/src/java/org/oppia/android/scripts/common/CommandResult.kt" exempted_file_path: "scripts/src/java/org/oppia/android/scripts/maven/data/MavenListDependency.kt" @@ -601,6 +600,7 @@ exempted_file_path: "testing/src/main/java/org/oppia/android/testing/threading/T exempted_file_path: "testing/src/main/java/org/oppia/android/testing/time/FakeOppiaClockModule.kt" exempted_file_path: "testing/src/main/java/org/oppia/android/testing/time/FakeSystemClock.kt" exempted_file_path: "testing/src/test/java/org/oppia/android/testing/threading/TestCoroutineDispatcherTestBase.kt" +exempted_file_path: "testing/src/main/java/org/oppia/android/testing/uiautomator/EndToEndTestHelper.kt" exempted_file_path: "utility/src/main/java/org/oppia/android/util/accessibility/AccessibilityChecker.kt" exempted_file_path: "utility/src/main/java/org/oppia/android/util/accessibility/AccessibilityCheckerImpl.kt" exempted_file_path: "utility/src/main/java/org/oppia/android/util/accessibility/AccessibilityProdModule.kt" From b9233c6c556ea7e4c3c9bf339bc4c3c2d6e2eb0d Mon Sep 17 00:00:00 2001 From: farees Date: Thu, 5 Aug 2021 03:58:38 +0530 Subject: [PATCH 25/63] deleted the previous utility --- .../instrumentation/EndToEndTestHelper.kt | 37 ------------------- 1 file changed, 37 deletions(-) delete mode 100644 instrumentation/src/javatest/org/oppia/android/instrumentation/EndToEndTestHelper.kt diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/EndToEndTestHelper.kt b/instrumentation/src/javatest/org/oppia/android/instrumentation/EndToEndTestHelper.kt deleted file mode 100644 index ee136884019..00000000000 --- a/instrumentation/src/javatest/org/oppia/android/instrumentation/EndToEndTestHelper.kt +++ /dev/null @@ -1,37 +0,0 @@ -package org.oppia.android.instrumentation - -import android.content.Context -import android.content.Intent -import androidx.test.core.app.ApplicationProvider -import androidx.test.uiautomator.By -import androidx.test.uiautomator.UiDevice -import androidx.test.uiautomator.Until -import org.junit.Assert - -/** This object contains common operations used for end-to-end tests. */ -object EndToEndTestHelper { - - private val OPPIA_PACKAGE = "org.oppia.android" - private val LAUNCH_TIMEOUT = 30000L - - /** Starts oppia from HomeScreen. */ - fun UiDevice.startOppiaFromScratch() { - // Start from the home screen - this.pressHome() - - // Wait for launcher - val launcherPackage = launcherPackageName - Assert.assertNotNull(launcherPackage) - this.wait(Until.hasObject(By.pkg(launcherPackage).depth(1)), LAUNCH_TIMEOUT) - - // Launch the blueprint app - val context = ApplicationProvider.getApplicationContext() - val intent = context.packageManager - .getLaunchIntentForPackage(OPPIA_PACKAGE) - intent!!.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) // Clear out any previous instances - context.startActivity(intent) - - // Wait for the app to appear - this.wait(Until.hasObject(By.pkg(OPPIA_PACKAGE)), LAUNCH_TIMEOUT) - } -} From 37b10e2ce4c7ef0844fe130396c50f31da81bbe5 Mon Sep 17 00:00:00 2001 From: farees Date: Thu, 5 Aug 2021 21:32:06 +0530 Subject: [PATCH 26/63] ignoring instrumentation in ComputeAffectedTests.kt --- .../instrumentation/{ => player}/BUILD.bazel | 10 +++------- .../player/ExplorationPlayerTest.kt | 17 +++++++---------- .../instrumentation/testing/BUILD.bazel | 19 +++++++++++++++++++ .../testing}/EndToEndTestHelper.kt | 14 +++++++------- .../scripts/ci/ComputeAffectedTests.kt | 9 ++++++--- testing/build.gradle | 1 - 6 files changed, 42 insertions(+), 28 deletions(-) rename instrumentation/src/javatest/org/oppia/android/instrumentation/{ => player}/BUILD.bazel (52%) create mode 100644 instrumentation/src/javatest/org/oppia/android/instrumentation/testing/BUILD.bazel rename {testing/src/main/java/org/oppia/android/testing/uiautomator => instrumentation/src/javatest/org/oppia/android/instrumentation/testing}/EndToEndTestHelper.kt (84%) diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/BUILD.bazel b/instrumentation/src/javatest/org/oppia/android/instrumentation/player/BUILD.bazel similarity index 52% rename from instrumentation/src/javatest/org/oppia/android/instrumentation/BUILD.bazel rename to instrumentation/src/javatest/org/oppia/android/instrumentation/player/BUILD.bazel index d1e2a994954..981d2c8694a 100644 --- a/instrumentation/src/javatest/org/oppia/android/instrumentation/BUILD.bazel +++ b/instrumentation/src/javatest/org/oppia/android/instrumentation/player/BUILD.bazel @@ -1,9 +1,5 @@ """ -This library contains the test suite source files of the instrumentation module. -Note that: - - Each source file has its own kt_android_library target - - Target name of each kt_android_library as to be in small letters, separated by a underscore - and ends with "_lib" +This library contains the test suite source files of the player package. """ load("//instrumentation:oppia_instrumentation_test.bzl", "oppia_instrumentation_test") @@ -11,10 +7,10 @@ load("//instrumentation:oppia_instrumentation_test.bzl", "oppia_instrumentation_ oppia_instrumentation_test( name = "ExplorationPlayerTest", srcs = [ - "player/ExplorationPlayerTest.kt", + "ExplorationPlayerTest.kt", ], deps = [ - "//testing/src/main/java/org/oppia/android/testing/uiautomator:e2e_test_helper", + "//instrumentation/src/javatest/org/oppia/android/instrumentation/testing:e2e_test_helper", "//third_party:androidx_test_ext_junit", "//third_party:androidx_test_runner", "//third_party:androidx_test_uiautomator_uiautomator", diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt b/instrumentation/src/javatest/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt index 20bbbf39771..b90fa294e07 100644 --- a/instrumentation/src/javatest/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt +++ b/instrumentation/src/javatest/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt @@ -6,10 +6,10 @@ import androidx.test.uiautomator.UiDevice import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test -import org.oppia.android.testing.uiautomator.EndToEndTestHelper.findObjectByRes -import org.oppia.android.testing.uiautomator.EndToEndTestHelper.scrollRecyclerViewTextIntoView -import org.oppia.android.testing.uiautomator.EndToEndTestHelper.startOppiaFromScratch -import org.oppia.android.testing.uiautomator.EndToEndTestHelper.waitForRes +import org.oppia.android.instrumentation.testing.EndToEndTestHelper.findObjectByRes +import org.oppia.android.instrumentation.testing.EndToEndTestHelper.scrollRecyclerViewTextIntoView +import org.oppia.android.instrumentation.testing.EndToEndTestHelper.startOppiaFromScratch +import org.oppia.android.instrumentation.testing.EndToEndTestHelper.waitForRes /** Tests for Explorations. */ class ExplorationPlayerTest { @@ -30,12 +30,9 @@ class ExplorationPlayerTest { /** Navigates and opens the Prototype Exploration using the admin profile. */ private fun navigateToPrototypeExploration() { - val skip_button = device.findObjectByRes("skip_text_view") - skip_button?.let { - it.click() - device.waitForRes("get_started_button") - device.findObjectByRes("get_started_button")?.click() - } + device.findObjectByRes("skip_text_view")?.click() + device.waitForRes("get_started_button") + device.findObjectByRes("get_started_button")?.click() device.waitForRes("profile_select_text") device.findObject(By.text("Admin")).click() scrollRecyclerViewTextIntoView("First Test Topic") diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/testing/BUILD.bazel b/instrumentation/src/javatest/org/oppia/android/instrumentation/testing/BUILD.bazel new file mode 100644 index 00000000000..17eb91b6c69 --- /dev/null +++ b/instrumentation/src/javatest/org/oppia/android/instrumentation/testing/BUILD.bazel @@ -0,0 +1,19 @@ +""" +This library contains the utilities used in end-to-end testing. +""" + +load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_android_library") + +kt_android_library( + name = "e2e_test_helper", + testonly = True, + srcs = [ + "EndToEndTestHelper.kt", + ], + visibility = ["//:oppia_testing_visibility"], + deps = [ + "//third_party:androidx_test_ext_junit", + "//third_party:androidx_test_uiautomator_uiautomator", + "//third_party:com_google_truth_truth", + ], +) diff --git a/testing/src/main/java/org/oppia/android/testing/uiautomator/EndToEndTestHelper.kt b/instrumentation/src/javatest/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt similarity index 84% rename from testing/src/main/java/org/oppia/android/testing/uiautomator/EndToEndTestHelper.kt rename to instrumentation/src/javatest/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt index 652f31ad7a0..ed2c1c928ce 100644 --- a/testing/src/main/java/org/oppia/android/testing/uiautomator/EndToEndTestHelper.kt +++ b/instrumentation/src/javatest/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt @@ -1,4 +1,4 @@ -package org.oppia.android.testing.uiautomator +package org.oppia.android.instrumentation.testing import android.content.Context import android.content.Intent @@ -15,18 +15,18 @@ import com.google.common.truth.Truth.assertThat object EndToEndTestHelper { private val OPPIA_PACKAGE = "org.oppia.android" - private val LAUNCH_TIMEOUT = 30000L - private val TRANSITION_TIMEOUT = 5000L + private val LAUNCH_TIMEOUT_30_SECONDS = 30000L + private val TRANSITION_TIMEOUT_5_SECONDS = 5000L /** Starts Oppia from the home screen. */ fun UiDevice.startOppiaFromScratch() { // Start from the home screen - this.pressHome() + pressHome() // Wait for launcher val launcherPackage = launcherPackageName assertThat(launcherPackage).isNotNull() - this.wait(Until.hasObject(By.pkg(launcherPackage).depth(1)), LAUNCH_TIMEOUT) + wait(Until.hasObject(By.pkg(launcherPackage).depth(1)), LAUNCH_TIMEOUT_30_SECONDS) // Launch the blueprint app val context = ApplicationProvider.getApplicationContext() @@ -36,11 +36,11 @@ object EndToEndTestHelper { context.startActivity(intent) // Wait for the app to appear - this.wait(Until.hasObject(By.pkg(OPPIA_PACKAGE)), LAUNCH_TIMEOUT) + wait(Until.hasObject(By.pkg(OPPIA_PACKAGE)), LAUNCH_TIMEOUT_30_SECONDS) } /** Waits for the view with given resourceId to appear. */ - fun UiDevice.waitForRes(resourceId: String, timeout: Long = TRANSITION_TIMEOUT) { + fun UiDevice.waitForRes(resourceId: String, timeout: Long = TRANSITION_TIMEOUT_5_SECONDS) { wait(Until.hasObject(By.res(resourceId)), timeout) } diff --git a/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt b/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt index b4f6172028d..b184802a032 100644 --- a/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt +++ b/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt @@ -91,9 +91,12 @@ private fun computeAffectedTargetsForNonDevelopBranch( // Compute the list of Bazel files that were changed. val changedBazelFiles = changedFiles.filter { file -> - file.endsWith(".bzl", ignoreCase = true) || - file.endsWith(".bazel", ignoreCase = true) || - file == "WORKSPACE" + ( + file.endsWith(".bzl", ignoreCase = true) || + file.endsWith(".bazel", ignoreCase = true) || + file == "WORKSPACE" + ) && + file.startsWith("instrumentation/") } println("Changed Bazel-specific support files: $changedBazelFiles") diff --git a/testing/build.gradle b/testing/build.gradle index 9ef4beeac20..44051cec11b 100644 --- a/testing/build.gradle +++ b/testing/build.gradle @@ -56,7 +56,6 @@ dependencies { 'androidx.test.espresso:espresso-accessibility:3.1.0', 'androidx.test.espresso:espresso-core:3.2.0', 'androidx.test:runner:1.2.0', - 'androidx.test.uiautomator:uiautomator:2.2.0', 'com.google.dagger:dagger:2.24', 'com.google.truth:truth:0.43', 'nl.dionsegijn:konfetti:1.2.5', From 3c1e79f476a0f2a751387f2690c0df57ac5daf5b Mon Sep 17 00:00:00 2001 From: farees Date: Thu, 5 Aug 2021 22:46:58 +0530 Subject: [PATCH 27/63] NIT --- scripts/assets/test_file_exemptions.textproto | 2 +- .../scripts/ci/ComputeAffectedTests.kt | 19 +++++++++++-------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/scripts/assets/test_file_exemptions.textproto b/scripts/assets/test_file_exemptions.textproto index e54cba5ebae..d95594a32fb 100644 --- a/scripts/assets/test_file_exemptions.textproto +++ b/scripts/assets/test_file_exemptions.textproto @@ -556,6 +556,7 @@ exempted_file_path: "domain/src/main/java/org/oppia/android/domain/util/FloatExt exempted_file_path: "domain/src/main/java/org/oppia/android/domain/util/FractionExtensions.kt" exempted_file_path: "domain/src/main/java/org/oppia/android/domain/util/JsonAssetRetriever.kt" exempted_file_path: "domain/src/test/java/org/oppia/android/domain/classify/InteractionObjectTestBuilder.kt" +exempted_file_path: "instrumentation/src/javatest/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt" exempted_file_path: "scripts/src/java/org/oppia/android/scripts/common/CommandExecutor.kt" exempted_file_path: "scripts/src/java/org/oppia/android/scripts/common/CommandResult.kt" exempted_file_path: "scripts/src/java/org/oppia/android/scripts/maven/data/MavenListDependency.kt" @@ -600,7 +601,6 @@ exempted_file_path: "testing/src/main/java/org/oppia/android/testing/threading/T exempted_file_path: "testing/src/main/java/org/oppia/android/testing/time/FakeOppiaClockModule.kt" exempted_file_path: "testing/src/main/java/org/oppia/android/testing/time/FakeSystemClock.kt" exempted_file_path: "testing/src/test/java/org/oppia/android/testing/threading/TestCoroutineDispatcherTestBase.kt" -exempted_file_path: "testing/src/main/java/org/oppia/android/testing/uiautomator/EndToEndTestHelper.kt" exempted_file_path: "utility/src/main/java/org/oppia/android/util/accessibility/AccessibilityChecker.kt" exempted_file_path: "utility/src/main/java/org/oppia/android/util/accessibility/AccessibilityCheckerImpl.kt" exempted_file_path: "utility/src/main/java/org/oppia/android/util/accessibility/AccessibilityProdModule.kt" diff --git a/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt b/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt index b184802a032..87ba8a316fc 100644 --- a/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt +++ b/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt @@ -91,18 +91,21 @@ private fun computeAffectedTargetsForNonDevelopBranch( // Compute the list of Bazel files that were changed. val changedBazelFiles = changedFiles.filter { file -> - ( - file.endsWith(".bzl", ignoreCase = true) || - file.endsWith(".bazel", ignoreCase = true) || - file == "WORKSPACE" - ) && - file.startsWith("instrumentation/") + file.endsWith(".bzl", ignoreCase = true) || + file.endsWith(".bazel", ignoreCase = true) || + file == "WORKSPACE" } - println("Changed Bazel-specific support files: $changedBazelFiles") + + // The list of Bazel files to be ignored in the CI. + val filteredBazelFiles = changedBazelFiles.filter { file -> + file.startsWith("instrumentation", ignorecase = true) + } + + println("Changed Bazel-specific support files: $filteredBazelFiles") // Compute the list of affected tests based on BUILD/Bazel/WORKSPACE files. These are generally // framed as: if a BUILD file changes, run all tests transitively connected to it. - val transitiveTestTargets = bazelClient.retrieveTransitiveTestTargets(changedBazelFiles) + val transitiveTestTargets = bazelClient.retrieveTransitiveTestTargets(filteredBazelFiles) println("Affected test targets due to transitive build deps: $transitiveTestTargets") val allAffectedTestTargets = (affectedTestTargets + transitiveTestTargets).toSet() From 44363c1c4e7425499b5a3ab5adb2763618cfb6b1 Mon Sep 17 00:00:00 2001 From: farees Date: Fri, 6 Aug 2021 00:49:03 +0530 Subject: [PATCH 28/63] NIT --- .../java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt b/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt index 87ba8a316fc..5f685ff80de 100644 --- a/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt +++ b/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt @@ -98,7 +98,7 @@ private fun computeAffectedTargetsForNonDevelopBranch( // The list of Bazel files to be ignored in the CI. val filteredBazelFiles = changedBazelFiles.filter { file -> - file.startsWith("instrumentation", ignorecase = true) + !file.startsWith("instrumentation/", ignoreCase = true) } println("Changed Bazel-specific support files: $filteredBazelFiles") From e95d29fb40426eda05d0278b3efe0b1e90d2349e Mon Sep 17 00:00:00 2001 From: farees Date: Fri, 6 Aug 2021 15:19:24 +0530 Subject: [PATCH 29/63] NIT --- .../java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt b/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt index 5f685ff80de..1f59494e4bd 100644 --- a/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt +++ b/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt @@ -98,7 +98,7 @@ private fun computeAffectedTargetsForNonDevelopBranch( // The list of Bazel files to be ignored in the CI. val filteredBazelFiles = changedBazelFiles.filter { file -> - !file.startsWith("instrumentation/", ignoreCase = true) + !file.startsWith("//instrumentation/", ignoreCase = true) } println("Changed Bazel-specific support files: $filteredBazelFiles") From c608f7c2ed356ee2bc4e455e176d4a9fed9ab7a4 Mon Sep 17 00:00:00 2001 From: farees Date: Fri, 6 Aug 2021 15:29:15 +0530 Subject: [PATCH 30/63] changed startsWith("instrumentation/") --- .../java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt b/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt index 1f59494e4bd..5f685ff80de 100644 --- a/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt +++ b/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt @@ -98,7 +98,7 @@ private fun computeAffectedTargetsForNonDevelopBranch( // The list of Bazel files to be ignored in the CI. val filteredBazelFiles = changedBazelFiles.filter { file -> - !file.startsWith("//instrumentation/", ignoreCase = true) + !file.startsWith("instrumentation/", ignoreCase = true) } println("Changed Bazel-specific support files: $filteredBazelFiles") From 66f6b5125d81bb05e0adaff22525ee14e878dfa0 Mon Sep 17 00:00:00 2001 From: farees Date: Fri, 6 Aug 2021 16:22:14 +0530 Subject: [PATCH 31/63] filtered bazel targets --- .../java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt b/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt index 5f685ff80de..6920286ca5c 100644 --- a/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt +++ b/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt @@ -84,6 +84,9 @@ private fun computeAffectedTargetsForNonDevelopBranch( println("Changed files (per Git): $changedFiles") val changedFileTargets = bazelClient.retrieveBazelTargets(changedFiles).toSet() + val filteredFileTargets = changedFileTargets.filter { file -> + !file.startsWith("//instrumentation/", ignoreCase = true) + } println("Changed Bazel file targets: $changedFileTargets") val affectedTestTargets = bazelClient.retrieveRelatedTestTargets(changedFileTargets).toSet() From 6514ba9cc8c98612ac02f98f4d87cdb9bc5b9453 Mon Sep 17 00:00:00 2001 From: farees Date: Fri, 6 Aug 2021 17:06:55 +0530 Subject: [PATCH 32/63] NIT --- .../java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt b/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt index 6920286ca5c..34dc80400fa 100644 --- a/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt +++ b/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt @@ -87,9 +87,9 @@ private fun computeAffectedTargetsForNonDevelopBranch( val filteredFileTargets = changedFileTargets.filter { file -> !file.startsWith("//instrumentation/", ignoreCase = true) } - println("Changed Bazel file targets: $changedFileTargets") + println("Changed Bazel file targets: $filteredFileTargets") - val affectedTestTargets = bazelClient.retrieveRelatedTestTargets(changedFileTargets).toSet() + val affectedTestTargets = bazelClient.retrieveRelatedTestTargets(filteredFileTargets).toSet() println("Affected Bazel test targets: $affectedTestTargets") // Compute the list of Bazel files that were changed. From e81706bc8d42b61589e6ef70f163dcc134601ced Mon Sep 17 00:00:00 2001 From: farees Date: Fri, 6 Aug 2021 18:26:58 +0530 Subject: [PATCH 33/63] NIT --- .../java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt b/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt index 34dc80400fa..b155620dd82 100644 --- a/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt +++ b/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt @@ -84,8 +84,10 @@ private fun computeAffectedTargetsForNonDevelopBranch( println("Changed files (per Git): $changedFiles") val changedFileTargets = bazelClient.retrieveBazelTargets(changedFiles).toSet() + + // The list of Bazel targets to be ignored in the CI. val filteredFileTargets = changedFileTargets.filter { file -> - !file.startsWith("//instrumentation/", ignoreCase = true) + !file.startsWith("//instrumentation", ignoreCase = true) } println("Changed Bazel file targets: $filteredFileTargets") From a4266e4dd5c421b4c2c4a9fb5e50d0f3fb10d274 Mon Sep 17 00:00:00 2001 From: farees Date: Fri, 6 Aug 2021 19:16:07 +0530 Subject: [PATCH 34/63] filtering the instrumentation from the total affected targets --- .../scripts/ci/ComputeAffectedTests.kt | 31 +++++++++---------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt b/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt index b155620dd82..c1347302fc6 100644 --- a/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt +++ b/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt @@ -84,14 +84,9 @@ private fun computeAffectedTargetsForNonDevelopBranch( println("Changed files (per Git): $changedFiles") val changedFileTargets = bazelClient.retrieveBazelTargets(changedFiles).toSet() + println("Changed Bazel file targets: $changedFileTargets") - // The list of Bazel targets to be ignored in the CI. - val filteredFileTargets = changedFileTargets.filter { file -> - !file.startsWith("//instrumentation", ignoreCase = true) - } - println("Changed Bazel file targets: $filteredFileTargets") - - val affectedTestTargets = bazelClient.retrieveRelatedTestTargets(filteredFileTargets).toSet() + val affectedTestTargets = bazelClient.retrieveRelatedTestTargets(changedFileTargets).toSet() println("Affected Bazel test targets: $affectedTestTargets") // Compute the list of Bazel files that were changed. @@ -100,24 +95,26 @@ private fun computeAffectedTargetsForNonDevelopBranch( file.endsWith(".bazel", ignoreCase = true) || file == "WORKSPACE" } - - // The list of Bazel files to be ignored in the CI. - val filteredBazelFiles = changedBazelFiles.filter { file -> - !file.startsWith("instrumentation/", ignoreCase = true) - } - - println("Changed Bazel-specific support files: $filteredBazelFiles") + println("Changed Bazel-specific support files: $changedBazelFiles") // Compute the list of affected tests based on BUILD/Bazel/WORKSPACE files. These are generally // framed as: if a BUILD file changes, run all tests transitively connected to it. - val transitiveTestTargets = bazelClient.retrieveTransitiveTestTargets(filteredBazelFiles) + val transitiveTestTargets = bazelClient.retrieveTransitiveTestTargets(changedBazelFiles) println("Affected test targets due to transitive build deps: $transitiveTestTargets") val allAffectedTestTargets = (affectedTestTargets + transitiveTestTargets).toSet() + + // Filtering out the targets to be ignored. + val filteredAffectedTestTargets = allAffectedTestTargets.filter { file -> + !file.startsWith("//instrumentation", ignoreCase = true) + } + println() println( "Affected test targets:" + - "\n${allAffectedTestTargets.joinToString(separator = "\n") { "- $it" }}" + "\n${filteredAffectedTestTargets.joinToString(separator = "\n") { "- $it" }}" ) - outputFile.printWriter().use { writer -> allAffectedTestTargets.forEach { writer.println(it) } } + outputFile.printWriter().use { writer -> + filteredAffectedTestTargets.forEach { writer.println(it) } + } } From 6f2836c6ba9d9ee0688fa3e5d2663c53a0db139f Mon Sep 17 00:00:00 2001 From: farees Date: Fri, 6 Aug 2021 20:09:40 +0530 Subject: [PATCH 35/63] NIT --- .../java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt b/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt index c1347302fc6..fce201ad18e 100644 --- a/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt +++ b/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt @@ -105,8 +105,8 @@ private fun computeAffectedTargetsForNonDevelopBranch( val allAffectedTestTargets = (affectedTestTargets + transitiveTestTargets).toSet() // Filtering out the targets to be ignored. - val filteredAffectedTestTargets = allAffectedTestTargets.filter { file -> - !file.startsWith("//instrumentation", ignoreCase = true) + val filteredAffectedTestTargets = allAffectedTestTargets.filter { targetPath -> + !targetPath.startsWith("//instrumentation", ignoreCase = true) } println() From 366024393dd73ea0a8e0b235150b722e77d9d0b7 Mon Sep 17 00:00:00 2001 From: farees Date: Tue, 10 Aug 2021 17:56:41 +0530 Subject: [PATCH 36/63] changed directory to javatests --- instrumentation/BUILD.bazel | 2 +- .../oppia_instrumentation_test.bzl | 4 ++-- .../instrumentation/testing/BUILD.bazel | 0 .../testing/EndToEndTestHelper.kt | 21 ++++++++++++++----- .../AndroidManifest.xml | 0 .../instrumentation/player/BUILD.bazel | 2 +- .../player/ExplorationPlayerTest.kt | 14 ++++++------- .../scripts/ci/ComputeAffectedTests.kt | 6 +++--- .../scripts/ci/ComputeAffectedTestsTest.kt | 10 +++++++++ 9 files changed, 39 insertions(+), 20 deletions(-) rename instrumentation/src/{javatest => java}/org/oppia/android/instrumentation/testing/BUILD.bazel (100%) rename instrumentation/src/{javatest => java}/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt (81%) rename instrumentation/src/{javatest => javatests}/AndroidManifest.xml (100%) rename instrumentation/src/{javatest => javatests}/org/oppia/android/instrumentation/player/BUILD.bazel (84%) rename instrumentation/src/{javatest => javatests}/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt (78%) diff --git a/instrumentation/BUILD.bazel b/instrumentation/BUILD.bazel index de81c82bbbb..6dc61c1ce98 100644 --- a/instrumentation/BUILD.bazel +++ b/instrumentation/BUILD.bazel @@ -6,7 +6,7 @@ Note that: of the test suite. """ -exports_files(["src/javatest/AndroidManifest.xml"]) +exports_files(["src/javatests/AndroidManifest.xml"]) # Used for end-to-end tests android_binary( diff --git a/instrumentation/oppia_instrumentation_test.bzl b/instrumentation/oppia_instrumentation_test.bzl index 5d935ebe833..e61e3c1ae7d 100644 --- a/instrumentation/oppia_instrumentation_test.bzl +++ b/instrumentation/oppia_instrumentation_test.bzl @@ -28,12 +28,12 @@ def oppia_instrumentation_test( testonly = True, custom_package = "org.oppia.android", instruments = "//instrumentation:oppia_test", - manifest = "//instrumentation:src/javatest/AndroidManifest.xml", + manifest = "//instrumentation:src/javatests/AndroidManifest.xml", deps = [":%s_lib" % name], ) native.android_instrumentation_test( name = name, target_device = "@android_test_support//tools/android/emulated_devices/generic_phone:android_23_x86_qemu2", - test_app = ":" + name + "Binary", + test_app = ":%sBinary" % name, ) diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/testing/BUILD.bazel b/instrumentation/src/java/org/oppia/android/instrumentation/testing/BUILD.bazel similarity index 100% rename from instrumentation/src/javatest/org/oppia/android/instrumentation/testing/BUILD.bazel rename to instrumentation/src/java/org/oppia/android/instrumentation/testing/BUILD.bazel diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt b/instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt similarity index 81% rename from instrumentation/src/javatest/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt rename to instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt index ed2c1c928ce..776b59a704b 100644 --- a/instrumentation/src/javatest/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt +++ b/instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt @@ -15,8 +15,8 @@ import com.google.common.truth.Truth.assertThat object EndToEndTestHelper { private val OPPIA_PACKAGE = "org.oppia.android" - private val LAUNCH_TIMEOUT_30_SECONDS = 30000L - private val TRANSITION_TIMEOUT_5_SECONDS = 5000L + private val LAUNCH_TIMEOUT_SECONDS = 30000L + private val TRANSITION_TIMEOUT_SECONDS = 5000L /** Starts Oppia from the home screen. */ fun UiDevice.startOppiaFromScratch() { @@ -26,7 +26,7 @@ object EndToEndTestHelper { // Wait for launcher val launcherPackage = launcherPackageName assertThat(launcherPackage).isNotNull() - wait(Until.hasObject(By.pkg(launcherPackage).depth(1)), LAUNCH_TIMEOUT_30_SECONDS) + wait(Until.hasObject(By.pkg(launcherPackage).depth(1)), LAUNCH_TIMEOUT_SECONDS) // Launch the blueprint app val context = ApplicationProvider.getApplicationContext() @@ -36,14 +36,25 @@ object EndToEndTestHelper { context.startActivity(intent) // Wait for the app to appear - wait(Until.hasObject(By.pkg(OPPIA_PACKAGE)), LAUNCH_TIMEOUT_30_SECONDS) + wait(Until.hasObject(By.pkg(OPPIA_PACKAGE)), LAUNCH_TIMEOUT_SECONDS) } /** Waits for the view with given resourceId to appear. */ - fun UiDevice.waitForRes(resourceId: String, timeout: Long = TRANSITION_TIMEOUT_5_SECONDS) { + fun UiDevice.waitForRes(resourceId: String, timeout: Long = TRANSITION_TIMEOUT_SECONDS) { wait(Until.hasObject(By.res(resourceId)), timeout) } + /** Waits for the view with given text to appear. */ + fun UiDevice.waitForText(text: String) { + wait(Until.hasObject(By.text(text)), TRANSITION_TIMEOUT_SECONDS) + } + + /** Return the UiObject with the given text. */ + fun UiDevice.findObjectByText(text: String): UiObject2? { + waitForText(text) + return findObject(By.text(text)) + } + /** Returns the UiObject for the given resourceId. */ fun UiDevice.findObjectByRes(resourceId: String): UiObject2? { waitForRes(resourceId) diff --git a/instrumentation/src/javatest/AndroidManifest.xml b/instrumentation/src/javatests/AndroidManifest.xml similarity index 100% rename from instrumentation/src/javatest/AndroidManifest.xml rename to instrumentation/src/javatests/AndroidManifest.xml diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/player/BUILD.bazel b/instrumentation/src/javatests/org/oppia/android/instrumentation/player/BUILD.bazel similarity index 84% rename from instrumentation/src/javatest/org/oppia/android/instrumentation/player/BUILD.bazel rename to instrumentation/src/javatests/org/oppia/android/instrumentation/player/BUILD.bazel index 981d2c8694a..35cdf45f2b4 100644 --- a/instrumentation/src/javatest/org/oppia/android/instrumentation/player/BUILD.bazel +++ b/instrumentation/src/javatests/org/oppia/android/instrumentation/player/BUILD.bazel @@ -10,7 +10,7 @@ oppia_instrumentation_test( "ExplorationPlayerTest.kt", ], deps = [ - "//instrumentation/src/javatest/org/oppia/android/instrumentation/testing:e2e_test_helper", + "//instrumentation/src/java/org/oppia/android/instrumentation/testing:e2e_test_helper", "//third_party:androidx_test_ext_junit", "//third_party:androidx_test_runner", "//third_party:androidx_test_uiautomator_uiautomator", diff --git a/instrumentation/src/javatest/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt b/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt similarity index 78% rename from instrumentation/src/javatest/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt rename to instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt index b90fa294e07..a6d16c181c0 100644 --- a/instrumentation/src/javatest/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt +++ b/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt @@ -1,12 +1,12 @@ package org.oppia.android.instrumentation.player import androidx.test.platform.app.InstrumentationRegistry -import androidx.test.uiautomator.By import androidx.test.uiautomator.UiDevice import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test import org.oppia.android.instrumentation.testing.EndToEndTestHelper.findObjectByRes +import org.oppia.android.instrumentation.testing.EndToEndTestHelper.findObjectByText import org.oppia.android.instrumentation.testing.EndToEndTestHelper.scrollRecyclerViewTextIntoView import org.oppia.android.instrumentation.testing.EndToEndTestHelper.startOppiaFromScratch import org.oppia.android.instrumentation.testing.EndToEndTestHelper.waitForRes @@ -31,16 +31,14 @@ class ExplorationPlayerTest { /** Navigates and opens the Prototype Exploration using the admin profile. */ private fun navigateToPrototypeExploration() { device.findObjectByRes("skip_text_view")?.click() - device.waitForRes("get_started_button") device.findObjectByRes("get_started_button")?.click() device.waitForRes("profile_select_text") - device.findObject(By.text("Admin")).click() + device.findObjectByText("Admin")?.click() scrollRecyclerViewTextIntoView("First Test Topic") - device.findObject(By.text("First Test Topic")).click() - device.waitForRes("topic_toolbar_title") - device.findObject(By.text("LESSONS")).click() - device.findObject(By.text("First Story")).click() + device.findObjectByText("First Test Topic")?.click() + device.findObjectByText("LESSONS")?.click() + device.findObjectByText("First Story")?.click() scrollRecyclerViewTextIntoView("Chapter 1: Prototype Exploration") - device.findObject(By.text("Chapter 1: Prototype Exploration")).click() + device.findObjectByText("Chapter 1: Prototype Exploration")?.click() } } diff --git a/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt b/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt index fce201ad18e..27d59fefab2 100644 --- a/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt +++ b/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt @@ -105,16 +105,16 @@ private fun computeAffectedTargetsForNonDevelopBranch( val allAffectedTestTargets = (affectedTestTargets + transitiveTestTargets).toSet() // Filtering out the targets to be ignored. - val filteredAffectedTestTargets = allAffectedTestTargets.filter { targetPath -> + val nonInstrumentationAffectedTestTargets = allAffectedTestTargets.filter { targetPath -> !targetPath.startsWith("//instrumentation", ignoreCase = true) } println() println( "Affected test targets:" + - "\n${filteredAffectedTestTargets.joinToString(separator = "\n") { "- $it" }}" + "\n${nonInstrumentationAffectedTestTargets.joinToString(separator = "\n") { "- $it" }}" ) outputFile.printWriter().use { writer -> - filteredAffectedTestTargets.forEach { writer.println(it) } + nonInstrumentationAffectedTestTargets.forEach { writer.println(it) } } } diff --git a/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt b/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt index c57f3c8b82c..a6a44a77b95 100644 --- a/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt +++ b/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt @@ -278,6 +278,16 @@ class ComputeAffectedTestsTest { assertThat(reportedTargets).containsExactly("//:FirstTest", "//:ThirdTest") } + @Test + fun testUtility_multipleTargetsChanged_committed_instrumentationTargetsAreIgnored() { + initializeEmptyGitRepository() + createAndCommitBasicTests("FirstTest", "SecondTest", "ThirdTest") + createBasicTests("InstrumentationTest", subpackage = "instrumentation") + val reportedTargets = runScript() + + assertThat(reportedTargets).doesNotContain("//instrumentation:InstrumentationTest") + } + /** * Runs the compute_affected_tests utility & returns all of the output lines. Note that the output * here is that which is saved directly to the output file, not debug lines printed to the From d4aa4d44816341d1b7e8bf3f0391821ba234f117 Mon Sep 17 00:00:00 2001 From: farees Date: Tue, 10 Aug 2021 19:27:09 +0530 Subject: [PATCH 37/63] NIT --- .github/CODEOWNERS | 4 ++-- .../android/testing/uiautomator/BUILD.bazel | 21 ------------------- 2 files changed, 2 insertions(+), 23 deletions(-) delete mode 100644 testing/src/main/java/org/oppia/android/testing/uiautomator/BUILD.bazel diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 4eb15b99c06..69246749682 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -200,8 +200,8 @@ NOTICE @BenHenning # instrumentation # ##################################################################################### -# UiAutomator test suites ownership. -/instrumentation/src/javatest/**/*.kt @anandwana001 @BenHenning +# end-to-end test utilities and modules. +/instrumentation/src/java/**/*.kt @anandwana001 @BenHenning ##################################################################################### # global overrides # diff --git a/testing/src/main/java/org/oppia/android/testing/uiautomator/BUILD.bazel b/testing/src/main/java/org/oppia/android/testing/uiautomator/BUILD.bazel deleted file mode 100644 index 3080489574e..00000000000 --- a/testing/src/main/java/org/oppia/android/testing/uiautomator/BUILD.bazel +++ /dev/null @@ -1,21 +0,0 @@ -# TODO(#1532): Rename file to 'BUILD' post-Gradle. -""" -Package for Ui Automator utilities. -""" - -load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_android_library") - -kt_android_library( - name = "e2e_test_helper", - testonly = True, - srcs = [ - "EndToEndTestHelper.kt", - ], - visibility = ["//:oppia_testing_visibility"], - deps = [ - "//third_party:androidx_test_ext_junit", - "//third_party:androidx_test_uiautomator_uiautomator", - "//third_party:com_google_truth_truth", - "//third_party:junit_junit", - ], -) From 41ea23f55f550929339b7530460bbaefead09da3 Mon Sep 17 00:00:00 2001 From: farees Date: Wed, 11 Aug 2021 00:13:45 +0530 Subject: [PATCH 38/63] NIT --- scripts/assets/test_file_exemptions.textproto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/assets/test_file_exemptions.textproto b/scripts/assets/test_file_exemptions.textproto index d95594a32fb..bbacabe8561 100644 --- a/scripts/assets/test_file_exemptions.textproto +++ b/scripts/assets/test_file_exemptions.textproto @@ -556,7 +556,7 @@ exempted_file_path: "domain/src/main/java/org/oppia/android/domain/util/FloatExt exempted_file_path: "domain/src/main/java/org/oppia/android/domain/util/FractionExtensions.kt" exempted_file_path: "domain/src/main/java/org/oppia/android/domain/util/JsonAssetRetriever.kt" exempted_file_path: "domain/src/test/java/org/oppia/android/domain/classify/InteractionObjectTestBuilder.kt" -exempted_file_path: "instrumentation/src/javatest/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt" +exempted_file_path: "instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt" exempted_file_path: "scripts/src/java/org/oppia/android/scripts/common/CommandExecutor.kt" exempted_file_path: "scripts/src/java/org/oppia/android/scripts/common/CommandResult.kt" exempted_file_path: "scripts/src/java/org/oppia/android/scripts/maven/data/MavenListDependency.kt" From b15451b505e9cace4a493956b7d0f09c4b3e6a95 Mon Sep 17 00:00:00 2001 From: farees Date: Wed, 11 Aug 2021 10:24:23 +0530 Subject: [PATCH 39/63] fixed scripts --- .github/CODEOWNERS | 2 +- instrumentation/oppia_instrumentation_test.bzl | 1 + .../android/scripts/ci/ComputeAffectedTests.kt | 12 ++++++++++-- .../android/scripts/ci/ComputeAffectedTestsTest.kt | 13 ++++++++++++- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 69246749682..5517f72da2f 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -200,7 +200,7 @@ NOTICE @BenHenning # instrumentation # ##################################################################################### -# end-to-end test utilities and modules. +# End-to-end test utilities and modules. /instrumentation/src/java/**/*.kt @anandwana001 @BenHenning ##################################################################################### diff --git a/instrumentation/oppia_instrumentation_test.bzl b/instrumentation/oppia_instrumentation_test.bzl index e61e3c1ae7d..b51554b3054 100644 --- a/instrumentation/oppia_instrumentation_test.bzl +++ b/instrumentation/oppia_instrumentation_test.bzl @@ -32,6 +32,7 @@ def oppia_instrumentation_test( deps = [":%s_lib" % name], ) + # TODO(#3617): Target isn't supported yet. native.android_instrumentation_test( name = name, target_device = "@android_test_support//tools/android/emulated_devices/generic_phone:android_23_x86_qemu2", diff --git a/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt b/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt index 27d59fefab2..958bd2e3481 100644 --- a/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt +++ b/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt @@ -63,11 +63,19 @@ private fun computeAffectedTargetsForDevelopBranch(bazelClient: BazelClient, out val allTestTargets = bazelClient.retrieveAllTestTargets() println() + + // Filtering out the targets to be ignored. + val nonInstrumentationAffectedTestTargets = allTestTargets.filter { targetPath -> + !targetPath.startsWith("//instrumentation", ignoreCase = true) + } + println( "Affected test targets:" + - "\n${allTestTargets.joinToString(separator = "\n") { "- $it" }}" + "\n${nonInstrumentationAffectedTestTargets.joinToString(separator = "\n") { "- $it" }}" ) - outputFile.printWriter().use { writer -> allTestTargets.forEach { writer.println(it) } } + outputFile.printWriter().use { + writer -> nonInstrumentationAffectedTestTargets.forEach { writer.println(it) } + } } private fun computeAffectedTargetsForNonDevelopBranch( diff --git a/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt b/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt index a6a44a77b95..f1d5251b009 100644 --- a/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt +++ b/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt @@ -279,7 +279,18 @@ class ComputeAffectedTestsTest { } @Test - fun testUtility_multipleTargetsChanged_committed_instrumentationTargetsAreIgnored() { + fun testUtility_featureBranch_instrumentationModuleChanged_instrumentationTargetsAreIgnored() { + initializeEmptyGitRepository() + createAndCommitBasicTests("FirstTest", "SecondTest", "ThirdTest") + switchToFeatureBranch() + createBasicTests("InstrumentationTest", subpackage = "instrumentation") + val reportedTargets = runScript() + + assertThat(reportedTargets).doesNotContain("//instrumentation:InstrumentationTest") + } + + @Test + fun testUtility_developBranch_instrumentationModuleChanged_instrumentationTargetsAreIgnored() { initializeEmptyGitRepository() createAndCommitBasicTests("FirstTest", "SecondTest", "ThirdTest") createBasicTests("InstrumentationTest", subpackage = "instrumentation") From 73c650e4aede19b4db064a9cf76756febeb72a64 Mon Sep 17 00:00:00 2001 From: farees Date: Wed, 11 Aug 2021 10:30:27 +0530 Subject: [PATCH 40/63] NIT --- .../java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt b/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt index 958bd2e3481..adf2e051d00 100644 --- a/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt +++ b/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt @@ -73,8 +73,8 @@ private fun computeAffectedTargetsForDevelopBranch(bazelClient: BazelClient, out "Affected test targets:" + "\n${nonInstrumentationAffectedTestTargets.joinToString(separator = "\n") { "- $it" }}" ) - outputFile.printWriter().use { - writer -> nonInstrumentationAffectedTestTargets.forEach { writer.println(it) } + outputFile.printWriter().use { writer -> + nonInstrumentationAffectedTestTargets.forEach { writer.println(it) } } } From 0d509144b37e7bfeac3676099005d6e92b6fae90 Mon Sep 17 00:00:00 2001 From: farees Date: Fri, 13 Aug 2021 10:01:26 +0530 Subject: [PATCH 41/63] updated the ComputedAffectedTests --- .../org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt b/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt index f1d5251b009..a0f5325e495 100644 --- a/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt +++ b/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt @@ -281,9 +281,10 @@ class ComputeAffectedTestsTest { @Test fun testUtility_featureBranch_instrumentationModuleChanged_instrumentationTargetsAreIgnored() { initializeEmptyGitRepository() - createAndCommitBasicTests("FirstTest", "SecondTest", "ThirdTest") + createAndCommitBasicTests("FirstTest", "SecondTest") switchToFeatureBranch() createBasicTests("InstrumentationTest", subpackage = "instrumentation") + createBasicTests("ThirdTest") val reportedTargets = runScript() assertThat(reportedTargets).doesNotContain("//instrumentation:InstrumentationTest") From e2db95763448d1222b36bf362ef43ed8c133ec1c Mon Sep 17 00:00:00 2001 From: farees Date: Fri, 13 Aug 2021 13:49:14 +0530 Subject: [PATCH 42/63] ignoring player directory --- .../scripts/ci/ComputeAffectedTests.kt | 12 +++++++-- .../scripts/ci/ComputeAffectedTestsTest.kt | 26 ++++++++++++++++--- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt b/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt index adf2e051d00..be1edfb5b3e 100644 --- a/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt +++ b/scripts/src/java/org/oppia/android/scripts/ci/ComputeAffectedTests.kt @@ -66,7 +66,11 @@ private fun computeAffectedTargetsForDevelopBranch(bazelClient: BazelClient, out // Filtering out the targets to be ignored. val nonInstrumentationAffectedTestTargets = allTestTargets.filter { targetPath -> - !targetPath.startsWith("//instrumentation", ignoreCase = true) + !targetPath + .startsWith( + "//instrumentation/src/javatests/org/oppia/android/instrumentation/player", + ignoreCase = true + ) } println( @@ -114,7 +118,11 @@ private fun computeAffectedTargetsForNonDevelopBranch( // Filtering out the targets to be ignored. val nonInstrumentationAffectedTestTargets = allAffectedTestTargets.filter { targetPath -> - !targetPath.startsWith("//instrumentation", ignoreCase = true) + !targetPath + .startsWith( + "//instrumentation/src/javatests/org/oppia/android/instrumentation/player", + ignoreCase = true + ) } println() diff --git a/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt b/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt index a0f5325e495..b9fe491ace6 100644 --- a/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt +++ b/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt @@ -283,21 +283,39 @@ class ComputeAffectedTestsTest { initializeEmptyGitRepository() createAndCommitBasicTests("FirstTest", "SecondTest") switchToFeatureBranch() - createBasicTests("InstrumentationTest", subpackage = "instrumentation") + createBasicTests( + "InstrumentationTest", + subpackage = "instrumentation.src.javatests.org.oppia.android.instrumentation.player" + ) createBasicTests("ThirdTest") val reportedTargets = runScript() - assertThat(reportedTargets).doesNotContain("//instrumentation:InstrumentationTest") + assertThat( + reportedTargets + ).doesNotContain( + "//instrumentation/src/javatests/org/oppia/android/instrumentation/player:InstrumentationTest" + ) } @Test fun testUtility_developBranch_instrumentationModuleChanged_instrumentationTargetsAreIgnored() { initializeEmptyGitRepository() createAndCommitBasicTests("FirstTest", "SecondTest", "ThirdTest") - createBasicTests("InstrumentationTest", subpackage = "instrumentation") + createBasicTests( + "InstrumentationTest", + subpackage = "instrumentation.src.javatests.org.oppia.android.instrumentation.player" + ) + createBasicTests( + "RobolectricTest", + subpackage = "instrumentation.src.javatests.org.oppia.android.instrumentation.application" + ) val reportedTargets = runScript() - assertThat(reportedTargets).doesNotContain("//instrumentation:InstrumentationTest") + assertThat( + reportedTargets + ).doesNotContain( + "//instrumentation/src/javatests/org/oppia/android/instrumentation/player:InstrumentationTest" + ) } /** From 16b51e542bdc3c37ce31ccb494cff344e80a84a9 Mon Sep 17 00:00:00 2001 From: farees Date: Sun, 15 Aug 2021 05:40:31 +0530 Subject: [PATCH 43/63] Updated with new changes --- .../testing/EndToEndTestHelper.kt | 11 ++ .../player/ExplorationPlayerTest.kt | 110 ++++++++++++++++++ 2 files changed, 121 insertions(+) diff --git a/instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt b/instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt index 776b59a704b..7d697a56853 100644 --- a/instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt +++ b/instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt @@ -49,6 +49,11 @@ object EndToEndTestHelper { wait(Until.hasObject(By.text(text)), TRANSITION_TIMEOUT_SECONDS) } + /** Waits for the view with given content description to appear. */ + fun UiDevice.waitForDesc(text: String) { + wait(Until.hasObject(By.desc(text)), TRANSITION_TIMEOUT_SECONDS) + } + /** Return the UiObject with the given text. */ fun UiDevice.findObjectByText(text: String): UiObject2? { waitForText(text) @@ -61,6 +66,12 @@ object EndToEndTestHelper { return findObject(By.res("$OPPIA_PACKAGE:id/$resourceId")) } + /** Returns the UiObject for the given content description. */ + fun UiDevice.findObjectByDesc(text: String): UiObject2? { + waitForDesc(text) + return findObject(By.desc(text)) + } + /** Performs a scroll until the view with the give text is visible. */ fun scrollRecyclerViewTextIntoView(text: String, isVertical: Boolean = true) { val recyclerView = UiScrollable(UiSelector().scrollable(true)) diff --git a/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt b/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt index a6d16c181c0..be99f08e888 100644 --- a/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt +++ b/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt @@ -5,6 +5,7 @@ import androidx.test.uiautomator.UiDevice import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test +import org.oppia.android.instrumentation.testing.EndToEndTestHelper.findObjectByDesc import org.oppia.android.instrumentation.testing.EndToEndTestHelper.findObjectByRes import org.oppia.android.instrumentation.testing.EndToEndTestHelper.findObjectByText import org.oppia.android.instrumentation.testing.EndToEndTestHelper.scrollRecyclerViewTextIntoView @@ -28,6 +29,41 @@ class ExplorationPlayerTest { assertThat(device.findObjectByRes("exploration_toolbar_title")).isNotNull() } + @Test + fun testProtoTypeExploration_answerAllInteractionsAndCompleteExploration() { + navigateToPrototypeExploration() + completePrototypeExploration() + + // Assert Topic Completed. + scrollRecyclerViewTextIntoView("Chapter 1: Prototype Exploration") + val chapterCompletedTick = device.findObjectByText( + "Chapter 1: Prototype Exploration" + )?.parent?.children?.get(2) + assertThat(chapterCompletedTick).isNotNull() + } + + @Test + fun testImageRegionSelectionInteraction_answerAllInteractionsAndCompleteExploration() { + navigateToImageRegionSelectionInteraction() + + // / Image Region Selection Interaction. + val imageSelectionView = device.findObjectByRes("interaction_container_frame_layout") + device.waitForRes("image_click_interaction_image_view") + imageSelectionView?.children?.get(2)?.click() + device.findObjectByText("SUBMIT")?.click() + device.findObjectByText("CONTINUE")?.click() + + // End Exploration. + device.findObjectByText("RETURN TO TOPIC")?.click() + + // Assert Topic Completed. + scrollRecyclerViewTextIntoView("Chapter 2: Image Region Selection Exploration") + val chapterCompletedTick = device.findObjectByText( + "Chapter 2: Image Region Selection Exploration" + )?.parent?.children?.get(2) + assertThat(chapterCompletedTick).isNotNull() + } + /** Navigates and opens the Prototype Exploration using the admin profile. */ private fun navigateToPrototypeExploration() { device.findObjectByRes("skip_text_view")?.click() @@ -41,4 +77,78 @@ class ExplorationPlayerTest { scrollRecyclerViewTextIntoView("Chapter 1: Prototype Exploration") device.findObjectByText("Chapter 1: Prototype Exploration")?.click() } + + /** Answers all the interactions and ends the exploration. */ + private fun completePrototypeExploration() { + // Exploration description. + device.findObjectByText("CONTINUE")?.click() + + // Fraction Input Interaction. + device.findObjectByRes("fraction_input_interaction_view")?.text = "1/2" + device.findObjectByText("SUBMIT")?.click() + device.findObjectByText("CONTINUE")?.click() + + // Multiple Choice Interaction - 1. + device.findObjectByText("Eagle")?.click() + device.findObjectByText("CONTINUE")?.click() + + // Multiple Choice Interaction - 2. + device.findObjectByText("Green")?.click() + device.findObjectByText("CONTINUE")?.click() + + // Item Selection Interaction. + device.findObjectByText("Red")?.click() + device.findObjectByText("Green")?.click() + device.findObjectByText("Blue")?.click() + device.findObjectByText("SUBMIT")?.click() + device.findObjectByText("CONTINUE")?.click() + + // Numeric Input Interaction. + device.findObjectByRes("numeric_input_interaction_view")?.text = "121" + device.findObjectByText("SUBMIT")?.click() + device.findObjectByText("CONTINUE")?.click() + + // Ratio Input Interaction. + device.findObjectByRes("ratio_input_interaction_view")?.text = "4:5" + device.findObjectByText("SUBMIT")?.click() + device.findObjectByText("CONTINUE")?.click() + + // Text Input Interaction. + device.findObjectByRes("text_input_interaction_view")?.text = "Finnish" + device.findObjectByText("SUBMIT")?.click() + device.findObjectByText("CONTINUE")?.click() + + // Drag And Drop Interaction. + device.findObjectByDesc("Move item down to 2")?.click() + device.findObjectByDesc("Move item down to 3")?.click() + device.findObjectByDesc("Move item down to 4")?.click() + device.findObjectByText("SUBMIT")?.click() + device.findObjectByText("CONTINUE")?.click() + + // Drag Drop Merge Interaction. + device.findObjectByDesc("Link to item 2")?.click() + device.findObjectByDesc("Move item down to 3")?.click() + device.findObjectByText("SUBMIT")?.click() + device.findObjectByText("CONTINUE")?.click() + + // End Exploration. + device.findObjectByText("RETURN TO TOPIC")?.click() + } + + /** Navigates and opens the Image Region Selection Exploration using the admin profile. */ + private fun navigateToImageRegionSelectionInteraction() { + device.findObjectByRes("skip_text_view")?.click() + device.findObjectByRes("get_started_button")?.click() + device.waitForRes("profile_select_text") + device.findObjectByText("Admin")?.click() + scrollRecyclerViewTextIntoView("First Test Topic") + device.findObjectByText("First Test Topic")?.click() + device.findObjectByText("LESSONS")?.click() + device.findObjectByText("First Story")?.click() + scrollRecyclerViewTextIntoView("Chapter 1: Prototype Exploration") + device.findObjectByText("Chapter 1: Prototype Exploration")?.click() + completePrototypeExploration() + scrollRecyclerViewTextIntoView("Chapter 2: Image Region Selection Exploration") + device.findObjectByText("Chapter 2: Image Region Selection Exploration")?.click() + } } From e39903f8f8d4e2139e862aa9a9035cef80db599d Mon Sep 17 00:00:00 2001 From: farees Date: Tue, 17 Aug 2021 09:17:14 +0530 Subject: [PATCH 44/63] updated tests --- .../player/ExplorationPlayerTest.kt | 67 +++---------------- 1 file changed, 9 insertions(+), 58 deletions(-) diff --git a/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt b/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt index be99f08e888..993cc54e4c3 100644 --- a/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt +++ b/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt @@ -23,63 +23,10 @@ class ExplorationPlayerTest { device.startOppiaFromScratch() } - @Test - fun testExploration_prototypeExploration_toolbarTitle_isDisplayedSuccessfully() { - navigateToPrototypeExploration() - assertThat(device.findObjectByRes("exploration_toolbar_title")).isNotNull() - } - @Test fun testProtoTypeExploration_answerAllInteractionsAndCompleteExploration() { navigateToPrototypeExploration() - completePrototypeExploration() - // Assert Topic Completed. - scrollRecyclerViewTextIntoView("Chapter 1: Prototype Exploration") - val chapterCompletedTick = device.findObjectByText( - "Chapter 1: Prototype Exploration" - )?.parent?.children?.get(2) - assertThat(chapterCompletedTick).isNotNull() - } - - @Test - fun testImageRegionSelectionInteraction_answerAllInteractionsAndCompleteExploration() { - navigateToImageRegionSelectionInteraction() - - // / Image Region Selection Interaction. - val imageSelectionView = device.findObjectByRes("interaction_container_frame_layout") - device.waitForRes("image_click_interaction_image_view") - imageSelectionView?.children?.get(2)?.click() - device.findObjectByText("SUBMIT")?.click() - device.findObjectByText("CONTINUE")?.click() - - // End Exploration. - device.findObjectByText("RETURN TO TOPIC")?.click() - - // Assert Topic Completed. - scrollRecyclerViewTextIntoView("Chapter 2: Image Region Selection Exploration") - val chapterCompletedTick = device.findObjectByText( - "Chapter 2: Image Region Selection Exploration" - )?.parent?.children?.get(2) - assertThat(chapterCompletedTick).isNotNull() - } - - /** Navigates and opens the Prototype Exploration using the admin profile. */ - private fun navigateToPrototypeExploration() { - device.findObjectByRes("skip_text_view")?.click() - device.findObjectByRes("get_started_button")?.click() - device.waitForRes("profile_select_text") - device.findObjectByText("Admin")?.click() - scrollRecyclerViewTextIntoView("First Test Topic") - device.findObjectByText("First Test Topic")?.click() - device.findObjectByText("LESSONS")?.click() - device.findObjectByText("First Story")?.click() - scrollRecyclerViewTextIntoView("Chapter 1: Prototype Exploration") - device.findObjectByText("Chapter 1: Prototype Exploration")?.click() - } - - /** Answers all the interactions and ends the exploration. */ - private fun completePrototypeExploration() { // Exploration description. device.findObjectByText("CONTINUE")?.click() @@ -133,10 +80,17 @@ class ExplorationPlayerTest { // End Exploration. device.findObjectByText("RETURN TO TOPIC")?.click() + + // Assert Topic Completed. + scrollRecyclerViewTextIntoView("Chapter 1: Prototype Exploration") + val chapterCompletedTick = device.findObjectByText( + "Chapter 1: Prototype Exploration" + )?.parent?.children?.get(2) + assertThat(chapterCompletedTick).isNotNull() } - /** Navigates and opens the Image Region Selection Exploration using the admin profile. */ - private fun navigateToImageRegionSelectionInteraction() { + /** Navigates and opens the Prototype Exploration using the admin profile. */ + private fun navigateToPrototypeExploration() { device.findObjectByRes("skip_text_view")?.click() device.findObjectByRes("get_started_button")?.click() device.waitForRes("profile_select_text") @@ -147,8 +101,5 @@ class ExplorationPlayerTest { device.findObjectByText("First Story")?.click() scrollRecyclerViewTextIntoView("Chapter 1: Prototype Exploration") device.findObjectByText("Chapter 1: Prototype Exploration")?.click() - completePrototypeExploration() - scrollRecyclerViewTextIntoView("Chapter 2: Image Region Selection Exploration") - device.findObjectByText("Chapter 2: Image Region Selection Exploration")?.click() } } From 838c713ab5318bdbbf34938d1cbc434cc1784227 Mon Sep 17 00:00:00 2001 From: farees Date: Tue, 17 Aug 2021 09:41:39 +0530 Subject: [PATCH 45/63] updated tests --- .../player/ExplorationPlayerTest.kt | 117 ++++++++++++++---- 1 file changed, 95 insertions(+), 22 deletions(-) diff --git a/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt b/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt index 993cc54e4c3..f57619ac41b 100644 --- a/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt +++ b/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt @@ -27,70 +27,140 @@ class ExplorationPlayerTest { fun testProtoTypeExploration_answerAllInteractionsAndCompleteExploration() { navigateToPrototypeExploration() - // Exploration description. + // Play through all interactions in PrototypeExploration + playExplorationDescription() + playFractionInputInteraction() + playMultipleChoiceIntearction1() + playMultipleChoiceIntearction2() + playItemSelectionInteraction() + playNumericInputInteraction() + playRatioInputInteraction() + playTextInputInteraction() + playDragAndDropInteraction() + playDragDropMergeInteraction() + endExploration() + + // Assert Topic Completed. + scrollRecyclerViewTextIntoView("Chapter 1: Prototype Exploration") + val chapterCompletedTick = device.findObjectByText( + "Chapter 1: Prototype Exploration" + )?.parent?.children?.get(2) + assertThat(chapterCompletedTick).isNotNull() + } + + @Ignore + @Test + fun testImageRegionSelectionInteraction_answerAllInteractionsAndCompleteExploration() { + navigateToImageRegionSelectionInteraction() + + // / Image Region Selection Interaction. + val imageSelectionView = device.findObjectByRes("interaction_container_frame_layout") + device.waitForRes("image_click_interaction_image_view") + imageSelectionView?.children?.get(2)?.click() + device.findObjectByText("SUBMIT")?.click() device.findObjectByText("CONTINUE")?.click() - // Fraction Input Interaction. + // End Exploration. + device.findObjectByText("RETURN TO TOPIC")?.click() + + // Assert Topic Completed. + scrollRecyclerViewTextIntoView("Chapter 2: Image Region Selection Exploration") + val chapterCompletedTick = device.findObjectByText( + "Chapter 2: Image Region Selection Exploration" + )?.parent?.children?.get(2) + assertThat(chapterCompletedTick).isNotNull() + } + + /** Navigates and opens the Prototype Exploration using the admin profile. */ + private fun navigateToPrototypeExploration() { + device.findObjectByRes("skip_text_view")?.click() + device.findObjectByRes("get_started_button")?.click() + device.waitForRes("profile_select_text") + device.findObjectByText("Admin")?.click() + scrollRecyclerViewTextIntoView("First Test Topic") + device.findObjectByText("First Test Topic")?.click() + device.findObjectByText("LESSONS")?.click() + device.findObjectByText("First Story")?.click() + scrollRecyclerViewTextIntoView("Chapter 1: Prototype Exploration") + device.findObjectByText("Chapter 1: Prototype Exploration")?.click() + } + + /** Continue Description of ProtoTypeExploration. */ + private fun playExplorationDescription() { + device.findObjectByText("CONTINUE")?.click() + } + + /** Play FractionInputInteraction for PrototypeExporation. */ + private fun playFractionInputInteraction() { device.findObjectByRes("fraction_input_interaction_view")?.text = "1/2" device.findObjectByText("SUBMIT")?.click() device.findObjectByText("CONTINUE")?.click() - - // Multiple Choice Interaction - 1. + } + /** Play first MultipleChoiceInteraction for PrototypeExporation. */ + private fun playMultipleChoiceIntearction1() { device.findObjectByText("Eagle")?.click() device.findObjectByText("CONTINUE")?.click() - - // Multiple Choice Interaction - 2. + } + /** Play second MultipleChoiceInteraction for PrototypeExporation. */ + private fun playMultipleChoiceIntearction2() { device.findObjectByText("Green")?.click() device.findObjectByText("CONTINUE")?.click() + } - // Item Selection Interaction. + /** Play second ItemSelectionInteraction for PrototypeExporation. */ + private fun playItemSelectionInteraction() { device.findObjectByText("Red")?.click() device.findObjectByText("Green")?.click() device.findObjectByText("Blue")?.click() device.findObjectByText("SUBMIT")?.click() device.findObjectByText("CONTINUE")?.click() + } - // Numeric Input Interaction. + /** Play second NumericInputInteraction for PrototypeExporation. */ + private fun playNumericInputInteraction() { device.findObjectByRes("numeric_input_interaction_view")?.text = "121" device.findObjectByText("SUBMIT")?.click() device.findObjectByText("CONTINUE")?.click() + } - // Ratio Input Interaction. + /** Play second RatioInputInteraction for PrototypeExporation. */ + private fun playRatioInputInteraction() { device.findObjectByRes("ratio_input_interaction_view")?.text = "4:5" device.findObjectByText("SUBMIT")?.click() device.findObjectByText("CONTINUE")?.click() + } - // Text Input Interaction. + /** Play second TextInputInteraction for PrototypeExporation. */ + private fun playTextInputInteraction() { device.findObjectByRes("text_input_interaction_view")?.text = "Finnish" device.findObjectByText("SUBMIT")?.click() device.findObjectByText("CONTINUE")?.click() + } - // Drag And Drop Interaction. + /** Play second DragAndDropInteraction for PrototypeExporation. */ + private fun playDragAndDropInteraction() { device.findObjectByDesc("Move item down to 2")?.click() device.findObjectByDesc("Move item down to 3")?.click() device.findObjectByDesc("Move item down to 4")?.click() device.findObjectByText("SUBMIT")?.click() device.findObjectByText("CONTINUE")?.click() + } - // Drag Drop Merge Interaction. + /** Play second DragDropMergeInteraction for PrototypeExporation. */ + private fun playDragDropMergeInteraction() { device.findObjectByDesc("Link to item 2")?.click() device.findObjectByDesc("Move item down to 3")?.click() device.findObjectByText("SUBMIT")?.click() device.findObjectByText("CONTINUE")?.click() + } - // End Exploration. + /** End exploration for PrototypeExploration. */ + private fun endExploration() { device.findObjectByText("RETURN TO TOPIC")?.click() - - // Assert Topic Completed. - scrollRecyclerViewTextIntoView("Chapter 1: Prototype Exploration") - val chapterCompletedTick = device.findObjectByText( - "Chapter 1: Prototype Exploration" - )?.parent?.children?.get(2) - assertThat(chapterCompletedTick).isNotNull() } - /** Navigates and opens the Prototype Exploration using the admin profile. */ - private fun navigateToPrototypeExploration() { + /** Navigates and opens the Image Region Selection Exploration using the admin profile. */ + private fun navigateToImageRegionSelectionInteraction() { device.findObjectByRes("skip_text_view")?.click() device.findObjectByRes("get_started_button")?.click() device.waitForRes("profile_select_text") @@ -101,5 +171,8 @@ class ExplorationPlayerTest { device.findObjectByText("First Story")?.click() scrollRecyclerViewTextIntoView("Chapter 1: Prototype Exploration") device.findObjectByText("Chapter 1: Prototype Exploration")?.click() + completePrototypeExploration() + scrollRecyclerViewTextIntoView("Chapter 2: Image Region Selection Exploration") + device.findObjectByText("Chapter 2: Image Region Selection Exploration")?.click() } } From 08ffe7596f93ba9d4df801728622447f2ec85a9e Mon Sep 17 00:00:00 2001 From: farees Date: Tue, 17 Aug 2021 19:53:06 +0530 Subject: [PATCH 46/63] fix OppiaTestApplication --- .../testing/EndToEndTestHelper.kt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt b/instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt index 7d697a56853..4a6c860a098 100644 --- a/instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt +++ b/instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt @@ -3,6 +3,7 @@ package org.oppia.android.instrumentation.testing import android.content.Context import android.content.Intent import androidx.test.core.app.ApplicationProvider +import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.By import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.UiObject2 @@ -22,6 +23,7 @@ object EndToEndTestHelper { fun UiDevice.startOppiaFromScratch() { // Start from the home screen pressHome() + clearAppData() // Wait for launcher val launcherPackage = launcherPackageName @@ -39,6 +41,22 @@ object EndToEndTestHelper { wait(Until.hasObject(By.pkg(OPPIA_PACKAGE)), LAUNCH_TIMEOUT_SECONDS) } + /** Clear oppia application data. */ + fun UiDevice.clearAppData() { + val context = InstrumentationRegistry.getInstrumentation().getTargetContext() + .getApplicationContext() + val cacheDir = context.filesDir + val filesToDelete = cacheDir.listFiles().filter { file -> + file.name.endsWith(".cache") + } + val filePath = "/data/data/$OPPIA_PACKAGE/files/" + filesToDelete.forEach { file -> + executeShellCommand( + "run-as org.oppia.android rm -f $filePath${file.name.substringAfterLast('/')}" + ) + } + } + /** Waits for the view with given resourceId to appear. */ fun UiDevice.waitForRes(resourceId: String, timeout: Long = TRANSITION_TIMEOUT_SECONDS) { wait(Until.hasObject(By.res(resourceId)), timeout) From e2ba2155455044ae82ce8180c644de6a9ad1953f Mon Sep 17 00:00:00 2001 From: farees Date: Tue, 17 Aug 2021 20:09:30 +0530 Subject: [PATCH 47/63] added todo --- .../android/instrumentation/player/ExplorationPlayerTest.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt b/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt index f57619ac41b..fc4caf7c8c9 100644 --- a/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt +++ b/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt @@ -48,8 +48,9 @@ class ExplorationPlayerTest { assertThat(chapterCompletedTick).isNotNull() } - @Ignore + // TODO(#3697): Update e2e tests when backend support is introduced. @Test + @Ignore("Need backend support to test the ImageRegionSelectionInteraction") fun testImageRegionSelectionInteraction_answerAllInteractionsAndCompleteExploration() { navigateToImageRegionSelectionInteraction() From 989342e2817346c0a7a1a4c59fdd7be1fa8acd2a Mon Sep 17 00:00:00 2001 From: farees Date: Tue, 17 Aug 2021 22:29:31 +0530 Subject: [PATCH 48/63] fixed clearAppData to delete all the .cache file of the app --- .../testing/EndToEndTestHelper.kt | 16 +++++++--------- .../player/ExplorationPlayerTest.kt | 16 +++++++++++++++- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt b/instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt index 4a6c860a098..e534fd88285 100644 --- a/instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt +++ b/instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt @@ -45,15 +45,13 @@ object EndToEndTestHelper { fun UiDevice.clearAppData() { val context = InstrumentationRegistry.getInstrumentation().getTargetContext() .getApplicationContext() - val cacheDir = context.filesDir - val filesToDelete = cacheDir.listFiles().filter { file -> - file.name.endsWith(".cache") - } - val filePath = "/data/data/$OPPIA_PACKAGE/files/" - filesToDelete.forEach { file -> - executeShellCommand( - "run-as org.oppia.android rm -f $filePath${file.name.substringAfterLast('/')}" - ) + val externalDirs = context.dataDir.listFiles() + externalDirs.forEach { dir -> + dir.listFiles().forEach { file -> + if(file.name.endsWith(".cache")) { + file.delete() + } + } } } diff --git a/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt b/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt index fc4caf7c8c9..202f0ec7bf5 100644 --- a/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt +++ b/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt @@ -5,6 +5,7 @@ import androidx.test.uiautomator.UiDevice import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test +import org.junit.Ignore import org.oppia.android.instrumentation.testing.EndToEndTestHelper.findObjectByDesc import org.oppia.android.instrumentation.testing.EndToEndTestHelper.findObjectByRes import org.oppia.android.instrumentation.testing.EndToEndTestHelper.findObjectByText @@ -172,7 +173,20 @@ class ExplorationPlayerTest { device.findObjectByText("First Story")?.click() scrollRecyclerViewTextIntoView("Chapter 1: Prototype Exploration") device.findObjectByText("Chapter 1: Prototype Exploration")?.click() - completePrototypeExploration() + + // Complete PrototypeExploration + playExplorationDescription() + playFractionInputInteraction() + playMultipleChoiceIntearction1() + playMultipleChoiceIntearction2() + playItemSelectionInteraction() + playNumericInputInteraction() + playRatioInputInteraction() + playTextInputInteraction() + playDragAndDropInteraction() + playDragDropMergeInteraction() + endExploration() + scrollRecyclerViewTextIntoView("Chapter 2: Image Region Selection Exploration") device.findObjectByText("Chapter 2: Image Region Selection Exploration")?.click() } From 56106515e8dc02bf21410eb42a0bf8bf37fe7ab1 Mon Sep 17 00:00:00 2001 From: farees Date: Tue, 17 Aug 2021 22:33:52 +0530 Subject: [PATCH 49/63] NIT --- .../oppia/android/instrumentation/testing/EndToEndTestHelper.kt | 2 +- .../android/instrumentation/player/ExplorationPlayerTest.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt b/instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt index e534fd88285..d69c0944661 100644 --- a/instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt +++ b/instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt @@ -48,7 +48,7 @@ object EndToEndTestHelper { val externalDirs = context.dataDir.listFiles() externalDirs.forEach { dir -> dir.listFiles().forEach { file -> - if(file.name.endsWith(".cache")) { + if (file.name.endsWith(".cache")) { file.delete() } } diff --git a/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt b/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt index 202f0ec7bf5..937b43b35c6 100644 --- a/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt +++ b/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt @@ -4,8 +4,8 @@ import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.UiDevice import com.google.common.truth.Truth.assertThat import org.junit.Before -import org.junit.Test import org.junit.Ignore +import org.junit.Test import org.oppia.android.instrumentation.testing.EndToEndTestHelper.findObjectByDesc import org.oppia.android.instrumentation.testing.EndToEndTestHelper.findObjectByRes import org.oppia.android.instrumentation.testing.EndToEndTestHelper.findObjectByText From 75c60cdd3469bb4076c7aea6be8a1e14d27dd429 Mon Sep 17 00:00:00 2001 From: farees Date: Thu, 19 Aug 2021 00:28:41 +0530 Subject: [PATCH 50/63] removed clearAppData --- .../testing/EndToEndTestHelper.kt | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt b/instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt index d69c0944661..7d697a56853 100644 --- a/instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt +++ b/instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt @@ -3,7 +3,6 @@ package org.oppia.android.instrumentation.testing import android.content.Context import android.content.Intent import androidx.test.core.app.ApplicationProvider -import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.By import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.UiObject2 @@ -23,7 +22,6 @@ object EndToEndTestHelper { fun UiDevice.startOppiaFromScratch() { // Start from the home screen pressHome() - clearAppData() // Wait for launcher val launcherPackage = launcherPackageName @@ -41,20 +39,6 @@ object EndToEndTestHelper { wait(Until.hasObject(By.pkg(OPPIA_PACKAGE)), LAUNCH_TIMEOUT_SECONDS) } - /** Clear oppia application data. */ - fun UiDevice.clearAppData() { - val context = InstrumentationRegistry.getInstrumentation().getTargetContext() - .getApplicationContext() - val externalDirs = context.dataDir.listFiles() - externalDirs.forEach { dir -> - dir.listFiles().forEach { file -> - if (file.name.endsWith(".cache")) { - file.delete() - } - } - } - } - /** Waits for the view with given resourceId to appear. */ fun UiDevice.waitForRes(resourceId: String, timeout: Long = TRANSITION_TIMEOUT_SECONDS) { wait(Until.hasObject(By.res(resourceId)), timeout) From a37bcbb7c1f81d7781ea3704a3ce68bb90ecef52 Mon Sep 17 00:00:00 2001 From: farees Date: Thu, 19 Aug 2021 01:28:01 +0530 Subject: [PATCH 51/63] updated ComputeAffectedTestsTest --- .../scripts/testing/TestBazelWorkspace.kt | 12 ++++++------ .../scripts/ci/ComputeAffectedTestsTest.kt | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/scripts/src/java/org/oppia/android/scripts/testing/TestBazelWorkspace.kt b/scripts/src/java/org/oppia/android/scripts/testing/TestBazelWorkspace.kt index 4f2bdf07431..c86567477a6 100644 --- a/scripts/src/java/org/oppia/android/scripts/testing/TestBazelWorkspace.kt +++ b/scripts/src/java/org/oppia/android/scripts/testing/TestBazelWorkspace.kt @@ -67,10 +67,10 @@ class TestBazelWorkspace(private val temporaryRootFolder: TemporaryFolder) { createLibrary("${testName}Dependency") } else null to listOf() val buildFile = if (subpackage != null) { - if (!File(temporaryRootFolder.root, subpackage).exists()) { - temporaryRootFolder.newFolder(subpackage) + if (!File(temporaryRootFolder.root, subpackage.replace(".", "/")).exists()) { + temporaryRootFolder.newFolder(*(subpackage.split(".")).toTypedArray()) } - val newBuildFile = temporaryRootFolder.newFile("$subpackage/BUILD.bazel") + val newBuildFile = temporaryRootFolder.newFile("${subpackage.replace(".", "/")}/BUILD.bazel") newBuildFile } else rootBuildFile prepareBuildFileForTests(buildFile) @@ -108,10 +108,10 @@ class TestBazelWorkspace(private val temporaryRootFolder: TemporaryFolder) { ): Iterable { check(testName !in testFileMap) { "Test '$testName' already exists" } val testFile = if (subpackage != null) { - if (!File(temporaryRootFolder.root, subpackage).exists()) { - temporaryRootFolder.newFolder(subpackage) + if (!File(temporaryRootFolder.root, subpackage.replace(".", "/")).exists()) { + temporaryRootFolder.newFolder(*(subpackage.split(".")).toTypedArray()) } - temporaryRootFolder.newFile("$subpackage/$testName.kt") + temporaryRootFolder.newFile("${subpackage.replace(".", "/")}/$testName.kt") } else temporaryRootFolder.newFile("$testName.kt") return addTestToBuildFile( testName, diff --git a/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt b/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt index b9fe491ace6..71984c07f7a 100644 --- a/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt +++ b/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt @@ -287,6 +287,10 @@ class ComputeAffectedTestsTest { "InstrumentationTest", subpackage = "instrumentation.src.javatests.org.oppia.android.instrumentation.player" ) + createBasicTests( + "RobolectricTest", + subpackage = "instrumentation.src.javatests.org.oppia.android.instrumentation.app" + ) createBasicTests("ThirdTest") val reportedTargets = runScript() @@ -295,6 +299,11 @@ class ComputeAffectedTestsTest { ).doesNotContain( "//instrumentation/src/javatests/org/oppia/android/instrumentation/player:InstrumentationTest" ) + assertThat( + reportedTargets + ).contains( + "//instrumentation/src/javatests/org/oppia/android/instrumentation/app:RobolectricTest" + ) } @Test @@ -309,6 +318,10 @@ class ComputeAffectedTestsTest { "RobolectricTest", subpackage = "instrumentation.src.javatests.org.oppia.android.instrumentation.application" ) + createBasicTests( + "RobolectricTest", + subpackage = "instrumentation.src.javatests.org.oppia.android.instrumentation.app" + ) val reportedTargets = runScript() assertThat( @@ -316,6 +329,11 @@ class ComputeAffectedTestsTest { ).doesNotContain( "//instrumentation/src/javatests/org/oppia/android/instrumentation/player:InstrumentationTest" ) + assertThat( + reportedTargets + ).contains( + "//instrumentation/src/javatests/org/oppia/android/instrumentation/app:RobolectricTest" + ) } /** From 33c4189a80c0a2bb5872d6786c17e41bf40e2bde Mon Sep 17 00:00:00 2001 From: farees Date: Thu, 19 Aug 2021 01:38:16 +0530 Subject: [PATCH 52/63] updated ComputeAffectedTestsTest --- .../org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt b/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt index 71984c07f7a..c70b453f3d0 100644 --- a/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt +++ b/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt @@ -314,10 +314,6 @@ class ComputeAffectedTestsTest { "InstrumentationTest", subpackage = "instrumentation.src.javatests.org.oppia.android.instrumentation.player" ) - createBasicTests( - "RobolectricTest", - subpackage = "instrumentation.src.javatests.org.oppia.android.instrumentation.application" - ) createBasicTests( "RobolectricTest", subpackage = "instrumentation.src.javatests.org.oppia.android.instrumentation.app" From d40cd4bd565638a7c2b9dee250807e31e53cdefe Mon Sep 17 00:00:00 2001 From: farees Date: Thu, 19 Aug 2021 11:52:02 +0530 Subject: [PATCH 53/63] reverted ComputeAffectedTestsTest.kt --- .../scripts/testing/TestBazelWorkspace.kt | 12 ++++++------ .../scripts/ci/ComputeAffectedTestsTest.kt | 16 +--------------- 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/scripts/src/java/org/oppia/android/scripts/testing/TestBazelWorkspace.kt b/scripts/src/java/org/oppia/android/scripts/testing/TestBazelWorkspace.kt index c86567477a6..4f2bdf07431 100644 --- a/scripts/src/java/org/oppia/android/scripts/testing/TestBazelWorkspace.kt +++ b/scripts/src/java/org/oppia/android/scripts/testing/TestBazelWorkspace.kt @@ -67,10 +67,10 @@ class TestBazelWorkspace(private val temporaryRootFolder: TemporaryFolder) { createLibrary("${testName}Dependency") } else null to listOf() val buildFile = if (subpackage != null) { - if (!File(temporaryRootFolder.root, subpackage.replace(".", "/")).exists()) { - temporaryRootFolder.newFolder(*(subpackage.split(".")).toTypedArray()) + if (!File(temporaryRootFolder.root, subpackage).exists()) { + temporaryRootFolder.newFolder(subpackage) } - val newBuildFile = temporaryRootFolder.newFile("${subpackage.replace(".", "/")}/BUILD.bazel") + val newBuildFile = temporaryRootFolder.newFile("$subpackage/BUILD.bazel") newBuildFile } else rootBuildFile prepareBuildFileForTests(buildFile) @@ -108,10 +108,10 @@ class TestBazelWorkspace(private val temporaryRootFolder: TemporaryFolder) { ): Iterable { check(testName !in testFileMap) { "Test '$testName' already exists" } val testFile = if (subpackage != null) { - if (!File(temporaryRootFolder.root, subpackage.replace(".", "/")).exists()) { - temporaryRootFolder.newFolder(*(subpackage.split(".")).toTypedArray()) + if (!File(temporaryRootFolder.root, subpackage).exists()) { + temporaryRootFolder.newFolder(subpackage) } - temporaryRootFolder.newFile("${subpackage.replace(".", "/")}/$testName.kt") + temporaryRootFolder.newFile("$subpackage/$testName.kt") } else temporaryRootFolder.newFile("$testName.kt") return addTestToBuildFile( testName, diff --git a/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt b/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt index c70b453f3d0..b9fe491ace6 100644 --- a/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt +++ b/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt @@ -287,10 +287,6 @@ class ComputeAffectedTestsTest { "InstrumentationTest", subpackage = "instrumentation.src.javatests.org.oppia.android.instrumentation.player" ) - createBasicTests( - "RobolectricTest", - subpackage = "instrumentation.src.javatests.org.oppia.android.instrumentation.app" - ) createBasicTests("ThirdTest") val reportedTargets = runScript() @@ -299,11 +295,6 @@ class ComputeAffectedTestsTest { ).doesNotContain( "//instrumentation/src/javatests/org/oppia/android/instrumentation/player:InstrumentationTest" ) - assertThat( - reportedTargets - ).contains( - "//instrumentation/src/javatests/org/oppia/android/instrumentation/app:RobolectricTest" - ) } @Test @@ -316,7 +307,7 @@ class ComputeAffectedTestsTest { ) createBasicTests( "RobolectricTest", - subpackage = "instrumentation.src.javatests.org.oppia.android.instrumentation.app" + subpackage = "instrumentation.src.javatests.org.oppia.android.instrumentation.application" ) val reportedTargets = runScript() @@ -325,11 +316,6 @@ class ComputeAffectedTestsTest { ).doesNotContain( "//instrumentation/src/javatests/org/oppia/android/instrumentation/player:InstrumentationTest" ) - assertThat( - reportedTargets - ).contains( - "//instrumentation/src/javatests/org/oppia/android/instrumentation/app:RobolectricTest" - ) } /** From 55bc4d921f45176bc542d287d021ba510002df95 Mon Sep 17 00:00:00 2001 From: farees Date: Thu, 19 Aug 2021 12:26:40 +0530 Subject: [PATCH 54/63] requested changes --- .../res/layout-land/story_chapter_view.xml | 2 +- .../res/layout-sw600dp/story_chapter_view.xml | 2 +- .../main/res/layout/story_chapter_view.xml | 2 +- .../player/ExplorationPlayerTest.kt | 89 ++++++++----------- 4 files changed, 39 insertions(+), 56 deletions(-) diff --git a/app/src/main/res/layout-land/story_chapter_view.xml b/app/src/main/res/layout-land/story_chapter_view.xml index fa22023c660..28a7e6cf637 100644 --- a/app/src/main/res/layout-land/story_chapter_view.xml +++ b/app/src/main/res/layout-land/story_chapter_view.xml @@ -91,7 +91,7 @@ android:layout_height="wrap_content" android:layout_marginEnd="8dp" android:layout_marginBottom="4dp" - android:contentDescription="@{@string/chapter_completed}" + android:contentDescription="@{String.format(@string/chapter_completed, (viewModel.index + 1), viewModel.name)}" android:src="@drawable/ic_check_24dp" android:visibility="@{viewModel.chapterSummary.chapterPlayState == ChapterPlayState.COMPLETED ? View.VISIBLE : View.GONE}" app:layout_constraintBottom_toBottomOf="parent" diff --git a/app/src/main/res/layout-sw600dp/story_chapter_view.xml b/app/src/main/res/layout-sw600dp/story_chapter_view.xml index fcaf7b1ab35..973645c8c98 100644 --- a/app/src/main/res/layout-sw600dp/story_chapter_view.xml +++ b/app/src/main/res/layout-sw600dp/story_chapter_view.xml @@ -126,7 +126,7 @@ android:layout_height="wrap_content" android:layout_marginEnd="8dp" android:layout_marginBottom="4dp" - android:contentDescription="@{@string/chapter_completed}" + android:contentDescription="@{String.format(@string/chapter_completed, (viewModel.index + 1), viewModel.name)}" android:src="@drawable/ic_check_24dp" android:visibility="@{viewModel.chapterSummary.chapterPlayState == ChapterPlayState.COMPLETED ? View.VISIBLE : View.GONE}" app:layout_constraintBottom_toBottomOf="parent" diff --git a/app/src/main/res/layout/story_chapter_view.xml b/app/src/main/res/layout/story_chapter_view.xml index fcaf7b1ab35..973645c8c98 100644 --- a/app/src/main/res/layout/story_chapter_view.xml +++ b/app/src/main/res/layout/story_chapter_view.xml @@ -126,7 +126,7 @@ android:layout_height="wrap_content" android:layout_marginEnd="8dp" android:layout_marginBottom="4dp" - android:contentDescription="@{@string/chapter_completed}" + android:contentDescription="@{String.format(@string/chapter_completed, (viewModel.index + 1), viewModel.name)}" android:src="@drawable/ic_check_24dp" android:visibility="@{viewModel.chapterSummary.chapterPlayState == ChapterPlayState.COMPLETED ? View.VISIBLE : View.GONE}" app:layout_constraintBottom_toBottomOf="parent" diff --git a/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt b/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt index 937b43b35c6..dd37ec695a5 100644 --- a/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt +++ b/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt @@ -25,21 +25,9 @@ class ExplorationPlayerTest { } @Test - fun testProtoTypeExploration_answerAllInteractionsAndCompleteExploration() { + fun testPlayExploration_prototypeExploration_playedFullyThrough_finishesSuccessfully() { navigateToPrototypeExploration() - - // Play through all interactions in PrototypeExploration - playExplorationDescription() - playFractionInputInteraction() - playMultipleChoiceIntearction1() - playMultipleChoiceIntearction2() - playItemSelectionInteraction() - playNumericInputInteraction() - playRatioInputInteraction() - playTextInputInteraction() - playDragAndDropInteraction() - playDragDropMergeInteraction() - endExploration() + completePrototypeExploration() // Assert Topic Completed. scrollRecyclerViewTextIntoView("Chapter 1: Prototype Exploration") @@ -51,8 +39,8 @@ class ExplorationPlayerTest { // TODO(#3697): Update e2e tests when backend support is introduced. @Test - @Ignore("Need backend support to test the ImageRegionSelectionInteraction") - fun testImageRegionSelectionInteraction_answerAllInteractionsAndCompleteExploration() { + @Ignore("Need backend connection support to test the ImageRegionSelectionInteraction") + fun testPlayExploration_imageRegionInteraction_playedFullyThrough_finishesSuccessfully() { navigateToImageRegionSelectionInteraction() // / Image Region Selection Interaction. @@ -63,13 +51,16 @@ class ExplorationPlayerTest { device.findObjectByText("CONTINUE")?.click() // End Exploration. - device.findObjectByText("RETURN TO TOPIC")?.click() + playEndExplorationInteraction() // Assert Topic Completed. scrollRecyclerViewTextIntoView("Chapter 2: Image Region Selection Exploration") val chapterCompletedTick = device.findObjectByText( "Chapter 2: Image Region Selection Exploration" )?.parent?.children?.get(2) + val chapterCompletedTick = device.findObjectByDesc( + "Chapter 1 with title Prototype Exploration is completed" + ) assertThat(chapterCompletedTick).isNotNull() } @@ -87,77 +78,82 @@ class ExplorationPlayerTest { device.findObjectByText("Chapter 1: Prototype Exploration")?.click() } - /** Continue Description of ProtoTypeExploration. */ - private fun playExplorationDescription() { + private fun completePrototypeExploration() { + playContinueInteraction() + playFractionInputInteraction() + playMultipleChoiceIntearction1() + playMultipleChoiceIntearction2() + playItemSelectionInteraction() + playNumericInputInteraction() + playRatioInputInteraction() + playTextInputInteraction() + playDragAndDropInteraction() + playDragDropMergeInteraction() + playEndExplorationInteraction() + } + + private fun playContinueInteraction() { device.findObjectByText("CONTINUE")?.click() } - /** Play FractionInputInteraction for PrototypeExporation. */ private fun playFractionInputInteraction() { device.findObjectByRes("fraction_input_interaction_view")?.text = "1/2" device.findObjectByText("SUBMIT")?.click() - device.findObjectByText("CONTINUE")?.click() + playContinueInteraction() } - /** Play first MultipleChoiceInteraction for PrototypeExporation. */ + private fun playMultipleChoiceIntearction1() { device.findObjectByText("Eagle")?.click() - device.findObjectByText("CONTINUE")?.click() + playContinueInteraction() } - /** Play second MultipleChoiceInteraction for PrototypeExporation. */ + private fun playMultipleChoiceIntearction2() { device.findObjectByText("Green")?.click() - device.findObjectByText("CONTINUE")?.click() + playContinueInteraction() } - /** Play second ItemSelectionInteraction for PrototypeExporation. */ private fun playItemSelectionInteraction() { device.findObjectByText("Red")?.click() device.findObjectByText("Green")?.click() device.findObjectByText("Blue")?.click() device.findObjectByText("SUBMIT")?.click() - device.findObjectByText("CONTINUE")?.click() + playContinueInteraction() } - /** Play second NumericInputInteraction for PrototypeExporation. */ private fun playNumericInputInteraction() { device.findObjectByRes("numeric_input_interaction_view")?.text = "121" device.findObjectByText("SUBMIT")?.click() - device.findObjectByText("CONTINUE")?.click() + playContinueInteraction() } - /** Play second RatioInputInteraction for PrototypeExporation. */ private fun playRatioInputInteraction() { device.findObjectByRes("ratio_input_interaction_view")?.text = "4:5" device.findObjectByText("SUBMIT")?.click() - device.findObjectByText("CONTINUE")?.click() + playContinueInteraction() } - /** Play second TextInputInteraction for PrototypeExporation. */ private fun playTextInputInteraction() { device.findObjectByRes("text_input_interaction_view")?.text = "Finnish" device.findObjectByText("SUBMIT")?.click() - device.findObjectByText("CONTINUE")?.click() + playContinueInteraction() } - /** Play second DragAndDropInteraction for PrototypeExporation. */ private fun playDragAndDropInteraction() { device.findObjectByDesc("Move item down to 2")?.click() device.findObjectByDesc("Move item down to 3")?.click() device.findObjectByDesc("Move item down to 4")?.click() device.findObjectByText("SUBMIT")?.click() - device.findObjectByText("CONTINUE")?.click() + playContinueInteraction() } - /** Play second DragDropMergeInteraction for PrototypeExporation. */ private fun playDragDropMergeInteraction() { device.findObjectByDesc("Link to item 2")?.click() device.findObjectByDesc("Move item down to 3")?.click() device.findObjectByText("SUBMIT")?.click() - device.findObjectByText("CONTINUE")?.click() + playContinueInteraction() } - /** End exploration for PrototypeExploration. */ - private fun endExploration() { + private fun playEndExplorationInteraction() { device.findObjectByText("RETURN TO TOPIC")?.click() } @@ -173,20 +169,7 @@ class ExplorationPlayerTest { device.findObjectByText("First Story")?.click() scrollRecyclerViewTextIntoView("Chapter 1: Prototype Exploration") device.findObjectByText("Chapter 1: Prototype Exploration")?.click() - - // Complete PrototypeExploration - playExplorationDescription() - playFractionInputInteraction() - playMultipleChoiceIntearction1() - playMultipleChoiceIntearction2() - playItemSelectionInteraction() - playNumericInputInteraction() - playRatioInputInteraction() - playTextInputInteraction() - playDragAndDropInteraction() - playDragDropMergeInteraction() - endExploration() - + completePrototypeExploration() scrollRecyclerViewTextIntoView("Chapter 2: Image Region Selection Exploration") device.findObjectByText("Chapter 2: Image Region Selection Exploration")?.click() } From 58caec19904455a271db0072f8481ece08e6a995 Mon Sep 17 00:00:00 2001 From: farees Date: Thu, 19 Aug 2021 14:19:42 +0530 Subject: [PATCH 55/63] Using !!. --- .../android/app/story/StoryFragmentTest.kt | 2 +- .../player/ExplorationPlayerTest.kt | 111 ++++++++++-------- 2 files changed, 61 insertions(+), 52 deletions(-) diff --git a/app/src/sharedTest/java/org/oppia/android/app/story/StoryFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/story/StoryFragmentTest.kt index 57942f13954..97797765dbe 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/story/StoryFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/story/StoryFragmentTest.kt @@ -235,7 +235,7 @@ class StoryFragmentTest { position = 1, targetViewId = R.id.chapter_completed_tick ) - ).check(matches(withContentDescription(R.string.chapter_completed))) + ).check(matches(withText("Chapter 1 with title What is a Fraction? is completed"))) } } diff --git a/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt b/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt index dd37ec695a5..687f61a15c4 100644 --- a/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt +++ b/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt @@ -27,55 +27,64 @@ class ExplorationPlayerTest { @Test fun testPlayExploration_prototypeExploration_playedFullyThrough_finishesSuccessfully() { navigateToPrototypeExploration() - completePrototypeExploration() + + // Play through all interactions. + playContinueInteraction() + playFractionInputInteraction() + playMultipleChoiceIntearction1() + playMultipleChoiceIntearction2() + playItemSelectionInteraction() + playNumericInputInteraction() + playRatioInputInteraction() + playTextInputInteraction() + playDragAndDropInteraction() + playDragDropMergeInteraction() + playEndExplorationInteraction() // Assert Topic Completed. scrollRecyclerViewTextIntoView("Chapter 1: Prototype Exploration") - val chapterCompletedTick = device.findObjectByText( - "Chapter 1: Prototype Exploration" - )?.parent?.children?.get(2) + val chapterCompletedTick = device.findObjectByDesc( + "Chapter 1 with title Prototype Exploration is completed" + )!! assertThat(chapterCompletedTick).isNotNull() } // TODO(#3697): Update e2e tests when backend support is introduced. @Test @Ignore("Need backend connection support to test the ImageRegionSelectionInteraction") - fun testPlayExploration_imageRegionInteraction_playedFullyThrough_finishesSuccessfully() { + fun testPlayExploration_imageRegionInteractionExp_playedFullyThrough_finishesSuccessfully() { navigateToImageRegionSelectionInteraction() // / Image Region Selection Interaction. val imageSelectionView = device.findObjectByRes("interaction_container_frame_layout") device.waitForRes("image_click_interaction_image_view") - imageSelectionView?.children?.get(2)?.click() - device.findObjectByText("SUBMIT")?.click() - device.findObjectByText("CONTINUE")?.click() + imageSelectionView!!.children!!.get(2)!!.click() + device.findObjectByText("SUBMIT")!!.click() + device.findObjectByText("CONTINUE")!!.click() // End Exploration. playEndExplorationInteraction() // Assert Topic Completed. scrollRecyclerViewTextIntoView("Chapter 2: Image Region Selection Exploration") - val chapterCompletedTick = device.findObjectByText( - "Chapter 2: Image Region Selection Exploration" - )?.parent?.children?.get(2) val chapterCompletedTick = device.findObjectByDesc( - "Chapter 1 with title Prototype Exploration is completed" - ) + "Chapter 2 with title Image Region Selection Exploration is completed" + )!! assertThat(chapterCompletedTick).isNotNull() } /** Navigates and opens the Prototype Exploration using the admin profile. */ private fun navigateToPrototypeExploration() { - device.findObjectByRes("skip_text_view")?.click() - device.findObjectByRes("get_started_button")?.click() + device.findObjectByRes("skip_text_view")!!.click() + device.findObjectByRes("get_started_button")!!.click() device.waitForRes("profile_select_text") - device.findObjectByText("Admin")?.click() + device.findObjectByText("Admin")!!.click() scrollRecyclerViewTextIntoView("First Test Topic") - device.findObjectByText("First Test Topic")?.click() - device.findObjectByText("LESSONS")?.click() - device.findObjectByText("First Story")?.click() + device.findObjectByText("First Test Topic")!!.click() + device.findObjectByText("LESSONS")!!.click() + device.findObjectByText("First Story")!!.click() scrollRecyclerViewTextIntoView("Chapter 1: Prototype Exploration") - device.findObjectByText("Chapter 1: Prototype Exploration")?.click() + device.findObjectByText("Chapter 1: Prototype Exploration")!!.click() } private fun completePrototypeExploration() { @@ -93,84 +102,84 @@ class ExplorationPlayerTest { } private fun playContinueInteraction() { - device.findObjectByText("CONTINUE")?.click() + device.findObjectByText("CONTINUE")!!.click() } private fun playFractionInputInteraction() { - device.findObjectByRes("fraction_input_interaction_view")?.text = "1/2" - device.findObjectByText("SUBMIT")?.click() + device.findObjectByRes("fraction_input_interaction_view")!!.text = "1/2" + device.findObjectByText("SUBMIT")!!.click() playContinueInteraction() } private fun playMultipleChoiceIntearction1() { - device.findObjectByText("Eagle")?.click() + device.findObjectByText("Eagle")!!.click() playContinueInteraction() } private fun playMultipleChoiceIntearction2() { - device.findObjectByText("Green")?.click() + device.findObjectByText("Green")!!.click() playContinueInteraction() } private fun playItemSelectionInteraction() { - device.findObjectByText("Red")?.click() - device.findObjectByText("Green")?.click() - device.findObjectByText("Blue")?.click() - device.findObjectByText("SUBMIT")?.click() + device.findObjectByText("Red")!!.click() + device.findObjectByText("Green")!!.click() + device.findObjectByText("Blue")!!.click() + device.findObjectByText("SUBMIT")!!.click() playContinueInteraction() } private fun playNumericInputInteraction() { - device.findObjectByRes("numeric_input_interaction_view")?.text = "121" - device.findObjectByText("SUBMIT")?.click() + device.findObjectByRes("numeric_input_interaction_view")!!.text = "121" + device.findObjectByText("SUBMIT")!!.click() playContinueInteraction() } private fun playRatioInputInteraction() { - device.findObjectByRes("ratio_input_interaction_view")?.text = "4:5" - device.findObjectByText("SUBMIT")?.click() + device.findObjectByRes("ratio_input_interaction_view")!!.text = "4:5" + device.findObjectByText("SUBMIT")!!.click() playContinueInteraction() } private fun playTextInputInteraction() { - device.findObjectByRes("text_input_interaction_view")?.text = "Finnish" - device.findObjectByText("SUBMIT")?.click() + device.findObjectByRes("text_input_interaction_view")!!.text = "Finnish" + device.findObjectByText("SUBMIT")!!.click() playContinueInteraction() } private fun playDragAndDropInteraction() { - device.findObjectByDesc("Move item down to 2")?.click() - device.findObjectByDesc("Move item down to 3")?.click() - device.findObjectByDesc("Move item down to 4")?.click() - device.findObjectByText("SUBMIT")?.click() + device.findObjectByDesc("Move item down to 2")!!.click() + device.findObjectByDesc("Move item down to 3")!!.click() + device.findObjectByDesc("Move item down to 4")!!.click() + device.findObjectByText("SUBMIT")!!.click() playContinueInteraction() } private fun playDragDropMergeInteraction() { - device.findObjectByDesc("Link to item 2")?.click() - device.findObjectByDesc("Move item down to 3")?.click() - device.findObjectByText("SUBMIT")?.click() + device.findObjectByDesc("Link to item 2")!!.click() + device.findObjectByDesc("Move item down to 3")!!.click() + device.findObjectByText("SUBMIT")!!.click() playContinueInteraction() } private fun playEndExplorationInteraction() { - device.findObjectByText("RETURN TO TOPIC")?.click() + device.findObjectByText("RETURN TO TOPIC")!!.click() } /** Navigates and opens the Image Region Selection Exploration using the admin profile. */ private fun navigateToImageRegionSelectionInteraction() { - device.findObjectByRes("skip_text_view")?.click() - device.findObjectByRes("get_started_button")?.click() + device.findObjectByRes("skip_text_view")!!.click() + device.findObjectByRes("get_started_button")!!.click() device.waitForRes("profile_select_text") - device.findObjectByText("Admin")?.click() + device.findObjectByText("Admin")!!.click() scrollRecyclerViewTextIntoView("First Test Topic") - device.findObjectByText("First Test Topic")?.click() - device.findObjectByText("LESSONS")?.click() - device.findObjectByText("First Story")?.click() + device.findObjectByText("First Test Topic")!!.click() + device.findObjectByText("LESSONS")!!.click() + device.findObjectByText("First Story")!!.click() scrollRecyclerViewTextIntoView("Chapter 1: Prototype Exploration") - device.findObjectByText("Chapter 1: Prototype Exploration")?.click() + device.findObjectByText("Chapter 1: Prototype Exploration")!!.click() completePrototypeExploration() scrollRecyclerViewTextIntoView("Chapter 2: Image Region Selection Exploration") - device.findObjectByText("Chapter 2: Image Region Selection Exploration")?.click() + device.findObjectByText("Chapter 2: Image Region Selection Exploration")!!.click() } } From 8d16408d67839cd516ca18ff84925cb440c26045 Mon Sep 17 00:00:00 2001 From: farees Date: Thu, 19 Aug 2021 14:20:16 +0530 Subject: [PATCH 56/63] NIT --- .../android/instrumentation/player/ExplorationPlayerTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt b/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt index 687f61a15c4..7834a81090c 100644 --- a/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt +++ b/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt @@ -55,7 +55,7 @@ class ExplorationPlayerTest { fun testPlayExploration_imageRegionInteractionExp_playedFullyThrough_finishesSuccessfully() { navigateToImageRegionSelectionInteraction() - // / Image Region Selection Interaction. + // Image Region Selection Interaction. val imageSelectionView = device.findObjectByRes("interaction_container_frame_layout") device.waitForRes("image_click_interaction_image_view") imageSelectionView!!.children!!.get(2)!!.click() From c7bd1dd4de9b86874a0ca272caad3b1e868aed1e Mon Sep 17 00:00:00 2001 From: farees Date: Thu, 19 Aug 2021 15:23:06 +0530 Subject: [PATCH 57/63] fixed tests --- .../java/org/oppia/android/app/story/StoryFragmentTest.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/src/sharedTest/java/org/oppia/android/app/story/StoryFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/story/StoryFragmentTest.kt index 97797765dbe..be9d405fa86 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/story/StoryFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/story/StoryFragmentTest.kt @@ -235,7 +235,13 @@ class StoryFragmentTest { position = 1, targetViewId = R.id.chapter_completed_tick ) - ).check(matches(withText("Chapter 1 with title What is a Fraction? is completed"))) + ).check( + matches( + withContentDescription( + "Chapter 1 with title What is a Fraction? is completed" + ) + ) + ) } } From f01a6553f8d6dbe328add1f0302526a7be91f6ed Mon Sep 17 00:00:00 2001 From: farees Date: Fri, 20 Aug 2021 01:48:17 +0530 Subject: [PATCH 58/63] reverted chapter_completed_tick content desc --- app/src/main/res/layout-land/story_chapter_view.xml | 2 +- .../main/res/layout-sw600dp/story_chapter_view.xml | 2 +- app/src/main/res/layout/story_chapter_view.xml | 2 +- .../org/oppia/android/app/story/StoryFragmentTest.kt | 8 +------- .../instrumentation/testing/EndToEndTestHelper.kt | 5 +++++ .../instrumentation/player/ExplorationPlayerTest.kt | 12 ++++++------ 6 files changed, 15 insertions(+), 16 deletions(-) diff --git a/app/src/main/res/layout-land/story_chapter_view.xml b/app/src/main/res/layout-land/story_chapter_view.xml index 28a7e6cf637..fa22023c660 100644 --- a/app/src/main/res/layout-land/story_chapter_view.xml +++ b/app/src/main/res/layout-land/story_chapter_view.xml @@ -91,7 +91,7 @@ android:layout_height="wrap_content" android:layout_marginEnd="8dp" android:layout_marginBottom="4dp" - android:contentDescription="@{String.format(@string/chapter_completed, (viewModel.index + 1), viewModel.name)}" + android:contentDescription="@{@string/chapter_completed}" android:src="@drawable/ic_check_24dp" android:visibility="@{viewModel.chapterSummary.chapterPlayState == ChapterPlayState.COMPLETED ? View.VISIBLE : View.GONE}" app:layout_constraintBottom_toBottomOf="parent" diff --git a/app/src/main/res/layout-sw600dp/story_chapter_view.xml b/app/src/main/res/layout-sw600dp/story_chapter_view.xml index 973645c8c98..fcaf7b1ab35 100644 --- a/app/src/main/res/layout-sw600dp/story_chapter_view.xml +++ b/app/src/main/res/layout-sw600dp/story_chapter_view.xml @@ -126,7 +126,7 @@ android:layout_height="wrap_content" android:layout_marginEnd="8dp" android:layout_marginBottom="4dp" - android:contentDescription="@{String.format(@string/chapter_completed, (viewModel.index + 1), viewModel.name)}" + android:contentDescription="@{@string/chapter_completed}" android:src="@drawable/ic_check_24dp" android:visibility="@{viewModel.chapterSummary.chapterPlayState == ChapterPlayState.COMPLETED ? View.VISIBLE : View.GONE}" app:layout_constraintBottom_toBottomOf="parent" diff --git a/app/src/main/res/layout/story_chapter_view.xml b/app/src/main/res/layout/story_chapter_view.xml index 973645c8c98..fcaf7b1ab35 100644 --- a/app/src/main/res/layout/story_chapter_view.xml +++ b/app/src/main/res/layout/story_chapter_view.xml @@ -126,7 +126,7 @@ android:layout_height="wrap_content" android:layout_marginEnd="8dp" android:layout_marginBottom="4dp" - android:contentDescription="@{String.format(@string/chapter_completed, (viewModel.index + 1), viewModel.name)}" + android:contentDescription="@{@string/chapter_completed}" android:src="@drawable/ic_check_24dp" android:visibility="@{viewModel.chapterSummary.chapterPlayState == ChapterPlayState.COMPLETED ? View.VISIBLE : View.GONE}" app:layout_constraintBottom_toBottomOf="parent" diff --git a/app/src/sharedTest/java/org/oppia/android/app/story/StoryFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/story/StoryFragmentTest.kt index be9d405fa86..57942f13954 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/story/StoryFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/story/StoryFragmentTest.kt @@ -235,13 +235,7 @@ class StoryFragmentTest { position = 1, targetViewId = R.id.chapter_completed_tick ) - ).check( - matches( - withContentDescription( - "Chapter 1 with title What is a Fraction? is completed" - ) - ) - ) + ).check(matches(withContentDescription(R.string.chapter_completed))) } } diff --git a/instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt b/instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt index 7d697a56853..3e41c09d771 100644 --- a/instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt +++ b/instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt @@ -66,6 +66,11 @@ object EndToEndTestHelper { return findObject(By.res("$OPPIA_PACKAGE:id/$resourceId")) } + /** Returns the UiObject for the given resourceId. */ + fun UiObject2.findObjectByRes(resourceId: String): UiObject2? { + return findObject(By.res("$OPPIA_PACKAGE:id/$resourceId")) + } + /** Returns the UiObject for the given content description. */ fun UiDevice.findObjectByDesc(text: String): UiObject2? { waitForDesc(text) diff --git a/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt b/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt index 7834a81090c..9739cdf2826 100644 --- a/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt +++ b/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt @@ -43,9 +43,9 @@ class ExplorationPlayerTest { // Assert Topic Completed. scrollRecyclerViewTextIntoView("Chapter 1: Prototype Exploration") - val chapterCompletedTick = device.findObjectByDesc( - "Chapter 1 with title Prototype Exploration is completed" - )!! + val chapterCompletedTick = device.findObjectByText( + "Chapter 1: Prototype Exploration" + )!!.parent.findObjectByRes("chapter_completed_tick") assertThat(chapterCompletedTick).isNotNull() } @@ -67,9 +67,9 @@ class ExplorationPlayerTest { // Assert Topic Completed. scrollRecyclerViewTextIntoView("Chapter 2: Image Region Selection Exploration") - val chapterCompletedTick = device.findObjectByDesc( - "Chapter 2 with title Image Region Selection Exploration is completed" - )!! + val chapterCompletedTick = device.findObjectByText( + "Chapter 2: Image Region Selection Exploration" + )!!.parent.findObjectByRes("chapter_completed_tick") assertThat(chapterCompletedTick).isNotNull() } From 4811a07cc788236005417a619c58a6db208a968a Mon Sep 17 00:00:00 2001 From: farees Date: Fri, 20 Aug 2021 03:27:41 +0530 Subject: [PATCH 59/63] Updated content description for ImageRegionSelectionInteraction --- .../java/org/oppia/android/app/utility/ClickableAreasImage.kt | 1 + .../android/instrumentation/player/ExplorationPlayerTest.kt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt b/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt index 31e52891d87..9013f3e1ae1 100644 --- a/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt +++ b/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt @@ -116,6 +116,7 @@ class ClickableAreasImage( newView.isFocusable = true newView.isFocusableInTouchMode = true newView.tag = clickableArea.label + newView.contentDescription = clickableArea.label newView.setOnTouchListener { _, event -> if (event.action == MotionEvent.ACTION_DOWN) { showOrHideRegion(newView, clickableArea) diff --git a/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt b/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt index 9739cdf2826..c4229b75d64 100644 --- a/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt +++ b/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt @@ -58,7 +58,7 @@ class ExplorationPlayerTest { // Image Region Selection Interaction. val imageSelectionView = device.findObjectByRes("interaction_container_frame_layout") device.waitForRes("image_click_interaction_image_view") - imageSelectionView!!.children!!.get(2)!!.click() + device.findObjectByDesc("Saturn")!!.click() device.findObjectByText("SUBMIT")!!.click() device.findObjectByText("CONTINUE")!!.click() From b9e9fbebdcad3cdadc5a12f273f8c57309baea23 Mon Sep 17 00:00:00 2001 From: farees Date: Fri, 20 Aug 2021 04:06:50 +0530 Subject: [PATCH 60/63] testing ImageRegionSelectionInteractionView --- ...ImageRegionSelectionInteractionViewTest.kt | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/app/src/sharedTest/java/org/oppia/android/app/testing/ImageRegionSelectionInteractionViewTest.kt b/app/src/sharedTest/java/org/oppia/android/app/testing/ImageRegionSelectionInteractionViewTest.kt index 63e0903dfad..8c4fa8f5cf9 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/testing/ImageRegionSelectionInteractionViewTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/testing/ImageRegionSelectionInteractionViewTest.kt @@ -6,8 +6,10 @@ import androidx.appcompat.app.AppCompatActivity import androidx.test.core.app.ActivityScenario.launch import androidx.test.core.app.ApplicationProvider import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.action.ViewActions.click import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.ViewMatchers.isDisplayed +import androidx.test.espresso.matcher.ViewMatchers.withContentDescription import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withTagValue import androidx.test.ext.junit.runners.AndroidJUnit4 @@ -135,6 +137,26 @@ class ImageRegionSelectionInteractionViewTest { } } + @Test + // TODO(#1611): Fix ImageRegionSelectionInteractionViewTest + @Ignore + fun testImageRegionSelectionInteractionView_clickDescRegion3_region3Clicked() { + launch(ImageRegionSelectionTestActivity::class.java).use { + it.onActivity { + it.findViewById(R.id.clickable_image_view) + .setListener(onClickableAreaClickedListener) + } + onView(withContentDescription("Region 3")).perform(click()) + + verify(onClickableAreaClickedListener) + .onClickableAreaTouched( + capture(regionClickedEvent) + ) + assertThat(regionClickedEvent.value) + .isEqualTo(NamedRegionClickedEvent(regionLabel = "Region 3")) + } + } + @Test // TODO(#1611): Fix ImageRegionSelectionInteractionViewTest @Ignore From 196f8dbc0a9121bbda45c74afb35d6ba80bbcad2 Mon Sep 17 00:00:00 2001 From: farees Date: Fri, 20 Aug 2021 14:22:25 +0530 Subject: [PATCH 61/63] updated test --- .../ImageRegionSelectionInteractionViewTest.kt | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/app/src/sharedTest/java/org/oppia/android/app/testing/ImageRegionSelectionInteractionViewTest.kt b/app/src/sharedTest/java/org/oppia/android/app/testing/ImageRegionSelectionInteractionViewTest.kt index 8c4fa8f5cf9..7f8f642a991 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/testing/ImageRegionSelectionInteractionViewTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/testing/ImageRegionSelectionInteractionViewTest.kt @@ -6,7 +6,6 @@ import androidx.appcompat.app.AppCompatActivity import androidx.test.core.app.ActivityScenario.launch import androidx.test.core.app.ApplicationProvider import androidx.test.espresso.Espresso.onView -import androidx.test.espresso.action.ViewActions.click import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.ViewMatchers.isDisplayed import androidx.test.espresso.matcher.ViewMatchers.withContentDescription @@ -140,20 +139,15 @@ class ImageRegionSelectionInteractionViewTest { @Test // TODO(#1611): Fix ImageRegionSelectionInteractionViewTest @Ignore - fun testImageRegionSelectionInteractionView_clickDescRegion3_region3Clicked() { + fun testImageRegionSelectionInteractionView_region3_region3HasCorrectContentDescription() { launch(ImageRegionSelectionTestActivity::class.java).use { it.onActivity { it.findViewById(R.id.clickable_image_view) .setListener(onClickableAreaClickedListener) } - onView(withContentDescription("Region 3")).perform(click()) - - verify(onClickableAreaClickedListener) - .onClickableAreaTouched( - capture(regionClickedEvent) - ) - assertThat(regionClickedEvent.value) - .isEqualTo(NamedRegionClickedEvent(regionLabel = "Region 3")) + onView(withTagValue(`is`("Region 3"))).check( + matches(withContentDescription("Region 3")) + ) } } From bf1e0eb30c6a82b22eec7248b34f7a18160b6411 Mon Sep 17 00:00:00 2001 From: farees Date: Fri, 20 Aug 2021 15:04:24 +0530 Subject: [PATCH 62/63] remoced ignore --- .../app/testing/ImageRegionSelectionInteractionViewTest.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/src/sharedTest/java/org/oppia/android/app/testing/ImageRegionSelectionInteractionViewTest.kt b/app/src/sharedTest/java/org/oppia/android/app/testing/ImageRegionSelectionInteractionViewTest.kt index 7f8f642a991..f60c3fb0032 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/testing/ImageRegionSelectionInteractionViewTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/testing/ImageRegionSelectionInteractionViewTest.kt @@ -137,8 +137,6 @@ class ImageRegionSelectionInteractionViewTest { } @Test - // TODO(#1611): Fix ImageRegionSelectionInteractionViewTest - @Ignore fun testImageRegionSelectionInteractionView_region3_region3HasCorrectContentDescription() { launch(ImageRegionSelectionTestActivity::class.java).use { it.onActivity { From 63ed6809f2db5250b8680a1ea683fbb9365a2132 Mon Sep 17 00:00:00 2001 From: farees Date: Sat, 21 Aug 2021 04:35:29 +0530 Subject: [PATCH 63/63] Removed content description and Added checkNotNull --- .../app/utility/ClickableAreasImage.kt | 1 - ...ImageRegionSelectionInteractionViewTest.kt | 14 --- .../testing/EndToEndTestHelper.kt | 16 ++-- .../player/ExplorationPlayerTest.kt | 87 ++++++++++--------- 4 files changed, 52 insertions(+), 66 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt b/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt index 9013f3e1ae1..31e52891d87 100644 --- a/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt +++ b/app/src/main/java/org/oppia/android/app/utility/ClickableAreasImage.kt @@ -116,7 +116,6 @@ class ClickableAreasImage( newView.isFocusable = true newView.isFocusableInTouchMode = true newView.tag = clickableArea.label - newView.contentDescription = clickableArea.label newView.setOnTouchListener { _, event -> if (event.action == MotionEvent.ACTION_DOWN) { showOrHideRegion(newView, clickableArea) diff --git a/app/src/sharedTest/java/org/oppia/android/app/testing/ImageRegionSelectionInteractionViewTest.kt b/app/src/sharedTest/java/org/oppia/android/app/testing/ImageRegionSelectionInteractionViewTest.kt index f60c3fb0032..63e0903dfad 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/testing/ImageRegionSelectionInteractionViewTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/testing/ImageRegionSelectionInteractionViewTest.kt @@ -8,7 +8,6 @@ import androidx.test.core.app.ApplicationProvider import androidx.test.espresso.Espresso.onView import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.ViewMatchers.isDisplayed -import androidx.test.espresso.matcher.ViewMatchers.withContentDescription import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withTagValue import androidx.test.ext.junit.runners.AndroidJUnit4 @@ -136,19 +135,6 @@ class ImageRegionSelectionInteractionViewTest { } } - @Test - fun testImageRegionSelectionInteractionView_region3_region3HasCorrectContentDescription() { - launch(ImageRegionSelectionTestActivity::class.java).use { - it.onActivity { - it.findViewById(R.id.clickable_image_view) - .setListener(onClickableAreaClickedListener) - } - onView(withTagValue(`is`("Region 3"))).check( - matches(withContentDescription("Region 3")) - ) - } - } - @Test // TODO(#1611): Fix ImageRegionSelectionInteractionViewTest @Ignore diff --git a/instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt b/instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt index 3e41c09d771..3074b255a1e 100644 --- a/instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt +++ b/instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt @@ -55,26 +55,26 @@ object EndToEndTestHelper { } /** Return the UiObject with the given text. */ - fun UiDevice.findObjectByText(text: String): UiObject2? { + fun UiDevice.findObjectByText(text: String): UiObject2 { waitForText(text) - return findObject(By.text(text)) + return checkNotNull(findObject(By.text(text))) } /** Returns the UiObject for the given resourceId. */ - fun UiDevice.findObjectByRes(resourceId: String): UiObject2? { + fun UiDevice.findObjectByRes(resourceId: String): UiObject2 { waitForRes(resourceId) - return findObject(By.res("$OPPIA_PACKAGE:id/$resourceId")) + return checkNotNull(findObject(By.res("$OPPIA_PACKAGE:id/$resourceId"))) } /** Returns the UiObject for the given resourceId. */ - fun UiObject2.findObjectByRes(resourceId: String): UiObject2? { - return findObject(By.res("$OPPIA_PACKAGE:id/$resourceId")) + fun UiObject2.findObjectByRes(resourceId: String): UiObject2 { + return checkNotNull(findObject(By.res("$OPPIA_PACKAGE:id/$resourceId"))) } /** Returns the UiObject for the given content description. */ - fun UiDevice.findObjectByDesc(text: String): UiObject2? { + fun UiDevice.findObjectByDesc(text: String): UiObject2 { waitForDesc(text) - return findObject(By.desc(text)) + return checkNotNull(findObject(By.desc(text))) } /** Performs a scroll until the view with the give text is visible. */ diff --git a/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt b/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt index c4229b75d64..4bf77e7610b 100644 --- a/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt +++ b/instrumentation/src/javatests/org/oppia/android/instrumentation/player/ExplorationPlayerTest.kt @@ -45,7 +45,7 @@ class ExplorationPlayerTest { scrollRecyclerViewTextIntoView("Chapter 1: Prototype Exploration") val chapterCompletedTick = device.findObjectByText( "Chapter 1: Prototype Exploration" - )!!.parent.findObjectByRes("chapter_completed_tick") + ).parent.findObjectByRes("chapter_completed_tick") assertThat(chapterCompletedTick).isNotNull() } @@ -58,9 +58,10 @@ class ExplorationPlayerTest { // Image Region Selection Interaction. val imageSelectionView = device.findObjectByRes("interaction_container_frame_layout") device.waitForRes("image_click_interaction_image_view") - device.findObjectByDesc("Saturn")!!.click() - device.findObjectByText("SUBMIT")!!.click() - device.findObjectByText("CONTINUE")!!.click() + // TODO(#3712): Use content description to fetch the image region. + imageSelectionView.children.get(2).click() + device.findObjectByText("SUBMIT").click() + device.findObjectByText("CONTINUE").click() // End Exploration. playEndExplorationInteraction() @@ -69,22 +70,22 @@ class ExplorationPlayerTest { scrollRecyclerViewTextIntoView("Chapter 2: Image Region Selection Exploration") val chapterCompletedTick = device.findObjectByText( "Chapter 2: Image Region Selection Exploration" - )!!.parent.findObjectByRes("chapter_completed_tick") + ).parent.findObjectByRes("chapter_completed_tick") assertThat(chapterCompletedTick).isNotNull() } /** Navigates and opens the Prototype Exploration using the admin profile. */ private fun navigateToPrototypeExploration() { - device.findObjectByRes("skip_text_view")!!.click() - device.findObjectByRes("get_started_button")!!.click() + device.findObjectByRes("skip_text_view").click() + device.findObjectByRes("get_started_button").click() device.waitForRes("profile_select_text") - device.findObjectByText("Admin")!!.click() + device.findObjectByText("Admin").click() scrollRecyclerViewTextIntoView("First Test Topic") - device.findObjectByText("First Test Topic")!!.click() - device.findObjectByText("LESSONS")!!.click() - device.findObjectByText("First Story")!!.click() + device.findObjectByText("First Test Topic").click() + device.findObjectByText("LESSONS").click() + device.findObjectByText("First Story").click() scrollRecyclerViewTextIntoView("Chapter 1: Prototype Exploration") - device.findObjectByText("Chapter 1: Prototype Exploration")!!.click() + device.findObjectByText("Chapter 1: Prototype Exploration").click() } private fun completePrototypeExploration() { @@ -102,84 +103,84 @@ class ExplorationPlayerTest { } private fun playContinueInteraction() { - device.findObjectByText("CONTINUE")!!.click() + device.findObjectByText("CONTINUE").click() } private fun playFractionInputInteraction() { - device.findObjectByRes("fraction_input_interaction_view")!!.text = "1/2" - device.findObjectByText("SUBMIT")!!.click() + device.findObjectByRes("fraction_input_interaction_view").text = "1/2" + device.findObjectByText("SUBMIT").click() playContinueInteraction() } private fun playMultipleChoiceIntearction1() { - device.findObjectByText("Eagle")!!.click() + device.findObjectByText("Eagle").click() playContinueInteraction() } private fun playMultipleChoiceIntearction2() { - device.findObjectByText("Green")!!.click() + device.findObjectByText("Green").click() playContinueInteraction() } private fun playItemSelectionInteraction() { - device.findObjectByText("Red")!!.click() - device.findObjectByText("Green")!!.click() - device.findObjectByText("Blue")!!.click() - device.findObjectByText("SUBMIT")!!.click() + device.findObjectByText("Red").click() + device.findObjectByText("Green").click() + device.findObjectByText("Blue").click() + device.findObjectByText("SUBMIT").click() playContinueInteraction() } private fun playNumericInputInteraction() { - device.findObjectByRes("numeric_input_interaction_view")!!.text = "121" - device.findObjectByText("SUBMIT")!!.click() + device.findObjectByRes("numeric_input_interaction_view").text = "121" + device.findObjectByText("SUBMIT").click() playContinueInteraction() } private fun playRatioInputInteraction() { - device.findObjectByRes("ratio_input_interaction_view")!!.text = "4:5" - device.findObjectByText("SUBMIT")!!.click() + device.findObjectByRes("ratio_input_interaction_view").text = "4:5" + device.findObjectByText("SUBMIT").click() playContinueInteraction() } private fun playTextInputInteraction() { - device.findObjectByRes("text_input_interaction_view")!!.text = "Finnish" - device.findObjectByText("SUBMIT")!!.click() + device.findObjectByRes("text_input_interaction_view").text = "Finnish" + device.findObjectByText("SUBMIT").click() playContinueInteraction() } private fun playDragAndDropInteraction() { - device.findObjectByDesc("Move item down to 2")!!.click() - device.findObjectByDesc("Move item down to 3")!!.click() - device.findObjectByDesc("Move item down to 4")!!.click() - device.findObjectByText("SUBMIT")!!.click() + device.findObjectByDesc("Move item down to 2").click() + device.findObjectByDesc("Move item down to 3").click() + device.findObjectByDesc("Move item down to 4").click() + device.findObjectByText("SUBMIT").click() playContinueInteraction() } private fun playDragDropMergeInteraction() { - device.findObjectByDesc("Link to item 2")!!.click() - device.findObjectByDesc("Move item down to 3")!!.click() - device.findObjectByText("SUBMIT")!!.click() + device.findObjectByDesc("Link to item 2").click() + device.findObjectByDesc("Move item down to 3").click() + device.findObjectByText("SUBMIT").click() playContinueInteraction() } private fun playEndExplorationInteraction() { - device.findObjectByText("RETURN TO TOPIC")!!.click() + device.findObjectByText("RETURN TO TOPIC").click() } /** Navigates and opens the Image Region Selection Exploration using the admin profile. */ private fun navigateToImageRegionSelectionInteraction() { - device.findObjectByRes("skip_text_view")!!.click() - device.findObjectByRes("get_started_button")!!.click() + device.findObjectByRes("skip_text_view").click() + device.findObjectByRes("get_started_button").click() device.waitForRes("profile_select_text") - device.findObjectByText("Admin")!!.click() + device.findObjectByText("Admin").click() scrollRecyclerViewTextIntoView("First Test Topic") - device.findObjectByText("First Test Topic")!!.click() - device.findObjectByText("LESSONS")!!.click() - device.findObjectByText("First Story")!!.click() + device.findObjectByText("First Test Topic").click() + device.findObjectByText("LESSONS").click() + device.findObjectByText("First Story").click() scrollRecyclerViewTextIntoView("Chapter 1: Prototype Exploration") - device.findObjectByText("Chapter 1: Prototype Exploration")!!.click() + device.findObjectByText("Chapter 1: Prototype Exploration").click() completePrototypeExploration() scrollRecyclerViewTextIntoView("Chapter 2: Image Region Selection Exploration") - device.findObjectByText("Chapter 2: Image Region Selection Exploration")!!.click() + device.findObjectByText("Chapter 2: Image Region Selection Exploration").click() } }