fix(flutter_driver): various changes to get the flutter_driver part of the lib working so need to remove references to flutter_test / dart:ui

This commit is contained in:
Jon Samwell 2021-01-09 13:49:49 +11:00
parent 792f879707
commit 2111b71259
14 changed files with 97 additions and 134 deletions

View File

@ -1 +1 @@
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"integration_test","path":"C:\\\\Google\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\integration_test-1.0.1\\\\","dependencies":[]}],"android":[{"name":"integration_test","path":"C:\\\\Google\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\integration_test-1.0.1\\\\","dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"integration_test","dependencies":[]}],"date_created":"2021-01-09 12:45:44.220232","version":"1.22.5"}
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"integration_test","path":"C:\\\\Google\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\integration_test-1.0.1\\\\","dependencies":[]}],"android":[{"name":"integration_test","path":"C:\\\\Google\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\integration_test-1.0.1\\\\","dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"integration_test","dependencies":[]}],"date_created":"2021-01-09 13:46:58.184127","version":"1.22.5"}

8
.vscode/launch.json vendored
View File

@ -10,14 +10,14 @@
"type": "dart"
},
{
"name": "Debug example tests",
"program": "app_test.dart",
"cwd": "example/test_driver",
"name": "Debug flutter_driver example",
"program": "test_harness.dart",
"cwd": "example_with_flutter_driver/test_driver",
"request": "launch",
"type": "dart",
},
{
"name": "Debug integration_test",
"name": "Debug integration_test example",
"program": "test_driver/integration_test_driver.dart",
"cwd": "example_with_integration_test/",
"request": "launch",

View File

@ -15,44 +15,43 @@ The change to use the `integration_test` package is a fundamentally different ap
- build_runner
- flutter_gherkin
2. Add the following `build.yaml` to the root of your project. This file allows the dart code generator to target files outside of your application's `lib` folder
```
targets:
$default:
sources:
- lib/**
- pubspec.*
- $package$
# Allows the code generator to target files outside of the lib folder
- integration_test/**.dart
```
```
targets:
$default:
sources:
- lib/**
- pubspec.*
- $package$
# Allows the code generator to target files outside of the lib folder
- integration_test/**.dart
```
3. Add the following file (and folder) `example_with_integration_test\test_driver\integration_test_driver.dart`. This file is the entry point to run your tests. See `https://flutter.dev/docs/testing/integration-tests` for more information.
```
import 'package:integration_test/integration_test_driver.dart'
as integration_test_driver;
```dart
import 'package:integration_test/integration_test_driver.dart' as integration_test_driver;
Future<void> main() {
// The Gherkin report data send back to this runner by the app after
// the tests have run will be saved to this directory
integration_test_driver.testOutputsDirectory = 'integration_test/gherkin_reports';
Future<void> main() {
// The Gherkin report data send back to this runner by the app after
// the tests have run will be saved to this directory
integration_test_driver.testOutputsDirectory = 'integration_test/gherkin_reports';
return integration_test_driver.integrationDriver(
timeout: Duration(minutes: 90),
);
}
```
return integration_test_driver.integrationDriver(
timeout: Duration(minutes: 90),
);
}
```
4. Create a folder call `integration_test` this will eventually contain all your Gherkin feature files and the generated test files.
5. Add the following file (and folder) `integration_test\feature\counter.feature` with the following below contents. This is a basic feature file that will be transform in to a test file that can run a test against the sample app.
```
Feature: Counter
```
Feature: Counter
Scenario: User can increment the counter
Given I expect the "counter" to be "0"
When I tap the "increment" button
Then I expect the "counter" to be "1"
```
Scenario: User can increment the counter
Given I expect the "counter" to be "0"
When I tap the "increment" button
Then I expect the "counter" to be "1"
```
6. Add the following file (and folder) `integration_test\gherkin_suite_test.dart`. Notice the attribute `@GherkinTestSuite()` this indicates to the code generator to create a partial file for this file with the generated Gherkin tests in `part 'gherkin_suite_test.g.dart';`. Don't worry about the initial errors as this will disappear when the tests are generated.
```dart
import 'package:flutter_gherkin/flutter_gherkin.dart';
import 'package:flutter_gherkin/flutter_gherkin_integration_test.dart'; // notice new import name
import 'package:flutter_test/flutter_test.dart';
import 'package:gherkin/gherkin.dart';
@ -84,14 +83,14 @@ void main() {
}
```
7. We now need to generate the test by running the builder command from the command line in the root of your project. Much like `json_serializable` this will create a `.g.dart` part file that will contain the Gherkin tests in code format which are able to via using the `integration_test` package.
```
flutter pub run build_runner build
```
```
flutter pub run build_runner build
```
8. The errors in the `integration_test\gherkin_suite_test.dart` file should have not gone away and it you look in `integration_test\gherkin_suite_test.g.dart` you will see the coded version of the Gherkin tests described in the feature file `integration_test\feature\counter.feature`.
9. We can now run the test using the below command from the root of your project.
```
flutter drive --driver=test_driver/integration_test_driver.dart --target=integration_test/gherkin_suite_test.dart
```
```
flutter drive --driver=test_driver/integration_test_driver.dart --target=integration_test/gherkin_suite_test.dart
```
10. You can debug the tests by adding a breakpoint to line 12 in `integration_test\gherkin_suite_test.dart` and adding the below to your `.vscode\launch.json` file:
```json
{
@ -107,9 +106,9 @@ void main() {
```
11. Custom world need to extend `FlutterWorld` note `FlutterDriverWorld`.
12. If you change any of the feature files you will need to regenerate the tests using the below command
```
flutter pub run build_runner build
```
```
flutter pub run build_runner build
```
## [1.1.9] - 24/11/2020

View File

@ -1,30 +1,16 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
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,
// This makes the visual density adapt to the platform that you run
// the app on. For desktop platforms, the controls will be smaller and
// closer together (more dense) than on mobile platforms.
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
@ -35,15 +21,6 @@ class MyApp extends StatelessWidget {
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
@ -55,47 +32,18 @@ class _MyHomePageState extends State<MyHomePage> {
void _incrementCounter() {
setState(() {
// 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) {
// 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(
@ -103,6 +51,7 @@ class _MyHomePageState extends State<MyHomePage> {
),
Text(
'$_counter',
key: const Key('counter'),
style: Theme.of(context).textTheme.headline4,
),
],
@ -112,7 +61,8 @@ class _MyHomePageState extends State<MyHomePage> {
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
key: const Key('increment'),
),
);
}
}

View File

@ -178,9 +178,11 @@ packages:
gherkin:
dependency: transitive
description:
path: "../../dart_gherkin"
relative: true
source: path
path: "."
ref: "2eb30d84c3f7d7f6fa2ad5f93c8d9bfb160a3ced"
resolved-ref: "2eb30d84c3f7d7f6fa2ad5f93c8d9bfb160a3ced"
url: "https://github.com/jonsamwell/dart_gherkin.git"
source: git
version: "1.1.10"
glob:
dependency: transitive

View File

@ -1,12 +1,8 @@
// ignore: avoid_relative_lib_imports
import 'package:example_with_flutter_driver/main.dart' as app;
import 'package:flutter_driver/driver_extension.dart';
void main() {
// This line enables the extension
enableFlutterDriverExtension();
// Call the `main()` function of your app or call `runApp` with any widget you
// are interested in testing.
app.main();
}

View File

@ -0,0 +1 @@
[{"description":"","id":"counter","keyword":"Feature","line":1,"name":"Counter","uri":".\\features\\counter.feature","elements":[{"keyword":"Scenario","type":"scenario","id":"counter;user can increment the counter","name":"User can increment the counter","description":"","line":3,"steps":[{"keyword":"Given ","name":"I expect the \"counter\" to be \"0\"","line":4,"match":{"location":".\\features\\counter.feature:4"},"result":{"status":"passed","duration":66000000}},{"keyword":"When ","name":"I tap the \"increment\" button","line":5,"match":{"location":".\\features\\counter.feature:5"},"result":{"status":"passed","duration":347000000}},{"keyword":"Then ","name":"I expect the \"counter\" to be \"1\"","line":6,"match":{"location":".\\features\\counter.feature:6"},"result":{"status":"passed","duration":34000000}}]}]}]

View File

@ -15,7 +15,6 @@ Future<void> main() {
..restartAppBetweenScenarios = true
..targetAppWorkingDirectory = '../'
..targetAppPath = 'test_driver/app.dart'
..verboseFlutterProcessLogs = true
// ..buildFlavor = "staging" // uncomment when using build flavor and check android/ios flavor setup see android file android\app\build.gradle
// ..targetDeviceId = "all" // uncomment to run tests on all connected devices or set specific device target id
// ..tagExpression = '@smoke and not @ignore' // uncomment to see an example of running scenarios based on tag expressions

View File

@ -1,3 +0,0 @@
{
"gherkin_reports": "[[{\"description\":\"\",\"id\":\"counter:\",\"keyword\":\"Feature\",\"line\":1,\"name\":\"Counter:\",\"uri\":\"\",\"tags\":[{\"line\":1,\"name\":\"@tag\"}],\"elements\":[{\"keyword\":\"Scenario\",\"type\":\"scenario\",\"id\":\"counter:;user can increment the counter\",\"name\":\"User can increment the counter\",\"description\":\"\",\"line\":1,\"tags\":[{\"line\":1,\"name\":\"@tag\"},{\"line\":1,\"name\":\"@tag1\"},{\"line\":1,\"name\":\"@tag_two\"}],\"steps\":[{\"keyword\":\"Given \",\"name\":\"I expect the \\\"counter\\\" to be \\\"0\\\"\",\"line\":1,\"match\":{\"location\":\":1\"},\"result\":{\"status\":\"passed\",\"duration\":139000000}},{\"keyword\":\"When \",\"name\":\"I tap the \\\"increment\\\" button\",\"line\":1,\"match\":{\"location\":\":1\"},\"result\":{\"status\":\"passed\",\"duration\":309000000}},{\"keyword\":\"Then \",\"name\":\"I expect the \\\"counter\\\" to be \\\"1\\\"\",\"line\":1,\"match\":{\"location\":\":1\"},\"result\":{\"status\":\"passed\",\"duration\":116000000}},{\"keyword\":\"Given \",\"name\":\"the table\",\"line\":1,\"match\":{\"location\":\":1\"},\"result\":{\"status\":\"passed\",\"duration\":0},\"rows\":[{\"cells\":[\"Header One\",\"Header Two\",\"Header Three\"]},{\"cells\":[\"1\",\"2\",\"3\"]},{\"cells\":[\"4\",\"5\",\"6\"]}]}]}]}]]"
}

View File

@ -1,4 +1,4 @@
import 'package:flutter_gherkin/flutter_gherkin.dart';
import 'package:flutter_gherkin/flutter_gherkin_integration_test.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:gherkin/gherkin.dart';

View File

@ -11,17 +11,3 @@ Future<void> main() {
timeout: Duration(minutes: 90),
);
}
// import 'package:flutter_driver/flutter_driver.dart';
// import 'package:integration_test/integration_test_driver_extended.dart';
// Future<void> main() async {
// final driver = await FlutterDriver.connect();
// await integrationDriver(
// driver: driver,
// onScreenshot: (String screenshotName, List<int> screenshotBytes) async {
// return true;
// },
// );
// }

View File

@ -4,9 +4,7 @@ library flutter_gherkin;
export 'src/flutter/configuration/build_mode.dart';
export 'src/flutter/world/flutter_world.dart';
export 'src/flutter/configuration/flutter_test_configuration.dart';
export 'src/flutter/configuration/flutter_driver_test_configuration.dart';
export 'src/flutter/adapters/app_driver_adapter.dart';
export 'src/flutter/adapters/flutter_driver_app_driver_adapter.dart';
// Well known steps
export 'src/flutter/steps/given_i_open_the_drawer_step.dart';
@ -30,11 +28,7 @@ export 'src/flutter/steps/wait_until_type_exists_step.dart';
// Hooks
export 'src/flutter/hooks/attach_screenshot_on_failed_step_hook.dart';
// Reporters
// Flutter driver specific implementations
export 'src/flutter/configuration/flutter_driver_test_configuration.dart';
export 'src/flutter/adapters/flutter_driver_app_driver_adapter.dart';
export 'src/flutter/reporters/flutter_driver_reporter.dart';
// Code Generation
export 'src/flutter/code_generation/annotations/gherkin_full_test_suite_annotation.dart';
// Runners
export 'src/flutter/runners/gherkin_integration_test_runner.dart';

View File

@ -0,0 +1,39 @@
library flutter_gherkin;
/// ***************************************
/// Library export for use with integration_test with include reference to flutter_test which reference dart:ui
/// which are not allowed when running tests with flutter_driver hence this separate library declaration file
/// ***************************************
// Flutter specific implementations
export 'src/flutter/configuration/build_mode.dart';
export 'src/flutter/world/flutter_world.dart';
export 'src/flutter/configuration/flutter_test_configuration.dart';
export 'src/flutter/adapters/app_driver_adapter.dart';
// Well known steps
export 'src/flutter/steps/given_i_open_the_drawer_step.dart';
export 'src/flutter/steps/then_expect_element_to_have_value_step.dart';
export 'src/flutter/steps/when_fill_field_step.dart';
export 'src/flutter/steps/when_pause_step.dart';
export 'src/flutter/steps/when_tap_widget_step.dart';
export 'src/flutter/steps/restart_app_step.dart';
export 'src/flutter/steps/sibling_contains_text_step.dart';
export 'src/flutter/steps/swipe_step.dart';
export 'src/flutter/steps/tap_text_within_widget_step.dart';
export 'src/flutter/steps/tap_widget_of_type_step.dart';
export 'src/flutter/steps/tap_widget_of_type_within_step.dart';
export 'src/flutter/steps/tap_widget_with_text_step.dart';
export 'src/flutter/steps/text_exists_step.dart';
export 'src/flutter/steps/text_exists_within_step.dart';
export 'src/flutter/steps/wait_until_key_exists_step.dart';
export 'src/flutter/steps/when_tap_the_back_button_step.dart';
export 'src/flutter/steps/wait_until_type_exists_step.dart';
// Hooks
export 'src/flutter/hooks/attach_screenshot_on_failed_step_hook.dart';
// integration_test specific exports
export 'src/flutter/adapters/widget_tester_app_driver_adapter.dart';
export 'src/flutter/code_generation/annotations/gherkin_full_test_suite_annotation.dart';
export 'src/flutter/runners/gherkin_integration_test_runner.dart';

View File

@ -28,8 +28,8 @@ class FlutterTestConfiguration extends TestConfiguration {
/// Additional setting on the configuration object can be set on the returned instance.
static FlutterTestConfiguration DEFAULT(
Iterable<StepDefinitionGeneric<World>> steps, {
String featurePath = 'test_driver/features/**.feature',
String targetAppPath = 'test_driver/app.dart',
String featurePath = 'integration_test/features/**.feature',
String targetAppPath = 'test_driver/integration_test_driver.dart',
}) {
return FlutterTestConfiguration()
..features = [Glob(featurePath)]