Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
1743eab
Initial copy of e2e plugin renamed to espresso
collinjackson Nov 26, 2019
0bf791e
Switch to a new project based on template plugin
collinjackson Nov 26, 2019
f47c5a4
Update example app to be a button app
collinjackson Nov 26, 2019
45bf214
switch to Java
collinjackson Nov 26, 2019
195bb22
Add example Espresso test
collinjackson Nov 26, 2019
fded8ad
Midpoint check-in while addressing dependency errors
collinjackson Nov 26, 2019
60da0af
Demonstration of Espresso tests passing
collinjackson Nov 26, 2019
4f65053
All tests pass
collinjackson Nov 26, 2019
7c77635
Add shared preferences integration test
collinjackson Nov 26, 2019
86f133c
Fix test to match internal version
collinjackson Nov 26, 2019
02adfc8
Tests pass for shared prefs plugin
collinjackson Nov 26, 2019
f343591
Open source Espresso files
collinjackson Nov 26, 2019
521eb6c
License
collinjackson Dec 6, 2019
f2e0e56
SDK constraints
collinjackson Dec 6, 2019
6b86f04
Update README, changelog, remove test
collinjackson Dec 6, 2019
0b70161
Revert shared_preferences
collinjackson Dec 6, 2019
ce9de53
Update README.md
collinjackson Dec 7, 2019
cc2ebe5
Update README to make it clear this package is Android-only
collinjackson Dec 9, 2019
11b38af
Update licenses
collinjackson Dec 9, 2019
da89fee
Merge remote-tracking branch 'cj/new_espresso_plugin' into new_espres…
collinjackson Dec 9, 2019
211e358
remove commented dependencies
collinjackson Dec 9, 2019
b823741
More README updates
collinjackson Dec 9, 2019
5a1d274
Add a click test
collinjackson Dec 9, 2019
226a0d6
Fix build error
collinjackson Dec 9, 2019
2d0d9a1
More README updates
collinjackson Dec 9, 2019
0a2b5ab
fix file that wasn't meant to be checked in
collinjackson Dec 9, 2019
56360ff
Update README
collinjackson Dec 9, 2019
e3d340c
Merge remote-tracking branch 'origin/master' into new_espresso_plugin
collinjackson Dec 10, 2019
5377d27
Fix build failure
collinjackson Dec 10, 2019
8663ebd
Update README.md
collinjackson Dec 10, 2019
f69d012
Update README to clarify that iOS example is for the bots.
collinjackson Jan 9, 2020
a33410d
Code review feedback on plaintext traffic
collinjackson Jan 9, 2020
3a00269
Update README.md
collinjackson Jan 9, 2020
e5c1ae1
reformat
collinjackson Jan 9, 2020
5bf41b2
update pubspec.yaml
collinjackson Jan 9, 2020
9a85ad9
remove unused test
collinjackson Jan 9, 2020
d69e407
reformat
collinjackson Jan 9, 2020
6b6ff85
Merge remote-tracking branch 'origin/master' into new_espresso_plugin
collinjackson Jan 9, 2020
acef95e
Merge remote-tracking branch 'cj/new_espresso_plugin' into new_espres…
collinjackson Jan 9, 2020
a5a9c46
Fix analyzer issues
collinjackson Jan 9, 2020
8b6542b
fix ios build
collinjackson Jan 9, 2020
d18b2a0
remove lib/espresso.dart
collinjackson Jan 9, 2020
8129481
reformat
collinjackson Jan 9, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Demonstration of Espresso tests passing
  • Loading branch information
collinjackson committed Dec 6, 2019
commit 60da0afe1f7abea2b6e26cc39c5d6eefb2f54291
34 changes: 17 additions & 17 deletions packages/espresso/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ android {

dependencies {
implementation 'com.google.guava:guava:28.1-android'
implementation 'com.squareup.okhttp3:okhttp:3.2.0'
implementation 'com.squareup.okhttp3:okhttp:3.12.1'
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'org.hamcrest:hamcrest:2.2'
androidTestImplementation 'org.hamcrest:hamcrest:2.2'
// androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
// androidTestImplementation 'androidx.test:runner:1.1.0'
// androidTestImplementation 'androidx.test:rules:1.1.0'
Expand All @@ -47,34 +47,34 @@ dependencies {

testImplementation 'junit:junit:4.12'
testImplementation "com.google.truth:truth:1.0"
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
api 'androidx.test:runner:1.1.1'
api 'androidx.test.espresso:espresso-core:3.1.1'

// Core library
androidTestImplementation 'androidx.test:core:1.0.0'
api 'androidx.test:core:1.0.0'

// AndroidJUnitRunner and JUnit Rules
androidTestImplementation 'androidx.test:runner:1.1.0'
androidTestImplementation 'androidx.test:rules:1.1.0'
api 'androidx.test:runner:1.1.0'
api 'androidx.test:rules:1.1.0'

// Assertions
androidTestImplementation 'androidx.test.ext:junit:1.0.0'
androidTestImplementation 'androidx.test.ext:truth:1.0.0'
androidTestImplementation 'com.google.truth:truth:0.42'
api 'androidx.test.ext:junit:1.0.0'
api 'androidx.test.ext:truth:1.0.0'
api 'com.google.truth:truth:0.42'

// Espresso dependencies
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-intents:3.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-accessibility:3.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-web:3.1.0'
androidTestImplementation 'androidx.test.espresso.idling:idling-concurrent:3.1.0'
api 'androidx.test.espresso:espresso-core:3.1.0'
api 'androidx.test.espresso:espresso-contrib:3.1.0'
api 'androidx.test.espresso:espresso-intents:3.1.0'
api 'androidx.test.espresso:espresso-accessibility:3.1.0'
api 'androidx.test.espresso:espresso-web:3.1.0'
api 'androidx.test.espresso.idling:idling-concurrent:3.1.0'

// The following Espresso dependency can be either "implementation"
// or "androidTestImplementation", depending on whether you want the
// dependency to appear on your APK's compile classpath or the test APK
// classpath.
androidTestImplementation 'androidx.test.espresso:espresso-idling-resource:3.1.0'
api 'androidx.test.espresso:espresso-idling-resource:3.1.0'
}


Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#Tue Nov 26 13:04:21 PST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,22 @@
*/
package com.example.espresso_example;

//import static androidx.test.espresso.flutter.EspressoFlutter.onFlutterWidget;
//import static androidx.test.espresso.flutter.action.FlutterActions.click;
//import static androidx.test.espresso.flutter.action.FlutterActions.syntheticClick;
//import static androidx.test.espresso.flutter.assertion.FlutterAssertions.matches;
//import static androidx.test.espresso.flutter.matcher.FlutterMatchers.isDescendantOf;
//import static androidx.test.espresso.flutter.matcher.FlutterMatchers.withText;
//import static androidx.test.espresso.flutter.matcher.FlutterMatchers.withTooltip;
//import static androidx.test.espresso.flutter.matcher.FlutterMatchers.withType;
//import static androidx.test.espresso.flutter.matcher.FlutterMatchers.withValueKey;
import static androidx.test.espresso.flutter.EspressoFlutter.onFlutterWidget;
import static androidx.test.espresso.flutter.action.FlutterActions.click;
import static androidx.test.espresso.flutter.action.FlutterActions.syntheticClick;
import static androidx.test.espresso.flutter.assertion.FlutterAssertions.matches;
import static androidx.test.espresso.flutter.matcher.FlutterMatchers.isDescendantOf;
import static androidx.test.espresso.flutter.matcher.FlutterMatchers.withText;
import static androidx.test.espresso.flutter.matcher.FlutterMatchers.withTooltip;
import static androidx.test.espresso.flutter.matcher.FlutterMatchers.withType;
import static androidx.test.espresso.flutter.matcher.FlutterMatchers.withValueKey;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;

import androidx.test.core.app.ActivityScenario;
//import androidx.test.espresso.flutter.EspressoFlutter.WidgetInteraction;
//import androidx.test.espresso.flutter.assertion.FlutterAssertions;
//import androidx.test.espresso.flutter.matcher.FlutterMatchers;
import androidx.test.espresso.flutter.EspressoFlutter.WidgetInteraction;
import androidx.test.espresso.flutter.assertion.FlutterAssertions;
import androidx.test.espresso.flutter.matcher.FlutterMatchers;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
Expand All @@ -47,79 +47,79 @@ public void setUp() throws Exception {

@Test
public void performTripleClick() {
// WidgetInteraction interaction =
// onFlutterWidget(withTooltip("Increment")).perform(click(), click()).perform(click());
// assertThat(interaction).isNotNull();
// onFlutterWidget(withValueKey("CountText")).check(matches(withText("Button tapped 3 times.")));
// onFlutterWidget(withValueKey("CountRichText"))
// .check(matches(withText("Button tapped 3 times.")));
WidgetInteraction interaction =
onFlutterWidget(withTooltip("Increment")).perform(click(), click()).perform(click());
assertThat(interaction).isNotNull();
onFlutterWidget(withValueKey("CountText")).check(matches(withText("Button tapped 3 times.")));
onFlutterWidget(withValueKey("CountRichText"))
.check(matches(withText("Button tapped 3 times.")));
}

@Test
public void performSyntheticClick() {
// WidgetInteraction interaction =
// onFlutterWidget(withTooltip("Increment")).perform(syntheticClick());
// assertThat(interaction).isNotNull();
// onFlutterWidget(withValueKey("CountText")).check(matches(withText("Button tapped 1 time.")));
// onFlutterWidget(withValueKey("CountRichText"))
// .check(matches(withText("Button tapped 1 time.")));
WidgetInteraction interaction =
onFlutterWidget(withTooltip("Increment")).perform(syntheticClick());
assertThat(interaction).isNotNull();
onFlutterWidget(withValueKey("CountText")).check(matches(withText("Button tapped 1 time.")));
onFlutterWidget(withValueKey("CountRichText"))
.check(matches(withText("Button tapped 1 time.")));
}

@Test
public void performTwiceSyntheticClicks() {
// WidgetInteraction interaction =
// onFlutterWidget(withTooltip("Increment")).perform(syntheticClick(), syntheticClick());
// assertThat(interaction).isNotNull();
// onFlutterWidget(withValueKey("CountText")).check(matches(withText("Button tapped 2 times.")));
// onFlutterWidget(withValueKey("CountRichText"))
// .check(matches(withText("Button tapped 2 times.")));
WidgetInteraction interaction =
onFlutterWidget(withTooltip("Increment")).perform(syntheticClick(), syntheticClick());
assertThat(interaction).isNotNull();
onFlutterWidget(withValueKey("CountText")).check(matches(withText("Button tapped 2 times.")));
onFlutterWidget(withValueKey("CountRichText"))
.check(matches(withText("Button tapped 2 times.")));
}

@Test
public void isDescendantMatcher() {
// onFlutterWidget(withTooltip("Increment")).perform(click());
// onFlutterWidget(isDescendantOf(withValueKey("TwoTimesCounterContainer"), withType("Text")))
// .check(matches(withText("Button tapped 2 times.")));
onFlutterWidget(withTooltip("Increment")).perform(click());
onFlutterWidget(isDescendantOf(withValueKey("TwoTimesCounterContainer"), withType("Text")))
.check(matches(withText("Button tapped 2 times.")));
}

@Test
public void isDescendantMatcher_multipleMatches() {
// onFlutterWidget(withTooltip("Increment")).perform(click());
// try {
// onFlutterWidget(isDescendantOf(withType("ListView"), withType("Text")))
// .check(matches(withText("Button tapped 2 times.")));
// fail("Espresso should fail when there are more than one matched widgets.");
// } catch (Exception e) {
// assertThat(e)
// .hasCauseThat()
// .hasMessageThat()
// .contains("Error occurred during retrieving widget's diagnostics info.");
// }
onFlutterWidget(withTooltip("Increment")).perform(click());
try {
onFlutterWidget(isDescendantOf(withType("ListView"), withType("Text")))
.check(matches(withText("Button tapped 2 times.")));
fail("Espresso should fail when there are more than one matched widgets.");
} catch (Exception e) {
assertThat(e)
.hasCauseThat()
.hasMessageThat()
.contains("Error occurred during retrieving widget's diagnostics info.");
}
}

@Test
public void isIncrementButtonExists() {
// onFlutterWidget(FlutterMatchers.withTooltip("Increment"))
// .check(FlutterAssertions.matches(FlutterMatchers.isExisting()));
onFlutterWidget(FlutterMatchers.withTooltip("Increment"))
.check(FlutterAssertions.matches(FlutterMatchers.isExisting()));
}

@Test
public void isAppBarExists() {
// onFlutterWidget(FlutterMatchers.withType("AppBar"))
// .check(FlutterAssertions.matches(FlutterMatchers.isExisting()));
onFlutterWidget(FlutterMatchers.withType("AppBar"))
.check(FlutterAssertions.matches(FlutterMatchers.isExisting()));
}

@Test
public void isWidgetNonExists() {
// try {
// onFlutterWidget(FlutterMatchers.withType("AppBar2"))
// .check(FlutterAssertions.matches(FlutterMatchers.isExisting()));
// fail("Espresso should fail when none of the widgets matches the given matcher.");
// } catch (Exception e) {
// assertThat(e)
// .hasCauseThat()
// .hasMessageThat()
// .contains("Error occurred during retrieving widget's diagnostics info.");
// }
try {
onFlutterWidget(FlutterMatchers.withType("AppBar2"))
.check(FlutterAssertions.matches(FlutterMatchers.isExisting()));
fail("Espresso should fail when none of the widgets matches the given matcher.");
} catch (Exception e) {
assertThat(e)
.hasCauseThat()
.hasMessageThat()
.contains("Error occurred during retrieving widget's diagnostics info.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<application
android:name="io.flutter.app.FlutterApplication"
android:label="espresso_example"
android:usesCleartextTraffic="true"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
Expand Down
123 changes: 89 additions & 34 deletions packages/espresso/example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,56 +1,111 @@
import 'package:flutter/material.dart';
import 'dart:async';

import 'package:flutter/services.dart';
import 'package:espresso/espresso.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
_MyAppState createState() => _MyAppState();
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}

class _MyAppState extends State<MyApp> {
String _platformVersion = 'Unknown';
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);

// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.

// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".

final String title;

@override
void initState() {
super.initState();
initPlatformState();
}
_MyHomePageState createState() => _MyHomePageState();
}

// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initPlatformState() async {
String platformVersion;
// Platform messages may fail, so we use a try/catch PlatformException.
try {
platformVersion = await Espresso.platformVersion;
} on PlatformException {
platformVersion = 'Failed to get platform version.';
}

// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;

void _incrementCounter() {
setState(() {
_platformVersion = platformVersion;
// This call to setState tells the Flutter framework that something has
// changed in this State, which causes it to rerun the build method below
// so that the display can reflect the updated values. If we changed
// _counter without calling setState(), then the build method would not be
// called again, and so nothing would appear to happen.
_counter++;
});
}

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
child: Text('Running on: $_platformVersion\n'),
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
),
body: Center(
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: Column(
// Column is also a layout widget. It takes a list of children and
// arranges them vertically. By default, it sizes itself to fit its
// children horizontally, and tries to be as tall as its parent.
//
// Invoke "debug painting" (press "p" in the console, choose the
// "Toggle Debug Paint" action from the Flutter Inspector in Android
// Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
// to see the wireframe for each widget.
//
// Column has various properties to control how it sizes itself and
// how it positions its children. Here we use mainAxisAlignment to
// center the children vertically; the main axis here is the vertical
// axis because Columns are vertical (the cross axis would be
// horizontal).
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
2 changes: 2 additions & 0 deletions packages/espresso/example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ dependencies:
dev_dependencies:
flutter_test:
sdk: flutter
flutter_driver:
sdk: flutter

espresso:
path: ../
Expand Down