Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit a1a4f21

Browse files
[espresso] Adds EspressoFlutter as a first-party plugin (#2369)
* Initial open source release of Espresso bindings for Flutter as a new first-party plugin, espresso.
1 parent c544c0e commit a1a4f21

File tree

129 files changed

+6117
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

129 files changed

+6117
-0
lines changed

packages/espresso/.gitignore

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.DS_Store
2+
.dart_tool/
3+
4+
.packages
5+
.pub/
6+
7+
build/

packages/espresso/.metadata

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# This file tracks properties of this Flutter project.
2+
# Used by Flutter tool to assess capabilities and perform upgrades etc.
3+
#
4+
# This file should be version controlled and should not be manually edited.
5+
6+
version:
7+
revision: 0190e40457d43e17bdfaf046dfa634cbc5bf28b9
8+
channel: unknown
9+
10+
project_type: plugin

packages/espresso/CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## 0.0.1
2+
3+
* Initial open-source release of Espresso bindings for Flutter.

packages/espresso/LICENSE

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2019 The Chromium Authors. All rights reserved.
2+
//
3+
// Redistribution and use in source and binary forms, with or without
4+
// modification, are permitted provided that the following conditions are
5+
// met:
6+
//
7+
// * Redistributions of source code must retain the above copyright
8+
// notice, this list of conditions and the following disclaimer.
9+
// * Redistributions in binary form must reproduce the above
10+
// copyright notice, this list of conditions and the following disclaimer
11+
// in the documentation and/or other materials provided with the
12+
// distribution.
13+
// * Neither the name of Google Inc. nor the names of its
14+
// contributors may be used to endorse or promote products derived from
15+
// this software without specific prior written permission.
16+
//
17+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18+
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19+
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20+
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21+
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22+
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23+
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24+
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25+
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26+
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

packages/espresso/README.md

+125
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# espresso
2+
3+
Provides bindings for Espresso tests of Flutter Android apps.
4+
5+
## Installation
6+
7+
Add the `espresso` package as a `dev_dependency` in your app's pubspec.yaml. If you're testing the example app of a package, add it as a dev_dependency of the main package as well.
8+
9+
Add ```android:usesCleartextTraffic="true"``` in the ```<application>``` in the AndroidManifest.xml
10+
of the Android app used for testing. It's best to put this in a debug or androidTest
11+
AndroidManifest.xml so that you don't ship it to end users. (See the example app of this package.)
12+
13+
Add dependencies to your build.gradle:
14+
15+
```groovy
16+
dependencies {
17+
testImplementation 'junit:junit:4.12'
18+
testImplementation "com.google.truth:truth:1.0"
19+
androidTestImplementation 'androidx.test:runner:1.1.1'
20+
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
21+
22+
// Core library
23+
api 'androidx.test:core:1.2.0'
24+
25+
// AndroidJUnitRunner and JUnit Rules
26+
androidTestImplementation 'androidx.test:runner:1.1.0'
27+
androidTestImplementation 'androidx.test:rules:1.1.0'
28+
29+
// Assertions
30+
androidTestImplementation 'androidx.test.ext:junit:1.0.0'
31+
androidTestImplementation 'androidx.test.ext:truth:1.0.0'
32+
androidTestImplementation 'com.google.truth:truth:0.42'
33+
34+
// Espresso dependencies
35+
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
36+
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.1.0'
37+
androidTestImplementation 'androidx.test.espresso:espresso-intents:3.1.0'
38+
androidTestImplementation 'androidx.test.espresso:espresso-accessibility:3.1.0'
39+
androidTestImplementation 'androidx.test.espresso:espresso-web:3.1.0'
40+
androidTestImplementation 'androidx.test.espresso.idling:idling-concurrent:3.1.0'
41+
42+
// The following Espresso dependency can be either "implementation"
43+
// or "androidTestImplementation", depending on whether you want the
44+
// dependency to appear on your APK's compile classpath or the test APK
45+
// classpath.
46+
androidTestImplementation 'androidx.test.espresso:espresso-idling-resource:3.1.0'
47+
}
48+
```
49+
50+
Create an `android/app/src/androidTest` folder and put a test file in a package-appropriate subfolder, e.g. `android/app/src/androidTest/java/com/example/MainActivityTest.java`:
51+
52+
```java
53+
package com.example.espresso_example;
54+
55+
import static androidx.test.espresso.flutter.EspressoFlutter.onFlutterWidget;
56+
import static androidx.test.espresso.flutter.action.FlutterActions.click;
57+
import static androidx.test.espresso.flutter.action.FlutterActions.syntheticClick;
58+
import static androidx.test.espresso.flutter.assertion.FlutterAssertions.matches;
59+
import static androidx.test.espresso.flutter.matcher.FlutterMatchers.isDescendantOf;
60+
import static androidx.test.espresso.flutter.matcher.FlutterMatchers.withText;
61+
import static androidx.test.espresso.flutter.matcher.FlutterMatchers.withTooltip;
62+
import static androidx.test.espresso.flutter.matcher.FlutterMatchers.withType;
63+
import static androidx.test.espresso.flutter.matcher.FlutterMatchers.withValueKey;
64+
import static com.google.common.truth.Truth.assertThat;
65+
import static org.junit.Assert.fail;
66+
67+
import androidx.test.core.app.ActivityScenario;
68+
import androidx.test.espresso.flutter.EspressoFlutter.WidgetInteraction;
69+
import androidx.test.espresso.flutter.assertion.FlutterAssertions;
70+
import androidx.test.espresso.flutter.matcher.FlutterMatchers;
71+
import androidx.test.ext.junit.runners.AndroidJUnit4;
72+
import org.junit.Before;
73+
import org.junit.Test;
74+
import org.junit.runner.RunWith;
75+
76+
/** Unit tests for {@link EspressoFlutter}. */
77+
@RunWith(AndroidJUnit4.class)
78+
public class MainActivityTest {
79+
80+
@Before
81+
public void setUp() throws Exception {
82+
ActivityScenario.launch(MainActivity.class);
83+
}
84+
85+
@Test
86+
public void performClick() {
87+
onFlutterWidget(withTooltip("Increment")).perform(click());
88+
onFlutterWidget(withValueKey("CountText")).check(matches(withText("Button tapped 1 time.")));
89+
}
90+
```
91+
92+
You'll need to create a test app that enables the Flutter driver extension.
93+
You can put this in your test_driver/ folder, e.g. test_driver/example.dart.
94+
95+
```dart
96+
import 'package:flutter_driver/driver_extension.dart';
97+
import '../lib/main.dart' as app;
98+
99+
void main() {
100+
enableFlutterDriverExtension();
101+
app.main();
102+
}
103+
```
104+
105+
The following command line command runs the test locally:
106+
107+
```
108+
./gradlew app:connectedAndroidTest -Ptarget=`pwd`/../test_driver/example.dart
109+
```
110+
111+
Espresso tests can also be run on [Firebase Test Lab](https://firebase.google.com/docs/test-lab):
112+
113+
```
114+
./gradlew app:assembleAndroidTest
115+
./gradlew app:assembleDebug -Ptarget=<path_to_test>.dart
116+
gcloud auth activate-service-account --key-file=<PATH_TO_KEY_FILE>
117+
gcloud --quiet config set project <PROJECT_NAME>
118+
gcloud firebase test android run --type instrumentation \
119+
--app build/app/outputs/apk/debug/app-debug.apk \
120+
--test build/app/outputs/apk/androidTest/debug/app-debug-androidTest.apk\
121+
--timeout 2m \
122+
--results-bucket=<RESULTS_BUCKET> \
123+
--results-dir=<RESULTS_DIRECTORY>
124+
```
125+

packages/espresso/android/.gitignore

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
*.iml
2+
.gradle
3+
/local.properties
4+
/.idea/workspace.xml
5+
/.idea/libraries
6+
.DS_Store
7+
/build
8+
/captures
+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
group 'com.example.espresso'
2+
version '1.0'
3+
4+
buildscript {
5+
repositories {
6+
google()
7+
jcenter()
8+
}
9+
10+
dependencies {
11+
classpath 'com.android.tools.build:gradle:3.5.0'
12+
}
13+
}
14+
15+
rootProject.allprojects {
16+
repositories {
17+
google()
18+
jcenter()
19+
}
20+
}
21+
22+
apply plugin: 'com.android.library'
23+
24+
android {
25+
compileSdkVersion 28
26+
27+
defaultConfig {
28+
minSdkVersion 16
29+
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
30+
}
31+
lintOptions {
32+
disable 'InvalidPackage'
33+
}
34+
}
35+
36+
dependencies {
37+
implementation 'com.google.guava:guava:28.1-android'
38+
implementation 'com.squareup.okhttp3:okhttp:3.12.1'
39+
implementation 'com.google.code.gson:gson:2.8.6'
40+
androidTestImplementation 'org.hamcrest:hamcrest:2.2'
41+
42+
testImplementation 'junit:junit:4.12'
43+
testImplementation "com.google.truth:truth:1.0"
44+
api 'androidx.test:runner:1.1.1'
45+
api 'androidx.test.espresso:espresso-core:3.1.1'
46+
47+
// Core library
48+
api 'androidx.test:core:1.0.0'
49+
50+
// AndroidJUnitRunner and JUnit Rules
51+
api 'androidx.test:runner:1.1.0'
52+
api 'androidx.test:rules:1.1.0'
53+
54+
// Assertions
55+
api 'androidx.test.ext:junit:1.0.0'
56+
api 'androidx.test.ext:truth:1.0.0'
57+
api 'com.google.truth:truth:0.42'
58+
59+
// Espresso dependencies
60+
api 'androidx.test.espresso:espresso-core:3.1.0'
61+
api 'androidx.test.espresso:espresso-contrib:3.1.0'
62+
api 'androidx.test.espresso:espresso-intents:3.1.0'
63+
api 'androidx.test.espresso:espresso-accessibility:3.1.0'
64+
api 'androidx.test.espresso:espresso-web:3.1.0'
65+
api 'androidx.test.espresso.idling:idling-concurrent:3.1.0'
66+
67+
// The following Espresso dependency can be either "implementation"
68+
// or "androidTestImplementation", depending on whether you want the
69+
// dependency to appear on your APK's compile classpath or the test APK
70+
// classpath.
71+
api 'androidx.test.espresso:espresso-idling-resource:3.1.0'
72+
}
73+
74+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
org.gradle.jvmargs=-Xmx1536M
2+
android.enableR8=true
3+
android.useAndroidX=true
4+
android.enableJetifier=true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#Tue Nov 26 13:04:21 PST 2019
2+
distributionBase=GRADLE_USER_HOME
3+
distributionPath=wrapper/dists
4+
zipStoreBase=GRADLE_USER_HOME
5+
zipStorePath=wrapper/dists
6+
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rootProject.name = 'espresso'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2+
package="com.example.espresso">
3+
</manifest>

0 commit comments

Comments
 (0)