diff --git a/projects.conf b/projects.conf index 406630265..f9b14cdb2 100644 --- a/projects.conf +++ b/projects.conf @@ -5,6 +5,7 @@ ui/espresso/AccessibilitySample ui/espresso/BasicSample ui/espresso/CustomMatcherSample ui/espresso/DataAdapterSample +ui/espresso/EspressoDeviceSample ui/espresso/FragmentScenarioSample ui/espresso/IdlingResourceSample ui/espresso/IntentsAdvancedSample @@ -15,4 +16,4 @@ ui/espresso/RecyclerViewSample ui/espresso/ScreenshotSample ui/espresso/WebBasicSample ui/uiautomator/BasicSample -unit/BasicNativeAndroidTest \ No newline at end of file +unit/BasicNativeAndroidTest diff --git a/ui/espresso/EspressoDeviceSample/.gitignore b/ui/espresso/EspressoDeviceSample/.gitignore new file mode 100644 index 000000000..1406630a7 --- /dev/null +++ b/ui/espresso/EspressoDeviceSample/.gitignore @@ -0,0 +1,6 @@ +.gradle +local.properties +.idea +.DS_Store +build +*.iml diff --git a/ui/espresso/EspressoDeviceSample/BUILD.bazel b/ui/espresso/EspressoDeviceSample/BUILD.bazel new file mode 100644 index 000000000..1cf22e43f --- /dev/null +++ b/ui/espresso/EspressoDeviceSample/BUILD.bazel @@ -0,0 +1,58 @@ +licenses(["notice"]) # Apache 2.0 + +load("//:common_defs.bzl", "minSdkVersion", "targetSdkVersion") +load("@rules_jvm_external//:defs.bzl", "artifact") + +android_library( + name = "EspressoDeviceSampleLib", + srcs = glob(["app/src/main/**/*.java"]), + custom_package = "com.example.android.testing.espresso.EspressoDeviceSample", + manifest = "app/src/main/AndroidManifest.xml", + resource_files = glob(["app/src/main/res/**/*"]), +) + +android_binary( + name = "EspressoDeviceSample", + custom_package = "com.example.android.testing.espresso.EspressoDeviceSample", + manifest = "app/src/main/AppManifest.xml", + manifest_values = { + "minSdkVersion": minSdkVersion, + "targetSdkVersion": targetSdkVersion, + }, + deps = [":EspressoDeviceSampleLib"], +) + +android_library( + name = "EspressoDeviceSampleTestLib", + srcs = glob(["app/src/androidTest/**/*.java"]), + custom_package = "com.example.android.testing.espresso.EspressoDeviceSample.test", + deps = [ + ":EspressoDeviceSampleLib", + "//:test_deps", + ], +) + +android_binary( + name = "EspressoDeviceSampleTest", + custom_package = "com.example.android.testing.espresso.EspressoDeviceSample.test", + instruments = ":EspressoDeviceSample", + manifest = "app/src/androidTest/AndroidManifest.xml", + manifest_values = { + "minSdkVersion": minSdkVersion, + "targetSdkVersion": targetSdkVersion, + }, + deps = [":EspressoDeviceSampleTestLib"], +) + +API_LEVELS = [ + "19_x86", + "21_x86", + "22_x86", + "23_x86", +] + +[android_instrumentation_test( + name = "EspressoDeviceSampleInstrumentationTest_%s" % API_LEVEL, + target_device = "@android_test_support//tools/android/emulated_devices/generic_phone:android_%s_qemu2" % API_LEVEL, + test_app = ":EspressoDeviceSampleTest", +) for API_LEVEL in API_LEVELS] diff --git a/ui/espresso/EspressoDeviceSample/README.md b/ui/espresso/EspressoDeviceSample/README.md new file mode 100644 index 000000000..4be8ed983 --- /dev/null +++ b/ui/espresso/EspressoDeviceSample/README.md @@ -0,0 +1,25 @@ +# Basic sample for Espresso Device + +The Espresso Device API enables synchronized interactions with the test device. This API is experimental and subject to change. Currently, it is only supported on instrumentation tests run on emulators. + +To skip tests on devices that do not have certain display attributes, such as display width and height, annotate your test with @RequiresDisplay. This annotation takes in a WidthSizeClassEnum and a HeightSizeClassEnum. It can be applied to test classes or test methods. For details on these size classes, see https://developer.android.com/guide/topics/large-screens/support-different-screen-sizes. + +This project uses the Gradle build system. You don't need an IDE to build and execute it but Android Studio 3.4 is recommended. + +1. Download the project code, preferably using `git clone`. +1. In Android Studio, select *File* | *Open...* and point to the `./build.gradle` file. +1. Check out the relevant code: + * The application under test is located in `src/main/java` + * Instrumentation Tests are in `src/androidTest/java` + * Local Tests are in `src/test/java` +1. Create and run the Instrumented test configuration + * Open *Run* menu | *Edit Configurations* + * Add a new *Android Instrumented Tests* configuration + * Choose the `app` module + * Connect a device or start an emulator + * Turn animations off. + (On your device, under Settings->Developer options disable the following 3 settings: "Window animation scale", "Transition animation scale" and "Animator duration scale") + * Run the newly created configuration + * The application will be started on the device/emulator and a series of actions will be performed automatically. + +If you are using Android Studio, the *Run* window will show the test results. \ No newline at end of file diff --git a/ui/espresso/EspressoDeviceSample/app/build.gradle b/ui/espresso/EspressoDeviceSample/app/build.gradle new file mode 100644 index 000000000..a65bca6e6 --- /dev/null +++ b/ui/espresso/EspressoDeviceSample/app/build.gradle @@ -0,0 +1,60 @@ +apply plugin: 'com.android.application' + +apply plugin: 'kotlin-android' + +apply plugin: 'kotlin-android-extensions' + +android { + compileSdkVersion 33 + buildToolsVersion rootProject.buildToolsVersion + defaultConfig { + applicationId "com.example.android.testing.espresso.EspressoDeviceSample" + minSdkVersion 14 + targetSdkVersion 33 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + lintOptions { + abortOnError false + } + productFlavors { + } + testOptions { + unitTests { + includeAndroidResources = true + } + managedDevices { + devices { + // run with ../gradlew nexusOneApi30DebugAndroidTest + nexusOneApi30(com.android.build.api.dsl.ManagedVirtualDevice) { + // A lower resolution device is used here for better emulator performance + device = "Nexus One" + apiLevel = 30 + // Also use the AOSP ATD image for better emulator performance + // The androidx.test screenshot APIs will automatically enable hardware rendering + // to take a screenshot + systemImageSource = "aosp-atd" + } + } + } + } +} + +tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { + kotlinOptions { + jvmTarget = "1.8" + } +} + +dependencies { + androidTestImplementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" + androidTestImplementation 'androidx.test.ext:junit:' + rootProject.extJUnitVersion + androidTestImplementation 'androidx.test.ext:junit-ktx:' + rootProject.extJUnitVersion + androidTestImplementation 'androidx.test.espresso:espresso-device:' + rootProject.espressoDeviceVersion + + testImplementation 'androidx.test.ext:junit:' + rootProject.extJUnitVersion + testImplementation 'junit:junit:4.12' + testImplementation 'org.robolectric:robolectric:' + rootProject.robolectricVersion +} diff --git a/ui/espresso/EspressoDeviceSample/app/src/androidTest/AndroidManifest.xml b/ui/espresso/EspressoDeviceSample/app/src/androidTest/AndroidManifest.xml new file mode 100644 index 000000000..59978599c --- /dev/null +++ b/ui/espresso/EspressoDeviceSample/app/src/androidTest/AndroidManifest.xml @@ -0,0 +1,27 @@ + + + + + + + + diff --git a/ui/espresso/EspressoDeviceSample/app/src/androidTest/java/com/example/android/testing/espresso/EspressoDeviceSample/RequiresDisplayTest.kt b/ui/espresso/EspressoDeviceSample/app/src/androidTest/java/com/example/android/testing/espresso/EspressoDeviceSample/RequiresDisplayTest.kt new file mode 100644 index 000000000..6ba423979 --- /dev/null +++ b/ui/espresso/EspressoDeviceSample/app/src/androidTest/java/com/example/android/testing/espresso/EspressoDeviceSample/RequiresDisplayTest.kt @@ -0,0 +1,93 @@ +/* + * Copyright 2022, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.android.testing.espresso.EspressoDeviceSample + +import androidx.test.espresso.device.filter.RequiresDisplay +import androidx.test.espresso.device.sizeclass.HeightSizeClass +import androidx.test.espresso.device.sizeclass.WidthSizeClass +import androidx.test.ext.junit.runners.AndroidJUnit4 +import org.junit.Test +import org.junit.runner.RunWith + +/* + * Illustrates usage of @RequiresDisplay API to filter tests based on display attributes such a screen size. + */ +@RunWith(AndroidJUnit4::class) +class RequiresDisplayTest { + @RequiresDisplay( + widthSizeClass = WidthSizeClass.Companion.WidthSizeClassEnum.COMPACT, + heightSizeClass = HeightSizeClass.Companion.HeightSizeClassEnum.COMPACT + ) + @Test + fun testOnDevicesWithCompactWidthAndHeight() {} + + @RequiresDisplay( + widthSizeClass = WidthSizeClass.Companion.WidthSizeClassEnum.COMPACT, + heightSizeClass = HeightSizeClass.Companion.HeightSizeClassEnum.MEDIUM + ) + @Test + fun testOnDevicesWithCompactWidthAndMediumHeight() {} + + @RequiresDisplay( + widthSizeClass = WidthSizeClass.Companion.WidthSizeClassEnum.MEDIUM, + heightSizeClass = HeightSizeClass.Companion.HeightSizeClassEnum.COMPACT + ) + @Test + fun testOnDevicesWithMediumWidthAndCompactHeight() {} + + @RequiresDisplay( + widthSizeClass = WidthSizeClass.Companion.WidthSizeClassEnum.COMPACT, + heightSizeClass = HeightSizeClass.Companion.HeightSizeClassEnum.EXPANDED + ) + @Test + fun testOnDevicesWithCompactWidthAndExpandedHeight() {} + + @RequiresDisplay( + widthSizeClass = WidthSizeClass.Companion.WidthSizeClassEnum.EXPANDED, + heightSizeClass = HeightSizeClass.Companion.HeightSizeClassEnum.COMPACT + ) + @Test + fun testOnDevicesWithExpandedWidthAndCompactHeight() {} + + @RequiresDisplay( + widthSizeClass = WidthSizeClass.Companion.WidthSizeClassEnum.MEDIUM, + heightSizeClass = HeightSizeClass.Companion.HeightSizeClassEnum.MEDIUM + ) + @Test + fun testOnDevicesWithMediumWidthAndHeight() {} + + @RequiresDisplay( + widthSizeClass = WidthSizeClass.Companion.WidthSizeClassEnum.EXPANDED, + heightSizeClass = HeightSizeClass.Companion.HeightSizeClassEnum.MEDIUM, + ) + @Test + fun testOnDevicesWithExpandedWidthAndMediumHeight() {} + + + @RequiresDisplay( + widthSizeClass = WidthSizeClass.Companion.WidthSizeClassEnum.MEDIUM, + heightSizeClass = HeightSizeClass.Companion.HeightSizeClassEnum.EXPANDED + ) + @Test + fun testOnDevicesWithMediumWidthAndExpandedHeight() {} + + @RequiresDisplay( + widthSizeClass = WidthSizeClass.Companion.WidthSizeClassEnum.EXPANDED, + heightSizeClass = HeightSizeClass.Companion.HeightSizeClassEnum.EXPANDED + ) + @Test + fun testOnDevicesWithExpandedWidthAndHeight() {} +} \ No newline at end of file diff --git a/ui/espresso/EspressoDeviceSample/app/src/main/AndroidManifest.xml b/ui/espresso/EspressoDeviceSample/app/src/main/AndroidManifest.xml new file mode 100644 index 000000000..361a31168 --- /dev/null +++ b/ui/espresso/EspressoDeviceSample/app/src/main/AndroidManifest.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/ui/espresso/EspressoDeviceSample/app/src/main/AppManifest.xml b/ui/espresso/EspressoDeviceSample/app/src/main/AppManifest.xml new file mode 100644 index 000000000..a314a52af --- /dev/null +++ b/ui/espresso/EspressoDeviceSample/app/src/main/AppManifest.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/ui/espresso/EspressoDeviceSample/app/src/main/java/com/example/android/testing/espresso/EspressoDeviceSample/MainActivity.java b/ui/espresso/EspressoDeviceSample/app/src/main/java/com/example/android/testing/espresso/EspressoDeviceSample/MainActivity.java new file mode 100644 index 000000000..99710b8ba --- /dev/null +++ b/ui/espresso/EspressoDeviceSample/app/src/main/java/com/example/android/testing/espresso/EspressoDeviceSample/MainActivity.java @@ -0,0 +1,31 @@ +/* + * Copyright 2022, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.android.testing.espresso.EspressoDeviceSample; + +import android.app.Activity; +import android.os.Bundle; + +/** + * An empty {@link Activity} that Espresso Device APIs are tested against. + */ +public class MainActivity extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + } +} diff --git a/ui/espresso/EspressoDeviceSample/app/src/main/res/drawable-hdpi/ic_launcher.png b/ui/espresso/EspressoDeviceSample/app/src/main/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 000000000..6b0f252c4 Binary files /dev/null and b/ui/espresso/EspressoDeviceSample/app/src/main/res/drawable-hdpi/ic_launcher.png differ diff --git a/ui/espresso/EspressoDeviceSample/app/src/main/res/drawable-mdpi/ic_launcher.png b/ui/espresso/EspressoDeviceSample/app/src/main/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 000000000..b2fe59cc2 Binary files /dev/null and b/ui/espresso/EspressoDeviceSample/app/src/main/res/drawable-mdpi/ic_launcher.png differ diff --git a/ui/espresso/EspressoDeviceSample/app/src/main/res/drawable-xhdpi/ic_launcher.png b/ui/espresso/EspressoDeviceSample/app/src/main/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 000000000..0edc166fe Binary files /dev/null and b/ui/espresso/EspressoDeviceSample/app/src/main/res/drawable-xhdpi/ic_launcher.png differ diff --git a/ui/espresso/EspressoDeviceSample/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/ui/espresso/EspressoDeviceSample/app/src/main/res/drawable-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..252724020 Binary files /dev/null and b/ui/espresso/EspressoDeviceSample/app/src/main/res/drawable-xxhdpi/ic_launcher.png differ diff --git a/ui/espresso/EspressoDeviceSample/app/src/main/res/drawable-xxxhdpi/ic_launcher.png b/ui/espresso/EspressoDeviceSample/app/src/main/res/drawable-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..0e23e29d8 Binary files /dev/null and b/ui/espresso/EspressoDeviceSample/app/src/main/res/drawable-xxxhdpi/ic_launcher.png differ diff --git a/ui/espresso/EspressoDeviceSample/app/src/main/res/layout/activity_main.xml b/ui/espresso/EspressoDeviceSample/app/src/main/res/layout/activity_main.xml new file mode 100644 index 000000000..3e52e22f1 --- /dev/null +++ b/ui/espresso/EspressoDeviceSample/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,24 @@ + + + + diff --git a/ui/espresso/EspressoDeviceSample/app/src/main/res/values-v13/styles.xml b/ui/espresso/EspressoDeviceSample/app/src/main/res/values-v13/styles.xml new file mode 100644 index 000000000..90618916c --- /dev/null +++ b/ui/espresso/EspressoDeviceSample/app/src/main/res/values-v13/styles.xml @@ -0,0 +1,19 @@ + + + +