feat(null-safety): first pass of null safety
This commit is contained in:
parent
172dde7a56
commit
31bf38cef1
|
@ -1,2 +1,2 @@
|
|||
# This is a generated file; do not edit or check into version control.
|
||||
integration_test=C:\\Google\\flutter\\.pub-cache\\hosted\\pub.dartlang.org\\integration_test-1.0.2+2\\
|
||||
integration_test=C:\\Google\\flutter\\packages\\integration_test\\
|
||||
|
|
|
@ -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.2+2\\\\","dependencies":[]}],"android":[{"name":"integration_test","path":"C:\\\\Google\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\integration_test-1.0.2+2\\\\","dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"integration_test","dependencies":[]}],"date_created":"2021-02-10 11:35:15.103743","version":"1.22.6"}
|
||||
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"integration_test","path":"C:\\\\Google\\\\flutter\\\\packages\\\\integration_test\\\\","dependencies":[]}],"android":[{"name":"integration_test","path":"C:\\\\Google\\\\flutter\\\\packages\\\\integration_test\\\\","dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"integration_test","dependencies":[]}],"date_created":"2021-05-01 13:05:07.936285","version":"2.0.5"}
|
|
@ -27,7 +27,7 @@ targets:
|
|||
# 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.
|
||||
3. Add the following file (and folder) `\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.
|
||||
```dart
|
||||
import 'package:integration_test/integration_test_driver.dart' as integration_test_driver;
|
||||
|
||||
|
|
|
@ -13,13 +13,13 @@ class MyApp extends StatelessWidget {
|
|||
primarySwatch: Colors.blue,
|
||||
visualDensity: VisualDensity.adaptivePlatformDensity,
|
||||
),
|
||||
home: MyHomePage(title: 'Flutter Demo Home Page'),
|
||||
home: MyHomePage('Flutter Demo Home Page'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MyHomePage extends StatefulWidget {
|
||||
MyHomePage({Key key, this.title}) : super(key: key);
|
||||
MyHomePage(this.title) : super();
|
||||
|
||||
final String title;
|
||||
|
||||
|
@ -60,8 +60,8 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: _incrementCounter,
|
||||
tooltip: 'Increment',
|
||||
child: Icon(Icons.add),
|
||||
key: const Key('increment'),
|
||||
child: Icon(Icons.add),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -35,49 +35,28 @@ packages:
|
|||
name: async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.5.0-nullsafety.1"
|
||||
version: "2.5.0"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: boolean_selector
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0-nullsafety.1"
|
||||
build:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.6.0"
|
||||
build_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_config
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.5"
|
||||
version: "2.1.0"
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: characters
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0-nullsafety.3"
|
||||
version: "1.1.0"
|
||||
charcode:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: charcode
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0-nullsafety.1"
|
||||
checked_yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: checked_yaml
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
version: "1.2.0"
|
||||
cli_util:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -91,14 +70,14 @@ packages:
|
|||
name: clock
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0-nullsafety.1"
|
||||
version: "1.1.0"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.15.0-nullsafety.3"
|
||||
version: "1.15.0"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -112,7 +91,7 @@ packages:
|
|||
name: coverage
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.14.2"
|
||||
version: "0.15.2"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -120,34 +99,20 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.5"
|
||||
cupertino_icons:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: cupertino_icons
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
dart_style:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dart_style
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.10"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fake_async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0-nullsafety.1"
|
||||
version: "1.2.0"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.0.0-nullsafety.2"
|
||||
version: "6.0.0"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
|
@ -178,12 +143,10 @@ packages:
|
|||
gherkin:
|
||||
dependency: transitive
|
||||
description:
|
||||
path: "."
|
||||
ref: "2eb30d84c3f7d7f6fa2ad5f93c8d9bfb160a3ced"
|
||||
resolved-ref: "2eb30d84c3f7d7f6fa2ad5f93c8d9bfb160a3ced"
|
||||
url: "https://github.com/jonsamwell/dart_gherkin.git"
|
||||
source: git
|
||||
version: "1.1.10"
|
||||
name: gherkin
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
glob:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -191,90 +154,62 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
http:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.2"
|
||||
http_multi_server:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_multi_server
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
version: "3.0.1"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_parser
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.1.4"
|
||||
integration_test:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: integration_test
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
version: "4.0.0"
|
||||
io:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: io
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.4"
|
||||
version: "1.0.0"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: js
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.6.3-nullsafety.2"
|
||||
json_annotation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: json_annotation
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.1.1"
|
||||
json_rpc_2:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: json_rpc_2
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.2"
|
||||
version: "0.6.3"
|
||||
logging:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: logging
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.11.4"
|
||||
version: "1.0.1"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.10-nullsafety.1"
|
||||
version: "0.12.10"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.0-nullsafety.3"
|
||||
version: "1.3.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: mime
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.9.7"
|
||||
version: "1.0.0"
|
||||
node_interop:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -295,7 +230,7 @@ packages:
|
|||
name: node_preamble
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.12"
|
||||
version: "1.4.13"
|
||||
package_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -309,35 +244,35 @@ packages:
|
|||
name: path
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.0-nullsafety.1"
|
||||
version: "1.8.0"
|
||||
pedantic:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pedantic
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.10.0-nullsafety.2"
|
||||
version: "1.11.0"
|
||||
platform:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: platform
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.0-nullsafety.2"
|
||||
version: "3.0.0"
|
||||
pool:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pool
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.5.0-nullsafety.2"
|
||||
version: "1.5.0"
|
||||
process:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: process
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.0.0-nullsafety.2"
|
||||
version: "4.0.0"
|
||||
pub_semver:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -345,95 +280,81 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.4"
|
||||
pubspec_parse:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pubspec_parse
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.7"
|
||||
shelf:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.7.9"
|
||||
version: "1.1.1"
|
||||
shelf_packages_handler:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_packages_handler
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
version: "2.0.1"
|
||||
shelf_static:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_static
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.9+1"
|
||||
version: "0.2.9+2"
|
||||
shelf_web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_web_socket
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.3"
|
||||
version: "0.2.4+1"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.99"
|
||||
source_gen:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_gen
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.9.10+1"
|
||||
source_map_stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_map_stack_trace
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0-nullsafety.3"
|
||||
version: "2.1.0"
|
||||
source_maps:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_maps
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.10.10-nullsafety.2"
|
||||
version: "0.10.10"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_span
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.0-nullsafety.2"
|
||||
version: "1.8.0"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.10.0-nullsafety.1"
|
||||
version: "1.10.0"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_channel
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0-nullsafety.1"
|
||||
version: "2.1.0"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0-nullsafety.1"
|
||||
version: "1.1.0"
|
||||
sync_http:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -447,42 +368,42 @@ packages:
|
|||
name: term_glyph
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0-nullsafety.1"
|
||||
version: "1.2.0"
|
||||
test:
|
||||
dependency: transitive
|
||||
dependency: "direct overridden"
|
||||
description:
|
||||
name: test
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.16.0-nullsafety.5"
|
||||
version: "1.16.5"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
dependency: "direct overridden"
|
||||
description:
|
||||
name: test_api
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.19-nullsafety.2"
|
||||
version: "0.3.0"
|
||||
test_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_core
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.12-nullsafety.5"
|
||||
version: "0.3.15"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: typed_data
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.0-nullsafety.3"
|
||||
version: "1.3.0"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_math
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0-nullsafety.3"
|
||||
version: "2.1.0"
|
||||
vm_service:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -490,13 +411,6 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "5.5.0"
|
||||
vm_service_client:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vm_service_client
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.6+2"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -510,7 +424,7 @@ packages:
|
|||
name: web_socket_channel
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.2.0"
|
||||
webdriver:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -524,7 +438,7 @@ packages:
|
|||
name: webkit_inspection_protocol
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.7.4"
|
||||
version: "1.0.0"
|
||||
yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -533,5 +447,5 @@ packages:
|
|||
source: hosted
|
||||
version: "2.2.1"
|
||||
sdks:
|
||||
dart: ">=2.10.0 <2.11.0"
|
||||
flutter: ">=1.17.0 <2.0.0"
|
||||
dart: ">=2.12.3 <3.0.0"
|
||||
flutter: ">=2.0.0"
|
||||
|
|
|
@ -6,13 +6,15 @@ publish_to: 'none'
|
|||
version: 1.0.0+1
|
||||
|
||||
environment:
|
||||
sdk: ">=2.7.0 <3.0.0"
|
||||
sdk: '>=2.12.0 <3.0.0'
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
|
||||
cupertino_icons: ^1.0.0
|
||||
dependency_overrides:
|
||||
test: ^1.16.5 # gherkin still depends on 1.16.8 :-(
|
||||
test_api: ^0.3.0 # flutter_test still depends on 0.2.19 :-(
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
@ -21,5 +23,4 @@ dev_dependencies:
|
|||
path: ../
|
||||
|
||||
flutter:
|
||||
|
||||
uses-material-design: true
|
||||
|
|
|
@ -1,29 +1,24 @@
|
|||
import 'dart:async';
|
||||
import 'package:flutter_gherkin/flutter_gherkin.dart';
|
||||
import 'package:flutter_gherkin/flutter_gherkin_with_driver.dart';
|
||||
import 'package:gherkin/gherkin.dart';
|
||||
|
||||
Future<void> main() {
|
||||
final steps = <StepDefinitionGeneric>[];
|
||||
|
||||
final config = FlutterDriverTestConfiguration.DEFAULT(
|
||||
steps,
|
||||
Iterable.empty(),
|
||||
featurePath: 'features/**.feature',
|
||||
targetAppPath: 'test_driver/app.dart',
|
||||
)
|
||||
..hooks = []
|
||||
..customStepParameterDefinitions = []
|
||||
..restartAppBetweenScenarios = true
|
||||
..targetAppWorkingDirectory = '../'
|
||||
..targetAppPath = 'test_driver/app.dart'
|
||||
// ..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
|
||||
// ..logFlutterProcessOutput = true // uncomment to see command invoked to start the flutter test app
|
||||
// ..verboseFlutterProcessLogs = true // uncomment to see the verbose output from the Flutter process
|
||||
// ..flutterBuildTimeout = Duration(minutes: 3) // uncomment to change the default period that flutter is expected to build and start the app within
|
||||
// ..runningAppProtocolEndpointUri =
|
||||
// 'http://127.0.0.1:51540/bkegoer6eH8=/' // already running app observatory / service protocol uri (with enableFlutterDriverExtension method invoked) to test against if you use this set `restartAppBetweenScenarios` to false
|
||||
..exitAfterTestRun = true; // set to false if debugging to exit cleanly
|
||||
..targetAppPath = 'test_driver/app.dart';
|
||||
// ..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
|
||||
// ..logFlutterProcessOutput = true // uncomment to see command invoked to start the flutter test app
|
||||
// ..verboseFlutterProcessLogs = true // uncomment to see the verbose output from the Flutter process
|
||||
// ..flutterBuildTimeout = Duration(minutes: 3) // uncomment to change the default period that flutter is expected to build and start the app within
|
||||
// ..runningAppProtocolEndpointUri =
|
||||
// 'http://127.0.0.1:51540/bkegoer6eH8=/' // already running app observatory / service protocol uri (with enableFlutterDriverExtension method invoked) to test against if you use this set `restartAppBetweenScenarios` to false
|
||||
|
||||
return GherkinRunner().execute(config);
|
||||
}
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"gherkin_results": "{\"test\":\"moo1\"}"
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:example_with_integration_test/main.dart';
|
||||
import 'package:example_with_integration_test/services/external_application_manager.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_gherkin/flutter_gherkin_integration_test.dart';
|
||||
import 'package:flutter_gherkin/flutter_gherkin.dart';
|
||||
import 'package:flutter_simple_dependency_injection/injector.dart';
|
||||
import 'package:gherkin/gherkin.dart';
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import 'package:flutter/material.dart';
|
||||
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';
|
||||
|
||||
|
@ -8,7 +7,7 @@ final thenIExpectTheTodos = then1<GherkinTable, FlutterWorld>(
|
|||
'I expect the todo list',
|
||||
(table, context) async {
|
||||
expect(context.configuration.timeout, isNotNull);
|
||||
expect(context.configuration.timeout.inSeconds, 5);
|
||||
expect(context.configuration.timeout!.inSeconds, 5);
|
||||
|
||||
// get the parent list
|
||||
final listTileFinder = context.world.appDriver.findBy(
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_gherkin/flutter_gherkin.dart';
|
||||
import 'package:gherkin/gherkin.dart';
|
||||
import 'package:flutter_gherkin/flutter_gherkin_integration_test.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
/// Shows are example of using the `WidgetTester` from the `World` context rather than
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import 'package:flutter_gherkin/flutter_gherkin.dart';
|
||||
import 'package:gherkin/gherkin.dart';
|
||||
import 'package:flutter_gherkin/flutter_gherkin_integration_test.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
final whenStepHasTimeout = when<FlutterWidgetTesterWorld>(
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import 'package:example_with_integration_test/services/external_application_manager.dart';
|
||||
import 'package:flutter_gherkin/flutter_gherkin_integration_test.dart';
|
||||
import 'package:flutter_gherkin/flutter_gherkin.dart';
|
||||
|
||||
class CustomWorld extends FlutterWidgetTesterWorld {
|
||||
ExternalApplicationManager _externalApplicationManager;
|
||||
ExternalApplicationManager? _externalApplicationManager;
|
||||
|
||||
ExternalApplicationManager get externalApplicationManager =>
|
||||
_externalApplicationManager;
|
||||
_externalApplicationManager!;
|
||||
|
||||
void setExternalApplicationManager(ExternalApplicationManager manager) {
|
||||
_externalApplicationManager = manager;
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
import 'package:flutter_gherkin/flutter_gherkin_integration_test.dart';
|
||||
import 'package:flutter_gherkin/flutter_gherkin.dart';
|
||||
import 'package:gherkin/gherkin.dart';
|
||||
|
||||
import 'gherkin/configuration.dart';
|
||||
|
||||
part 'gherkin_suite_test.g.dart';
|
||||
|
||||
@GherkinTestSuite()
|
||||
void main() {
|
||||
executeTestSuite(
|
||||
gherkinTestConfiguration,
|
||||
appInitializationFn,
|
||||
);
|
||||
// executeTestSuite(
|
||||
// gherkinTestConfiguration,
|
||||
// appInitializationFn,
|
||||
// );
|
||||
}
|
||||
|
|
|
@ -109,6 +109,13 @@ class _CustomGherkinIntegrationTestRunner extends GherkinIntegrationTestRunner {
|
|||
null,
|
||||
dependencies,
|
||||
);
|
||||
|
||||
await runStep(
|
||||
'When I test the default step timeout is not applied to step with custom timeout',
|
||||
<String>[],
|
||||
null,
|
||||
dependencies,
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
|
|
|
@ -7,7 +7,7 @@ class TodoBloc {
|
|||
final Subject<void> _dataRefresher = BehaviorSubject.seeded(null);
|
||||
final Subject<Todo> _newModel = ReplaySubject(maxSize: 1);
|
||||
final TodoRepository _repository;
|
||||
Stream<Iterable<Todo>> _todos;
|
||||
late final Stream<Iterable<Todo>> _todos;
|
||||
|
||||
Stream<Iterable<Todo>> get todos => _todos;
|
||||
Stream<Todo> get newModel => _newModel;
|
||||
|
|
|
@ -14,11 +14,11 @@ void main() {
|
|||
}
|
||||
|
||||
class TodoApp extends StatelessWidget {
|
||||
final ExternalApplicationManager externalApplicationManager;
|
||||
final ExternalApplicationManager? externalApplicationManager;
|
||||
final Injector injector;
|
||||
|
||||
TodoApp({
|
||||
this.injector,
|
||||
required this.injector,
|
||||
this.externalApplicationManager,
|
||||
}) : super() {
|
||||
ModuleContainer().initialise(injector);
|
||||
|
@ -40,7 +40,7 @@ class TodoApp extends StatelessWidget {
|
|||
return externalApplicationManager == null
|
||||
? app
|
||||
: StreamBuilder(
|
||||
stream: externalApplicationManager.applicationReset,
|
||||
stream: externalApplicationManager!.applicationReset,
|
||||
builder: (ctx, _) => app,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -5,11 +5,11 @@ part 'todo_model.g.dart';
|
|||
|
||||
@JsonSerializable()
|
||||
class Todo {
|
||||
String id;
|
||||
DateTime created;
|
||||
DateTime updated;
|
||||
String action;
|
||||
TodoStatus status;
|
||||
late String id;
|
||||
late DateTime created;
|
||||
late DateTime updated;
|
||||
late String action;
|
||||
late TodoStatus status;
|
||||
|
||||
Todo();
|
||||
|
||||
|
|
|
@ -9,54 +9,44 @@ part of 'todo_model.dart';
|
|||
Todo _$TodoFromJson(Map<String, dynamic> json) {
|
||||
return Todo()
|
||||
..id = json['id'] as String
|
||||
..created = json['created'] == null
|
||||
? null
|
||||
: DateTime.parse(json['created'] as String)
|
||||
..updated = json['updated'] == null
|
||||
? null
|
||||
: DateTime.parse(json['updated'] as String)
|
||||
..created = DateTime.parse(json['created'] as String)
|
||||
..updated = DateTime.parse(json['updated'] as String)
|
||||
..action = json['action'] as String
|
||||
..status = _$enumDecodeNullable(_$TodoStatusEnumMap, json['status']);
|
||||
..status = _$enumDecode(_$TodoStatusEnumMap, json['status']);
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$TodoToJson(Todo instance) => <String, dynamic>{
|
||||
'id': instance.id,
|
||||
'created': instance.created?.toIso8601String(),
|
||||
'updated': instance.updated?.toIso8601String(),
|
||||
'created': instance.created.toIso8601String(),
|
||||
'updated': instance.updated.toIso8601String(),
|
||||
'action': instance.action,
|
||||
'status': _$TodoStatusEnumMap[instance.status],
|
||||
};
|
||||
|
||||
T _$enumDecode<T>(
|
||||
Map<T, dynamic> enumValues,
|
||||
dynamic source, {
|
||||
T unknownValue,
|
||||
K _$enumDecode<K, V>(
|
||||
Map<K, V> enumValues,
|
||||
Object? source, {
|
||||
K? unknownValue,
|
||||
}) {
|
||||
if (source == null) {
|
||||
throw ArgumentError('A value must be provided. Supported values: '
|
||||
'${enumValues.values.join(', ')}');
|
||||
throw ArgumentError(
|
||||
'A value must be provided. Supported values: '
|
||||
'${enumValues.values.join(', ')}',
|
||||
);
|
||||
}
|
||||
|
||||
final value = enumValues.entries
|
||||
.singleWhere((e) => e.value == source, orElse: () => null)
|
||||
?.key;
|
||||
|
||||
if (value == null && unknownValue == null) {
|
||||
throw ArgumentError('`$source` is not one of the supported values: '
|
||||
'${enumValues.values.join(', ')}');
|
||||
}
|
||||
return value ?? unknownValue;
|
||||
}
|
||||
|
||||
T _$enumDecodeNullable<T>(
|
||||
Map<T, dynamic> enumValues,
|
||||
dynamic source, {
|
||||
T unknownValue,
|
||||
}) {
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
return _$enumDecode<T>(enumValues, source, unknownValue: unknownValue);
|
||||
return enumValues.entries.singleWhere(
|
||||
(e) => e.value == source,
|
||||
orElse: () {
|
||||
if (unknownValue == null) {
|
||||
throw ArgumentError(
|
||||
'`$source` is not one of the supported values: '
|
||||
'${enumValues.values.join(', ')}',
|
||||
);
|
||||
}
|
||||
return MapEntry(unknownValue, enumValues.values.first);
|
||||
},
|
||||
).key;
|
||||
}
|
||||
|
||||
const _$TodoStatusEnumMap = {
|
||||
|
|
|
@ -15,7 +15,7 @@ class TodoRepository {
|
|||
ReplaySubject<SharedPreferences>(maxSize: 1);
|
||||
|
||||
TodoRepository() {
|
||||
StreamSubscription<SharedPreferences> sub;
|
||||
StreamSubscription<SharedPreferences>? sub;
|
||||
sub = SharedPreferences.getInstance().asStream().listen(
|
||||
(sp) {
|
||||
_storage.add(sp);
|
||||
|
|
|
@ -9,8 +9,8 @@ class AddTodoComponent extends StatefulWidget {
|
|||
final Stream<Todo> todo;
|
||||
|
||||
const AddTodoComponent({
|
||||
@required this.todo,
|
||||
@required this.onAdded,
|
||||
required this.todo,
|
||||
required this.onAdded,
|
||||
}) : super();
|
||||
|
||||
@override
|
||||
|
@ -63,12 +63,12 @@ class _AddTodoComponentState extends State<AddTodoComponent>
|
|||
),
|
||||
),
|
||||
FloatingActionButton(
|
||||
child: Icon(Icons.add),
|
||||
key: const Key('add'),
|
||||
onPressed: onAdd,
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
focusElevation: 3,
|
||||
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||
child: const Icon(Icons.add),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
@ -7,11 +7,11 @@ class ViewUtilsMixin {
|
|||
@protected
|
||||
StreamSubscription<T> subscribeOnce<T>(
|
||||
Stream<T> stream, {
|
||||
void Function(T data) onData,
|
||||
void Function(Object, StackTrace) onError,
|
||||
void Function() onDone,
|
||||
void Function(T data)? onData,
|
||||
void Function(Object, StackTrace)? onError,
|
||||
void Function()? onDone,
|
||||
}) {
|
||||
StreamSubscription<T> sub;
|
||||
StreamSubscription<T>? sub;
|
||||
var hasErrored = false;
|
||||
return sub = stream.listen(
|
||||
(data) {
|
||||
|
|
|
@ -11,8 +11,8 @@ class HomeView extends StatefulWidget {
|
|||
final TodoBloc Function() blocFactory;
|
||||
|
||||
const HomeView({
|
||||
@required this.blocFactory,
|
||||
Key key,
|
||||
required this.blocFactory,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
@ -56,7 +56,7 @@ class _HomeViewState extends State<HomeView> with ViewUtilsMixin {
|
|||
stream: bloc.todos,
|
||||
builder: (_, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
final data = snapshot.data;
|
||||
final data = snapshot.data!;
|
||||
if (data.isEmpty) {
|
||||
return Center(
|
||||
child: Column(
|
||||
|
@ -108,7 +108,7 @@ class _HomeViewState extends State<HomeView> with ViewUtilsMixin {
|
|||
subscribeOnce(
|
||||
bloc.remove(todo),
|
||||
onDone: () {
|
||||
Scaffold.of(context).showSnackBar(
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('Todo deleted'),
|
||||
),
|
||||
|
@ -121,7 +121,7 @@ class _HomeViewState extends State<HomeView> with ViewUtilsMixin {
|
|||
todo.action,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyText1
|
||||
.bodyText1!
|
||||
.copyWith(
|
||||
decoration:
|
||||
todo.status == TodoStatus.complete
|
||||
|
|
|
@ -7,14 +7,14 @@ packages:
|
|||
name: _fe_analyzer_shared
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "12.0.0"
|
||||
version: "21.0.0"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: analyzer
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.40.6"
|
||||
version: "1.5.0"
|
||||
archive:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -35,56 +35,56 @@ packages:
|
|||
name: async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.5.0-nullsafety.1"
|
||||
version: "2.5.0"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: boolean_selector
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0-nullsafety.1"
|
||||
version: "2.1.0"
|
||||
build:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.6.0"
|
||||
version: "2.0.1"
|
||||
build_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_config
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.5"
|
||||
version: "0.4.7"
|
||||
build_daemon:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_daemon
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
version: "2.1.10"
|
||||
build_resolvers:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_resolvers
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.5.1"
|
||||
version: "2.0.0"
|
||||
build_runner:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: build_runner
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.10.11"
|
||||
version: "1.12.2"
|
||||
build_runner_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_runner_core
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.1.5"
|
||||
version: "6.1.12"
|
||||
built_collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -105,35 +105,35 @@ packages:
|
|||
name: characters
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0-nullsafety.3"
|
||||
version: "1.1.0"
|
||||
charcode:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: charcode
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0-nullsafety.1"
|
||||
version: "1.2.0"
|
||||
checked_yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: checked_yaml
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
version: "2.0.1"
|
||||
cli_util:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cli_util
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
version: "0.3.0"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: clock
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0-nullsafety.1"
|
||||
version: "1.1.0"
|
||||
code_builder:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -147,63 +147,56 @@ packages:
|
|||
name: collection
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.15.0-nullsafety.3"
|
||||
version: "1.15.0"
|
||||
convert:
|
||||
dependency: transitive
|
||||
dependency: "direct overridden"
|
||||
description:
|
||||
name: convert
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
version: "3.0.0"
|
||||
coverage:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: coverage
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.14.2"
|
||||
version: "0.15.2"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
dependency: "direct overridden"
|
||||
description:
|
||||
name: crypto
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.5"
|
||||
cupertino_icons:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: cupertino_icons
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
version: "3.0.1"
|
||||
dart_style:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dart_style
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.10"
|
||||
version: "2.0.1"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fake_async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0-nullsafety.1"
|
||||
version: "1.2.0"
|
||||
ffi:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: ffi
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.3"
|
||||
version: "1.0.0"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.0.0-nullsafety.2"
|
||||
version: "6.0.0"
|
||||
fixnum:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -234,7 +227,7 @@ packages:
|
|||
name: flutter_simple_dependency_injection
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
version: "2.0.0"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
|
@ -253,33 +246,24 @@ packages:
|
|||
gherkin:
|
||||
dependency: transitive
|
||||
description:
|
||||
path: "."
|
||||
ref: f0b3f955191b53a78075ed2c9387ea8bee12f111
|
||||
resolved-ref: f0b3f955191b53a78075ed2c9387ea8bee12f111
|
||||
url: "https://github.com/jonsamwell/dart_gherkin.git"
|
||||
source: git
|
||||
version: "1.1.10"
|
||||
name: gherkin
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
glob:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: glob
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "2.0.1"
|
||||
graphs:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: graphs
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
http:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.2"
|
||||
version: "1.0.0"
|
||||
http_multi_server:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -296,11 +280,9 @@ packages:
|
|||
version: "3.1.4"
|
||||
integration_test:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: integration_test
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.9.2+2"
|
||||
io:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -314,49 +296,42 @@ packages:
|
|||
name: js
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.6.3-nullsafety.2"
|
||||
version: "0.6.3"
|
||||
json_annotation:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: json_annotation
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.1.1"
|
||||
json_rpc_2:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: json_rpc_2
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.2"
|
||||
version: "4.0.1"
|
||||
json_serializable:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: json_serializable
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.5.1"
|
||||
version: "4.1.1"
|
||||
logging:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: logging
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.11.4"
|
||||
version: "1.0.1"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.10-nullsafety.1"
|
||||
version: "0.12.10"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.0-nullsafety.3"
|
||||
version: "1.3.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -364,111 +339,97 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.9.7"
|
||||
node_interop:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: node_interop
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
node_io:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: node_io
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
node_preamble:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: node_preamble
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.12"
|
||||
version: "1.4.13"
|
||||
package_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_config
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.9.3"
|
||||
version: "2.0.0"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.0-nullsafety.1"
|
||||
version: "1.8.0"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_linux
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.1+2"
|
||||
version: "2.0.0"
|
||||
path_provider_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
version: "2.0.1"
|
||||
path_provider_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_windows
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.4+3"
|
||||
version: "2.0.1"
|
||||
pedantic:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pedantic
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.10.0-nullsafety.2"
|
||||
version: "1.11.0"
|
||||
platform:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: platform
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.0-nullsafety.2"
|
||||
version: "3.0.0"
|
||||
plugin_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: plugin_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
version: "2.0.0"
|
||||
pool:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pool
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.5.0-nullsafety.2"
|
||||
version: "1.5.0"
|
||||
process:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: process
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.0.0-nullsafety.2"
|
||||
version: "4.0.0"
|
||||
pub_semver:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pub_semver
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.4"
|
||||
version: "2.0.0"
|
||||
pubspec_parse:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pubspec_parse
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.7"
|
||||
version: "1.0.0"
|
||||
quiver:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -482,49 +443,49 @@ packages:
|
|||
name: rxdart
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.25.0"
|
||||
version: "0.26.0"
|
||||
shared_preferences:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: shared_preferences
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.5.12+4"
|
||||
version: "2.0.5"
|
||||
shared_preferences_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_linux
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.2+4"
|
||||
version: "2.0.0"
|
||||
shared_preferences_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_macos
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.1+11"
|
||||
version: "2.0.0"
|
||||
shared_preferences_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
version: "2.0.0"
|
||||
shared_preferences_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_web
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.2+7"
|
||||
version: "2.0.0"
|
||||
shared_preferences_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_windows
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.1+3"
|
||||
version: "2.0.0"
|
||||
shelf:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -538,14 +499,14 @@ packages:
|
|||
name: shelf_packages_handler
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
version: "2.0.1"
|
||||
shelf_static:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_static
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.9+1"
|
||||
version: "0.2.9+2"
|
||||
shelf_web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -564,56 +525,56 @@ packages:
|
|||
name: source_gen
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.9.10+1"
|
||||
version: "1.0.0"
|
||||
source_map_stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_map_stack_trace
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0-nullsafety.3"
|
||||
version: "2.1.0"
|
||||
source_maps:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_maps
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.10.10-nullsafety.2"
|
||||
version: "0.10.10"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_span
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.0-nullsafety.2"
|
||||
version: "1.8.0"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.10.0-nullsafety.1"
|
||||
version: "1.10.0"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_channel
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0-nullsafety.1"
|
||||
version: "2.1.0"
|
||||
stream_transform:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_transform
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "2.0.0"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0-nullsafety.1"
|
||||
version: "1.1.0"
|
||||
sync_http:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -627,28 +588,28 @@ packages:
|
|||
name: term_glyph
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0-nullsafety.1"
|
||||
version: "1.2.0"
|
||||
test:
|
||||
dependency: transitive
|
||||
dependency: "direct overridden"
|
||||
description:
|
||||
name: test
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.16.0-nullsafety.5"
|
||||
version: "1.16.5"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
dependency: "direct overridden"
|
||||
description:
|
||||
name: test_api
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.19-nullsafety.2"
|
||||
version: "0.3.0"
|
||||
test_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_core
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.12-nullsafety.5"
|
||||
version: "0.3.15"
|
||||
timing:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -662,21 +623,21 @@ packages:
|
|||
name: typed_data
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.0-nullsafety.3"
|
||||
version: "1.3.0"
|
||||
uuid:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: uuid
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.2"
|
||||
version: "3.0.4"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_math
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0-nullsafety.3"
|
||||
version: "2.1.0"
|
||||
vm_service:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -684,20 +645,13 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "5.5.0"
|
||||
vm_service_client:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vm_service_client
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.6+2"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: watcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.9.7+15"
|
||||
version: "1.0.0"
|
||||
web_socket_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -718,28 +672,28 @@ packages:
|
|||
name: webkit_inspection_protocol
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.7.4"
|
||||
version: "1.0.0"
|
||||
win32:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.7.4"
|
||||
version: "2.0.5"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xdg_directories
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.2"
|
||||
version: "0.2.0"
|
||||
yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: yaml
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.1"
|
||||
version: "3.1.0"
|
||||
sdks:
|
||||
dart: ">=2.10.0 <2.11.0"
|
||||
flutter: ">=1.17.0 <2.0.0"
|
||||
dart: ">=2.12.3 <3.0.0"
|
||||
flutter: ">=2.0.0"
|
||||
|
|
|
@ -6,26 +6,30 @@ publish_to: 'none'
|
|||
version: 1.0.0+1
|
||||
|
||||
environment:
|
||||
sdk: ">=2.7.0 <3.0.0"
|
||||
sdk: '>=2.12.0 <3.0.0'
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
json_serializable: ^4.1.1
|
||||
json_annotation: ^4.0.1
|
||||
rxdart: ^0.26.0
|
||||
shared_preferences: ^2.0.5
|
||||
uuid: ^3.0.4
|
||||
flutter_simple_dependency_injection: ^2.0.0
|
||||
|
||||
cupertino_icons: ^1.0.0
|
||||
|
||||
json_serializable: ^3.5.1
|
||||
json_annotation: ^3.1.1
|
||||
rxdart: ^0.25.0
|
||||
shared_preferences: ^0.5.12+4
|
||||
uuid: ^2.2.2
|
||||
flutter_simple_dependency_injection: ^1.0.4
|
||||
dependency_overrides:
|
||||
crypto: ^3.0.0 # flutter_driver still depends on 2.1.5 :-(
|
||||
convert: ^3.0.0 # flutter_driver still depends on >=2.0.0 :-(
|
||||
test: ^1.16.5 # gherkin still depends on 1.16.8 :-(
|
||||
test_api: ^0.3.0 # flutter_test still depends on 0.2.19 :-(
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
integration_test: ^1.0.0
|
||||
build_runner: ^1.10.11
|
||||
integration_test:
|
||||
sdk: flutter
|
||||
build_runner:
|
||||
flutter_gherkin:
|
||||
path: ../
|
||||
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
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';
|
||||
|
@ -28,11 +33,8 @@ export 'src/flutter/steps/wait_until_type_exists_step.dart';
|
|||
// Hooks
|
||||
export 'src/flutter/hooks/attach_screenshot_on_failed_step_hook.dart';
|
||||
|
||||
// Flutter WidgetTester specific implementations
|
||||
// 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';
|
||||
export 'src/flutter/world/flutter_widget_tester_world.dart';
|
||||
|
||||
// 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';
|
||||
export 'src/flutter/world/flutter_driver_world.dart';
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
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';
|
||||
|
@ -33,8 +28,8 @@ 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';
|
||||
export 'src/flutter/world/flutter_widget_tester_world.dart';
|
||||
// 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';
|
||||
export 'src/flutter/world/flutter_driver_world.dart';
|
|
@ -61,34 +61,34 @@ abstract class AppDriverAdapter<TRawAdapter, TFinderType, TWidgetBaseType> {
|
|||
|
||||
Future<bool> isPresent(
|
||||
TFinderType finder, {
|
||||
Duration timeout = const Duration(seconds: 1),
|
||||
Duration? timeout = const Duration(seconds: 1),
|
||||
});
|
||||
|
||||
Future<bool> isAbsent(
|
||||
TFinderType finder, {
|
||||
Duration timeout = const Duration(seconds: 1),
|
||||
Duration? timeout = const Duration(seconds: 1),
|
||||
});
|
||||
|
||||
Future<void> enterText(
|
||||
TFinderType finder,
|
||||
String text, {
|
||||
Duration timeout = const Duration(seconds: 30),
|
||||
Duration? timeout = const Duration(seconds: 30),
|
||||
});
|
||||
|
||||
Future<String> getText(
|
||||
Future<String?> getText(
|
||||
TFinderType finder, {
|
||||
Duration timeout = const Duration(seconds: 30),
|
||||
Duration? timeout = const Duration(seconds: 30),
|
||||
});
|
||||
|
||||
Future<void> tap(
|
||||
TFinderType finder, {
|
||||
Duration timeout = const Duration(seconds: 30),
|
||||
Duration? timeout = const Duration(seconds: 30),
|
||||
});
|
||||
|
||||
Future<void> longPress(
|
||||
TFinderType finder, {
|
||||
Duration pressDuration = const Duration(milliseconds: 500),
|
||||
Duration timeout = const Duration(seconds: 30),
|
||||
Duration? timeout = const Duration(seconds: 30),
|
||||
});
|
||||
|
||||
Future<void> pageBack();
|
||||
|
@ -98,8 +98,8 @@ abstract class AppDriverAdapter<TRawAdapter, TFinderType, TWidgetBaseType> {
|
|||
TFinderType finder, {
|
||||
double dx,
|
||||
double dy,
|
||||
Duration duration = const Duration(milliseconds: 200),
|
||||
Duration timeout = const Duration(seconds: 30),
|
||||
Duration? duration = const Duration(milliseconds: 200),
|
||||
Duration? timeout = const Duration(seconds: 30),
|
||||
});
|
||||
|
||||
/// Repeatedly scrolls a [Scrollable] by delta until finder is visible.
|
||||
|
@ -110,26 +110,26 @@ abstract class AppDriverAdapter<TRawAdapter, TFinderType, TWidgetBaseType> {
|
|||
TFinderType scrollable,
|
||||
double dx,
|
||||
double dy,
|
||||
Duration timeout = const Duration(seconds: 30),
|
||||
Duration? timeout = const Duration(seconds: 30),
|
||||
});
|
||||
|
||||
Future<void> scrollIntoView(
|
||||
TFinderType finder, {
|
||||
Duration timeout = const Duration(seconds: 30),
|
||||
Duration? timeout = const Duration(seconds: 30),
|
||||
});
|
||||
|
||||
/// Will wait until the give condition returns `true` polling every `pollInterval`. If `condition` has not returned true
|
||||
/// within the given `timeout` this will cause the returned future to complete with a [TimeoutException].
|
||||
Future<void> waitUntil(
|
||||
Future<bool> Function() condition, {
|
||||
Duration timeout = const Duration(seconds: 10),
|
||||
Duration pollInterval = const Duration(milliseconds: 500),
|
||||
Duration? timeout = const Duration(seconds: 10),
|
||||
Duration? pollInterval = const Duration(milliseconds: 500),
|
||||
}) async {
|
||||
return Future.microtask(
|
||||
() async {
|
||||
final completer = Completer<void>();
|
||||
var maxAttempts =
|
||||
(timeout.inMilliseconds / pollInterval.inMilliseconds).round();
|
||||
(timeout!.inMilliseconds / pollInterval!.inMilliseconds).round();
|
||||
var attempts = 0;
|
||||
|
||||
while (attempts < maxAttempts) {
|
||||
|
@ -143,7 +143,7 @@ abstract class AppDriverAdapter<TRawAdapter, TFinderType, TWidgetBaseType> {
|
|||
}
|
||||
},
|
||||
).timeout(
|
||||
timeout,
|
||||
timeout!,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,25 +10,26 @@ class FlutterDriverAppDriverAdapter
|
|||
|
||||
@override
|
||||
Future<int> waitForAppToSettle({
|
||||
Duration duration = const Duration(milliseconds: 100),
|
||||
Duration timeout = const Duration(seconds: 30),
|
||||
Duration? duration = const Duration(milliseconds: 100),
|
||||
Duration? timeout = const Duration(seconds: 30),
|
||||
}) async {
|
||||
try {
|
||||
await rawDriver.waitUntilNoTransientCallbacks(timeout: timeout);
|
||||
} catch (_) {
|
||||
return null;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return null;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<T> widget<T extends Object>(
|
||||
Future<T> widget<T extends dynamic>(
|
||||
SerializableFinder finder, [
|
||||
ExpectedWidgetResultType expectResultType = ExpectedWidgetResultType.first,
|
||||
]) {
|
||||
throw UnimplementedError(
|
||||
'Flutter driver does not support directly interacting with the widget tree');
|
||||
'Flutter driver does not support directly interacting with the widget tree',
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -49,7 +50,7 @@ class FlutterDriverAppDriverAdapter
|
|||
@override
|
||||
Future<bool> isPresent(
|
||||
SerializableFinder finder, {
|
||||
Duration timeout = const Duration(seconds: 1),
|
||||
Duration? timeout = const Duration(seconds: 1),
|
||||
}) async {
|
||||
try {
|
||||
await rawDriver.waitFor(
|
||||
|
@ -65,7 +66,7 @@ class FlutterDriverAppDriverAdapter
|
|||
@override
|
||||
Future<bool> isAbsent(
|
||||
SerializableFinder finder, {
|
||||
Duration timeout = const Duration(seconds: 1),
|
||||
Duration? timeout = const Duration(seconds: 1),
|
||||
}) async {
|
||||
try {
|
||||
await rawDriver.waitForAbsent(
|
||||
|
@ -79,9 +80,9 @@ class FlutterDriverAppDriverAdapter
|
|||
}
|
||||
|
||||
@override
|
||||
Future<String> getText(
|
||||
Future<String?> getText(
|
||||
SerializableFinder finder, {
|
||||
Duration timeout = const Duration(seconds: 30),
|
||||
Duration? timeout = const Duration(seconds: 30),
|
||||
}) async {
|
||||
await waitForAppToSettle(timeout: timeout);
|
||||
|
||||
|
@ -95,7 +96,7 @@ class FlutterDriverAppDriverAdapter
|
|||
Future<void> enterText(
|
||||
SerializableFinder finder,
|
||||
String text, {
|
||||
Duration timeout = const Duration(seconds: 30),
|
||||
Duration? timeout = const Duration(seconds: 30),
|
||||
}) async {
|
||||
await tap(
|
||||
finder,
|
||||
|
@ -110,7 +111,7 @@ class FlutterDriverAppDriverAdapter
|
|||
@override
|
||||
Future<void> tap(
|
||||
SerializableFinder finder, {
|
||||
Duration timeout = const Duration(seconds: 30),
|
||||
Duration? timeout = const Duration(seconds: 30),
|
||||
}) async {
|
||||
await rawDriver.tap(finder, timeout: timeout);
|
||||
await waitForAppToSettle(timeout: timeout);
|
||||
|
@ -119,8 +120,8 @@ class FlutterDriverAppDriverAdapter
|
|||
@override
|
||||
Future<void> longPress(
|
||||
SerializableFinder finder, {
|
||||
Duration pressDuration = const Duration(milliseconds: 500),
|
||||
Duration timeout = const Duration(seconds: 30),
|
||||
Duration? pressDuration = const Duration(milliseconds: 500),
|
||||
Duration? timeout = const Duration(seconds: 30),
|
||||
}) async {
|
||||
await scroll(
|
||||
finder,
|
||||
|
@ -135,10 +136,10 @@ class FlutterDriverAppDriverAdapter
|
|||
@override
|
||||
Future<void> scroll(
|
||||
SerializableFinder finder, {
|
||||
double dx,
|
||||
double dy,
|
||||
Duration duration = const Duration(milliseconds: 200),
|
||||
Duration timeout = const Duration(seconds: 30),
|
||||
double? dx,
|
||||
double? dy,
|
||||
Duration? duration = const Duration(milliseconds: 200),
|
||||
Duration? timeout = const Duration(seconds: 30),
|
||||
}) async {
|
||||
await rawDriver.scroll(
|
||||
finder,
|
||||
|
@ -165,8 +166,6 @@ class FlutterDriverAppDriverAdapter
|
|||
case FindType.type:
|
||||
return find.byType(data.toString());
|
||||
}
|
||||
|
||||
throw Exception('unknown finder');
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -202,10 +201,10 @@ class FlutterDriverAppDriverAdapter
|
|||
@override
|
||||
Future<void> scrollUntilVisible(
|
||||
SerializableFinder item, {
|
||||
SerializableFinder scrollable,
|
||||
double dx,
|
||||
double dy,
|
||||
Duration timeout = const Duration(seconds: 30),
|
||||
SerializableFinder? scrollable,
|
||||
double? dx,
|
||||
double? dy,
|
||||
Duration? timeout = const Duration(seconds: 30),
|
||||
}) async {
|
||||
await rawDriver.scrollUntilVisible(
|
||||
scrollable,
|
||||
|
@ -219,7 +218,7 @@ class FlutterDriverAppDriverAdapter
|
|||
@override
|
||||
Future<void> scrollIntoView(
|
||||
SerializableFinder finder, {
|
||||
Duration timeout = const Duration(seconds: 30),
|
||||
Duration? timeout = const Duration(seconds: 30),
|
||||
}) async {
|
||||
await rawDriver.scrollIntoView(
|
||||
finder,
|
||||
|
|
|
@ -14,20 +14,18 @@ class WidgetTesterAppDriverAdapter
|
|||
|
||||
@override
|
||||
Future<int> waitForAppToSettle({
|
||||
Duration duration = const Duration(milliseconds: 100),
|
||||
Duration timeout = const Duration(seconds: 30),
|
||||
Duration? duration = const Duration(milliseconds: 100),
|
||||
Duration? timeout = const Duration(seconds: 30),
|
||||
}) async {
|
||||
try {
|
||||
await rawDriver.pumpAndSettle(
|
||||
duration,
|
||||
EnginePhase.sendSemanticsUpdate,
|
||||
timeout,
|
||||
return await rawDriver.pumpAndSettle(
|
||||
duration!,
|
||||
EnginePhase.paint,
|
||||
timeout!,
|
||||
);
|
||||
} catch (_) {
|
||||
return null;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -48,24 +46,25 @@ class WidgetTesterAppDriverAdapter
|
|||
|
||||
@override
|
||||
Future<List<int>> screenshot() {
|
||||
var renderObject = rawDriver.binding.renderViewElement.renderObject;
|
||||
while (!renderObject.isRepaintBoundary) {
|
||||
var renderObject = rawDriver.binding.renderViewElement?.renderObject;
|
||||
|
||||
while (renderObject != null && !renderObject.isRepaintBoundary) {
|
||||
renderObject = renderObject.parent as RenderObject;
|
||||
assert(renderObject != null);
|
||||
}
|
||||
assert(!renderObject.debugNeedsPaint);
|
||||
final layer = renderObject.debugLayer as OffsetLayer;
|
||||
|
||||
assert(renderObject != null && !renderObject.debugNeedsPaint);
|
||||
final layer = renderObject!.debugLayer as OffsetLayer;
|
||||
|
||||
return layer
|
||||
.toImage(renderObject.semanticBounds)
|
||||
.then((value) => value.toByteData(format: ui.ImageByteFormat.png))
|
||||
.then((value) => value.buffer.asUint8List());
|
||||
.then((value) => value?.buffer.asUint8List() ?? List<int>.empty());
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> isPresent(
|
||||
Finder finder, {
|
||||
Duration timeout = const Duration(seconds: 1),
|
||||
Duration? timeout = const Duration(seconds: 1),
|
||||
}) async {
|
||||
return finder.evaluate().isNotEmpty;
|
||||
}
|
||||
|
@ -73,15 +72,15 @@ class WidgetTesterAppDriverAdapter
|
|||
@override
|
||||
Future<bool> isAbsent(
|
||||
Finder finder, {
|
||||
Duration timeout = const Duration(seconds: 1),
|
||||
Duration? timeout = const Duration(seconds: 1),
|
||||
}) async {
|
||||
return await isPresent(finder).then((value) => !value);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> getText(
|
||||
Future<String?> getText(
|
||||
Finder finder, {
|
||||
Duration timeout = const Duration(seconds: 30),
|
||||
Duration? timeout = const Duration(seconds: 30),
|
||||
}) async {
|
||||
await waitForAppToSettle(timeout: timeout);
|
||||
|
||||
|
@ -102,7 +101,7 @@ class WidgetTesterAppDriverAdapter
|
|||
Future<void> enterText(
|
||||
Finder finder,
|
||||
String text, {
|
||||
Duration timeout = const Duration(seconds: 30),
|
||||
Duration? timeout = const Duration(seconds: 30),
|
||||
}) async {
|
||||
await tap(
|
||||
finder,
|
||||
|
@ -117,7 +116,7 @@ class WidgetTesterAppDriverAdapter
|
|||
@override
|
||||
Future<void> tap(
|
||||
Finder finder, {
|
||||
Duration timeout = const Duration(seconds: 30),
|
||||
Duration? timeout = const Duration(seconds: 30),
|
||||
}) async {
|
||||
await rawDriver.tap(finder);
|
||||
await waitForAppToSettle(timeout: timeout);
|
||||
|
@ -126,8 +125,8 @@ class WidgetTesterAppDriverAdapter
|
|||
@override
|
||||
Future<void> longPress(
|
||||
Finder finder, {
|
||||
Duration pressDuration = const Duration(milliseconds: 500),
|
||||
Duration timeout = const Duration(seconds: 30),
|
||||
Duration? pressDuration = const Duration(milliseconds: 500),
|
||||
Duration? timeout = const Duration(seconds: 30),
|
||||
}) async {
|
||||
await scroll(
|
||||
finder,
|
||||
|
@ -142,10 +141,10 @@ class WidgetTesterAppDriverAdapter
|
|||
@override
|
||||
Future<void> scroll(
|
||||
Finder finder, {
|
||||
double dx,
|
||||
double dy,
|
||||
Duration duration = const Duration(milliseconds: 200),
|
||||
Duration timeout = const Duration(seconds: 30),
|
||||
double? dx,
|
||||
double? dy,
|
||||
Duration? duration = const Duration(milliseconds: 200),
|
||||
Duration? timeout = const Duration(seconds: 30),
|
||||
}) async {
|
||||
final scrollableFinder = findByDescendant(
|
||||
finder,
|
||||
|
@ -154,7 +153,7 @@ class WidgetTesterAppDriverAdapter
|
|||
);
|
||||
final state = rawDriver.state(scrollableFinder) as ScrollableState;
|
||||
final position = state.position;
|
||||
position.jumpTo(dy ?? dx);
|
||||
position.jumpTo(dy ?? dx ?? 0);
|
||||
|
||||
await rawDriver.pump();
|
||||
}
|
||||
|
@ -174,8 +173,6 @@ class WidgetTesterAppDriverAdapter
|
|||
case FindType.type:
|
||||
return find.byType(data);
|
||||
}
|
||||
|
||||
throw Exception('unknown finder');
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -209,14 +206,14 @@ class WidgetTesterAppDriverAdapter
|
|||
@override
|
||||
Future<void> scrollUntilVisible(
|
||||
Finder item, {
|
||||
Finder scrollable,
|
||||
double dx,
|
||||
double dy,
|
||||
Duration timeout = const Duration(seconds: 30),
|
||||
Finder? scrollable,
|
||||
double? dx,
|
||||
double? dy,
|
||||
Duration? timeout = const Duration(seconds: 30),
|
||||
}) async {
|
||||
await rawDriver.scrollUntilVisible(
|
||||
item,
|
||||
dy ?? dx,
|
||||
dy ?? dx ?? 0,
|
||||
scrollable: scrollable,
|
||||
);
|
||||
}
|
||||
|
@ -224,7 +221,7 @@ class WidgetTesterAppDriverAdapter
|
|||
@override
|
||||
Future<void> scrollIntoView(
|
||||
Finder finder, {
|
||||
Duration timeout = const Duration(seconds: 30),
|
||||
Duration? timeout = const Duration(seconds: 30),
|
||||
}) async {
|
||||
await rawDriver.ensureVisible(finder);
|
||||
await waitForAppToSettle();
|
||||
|
|
|
@ -4,7 +4,7 @@ import 'package:gherkin/gherkin.dart';
|
|||
/// to the style required by the integration_test package
|
||||
class GherkinTestSuite {
|
||||
/// Path to the feature files to generate tests for
|
||||
final Iterable<String> featurePaths;
|
||||
final Iterable<Pattern> featurePaths;
|
||||
|
||||
/// The execution order of features - this default to random to avoid any inter-test dependencies
|
||||
final ExecutionOrder executionOrder;
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'package:analyzer/dart/element/element.dart';
|
|||
import 'package:flutter_gherkin/src/flutter/code_generation/annotations/gherkin_full_test_suite_annotation.dart';
|
||||
import 'package:gherkin/gherkin.dart';
|
||||
import 'package:glob/glob.dart';
|
||||
import 'package:glob/list_local_fs.dart';
|
||||
import 'package:source_gen/source_gen.dart';
|
||||
|
||||
class NoOpReporter extends Reporter {}
|
||||
|
@ -45,25 +46,25 @@ void executeTestSuite(
|
|||
_languageService.initialise(
|
||||
annotation.read('featureDefaultLanguage').literalValue.toString(),
|
||||
);
|
||||
final executionOrder = ExecutionOrder.values[annotation
|
||||
final idx = annotation
|
||||
.read('executionOrder')
|
||||
.objectValue
|
||||
.getField('index')
|
||||
.toIntValue()];
|
||||
.getField('index')!
|
||||
.toIntValue()!;
|
||||
final executionOrder = ExecutionOrder.values[idx];
|
||||
final featureFiles = annotation
|
||||
.read('featurePaths')
|
||||
.listValue
|
||||
.map((path) => Glob(path.toStringValue()))
|
||||
.map((path) => Glob(path.toStringValue()!))
|
||||
.map(
|
||||
(glob) => glob
|
||||
.listSync()
|
||||
(glob) => glob.listSync()
|
||||
.map((entity) => File(entity.path).readAsStringSync())
|
||||
.toList(),
|
||||
)
|
||||
.reduce((value, element) => value..addAll(element));
|
||||
|
||||
if (executionOrder == ExecutionOrder.random) {
|
||||
featureFiles..shuffle();
|
||||
featureFiles.shuffle();
|
||||
}
|
||||
|
||||
final featureExecutionFunctionsBuilder = StringBuffer();
|
||||
|
@ -146,9 +147,9 @@ class FeatureFileTestGeneratorVisitor extends FeatureFileVisitor {
|
|||
''';
|
||||
|
||||
final StringBuffer _buffer = StringBuffer();
|
||||
int _id;
|
||||
String _currentFeatureCode;
|
||||
String _currentScenarioCode;
|
||||
int? _id;
|
||||
String? _currentFeatureCode;
|
||||
String? _currentScenarioCode;
|
||||
final StringBuffer _scenarioBuffer = StringBuffer();
|
||||
final StringBuffer _stepBuffer = StringBuffer();
|
||||
|
||||
|
@ -176,18 +177,21 @@ class FeatureFileTestGeneratorVisitor extends FeatureFileVisitor {
|
|||
@override
|
||||
Future<void> visitFeature(
|
||||
String name,
|
||||
String description,
|
||||
String? description,
|
||||
Iterable<String> tags,
|
||||
) async {
|
||||
_currentFeatureCode =
|
||||
_replaceVariable(FUNCTION_TEMPLATE, 'feature_number', _id.toString());
|
||||
_currentFeatureCode = _replaceVariable(
|
||||
_currentFeatureCode,
|
||||
FUNCTION_TEMPLATE,
|
||||
'feature_number',
|
||||
_id.toString(),
|
||||
);
|
||||
_currentFeatureCode = _replaceVariable(
|
||||
_currentFeatureCode!,
|
||||
'feature_name',
|
||||
_escapeText(name),
|
||||
);
|
||||
_currentFeatureCode = _replaceVariable(
|
||||
_currentFeatureCode,
|
||||
_currentFeatureCode!,
|
||||
'tags',
|
||||
'<String>[${tags.map((e) => "'$e'").join(', ')}]',
|
||||
);
|
||||
|
@ -202,7 +206,7 @@ class FeatureFileTestGeneratorVisitor extends FeatureFileVisitor {
|
|||
_escapeText(name),
|
||||
);
|
||||
_currentScenarioCode = _replaceVariable(
|
||||
_currentScenarioCode,
|
||||
_currentScenarioCode!,
|
||||
'tags',
|
||||
'<String>[${tags.map((e) => "'$e'").join(', ')}]',
|
||||
);
|
||||
|
@ -212,7 +216,7 @@ class FeatureFileTestGeneratorVisitor extends FeatureFileVisitor {
|
|||
Future<void> visitScenarioStep(
|
||||
String name,
|
||||
Iterable<String> multiLineStrings,
|
||||
GherkinTable table,
|
||||
GherkinTable? table,
|
||||
) async {
|
||||
var code = _replaceVariable(
|
||||
STEP_TEMPLATE,
|
||||
|
@ -236,7 +240,7 @@ class FeatureFileTestGeneratorVisitor extends FeatureFileVisitor {
|
|||
void _flushFeature() {
|
||||
if (_currentFeatureCode != null) {
|
||||
_currentFeatureCode = _replaceVariable(
|
||||
_currentFeatureCode,
|
||||
_currentFeatureCode!,
|
||||
'scenarios',
|
||||
_scenarioBuffer.toString(),
|
||||
);
|
||||
|
@ -252,7 +256,7 @@ class FeatureFileTestGeneratorVisitor extends FeatureFileVisitor {
|
|||
if (_currentScenarioCode != null) {
|
||||
if (_stepBuffer.isNotEmpty) {
|
||||
_currentScenarioCode = _replaceVariable(
|
||||
_currentScenarioCode,
|
||||
_currentScenarioCode!,
|
||||
'steps',
|
||||
_stepBuffer.toString(),
|
||||
);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'package:flutter_gherkin/flutter_gherkin.dart';
|
||||
import 'package:flutter_gherkin/flutter_gherkin_with_driver.dart';
|
||||
import 'package:flutter_gherkin/src/flutter/configuration/build_mode.dart';
|
||||
import 'package:flutter_gherkin/src/flutter/world/flutter_driver_world.dart';
|
||||
import 'package:flutter_gherkin/src/flutter/world/flutter_world.dart';
|
||||
|
@ -12,7 +12,7 @@ import 'package:glob/glob.dart';
|
|||
import 'flutter_test_configuration.dart';
|
||||
|
||||
class FlutterDriverTestConfiguration extends FlutterTestConfiguration {
|
||||
String _observatoryDebuggerUri;
|
||||
String? _observatoryDebuggerUri;
|
||||
|
||||
/// Provide a configuration object with default settings such as the reports and feature file location
|
||||
/// Additional setting on the configuration object can be set on the returned instance.
|
||||
|
@ -36,8 +36,7 @@ class FlutterDriverTestConfiguration extends FlutterTestConfiguration {
|
|||
]
|
||||
..targetAppPath = targetAppPath
|
||||
..stepDefinitions = steps
|
||||
..restartAppBetweenScenarios = true
|
||||
..exitAfterTestRun = true;
|
||||
..restartAppBetweenScenarios = true;
|
||||
}
|
||||
|
||||
/// restarts the application under test between each scenario.
|
||||
|
@ -51,11 +50,11 @@ class FlutterDriverTestConfiguration extends FlutterTestConfiguration {
|
|||
|
||||
/// Option to define the working directory for the process that runs the app under test (optional)
|
||||
/// Handy if your app is separated from your tests as flutter needs to be able to find a pubspec file
|
||||
String targetAppWorkingDirectory;
|
||||
String? targetAppWorkingDirectory;
|
||||
|
||||
/// The build flavor to run the tests against (optional)
|
||||
/// Defaults to empty
|
||||
String buildFlavor = '';
|
||||
/// Defaults to null
|
||||
String? buildFlavor;
|
||||
|
||||
/// The default build mode used for running tests is --debug.
|
||||
/// We are exposing the option to run the tests also in --profile mode
|
||||
|
@ -66,8 +65,8 @@ class FlutterDriverTestConfiguration extends FlutterTestConfiguration {
|
|||
bool build = true;
|
||||
|
||||
/// The target device id to run the tests against when multiple devices detected
|
||||
/// Defaults to empty
|
||||
String targetDeviceId = '';
|
||||
/// Defaults to null
|
||||
String? targetDeviceId;
|
||||
|
||||
/// Will keep the Flutter application running when done testing
|
||||
/// Defaults to false
|
||||
|
@ -100,19 +99,19 @@ class FlutterDriverTestConfiguration extends FlutterTestConfiguration {
|
|||
/// An observatory url that the test runner can connect to instead of creating a new running instance of the target application
|
||||
/// Url takes the form of `http://127.0.0.1:51540/EM72VtRsUV0=/` and usually printed to stdout in the form `Connecting to service protocol: http://127.0.0.1:51540/EM72VtRsUV0=/`
|
||||
/// You will have to add the `--verbose` flag to the command to start your flutter app to see this output and ensure `enableFlutterDriverExtension()` is called by the running app
|
||||
String runningAppProtocolEndpointUri;
|
||||
String? runningAppProtocolEndpointUri;
|
||||
|
||||
/// Called before any attempt to connect Flutter driver to the running application, Depending on your configuration this
|
||||
/// method will be called before each scenario is run.
|
||||
Future<void> Function() onBeforeFlutterDriverConnect;
|
||||
Future<void> Function()? onBeforeFlutterDriverConnect;
|
||||
|
||||
/// Called after the successful connection of Flutter driver to the running application. Depending on your configuration this
|
||||
/// method will be called on each new connection usually before each scenario is run.
|
||||
Future<void> Function(FlutterDriver driver) onAfterFlutterDriverConnect;
|
||||
Future<void> Function(FlutterDriver driver)? onAfterFlutterDriverConnect;
|
||||
|
||||
void setObservatoryDebuggerUri(String uri) => _observatoryDebuggerUri = uri;
|
||||
|
||||
Future<FlutterDriver> createFlutterDriver([String dartVmServiceUrl]) async {
|
||||
Future<FlutterDriver> createFlutterDriver([String? dartVmServiceUrl]) async {
|
||||
final completer = Completer<FlutterDriver>();
|
||||
dartVmServiceUrl = (dartVmServiceUrl ?? _observatoryDebuggerUri) ??
|
||||
Platform.environment['VM_SERVICE_URL'];
|
||||
|
@ -120,12 +119,12 @@ class FlutterDriverTestConfiguration extends FlutterTestConfiguration {
|
|||
await runZonedGuarded(
|
||||
() async {
|
||||
if (onBeforeFlutterDriverConnect != null) {
|
||||
await onBeforeFlutterDriverConnect();
|
||||
await onBeforeFlutterDriverConnect!();
|
||||
}
|
||||
|
||||
final driver = await _attemptDriverConnection(dartVmServiceUrl, 1, 3);
|
||||
if (onAfterFlutterDriverConnect != null) {
|
||||
await onAfterFlutterDriverConnect(driver);
|
||||
await onAfterFlutterDriverConnect!(driver);
|
||||
}
|
||||
|
||||
completer.complete(driver);
|
||||
|
@ -142,14 +141,15 @@ class FlutterDriverTestConfiguration extends FlutterTestConfiguration {
|
|||
|
||||
Future<FlutterWorld> createFlutterWorld(
|
||||
TestConfiguration config,
|
||||
FlutterWorld world,
|
||||
FlutterWorld? world,
|
||||
) async {
|
||||
var flutterConfig = config as FlutterDriverTestConfiguration;
|
||||
world = world ?? FlutterDriverWorld();
|
||||
|
||||
final driver = await createFlutterDriver(
|
||||
flutterConfig.runningAppProtocolEndpointUri != null &&
|
||||
flutterConfig.runningAppProtocolEndpointUri.isNotEmpty
|
||||
flutterConfig.runningAppProtocolEndpointUri != null &&
|
||||
flutterConfig.runningAppProtocolEndpointUri!.isNotEmpty
|
||||
? flutterConfig.runningAppProtocolEndpointUri
|
||||
: null,
|
||||
);
|
||||
|
@ -165,19 +165,19 @@ class FlutterDriverTestConfiguration extends FlutterTestConfiguration {
|
|||
_ensureCorrectConfiguration();
|
||||
final providedCreateWorld = createWorld;
|
||||
createWorld = (config) async {
|
||||
FlutterWorld world;
|
||||
FlutterWorld? world;
|
||||
if (providedCreateWorld != null) {
|
||||
world = await providedCreateWorld(config);
|
||||
world = await providedCreateWorld(config) as FlutterWorld;
|
||||
}
|
||||
|
||||
return await createFlutterWorld(config, world);
|
||||
};
|
||||
|
||||
hooks = List.from(hooks ?? [])..add(FlutterAppRunnerHook());
|
||||
hooks = List.from(hooks ?? Iterable.empty())..add(FlutterAppRunnerHook());
|
||||
}
|
||||
|
||||
Future<FlutterDriver> _attemptDriverConnection(
|
||||
String dartVmServiceUrl,
|
||||
String? dartVmServiceUrl,
|
||||
int attempt,
|
||||
int maxAttempts,
|
||||
) async {
|
||||
|
@ -189,7 +189,8 @@ class FlutterDriverTestConfiguration extends FlutterTestConfiguration {
|
|||
throw e;
|
||||
} else {
|
||||
print(
|
||||
'Fluter driver error connecting to application at `$dartVmServiceUrl`, retrying after delay of $flutterDriverReconnectionDelay',
|
||||
'Fluter driver error connecting to application at `$dartVmServiceUrl`,'
|
||||
'retrying after delay of $flutterDriverReconnectionDelay',
|
||||
);
|
||||
await Future<void>.delayed(flutterDriverReconnectionDelay);
|
||||
|
||||
|
@ -205,15 +206,17 @@ class FlutterDriverTestConfiguration extends FlutterTestConfiguration {
|
|||
|
||||
void _ensureCorrectConfiguration() {
|
||||
if (runningAppProtocolEndpointUri != null &&
|
||||
runningAppProtocolEndpointUri.isNotEmpty) {
|
||||
runningAppProtocolEndpointUri!.isNotEmpty) {
|
||||
if (restartAppBetweenScenarios) {
|
||||
throw AssertionError(
|
||||
'Cannot restart app between scenarios if using runningAppProtocolEndpointUri');
|
||||
'Cannot restart app between scenarios if using runningAppProtocolEndpointUri',
|
||||
);
|
||||
}
|
||||
|
||||
if (targetDeviceId != null && targetDeviceId.isNotEmpty) {
|
||||
if (targetDeviceId != null && targetDeviceId!.isNotEmpty) {
|
||||
throw AssertionError(
|
||||
'Cannot target specific device id if using runningAppProtocolEndpointUri');
|
||||
'Cannot target specific device id if using runningAppProtocolEndpointUri',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import 'package:flutter_gherkin/flutter_gherkin.dart';
|
||||
import 'package:flutter_gherkin/flutter_gherkin_with_driver.dart';
|
||||
import 'package:flutter_gherkin/src/flutter/parameters/existence_parameter.dart';
|
||||
import 'package:flutter_gherkin/src/flutter/parameters/swipe_direction_parameter.dart';
|
||||
import 'package:flutter_gherkin/src/flutter/steps/given_i_open_the_drawer_step.dart';
|
||||
|
@ -45,12 +45,12 @@ class FlutterTestConfiguration extends TestConfiguration {
|
|||
@override
|
||||
void prepare() {
|
||||
customStepParameterDefinitions =
|
||||
List.from(customStepParameterDefinitions ?? [])
|
||||
List.from(customStepParameterDefinitions ?? Iterable.empty())
|
||||
..addAll([
|
||||
ExistenceParameter(),
|
||||
SwipeDirectionParameter(),
|
||||
]);
|
||||
stepDefinitions = List.from(stepDefinitions ?? [])
|
||||
stepDefinitions = List.from(stepDefinitions ?? Iterable.empty())
|
||||
..addAll([
|
||||
ThenExpectElementToHaveValue(),
|
||||
WhenTapBackButtonWidget(),
|
||||
|
|
|
@ -7,7 +7,7 @@ import 'package:gherkin/gherkin.dart';
|
|||
/// A hook that manages running the target flutter application
|
||||
/// that is under test
|
||||
class FlutterAppRunnerHook extends Hook {
|
||||
FlutterRunProcessHandler _flutterRunProcessHandler;
|
||||
FlutterRunProcessHandler? _flutterRunProcessHandler;
|
||||
bool haveRunFirstScenario = false;
|
||||
|
||||
@override
|
||||
|
@ -55,17 +55,18 @@ class FlutterAppRunnerHook extends Hook {
|
|||
Iterable<Tag> tags,
|
||||
) async {
|
||||
if (world is FlutterDriverWorld) {
|
||||
world.setFlutterProcessHandler(_flutterRunProcessHandler);
|
||||
world.setFlutterProcessHandler(_flutterRunProcessHandler!);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _runApp(FlutterDriverTestConfiguration config) async {
|
||||
if (config.runningAppProtocolEndpointUri != null &&
|
||||
config.runningAppProtocolEndpointUri.isNotEmpty) {
|
||||
config.runningAppProtocolEndpointUri!.isNotEmpty) {
|
||||
stdout.writeln(
|
||||
"Connecting to running Flutter app under test at '${config.runningAppProtocolEndpointUri}', this might take a few moments",
|
||||
"Connecting to running Flutter app under test at '${config.runningAppProtocolEndpointUri}', "
|
||||
'this might take a few moments',
|
||||
);
|
||||
config.setObservatoryDebuggerUri(config.runningAppProtocolEndpointUri);
|
||||
config.setObservatoryDebuggerUri(config.runningAppProtocolEndpointUri!);
|
||||
} else {
|
||||
_flutterRunProcessHandler = FlutterRunProcessHandler()
|
||||
..setLogFlutterProcessOutput(config.logFlutterProcessOutput)
|
||||
|
@ -81,8 +82,8 @@ class FlutterAppRunnerHook extends Hook {
|
|||
|
||||
stdout.writeln(
|
||||
"Starting Flutter app under test '${config.targetAppPath}', this might take a few moments");
|
||||
await _flutterRunProcessHandler.run();
|
||||
final observatoryUri = await _flutterRunProcessHandler
|
||||
await _flutterRunProcessHandler!.run();
|
||||
final observatoryUri = await _flutterRunProcessHandler!
|
||||
.waitForObservatoryDebuggerUri(config.flutterBuildTimeout);
|
||||
config.setObservatoryDebuggerUri(observatoryUri);
|
||||
}
|
||||
|
@ -91,7 +92,7 @@ class FlutterAppRunnerHook extends Hook {
|
|||
Future<void> _terminateApp() async {
|
||||
if (_flutterRunProcessHandler != null) {
|
||||
stdout.writeln('Terminating Flutter app under test');
|
||||
await _flutterRunProcessHandler.terminate();
|
||||
await _flutterRunProcessHandler!.terminate();
|
||||
_flutterRunProcessHandler = null;
|
||||
}
|
||||
}
|
||||
|
@ -99,7 +100,7 @@ class FlutterAppRunnerHook extends Hook {
|
|||
Future<void> _restartApp() async {
|
||||
if (_flutterRunProcessHandler != null) {
|
||||
stdout.writeln('Restarting Flutter app under test');
|
||||
await _flutterRunProcessHandler.restart();
|
||||
await _flutterRunProcessHandler!.restart();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ class FlutterDriverReporter extends Reporter {
|
|||
|
||||
@override
|
||||
Future<void> dispose() async {
|
||||
driverLog = null;
|
||||
// driverLog = null;
|
||||
}
|
||||
|
||||
void _driverLogMessageHandler(String source, String message) {
|
||||
|
|
|
@ -41,20 +41,20 @@ class FlutterRunProcessHandler extends ProcessHandler {
|
|||
multiLine: false,
|
||||
);
|
||||
|
||||
Process _runningProcess;
|
||||
Stream<String> _processStdoutStream;
|
||||
Process? _runningProcess;
|
||||
Stream<String>? _processStdoutStream;
|
||||
final List<StreamSubscription> _openSubscriptions = <StreamSubscription>[];
|
||||
bool _buildApp = true;
|
||||
bool _logFlutterProcessOutput = false;
|
||||
bool _verboseFlutterLogs = false;
|
||||
bool _keepAppRunning = false;
|
||||
BuildMode _buildMode = BuildMode.Debug;
|
||||
String _workingDirectory;
|
||||
String _appTarget;
|
||||
String _buildFlavor;
|
||||
String _deviceTargetId;
|
||||
String? _workingDirectory;
|
||||
String? _appTarget;
|
||||
String? _buildFlavor;
|
||||
String? _deviceTargetId;
|
||||
Duration _driverConnectionDelay = const Duration(seconds: 2);
|
||||
String currentObservatoryUri;
|
||||
String? currentObservatoryUri;
|
||||
|
||||
void setLogFlutterProcessOutput(bool logFlutterProcessOutput) {
|
||||
_logFlutterProcessOutput = logFlutterProcessOutput;
|
||||
|
@ -64,15 +64,15 @@ class FlutterRunProcessHandler extends ProcessHandler {
|
|||
_appTarget = targetPath;
|
||||
}
|
||||
|
||||
void setDriverConnectionDelay(Duration duration) {
|
||||
void setDriverConnectionDelay(Duration? duration) {
|
||||
_driverConnectionDelay = duration ?? _driverConnectionDelay;
|
||||
}
|
||||
|
||||
void setWorkingDirectory(String workingDirectory) {
|
||||
void setWorkingDirectory(String? workingDirectory) {
|
||||
_workingDirectory = workingDirectory;
|
||||
}
|
||||
|
||||
void setBuildFlavor(String buildFlavor) {
|
||||
void setBuildFlavor(String? buildFlavor) {
|
||||
_buildFlavor = buildFlavor;
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ class FlutterRunProcessHandler extends ProcessHandler {
|
|||
_buildMode = buildMode;
|
||||
}
|
||||
|
||||
void setDeviceTargetId(String deviceTargetId) {
|
||||
void setDeviceTargetId(String? deviceTargetId) {
|
||||
_deviceTargetId = deviceTargetId;
|
||||
}
|
||||
|
||||
|
@ -110,11 +110,11 @@ class FlutterRunProcessHandler extends ProcessHandler {
|
|||
arguments.add('--no-build');
|
||||
}
|
||||
|
||||
if (_buildFlavor != null && _buildFlavor.isNotEmpty) {
|
||||
if (_buildFlavor != null && _buildFlavor!.isNotEmpty) {
|
||||
arguments.add('--flavor=$_buildFlavor');
|
||||
}
|
||||
|
||||
if (_deviceTargetId != null && _deviceTargetId.isNotEmpty) {
|
||||
if (_deviceTargetId != null && _deviceTargetId!.isNotEmpty) {
|
||||
arguments.add('--device-id=$_deviceTargetId');
|
||||
}
|
||||
|
||||
|
@ -140,16 +140,16 @@ class FlutterRunProcessHandler extends ProcessHandler {
|
|||
);
|
||||
|
||||
_processStdoutStream =
|
||||
_runningProcess.stdout.transform(utf8.decoder).asBroadcastStream();
|
||||
_runningProcess!.stdout.transform(utf8.decoder).asBroadcastStream();
|
||||
|
||||
_openSubscriptions.add(_runningProcess.stderr
|
||||
_openSubscriptions.add(_runningProcess!.stderr
|
||||
.map((events) => String.fromCharCodes(events).trim())
|
||||
.where((event) => event.isNotEmpty)
|
||||
.listen((event) {
|
||||
if (event.contains(_errorMessageRegex)) {
|
||||
stderr.writeln('${FAIL_COLOR}Flutter build error: $event$RESET_COLOR');
|
||||
} else {
|
||||
// This is most likely a depricated api usage warnings (from Gradle) and should not
|
||||
// This is most likely a deprecated api usage warnings (from Gradle) and should not
|
||||
// cause the test run to fail.
|
||||
stdout.writeln('$WARN_COLOR$event$RESET_COLOR');
|
||||
}
|
||||
|
@ -161,19 +161,21 @@ class FlutterRunProcessHandler extends ProcessHandler {
|
|||
var exitCode = -1;
|
||||
_ensureRunningProcess();
|
||||
if (_runningProcess != null) {
|
||||
_runningProcess.stdin.write('q');
|
||||
_runningProcess!.stdin.write('q');
|
||||
_openSubscriptions.forEach((s) => s.cancel());
|
||||
_openSubscriptions.clear();
|
||||
exitCode = await _runningProcess.exitCode;
|
||||
exitCode = await _runningProcess!.exitCode;
|
||||
_runningProcess = null;
|
||||
}
|
||||
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
Future<bool> restart({Duration timeout = const Duration(seconds: 90)}) async {
|
||||
Future<bool> restart({
|
||||
Duration? timeout = const Duration(seconds: 90),
|
||||
}) async {
|
||||
_ensureRunningProcess();
|
||||
_runningProcess.stdin.write('R');
|
||||
_runningProcess!.stdin.write('R');
|
||||
await _waitForStdOutMessage(
|
||||
_restartedApplicationSuccessRegex,
|
||||
'Timeout waiting for app restart',
|
||||
|
@ -196,18 +198,18 @@ class FlutterRunProcessHandler extends ProcessHandler {
|
|||
timeout,
|
||||
);
|
||||
|
||||
return currentObservatoryUri;
|
||||
return currentObservatoryUri!;
|
||||
}
|
||||
|
||||
Future<String> _waitForStdOutMessage(
|
||||
RegExp matcher,
|
||||
String timeoutMessage, [
|
||||
Duration timeout = const Duration(seconds: 90),
|
||||
Duration? timeout = const Duration(seconds: 90),
|
||||
]) {
|
||||
_ensureRunningProcess();
|
||||
final completer = Completer<String>();
|
||||
StreamSubscription sub;
|
||||
sub = _processStdoutStream.timeout(
|
||||
StreamSubscription? sub;
|
||||
sub = _processStdoutStream!.timeout(
|
||||
timeout ?? const Duration(seconds: 90),
|
||||
onTimeout: (_) {
|
||||
sub?.cancel();
|
||||
|
@ -223,7 +225,7 @@ class FlutterRunProcessHandler extends ProcessHandler {
|
|||
if (matcher.hasMatch(logLine)) {
|
||||
sub?.cancel();
|
||||
if (!completer.isCompleted) {
|
||||
completer.complete(matcher.firstMatch(logLine).group(1));
|
||||
completer.complete(matcher.firstMatch(logLine)!.group(1));
|
||||
}
|
||||
} else if (_noConnectedDeviceRegex.hasMatch(logLine)) {
|
||||
sub?.cancel();
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import 'package:flutter_gherkin/flutter_gherkin_integration_test.dart';
|
||||
import 'package:flutter_gherkin/flutter_gherkin.dart';
|
||||
import 'package:flutter_gherkin/src/flutter/adapters/widget_tester_app_driver_adapter.dart';
|
||||
import 'package:flutter_gherkin/src/flutter/world/flutter_world.dart';
|
||||
import 'package:gherkin/gherkin.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
class TestDependencies {
|
||||
final World world;
|
||||
|
@ -21,15 +22,15 @@ abstract class GherkinIntegrationTestRunner {
|
|||
TagExpressionEvaluator();
|
||||
final TestConfiguration configuration;
|
||||
final void Function(World world) appMainFunction;
|
||||
Reporter _reporter;
|
||||
Hook _hook;
|
||||
Iterable<ExecutableStep> _executableSteps;
|
||||
Iterable<CustomParameter> _customParameters;
|
||||
Reporter? _reporter;
|
||||
Hook? _hook;
|
||||
Iterable<ExecutableStep>? _executableSteps;
|
||||
Iterable<CustomParameter>? _customParameters;
|
||||
|
||||
IntegrationTestWidgetsFlutterBinding _binding;
|
||||
IntegrationTestWidgetsFlutterBinding? _binding;
|
||||
|
||||
Reporter get reporter => _reporter;
|
||||
Hook get hook => _hook;
|
||||
Reporter get reporter => _reporter!;
|
||||
Hook get hook => _hook!;
|
||||
|
||||
Timeout scenarioExecutionTimeout = const Timeout(Duration(minutes: 10));
|
||||
|
||||
|
@ -43,8 +44,8 @@ abstract class GherkinIntegrationTestRunner {
|
|||
_customParameters =
|
||||
_registerCustomParameters(configuration.customStepParameterDefinitions);
|
||||
_executableSteps = _registerStepDefinitions(
|
||||
configuration.stepDefinitions,
|
||||
_customParameters,
|
||||
configuration.stepDefinitions!,
|
||||
_customParameters!,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -68,7 +69,7 @@ abstract class GherkinIntegrationTestRunner {
|
|||
void onRunComplete() {
|
||||
_safeInvokeFuture(() async => await reporter.onTestRunFinished());
|
||||
_safeInvokeFuture(() async => await hook.onAfterRun(configuration));
|
||||
setTestResultData(_binding);
|
||||
setTestResultData(_binding!);
|
||||
_safeInvokeFuture(() async => await reporter.dispose());
|
||||
}
|
||||
|
||||
|
@ -82,7 +83,7 @@ abstract class GherkinIntegrationTestRunner {
|
|||
@protected
|
||||
void runFeature(
|
||||
String name,
|
||||
Iterable<String> tags,
|
||||
Iterable<String>? tags,
|
||||
void Function() runFeature,
|
||||
) {
|
||||
group(
|
||||
|
@ -90,7 +91,7 @@ abstract class GherkinIntegrationTestRunner {
|
|||
() {
|
||||
final debugInformation = RunnableDebugInformation('', 0, name);
|
||||
final featureTags =
|
||||
(tags ?? Iterable<Tag>.empty()).map((t) => Tag(t, 0));
|
||||
(tags ?? Iterable<Tag>.empty()).map((t) => Tag(t.toString(), 0));
|
||||
_safeInvokeFuture(
|
||||
() async => await reporter.onFeatureStarted(
|
||||
StartedMessage(
|
||||
|
@ -120,7 +121,7 @@ abstract class GherkinIntegrationTestRunner {
|
|||
@protected
|
||||
void runScenario(
|
||||
String name,
|
||||
Iterable<String> tags,
|
||||
Iterable<String>? tags,
|
||||
Future<void> Function(TestDependencies dependencies) runTest,
|
||||
) {
|
||||
if (_evaluateTagFilterExpression(configuration.tagExpression, tags)) {
|
||||
|
@ -129,13 +130,13 @@ abstract class GherkinIntegrationTestRunner {
|
|||
(WidgetTester tester) async {
|
||||
final debugInformation = RunnableDebugInformation('', 0, name);
|
||||
final scenarioTags =
|
||||
(tags ?? Iterable<Tag>.empty()).map((t) => Tag(t, 0));
|
||||
(tags ?? Iterable<Tag>.empty()).map((t) => Tag(t.toString(), 0));
|
||||
final dependencies = await createTestDependencies(
|
||||
configuration,
|
||||
tester,
|
||||
);
|
||||
|
||||
await _hook.onBeforeScenario(
|
||||
await hook.onBeforeScenario(
|
||||
configuration,
|
||||
name,
|
||||
scenarioTags,
|
||||
|
@ -146,7 +147,7 @@ abstract class GherkinIntegrationTestRunner {
|
|||
dependencies.world,
|
||||
);
|
||||
|
||||
await _hook.onAfterScenarioWorldCreated(
|
||||
await hook.onAfterScenarioWorldCreated(
|
||||
dependencies.world,
|
||||
name,
|
||||
scenarioTags,
|
||||
|
@ -163,7 +164,7 @@ abstract class GherkinIntegrationTestRunner {
|
|||
|
||||
await runTest(dependencies);
|
||||
|
||||
await _reporter.onScenarioFinished(
|
||||
await reporter.onScenarioFinished(
|
||||
ScenarioFinishedMessage(
|
||||
name,
|
||||
debugInformation,
|
||||
|
@ -171,7 +172,7 @@ abstract class GherkinIntegrationTestRunner {
|
|||
),
|
||||
);
|
||||
|
||||
await _hook.onAfterScenario(
|
||||
await hook.onAfterScenario(
|
||||
configuration,
|
||||
name,
|
||||
scenarioTags,
|
||||
|
@ -184,7 +185,7 @@ abstract class GherkinIntegrationTestRunner {
|
|||
} else {
|
||||
_safeInvokeFuture(
|
||||
() async => reporter.message(
|
||||
'Ignoring scenario `${name}` as tag expression `${configuration.tagExpression}` not satisfied',
|
||||
'Ignoring scenario `$name` as tag expression `${configuration.tagExpression}` not satisfied',
|
||||
MessageLevel.info,
|
||||
),
|
||||
);
|
||||
|
@ -205,12 +206,12 @@ abstract class GherkinIntegrationTestRunner {
|
|||
TestConfiguration configuration,
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
World world;
|
||||
World? world;
|
||||
final attachmentManager =
|
||||
await configuration.getAttachmentManager(configuration);
|
||||
|
||||
if (configuration.createWorld != null) {
|
||||
world = await configuration.createWorld(configuration);
|
||||
world = await configuration.createWorld!(configuration);
|
||||
}
|
||||
|
||||
world = world ?? FlutterWidgetTesterWorld();
|
||||
|
@ -231,9 +232,8 @@ abstract class GherkinIntegrationTestRunner {
|
|||
dynamic table,
|
||||
TestDependencies dependencies,
|
||||
) async {
|
||||
final executable = _executableSteps.firstWhere(
|
||||
final executable = _executableSteps!.firstWhereOrNull(
|
||||
(s) => s.expression.isMatch(step),
|
||||
orElse: () => null,
|
||||
);
|
||||
|
||||
if (executable == null) {
|
||||
|
@ -280,11 +280,14 @@ abstract class GherkinIntegrationTestRunner {
|
|||
@protected
|
||||
void cleanupScenarioRun(TestDependencies dependencies) {
|
||||
_safeInvokeFuture(
|
||||
() async => await dependencies.attachmentManager.dispose());
|
||||
_safeInvokeFuture(() async => await dependencies.world.dispose());
|
||||
() async => dependencies.attachmentManager.dispose(),
|
||||
);
|
||||
_safeInvokeFuture(
|
||||
() async => dependencies.world.dispose(),
|
||||
);
|
||||
}
|
||||
|
||||
Reporter _registerReporters(Iterable<Reporter> reporters) {
|
||||
Reporter _registerReporters(Iterable<Reporter>? reporters) {
|
||||
final reporter = AggregatedReporter();
|
||||
if (reporters != null) {
|
||||
reporters.forEach((r) => reporter.addReporter(r));
|
||||
|
@ -293,7 +296,7 @@ abstract class GherkinIntegrationTestRunner {
|
|||
return reporter;
|
||||
}
|
||||
|
||||
Hook _registerHooks(Iterable<Hook> hooks) {
|
||||
Hook _registerHooks(Iterable<Hook>? hooks) {
|
||||
final hook = AggregatedHook();
|
||||
if (hooks != null) {
|
||||
hook.addHooks(hooks);
|
||||
|
@ -303,7 +306,7 @@ abstract class GherkinIntegrationTestRunner {
|
|||
}
|
||||
|
||||
Iterable<CustomParameter> _registerCustomParameters(
|
||||
Iterable<CustomParameter> customParameters,
|
||||
Iterable<CustomParameter>? customParameters,
|
||||
) {
|
||||
final parameters = <CustomParameter>[];
|
||||
|
||||
|
@ -332,7 +335,7 @@ abstract class GherkinIntegrationTestRunner {
|
|||
return stepDefinitions
|
||||
.map(
|
||||
(s) => ExecutableStep(
|
||||
GherkinExpression(s.pattern, customParameters),
|
||||
GherkinExpression(s.pattern as RegExp, customParameters),
|
||||
s,
|
||||
),
|
||||
)
|
||||
|
@ -362,12 +365,13 @@ abstract class GherkinIntegrationTestRunner {
|
|||
StepResult result,
|
||||
TestDependencies dependencies,
|
||||
) async {
|
||||
await _hook.onAfterStep(
|
||||
await hook.onAfterStep(
|
||||
dependencies.world,
|
||||
step,
|
||||
result,
|
||||
);
|
||||
await _reporter.onStepFinished(
|
||||
|
||||
await reporter.onStepFinished(
|
||||
StepFinishedMessage(
|
||||
step,
|
||||
RunnableDebugInformation('', 0, step),
|
||||
|
@ -383,7 +387,7 @@ abstract class GherkinIntegrationTestRunner {
|
|||
table,
|
||||
Iterable<String> multiLineStrings,
|
||||
) async {
|
||||
await _hook.onBeforeStep(world, step);
|
||||
await hook.onBeforeStep(world, step);
|
||||
await reporter.onStepStarted(
|
||||
StepStartedMessage(
|
||||
step,
|
||||
|
@ -402,11 +406,11 @@ abstract class GherkinIntegrationTestRunner {
|
|||
}
|
||||
|
||||
bool _evaluateTagFilterExpression(
|
||||
String tagExpression,
|
||||
List<String> tags,
|
||||
String? tagExpression,
|
||||
Iterable<String>? tags,
|
||||
) {
|
||||
return tagExpression == null || tagExpression.isEmpty
|
||||
? true
|
||||
: _tagExpressionEvaluator.evaluate(tagExpression, tags);
|
||||
: _tagExpressionEvaluator.evaluate(tagExpression, tags!.toList());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ StepDefinitionGeneric GivenOpenDrawer() {
|
|||
'Open navigation menu',
|
||||
FindType.tooltip,
|
||||
),
|
||||
timeout: context.configuration?.timeout,
|
||||
timeout: context.configuration.timeout,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ StepDefinitionGeneric RestartAppStep() {
|
|||
'I restart the app',
|
||||
(context) async {
|
||||
await context.world.restartApp(
|
||||
timeout: context.configuration?.timeout,
|
||||
timeout: context.configuration.timeout,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
|
|
@ -31,7 +31,7 @@ StepDefinitionGeneric SiblingContainsTextStep() {
|
|||
|
||||
final isPresent = await context.world.appDriver.isPresent(
|
||||
valueWidget,
|
||||
timeout: context.configuration?.timeout ?? const Duration(seconds: 20),
|
||||
timeout: context.configuration.timeout ?? const Duration(seconds: 20),
|
||||
);
|
||||
|
||||
context.expect(isPresent, true);
|
||||
|
|
|
@ -14,7 +14,7 @@ StepDefinitionGeneric TapTextWithinWidgetStep() {
|
|||
r'I tap the (?:button|element|label|field|text|widget) that contains the text {string} within the {string}'),
|
||||
(text, ancestorKey, context) async {
|
||||
final timeout =
|
||||
context.configuration?.timeout ?? const Duration(seconds: 20);
|
||||
context.configuration.timeout ?? const Duration(seconds: 20);
|
||||
final finder = context.world.appDriver.findByDescendant(
|
||||
context.world.appDriver.findBy(ancestorKey, FindType.key),
|
||||
context.world.appDriver.findBy(text, FindType.text),
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import 'package:flutter_driver/flutter_driver.dart';
|
||||
import 'package:flutter_gherkin/flutter_gherkin.dart';
|
||||
import 'package:flutter_gherkin/flutter_gherkin_with_driver.dart';
|
||||
|
||||
import '../runners/flutter_run_process_handler.dart';
|
||||
|
||||
/// Driver version of the FlutterWorld with a typed driver
|
||||
class FlutterDriverWorld extends FlutterTypedAdapterWorld<FlutterDriver,
|
||||
SerializableFinder, dynamic> {
|
||||
FlutterRunProcessHandler _flutterRunProcessHandler;
|
||||
FlutterRunProcessHandler? _flutterRunProcessHandler;
|
||||
|
||||
void setFlutterDriver(FlutterDriver flutterDriver) {
|
||||
setAppAdapter(FlutterDriverAppDriverAdapter(flutterDriver));
|
||||
|
@ -20,7 +20,7 @@ class FlutterDriverWorld extends FlutterTypedAdapterWorld<FlutterDriver,
|
|||
|
||||
@override
|
||||
Future<bool> restartApp({
|
||||
Duration timeout = const Duration(seconds: 60),
|
||||
Duration? timeout = const Duration(seconds: 60),
|
||||
}) async {
|
||||
await _closeDriver(timeout: timeout);
|
||||
final result = await _flutterRunProcessHandler?.restart(
|
||||
|
@ -28,12 +28,12 @@ class FlutterDriverWorld extends FlutterTypedAdapterWorld<FlutterDriver,
|
|||
);
|
||||
|
||||
final driver = await FlutterDriver.connect(
|
||||
dartVmServiceUrl: _flutterRunProcessHandler.currentObservatoryUri,
|
||||
dartVmServiceUrl: _flutterRunProcessHandler!.currentObservatoryUri,
|
||||
);
|
||||
|
||||
setFlutterDriver(driver);
|
||||
|
||||
return result;
|
||||
return result!;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -45,8 +45,9 @@ class FlutterDriverWorld extends FlutterTypedAdapterWorld<FlutterDriver,
|
|||
}
|
||||
|
||||
Future<void> _closeDriver({
|
||||
Duration timeout = const Duration(seconds: 60),
|
||||
Duration? timeout = const Duration(seconds: 60),
|
||||
}) async {
|
||||
// ignore: unnecessary_null_comparison
|
||||
if (rawAppDriver != null) {
|
||||
await rawAppDriver.close().catchError(
|
||||
(e, st) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter_gherkin/flutter_gherkin_integration_test.dart';
|
||||
import 'package:flutter_gherkin/flutter_gherkin.dart';
|
||||
|
||||
/// The world object that can be used to store state during a single test.
|
||||
/// It also allows interaction with the app under test through the `appDriver`
|
||||
|
|
|
@ -7,10 +7,10 @@ import '../adapters/app_driver_adapter.dart';
|
|||
/// It also allows interaction with the app under test through the `appDriver`
|
||||
/// which exposes an instance of `AppDriverAdapter`
|
||||
class FlutterWorld extends World {
|
||||
AppDriverAdapter _adapter;
|
||||
AppDriverAdapter? _adapter;
|
||||
|
||||
/// The adapter that is used to agnostically drive the app under test
|
||||
AppDriverAdapter get appDriver => _adapter;
|
||||
AppDriverAdapter get appDriver => _adapter!;
|
||||
|
||||
/// Sets the app driver that is used to control the app under test
|
||||
void setAppAdapter(AppDriverAdapter appAdapter) {
|
||||
|
@ -19,7 +19,7 @@ class FlutterWorld extends World {
|
|||
|
||||
/// Restart the app under test
|
||||
Future<bool> restartApp({
|
||||
Duration timeout = const Duration(seconds: 60),
|
||||
Duration? timeout = const Duration(seconds: 60),
|
||||
}) {
|
||||
throw UnimplementedError('Unable to restart the app during the test');
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ class FlutterTypedAdapterWorld<TDriver, TFinder, TWidget> extends FlutterWorld {
|
|||
/// It is suggested you use `appDriver` for all interactions with the app under tests
|
||||
/// however if you need a specific api not available on `appDriver` this property
|
||||
/// exposes the actual class that can interact with the app under test
|
||||
TDriver get rawAppDriver => _adapter.rawDriver as TDriver;
|
||||
TDriver get rawAppDriver => _adapter!.rawDriver as TDriver;
|
||||
|
||||
/// The adapter that is used to agnostically drive the app under test
|
||||
@override
|
||||
|
|
191
pubspec.lock
191
pubspec.lock
|
@ -7,14 +7,14 @@ packages:
|
|||
name: _fe_analyzer_shared
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "12.0.0"
|
||||
version: "21.0.0"
|
||||
analyzer:
|
||||
dependency: "direct main"
|
||||
dependency: transitive
|
||||
description:
|
||||
name: analyzer
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.40.6"
|
||||
version: "1.5.0"
|
||||
archive:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -35,112 +35,112 @@ packages:
|
|||
name: async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.5.0-nullsafety.1"
|
||||
version: "2.5.0"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: boolean_selector
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0-nullsafety.1"
|
||||
version: "2.1.0"
|
||||
build:
|
||||
dependency: "direct main"
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: build
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.6.2"
|
||||
version: "2.0.1"
|
||||
build_config:
|
||||
dependency: "direct main"
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: build_config
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.5"
|
||||
version: "1.0.0"
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: characters
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0-nullsafety.3"
|
||||
version: "1.1.0"
|
||||
charcode:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: charcode
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0-nullsafety.1"
|
||||
version: "1.2.0"
|
||||
checked_yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: checked_yaml
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
version: "2.0.1"
|
||||
cli_util:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cli_util
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
version: "0.3.0"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: clock
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0-nullsafety.1"
|
||||
version: "1.1.0"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.15.0-nullsafety.3"
|
||||
version: "1.15.0"
|
||||
convert:
|
||||
dependency: transitive
|
||||
dependency: "direct overridden"
|
||||
description:
|
||||
name: convert
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
version: "3.0.0"
|
||||
coverage:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: coverage
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.14.2"
|
||||
version: "0.15.2"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
dependency: "direct overridden"
|
||||
description:
|
||||
name: crypto
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.5"
|
||||
version: "3.0.1"
|
||||
dart_style:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dart_style
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.10"
|
||||
version: "2.0.1"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fake_async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0-nullsafety.1"
|
||||
version: "1.2.0"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.0.0-nullsafety.2"
|
||||
version: "6.0.0"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
|
@ -164,117 +164,85 @@ packages:
|
|||
gherkin:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "."
|
||||
ref: f0b3f955191b53a78075ed2c9387ea8bee12f111
|
||||
resolved-ref: f0b3f955191b53a78075ed2c9387ea8bee12f111
|
||||
url: "https://github.com/jonsamwell/dart_gherkin.git"
|
||||
source: git
|
||||
version: "1.1.10"
|
||||
name: gherkin
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
glob:
|
||||
dependency: "direct main"
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: glob
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
http:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.2"
|
||||
version: "2.0.1"
|
||||
http_multi_server:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_multi_server
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
version: "3.0.1"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_parser
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.1.4"
|
||||
version: "4.0.0"
|
||||
integration_test:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: integration_test
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.2+2"
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.9.2+2"
|
||||
io:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: io
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.4"
|
||||
version: "1.0.0"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: js
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.6.3-nullsafety.2"
|
||||
version: "0.6.3"
|
||||
json_annotation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: json_annotation
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.1.1"
|
||||
json_rpc_2:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: json_rpc_2
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.2"
|
||||
version: "4.0.1"
|
||||
logging:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: logging
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.11.4"
|
||||
version: "1.0.1"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.10-nullsafety.1"
|
||||
version: "0.12.10"
|
||||
meta:
|
||||
dependency: "direct main"
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: meta
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.0-nullsafety.3"
|
||||
version: "1.3.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: mime
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.9.7"
|
||||
node_interop:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: node_interop
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
node_io:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: node_io
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
version: "1.0.0"
|
||||
node_preamble:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -288,138 +256,138 @@ packages:
|
|||
name: package_config
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.9.3"
|
||||
version: "2.0.0"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.0-nullsafety.1"
|
||||
version: "1.8.0"
|
||||
pedantic:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: pedantic
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.10.0-nullsafety.2"
|
||||
version: "1.11.0"
|
||||
platform:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: platform
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.0-nullsafety.2"
|
||||
version: "3.0.0"
|
||||
pool:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pool
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.5.0-nullsafety.2"
|
||||
version: "1.5.0"
|
||||
process:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: process
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.0.0-nullsafety.2"
|
||||
version: "4.0.0"
|
||||
pub_semver:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pub_semver
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.4"
|
||||
version: "2.0.0"
|
||||
pubspec_parse:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pubspec_parse
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.8"
|
||||
version: "1.0.0"
|
||||
shelf:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.7.9"
|
||||
version: "1.1.1"
|
||||
shelf_packages_handler:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_packages_handler
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
version: "3.0.0"
|
||||
shelf_static:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_static
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.9+2"
|
||||
version: "1.0.0"
|
||||
shelf_web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_web_socket
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.4"
|
||||
version: "1.0.1"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.99"
|
||||
source_gen:
|
||||
dependency: "direct main"
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: source_gen
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.9.10+1"
|
||||
version: "1.0.0"
|
||||
source_map_stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_map_stack_trace
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0-nullsafety.3"
|
||||
version: "2.1.0"
|
||||
source_maps:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_maps
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.10.10-nullsafety.2"
|
||||
version: "0.10.10"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_span
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.0-nullsafety.2"
|
||||
version: "1.8.0"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.10.0-nullsafety.1"
|
||||
version: "1.10.0"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_channel
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0-nullsafety.1"
|
||||
version: "2.1.0"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0-nullsafety.1"
|
||||
version: "1.1.0"
|
||||
sync_http:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -433,42 +401,42 @@ packages:
|
|||
name: term_glyph
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0-nullsafety.1"
|
||||
version: "1.2.0"
|
||||
test:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: test
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.16.0-nullsafety.5"
|
||||
version: "1.16.5"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
dependency: "direct overridden"
|
||||
description:
|
||||
name: test_api
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.19-nullsafety.2"
|
||||
version: "0.3.0"
|
||||
test_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_core
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.12-nullsafety.5"
|
||||
version: "0.3.15"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: typed_data
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.0-nullsafety.3"
|
||||
version: "1.3.0"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_math
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0-nullsafety.3"
|
||||
version: "2.1.0"
|
||||
vm_service:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -476,27 +444,20 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "5.5.0"
|
||||
vm_service_client:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vm_service_client
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.6+2"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: watcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.9.7+15"
|
||||
version: "1.0.0"
|
||||
web_socket_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web_socket_channel
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "2.0.0"
|
||||
webdriver:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -510,14 +471,14 @@ packages:
|
|||
name: webkit_inspection_protocol
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.7.5"
|
||||
version: "1.0.0"
|
||||
yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: yaml
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.1"
|
||||
version: "3.1.0"
|
||||
sdks:
|
||||
dart: ">=2.10.0 <2.11.0"
|
||||
flutter: ">=1.17.0"
|
||||
dart: ">=2.12.3 <3.0.0"
|
||||
flutter: ">=2.0.0"
|
||||
|
|
39
pubspec.yaml
39
pubspec.yaml
|
@ -4,8 +4,8 @@ version: 1.2.0
|
|||
homepage: https://github.com/jonsamwell/flutter_gherkin
|
||||
|
||||
environment:
|
||||
sdk: ">=2.7.0 <3.0.0"
|
||||
flutter: ">=1.17.0"
|
||||
sdk: '>=2.12.3 <3.0.0'
|
||||
flutter: ">=2.0.0"
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
|
@ -14,24 +14,29 @@ dependencies:
|
|||
sdk: flutter
|
||||
flutter_driver:
|
||||
sdk: flutter
|
||||
analyzer: ">=0.37.0 <0.41.0"
|
||||
glob: ^1.1.7
|
||||
meta: ">=1.1.6 <2.0.0"
|
||||
source_gen: ^0.9.10+1
|
||||
build: ^1.6.0
|
||||
build_config: ^0.4.5
|
||||
integration_test: ^1.0.1
|
||||
# gherkin: ^1.1.9
|
||||
gherkin: ^2.0.0
|
||||
# gherkin:
|
||||
# path: ../dart_gherkin
|
||||
gherkin:
|
||||
git:
|
||||
url: https://github.com/jonsamwell/dart_gherkin.git
|
||||
ref: f0b3f955191b53a78075ed2c9387ea8bee12f111
|
||||
# ref: code_gen_changes
|
||||
# gherkin:
|
||||
# git:
|
||||
# url: https://github.com/jonsamwell/dart_gherkin.git
|
||||
# ref: f0b3f955191b53a78075ed2c9387ea8bee12f111
|
||||
|
||||
dependency_overrides:
|
||||
crypto: ^3.0.0 # flutter_driver still depends on 2.1.5 :-(
|
||||
convert: ^3.0.0 # flutter_driver still depends on >=2.0.0 :-(
|
||||
test: ^1.16.5 # gherkin still depends on 1.16.8 :-(
|
||||
test_api: ^0.3.0 # flutter_test still depends on 0.2.19 :-(
|
||||
|
||||
dev_dependencies:
|
||||
test:
|
||||
pedantic: ^1.9.2
|
||||
integration_test:
|
||||
sdk: flutter
|
||||
test: ^1.16.5
|
||||
meta: ^1.3.0
|
||||
pedantic: ^1.11.0
|
||||
glob: ^2.0.1
|
||||
source_gen: ^1.0.0
|
||||
build: ^2.0.1
|
||||
build_config: ^1.0.0
|
||||
|
||||
flutter:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import 'package:flutter_gherkin/flutter_gherkin.dart';
|
||||
import 'package:flutter_gherkin/flutter_gherkin_with_driver.dart';
|
||||
import 'package:flutter_gherkin/src/flutter/hooks/app_runner_hook.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
|
@ -13,8 +13,8 @@ void main() {
|
|||
expect(config.hooks, isNull);
|
||||
config.prepare();
|
||||
expect(config.hooks, isNotNull);
|
||||
expect(config.hooks.length, 1);
|
||||
expect(config.hooks.elementAt(0), (x) => x is FlutterAppRunnerHook);
|
||||
expect(config.hooks!.length, 1);
|
||||
expect(config.hooks!.elementAt(0), (x) => x is FlutterAppRunnerHook);
|
||||
});
|
||||
|
||||
test('common steps definition added', () {
|
||||
|
@ -23,25 +23,25 @@ void main() {
|
|||
|
||||
config.prepare();
|
||||
expect(config.stepDefinitions, isNotNull);
|
||||
expect(config.stepDefinitions.length, 23);
|
||||
expect(config.stepDefinitions!.length, 23);
|
||||
expect(config.customStepParameterDefinitions, isNotNull);
|
||||
expect(config.customStepParameterDefinitions.length, 2);
|
||||
expect(config.customStepParameterDefinitions!.length, 2);
|
||||
});
|
||||
|
||||
test('common step definition added to existing steps', () {
|
||||
final config = FlutterTestConfiguration()
|
||||
..stepDefinitions = [MockStepDefinition()]
|
||||
..customStepParameterDefinitions = [MockParameter()];
|
||||
expect(config.stepDefinitions.length, 1);
|
||||
expect(config.stepDefinitions!.length, 1);
|
||||
|
||||
config.prepare();
|
||||
expect(config.stepDefinitions, isNotNull);
|
||||
expect(config.stepDefinitions.length, 24);
|
||||
expect(config.stepDefinitions.elementAt(0),
|
||||
expect(config.stepDefinitions!.length, 24);
|
||||
expect(config.stepDefinitions!.elementAt(0),
|
||||
(x) => x is MockStepDefinition);
|
||||
expect(config.customStepParameterDefinitions, isNotNull);
|
||||
expect(config.customStepParameterDefinitions.length, 3);
|
||||
expect(config.customStepParameterDefinitions.elementAt(0),
|
||||
expect(config.customStepParameterDefinitions!.length, 3);
|
||||
expect(config.customStepParameterDefinitions!.elementAt(0),
|
||||
(x) => x is MockParameter);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,7 +5,7 @@ typedef OnRunCode = Future<void> Function(Iterable parameters);
|
|||
class MockStepDefinition extends StepDefinitionBase<World> {
|
||||
bool hasRun = false;
|
||||
int runCount = 0;
|
||||
final OnRunCode code;
|
||||
final OnRunCode? code;
|
||||
|
||||
MockStepDefinition([this.code, int expectedParameterCount = 0])
|
||||
: super(null, expectedParameterCount);
|
||||
|
@ -15,10 +15,10 @@ class MockStepDefinition extends StepDefinitionBase<World> {
|
|||
hasRun = true;
|
||||
runCount += 1;
|
||||
if (code != null) {
|
||||
await code(parameters);
|
||||
await code!(parameters);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
RegExp get pattern => null;
|
||||
RegExp get pattern => RegExp('');
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue