- Fix: #165: Empty .feature files causing void functions which get compiled out at runtime and cause errors
- Fix: #162: Incorrect feature name in HTML reports - many thanks to @AFASbart for suggesting the cause and fix. - Fix: #159: Swipe step is not working due to bad '??' statement - Fix: #155: Ensure stdout reporter only add ascii colour code when the target supports it
This commit is contained in:
parent
2db755d23b
commit
29eeb73f39
|
@ -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\\\\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-10-27 20:12:58.071212","version":"2.5.3"}
|
||||
{"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-11-10 11:13:27.428521","version":"2.5.3"}
|
|
@ -1,3 +1,10 @@
|
|||
## [3.0.0-rc.7] - 10/11/2021
|
||||
|
||||
- Fix: #165: Empty .feature files causing void functions which get compiled out at runtime and cause errors
|
||||
- Fix: #162: Incorrect feature name in HTML reports - many thanks to @AFASbart for suggesting the cause and fix.
|
||||
- Fix: #159: Swipe step is not working due to bad '??' statement
|
||||
- Fix: #155: Ensure stdout reporter only add ascii colour code when the target supports it
|
||||
|
||||
## [3.0.0-rc.6] - 27/10/2021
|
||||
|
||||
- BREAKING CHANGE: Made `appMainFunction` return a `Future<void>` so it can be async
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
```
|
||||
# generate the test suite
|
||||
flutter pub run build_runner build
|
||||
flutter pub run build_runner build --delete-conflicting-outputs
|
||||
|
||||
# run the tests
|
||||
flutter drive --driver=test_driver/integration_test_driver.dart --target=integration_test/gherkin_suite_test.dart
|
||||
|
|
|
@ -23,32 +23,32 @@ Feature: Creating todos
|
|||
| Buy apples |
|
||||
| Buy carrots |
|
||||
Given I wait 5 seconds for the animation to complete
|
||||
# Given I have item with data
|
||||
# """
|
||||
# {
|
||||
# "glossary": {
|
||||
# "title": "example glossary",
|
||||
# "GlossDiv": {
|
||||
# "title": "S",
|
||||
# "GlossList": {
|
||||
# "GlossEntry": {
|
||||
# "ID": "SGML",
|
||||
# "SortAs": "SGML",
|
||||
# "GlossTerm": "Standard Generalized Markup Language",
|
||||
# "Acronym": "SGML",
|
||||
# "Abbrev": "ISO 8879:1986",
|
||||
# "GlossDef": {
|
||||
# "para": "A meta-markup language, used to create markup languages such as DocBook.",
|
||||
# "GlossSeeAlso": [
|
||||
# "GML",
|
||||
# "XML"
|
||||
# ]
|
||||
# },
|
||||
# "GlossSee": "markup"
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
# """
|
||||
# When I test the default step timeout is not applied to step with custom timeout
|
||||
Given I have item with data
|
||||
"""
|
||||
{
|
||||
"glossary": {
|
||||
"title": "example glossary",
|
||||
"GlossDiv": {
|
||||
"title": "S",
|
||||
"GlossList": {
|
||||
"GlossEntry": {
|
||||
"ID": "SGML",
|
||||
"SortAs": "SGML",
|
||||
"GlossTerm": "Standard Generalized Markup Language",
|
||||
"Acronym": "SGML",
|
||||
"Abbrev": "ISO 8879:1986",
|
||||
"GlossDef": {
|
||||
"para": "A meta-markup language, used to create markup languages such as DocBook.",
|
||||
"GlossSeeAlso": [
|
||||
"GML",
|
||||
"XML"
|
||||
]
|
||||
},
|
||||
"GlossSee": "markup"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
# When I test the default step timeout is not applied to step with custom timeout
|
|
@ -0,0 +1,10 @@
|
|||
@tag
|
||||
Feature: Swiping
|
||||
|
||||
@debug
|
||||
Scenario: User can swipe cards left and right
|
||||
Given I swipe right by 250 pixels on the "scrollable cards"`
|
||||
Then Then I expect the text "Page 2" to be present
|
||||
|
||||
Given I swipe left by 250 pixels on the "scrollable cards"`
|
||||
Then Then I expect the text "Page 1" to be present
|
|
@ -16,9 +16,113 @@ class _CustomGherkinIntegrationTestRunner extends GherkinIntegrationTestRunner {
|
|||
void onRun() {
|
||||
testFeature0();
|
||||
testFeature1();
|
||||
testFeature2();
|
||||
}
|
||||
|
||||
void testFeature0() {
|
||||
runFeature(
|
||||
'Swiping:',
|
||||
<String>['@tag'],
|
||||
() {
|
||||
runScenario(
|
||||
'User can swipe cards left and right',
|
||||
<String>['@tag', '@debug'],
|
||||
(TestDependencies dependencies) async {
|
||||
await runStep(
|
||||
'Given I swipe right by 250 pixels on the "scrollable cards"`',
|
||||
<String>[],
|
||||
null,
|
||||
dependencies,
|
||||
);
|
||||
|
||||
await runStep(
|
||||
'Then Then I expect the text "Page 2" to be present',
|
||||
<String>[],
|
||||
null,
|
||||
dependencies,
|
||||
);
|
||||
|
||||
await runStep(
|
||||
'Given I swipe left by 250 pixels on the "scrollable cards"`',
|
||||
<String>[],
|
||||
null,
|
||||
dependencies,
|
||||
);
|
||||
|
||||
await runStep(
|
||||
'Then Then I expect the text "Page 1" to be present',
|
||||
<String>[],
|
||||
null,
|
||||
dependencies,
|
||||
);
|
||||
},
|
||||
onBefore: () async => onBeforeRunFeature(
|
||||
'Swiping',
|
||||
<String>['@tag'],
|
||||
),
|
||||
onAfter: () async => onAfterRunFeature(
|
||||
'Swiping',
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void testFeature1() {
|
||||
runFeature(
|
||||
'Checking data:',
|
||||
<String>['@tag'],
|
||||
() {
|
||||
runScenario(
|
||||
'User can have data',
|
||||
<String>['@tag', '@tag1'],
|
||||
(TestDependencies dependencies) async {
|
||||
await runStep(
|
||||
'Given I have item with data',
|
||||
<String>[
|
||||
"""{
|
||||
"glossary": {
|
||||
"title": "example glossary",
|
||||
"GlossDiv": {
|
||||
"title": "S",
|
||||
"GlossList": {
|
||||
"GlossEntry": {
|
||||
"ID": "SGML",
|
||||
"SortAs": "SGML",
|
||||
"GlossTerm": "Standard Generalized Markup Language",
|
||||
"Acronym": "SGML",
|
||||
"Abbrev": "ISO 8879:1986",
|
||||
"GlossDef": {
|
||||
"para": "A meta-markup language, used to create markup languages such as DocBook.",
|
||||
"GlossSeeAlso": [
|
||||
"GML",
|
||||
"XML"
|
||||
]
|
||||
},
|
||||
"GlossSee": "markup"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}"""
|
||||
],
|
||||
null,
|
||||
dependencies,
|
||||
);
|
||||
},
|
||||
onBefore: () async => onBeforeRunFeature(
|
||||
'Checking data',
|
||||
<String>['@tag'],
|
||||
),
|
||||
onAfter: () async => onAfterRunFeature(
|
||||
'Checking data',
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void testFeature2() {
|
||||
runFeature(
|
||||
'Creating todos:',
|
||||
<String>['@tag'],
|
||||
|
@ -49,8 +153,8 @@ class _CustomGherkinIntegrationTestRunner extends GherkinIntegrationTestRunner {
|
|||
);
|
||||
},
|
||||
onBefore: () async => onBeforeRunFeature(
|
||||
'User can create a new todo item',
|
||||
<String>['@tag', '@tag1', '@tag_two'],
|
||||
'Creating todos',
|
||||
<String>['@tag'],
|
||||
),
|
||||
onAfter: null,
|
||||
);
|
||||
|
@ -115,25 +219,7 @@ class _CustomGherkinIntegrationTestRunner extends GherkinIntegrationTestRunner {
|
|||
null,
|
||||
dependencies,
|
||||
);
|
||||
},
|
||||
onBefore: null,
|
||||
onAfter: () async => onAfterRunFeature(
|
||||
'User can create multiple new todo items',
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void testFeature1() {
|
||||
runFeature(
|
||||
'Checking data:',
|
||||
<String>['@tag'],
|
||||
() {
|
||||
runScenario(
|
||||
'User can have data',
|
||||
<String>['@tag', '@tag1'],
|
||||
(TestDependencies dependencies) async {
|
||||
await runStep(
|
||||
'Given I have item with data',
|
||||
<String>[
|
||||
|
@ -167,12 +253,9 @@ class _CustomGherkinIntegrationTestRunner extends GherkinIntegrationTestRunner {
|
|||
dependencies,
|
||||
);
|
||||
},
|
||||
onBefore: () async => onBeforeRunFeature(
|
||||
'User can have data',
|
||||
<String>['@tag', '@tag1'],
|
||||
),
|
||||
onBefore: null,
|
||||
onAfter: () async => onAfterRunFeature(
|
||||
'User can have data',
|
||||
'Creating todos',
|
||||
),
|
||||
);
|
||||
},
|
||||
|
|
|
@ -26,22 +26,29 @@ class TodoApp extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final app = MaterialApp(
|
||||
title: 'Todo App',
|
||||
theme: ThemeData(
|
||||
primarySwatch: Colors.blue,
|
||||
visualDensity: VisualDensity.adaptivePlatformDensity,
|
||||
),
|
||||
home: injector.get<HomeView>(),
|
||||
);
|
||||
|
||||
// if the app is in test mode and an ExternalApplicationManager is passed in
|
||||
// let the app respond to external changes
|
||||
return externalApplicationManager == null
|
||||
? app
|
||||
? MaterialApp(
|
||||
title: 'Todo App',
|
||||
theme: ThemeData(
|
||||
primarySwatch: Colors.blue,
|
||||
visualDensity: VisualDensity.adaptivePlatformDensity,
|
||||
),
|
||||
home: injector.get<HomeView>(),
|
||||
)
|
||||
: StreamBuilder(
|
||||
stream: externalApplicationManager!.applicationReset,
|
||||
builder: (ctx, _) => app,
|
||||
builder: (ctx, _) {
|
||||
return MaterialApp(
|
||||
title: 'Todo App',
|
||||
theme: ThemeData(
|
||||
primarySwatch: Colors.blue,
|
||||
visualDensity: VisualDensity.adaptivePlatformDensity,
|
||||
),
|
||||
home: injector.get<HomeView>(),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,115 +33,147 @@ class _HomeViewState extends State<HomeView> with ViewUtilsMixin {
|
|||
),
|
||||
),
|
||||
body: SafeArea(
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 100,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8,
|
||||
),
|
||||
child: AddTodoComponent(
|
||||
todo: bloc.newModel,
|
||||
onAdded: (todo) {
|
||||
subscribeOnce(bloc.add(todo));
|
||||
},
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 100,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8,
|
||||
),
|
||||
child: AddTodoComponent(
|
||||
todo: bloc.newModel,
|
||||
onAdded: (todo) {
|
||||
subscribeOnce(bloc.add(todo));
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 16,
|
||||
),
|
||||
StreamBuilder<Iterable<Todo>>(
|
||||
stream: bloc.todos,
|
||||
builder: (_, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
final data = snapshot.data!;
|
||||
if (data.isEmpty) {
|
||||
return Center(
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.list,
|
||||
size: 64,
|
||||
color: Colors.black26,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Text(
|
||||
'No todos!',
|
||||
key: const Key('empty'),
|
||||
style: Theme.of(context).textTheme.headline6,
|
||||
SizedBox(
|
||||
height: 16,
|
||||
),
|
||||
StreamBuilder<Iterable<Todo>>(
|
||||
stream: bloc.todos,
|
||||
builder: (_, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
final data = snapshot.data!;
|
||||
if (data.isEmpty) {
|
||||
return Center(
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.list,
|
||||
size: 64,
|
||||
color: Colors.black26,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
// child: Text(
|
||||
// 'No todos!',
|
||||
// key: const Key('empty'),
|
||||
// style: Theme.of(context).textTheme.headline6,
|
||||
// ),
|
||||
child: SizedBox(
|
||||
key: const Key('scrollable cards'),
|
||||
width: 300,
|
||||
height: 250,
|
||||
child: PageView.builder(
|
||||
itemCount: 3,
|
||||
itemBuilder: (ctx, index) {
|
||||
return Container(
|
||||
margin: const EdgeInsets.all(10),
|
||||
decoration: BoxDecoration(
|
||||
color: index == 0
|
||||
? Colors.amber
|
||||
: Colors.blueAccent,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: SizedBox(
|
||||
key: Key('Page ${index + 1}'),
|
||||
width: 200,
|
||||
height: 200,
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Page ${index + 1}',
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return ListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: data.length,
|
||||
itemBuilder: (ctx, index) {
|
||||
final todo = data.elementAt(index);
|
||||
return Dismissible(
|
||||
background: Container(
|
||||
color: Colors.red,
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.delete,
|
||||
color: Colors.white,
|
||||
),
|
||||
Icon(
|
||||
Icons.delete,
|
||||
color: Colors.white,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
key: Key(todo.action!),
|
||||
onDismissed: (direction) {
|
||||
subscribeOnce(
|
||||
bloc.remove(todo),
|
||||
onDone: () {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('Todo deleted'),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
child: ListTile(
|
||||
title: Text(
|
||||
todo.action!,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyText1!
|
||||
.copyWith(
|
||||
decoration:
|
||||
todo.status == TodoStatus.complete
|
||||
? TextDecoration.lineThrough
|
||||
: null,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return ListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: data.length,
|
||||
itemBuilder: (ctx, index) {
|
||||
final todo = data.elementAt(index);
|
||||
return Dismissible(
|
||||
background: Container(
|
||||
color: Colors.red,
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.delete,
|
||||
color: Colors.white,
|
||||
),
|
||||
Icon(
|
||||
Icons.delete,
|
||||
color: Colors.white,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
key: Key(todo.action!),
|
||||
onDismissed: (direction) {
|
||||
subscribeOnce(
|
||||
bloc.remove(todo),
|
||||
onDone: () {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('Todo deleted'),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
child: ListTile(
|
||||
title: Text(
|
||||
todo.action!,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyText1!
|
||||
.copyWith(
|
||||
decoration:
|
||||
todo.status == TodoStatus.complete
|
||||
? TextDecoration.lineThrough
|
||||
: null,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
return Center(
|
||||
child: Text('Loading...'),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return Center(
|
||||
child: Text('Loading...'),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -213,7 +213,7 @@ packages:
|
|||
path: ".."
|
||||
relative: true
|
||||
source: path
|
||||
version: "3.0.0-rc.6"
|
||||
version: "3.0.0-rc.7"
|
||||
flutter_simple_dependency_injection:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -249,7 +249,7 @@ packages:
|
|||
name: gherkin
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.5+1"
|
||||
version: "2.0.7"
|
||||
glob:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
@ -151,7 +151,7 @@ class WidgetTesterAppDriverAdapter
|
|||
}) async {
|
||||
final scrollableFinder = findByDescendant(
|
||||
finder,
|
||||
find.byType(Scrollable).first,
|
||||
find.byType(Scrollable),
|
||||
matchRoot: true,
|
||||
);
|
||||
final state = nativeDriver.state(scrollableFinder) as ScrollableState;
|
||||
|
|
|
@ -149,10 +149,10 @@ class FeatureFileTestGeneratorVisitor extends FeatureFileVisitor {
|
|||
);
|
||||
''';
|
||||
static const String ON_BEFORE_SCENARIO_RUN = '''
|
||||
() async => onBeforeRunFeature('{{scenario_name}}', {{tags}},)
|
||||
() async => onBeforeRunFeature('{{feature_name}}', {{feature_tags}},)
|
||||
''';
|
||||
static const String ON_AFTER_SCENARIO_RUN = '''
|
||||
() async => onAfterRunFeature('{{scenario_name}}',)
|
||||
() async => onAfterRunFeature('{{feature_name}}',)
|
||||
''';
|
||||
|
||||
final StringBuffer _buffer = StringBuffer();
|
||||
|
@ -188,26 +188,31 @@ class FeatureFileTestGeneratorVisitor extends FeatureFileVisitor {
|
|||
String name,
|
||||
String? description,
|
||||
Iterable<String> tags,
|
||||
int childScenarioCount,
|
||||
) async {
|
||||
_currentFeatureCode = _replaceVariable(
|
||||
FUNCTION_TEMPLATE,
|
||||
'feature_number',
|
||||
_id.toString(),
|
||||
);
|
||||
_currentFeatureCode = _replaceVariable(
|
||||
_currentFeatureCode!,
|
||||
'feature_name',
|
||||
_escapeText(name),
|
||||
);
|
||||
_currentFeatureCode = _replaceVariable(
|
||||
_currentFeatureCode!,
|
||||
'tags',
|
||||
'<String>[${tags.map((e) => "'$e'").join(', ')}]',
|
||||
);
|
||||
if (childScenarioCount > 0) {
|
||||
_currentFeatureCode = _replaceVariable(
|
||||
FUNCTION_TEMPLATE,
|
||||
'feature_number',
|
||||
_id.toString(),
|
||||
);
|
||||
_currentFeatureCode = _replaceVariable(
|
||||
_currentFeatureCode!,
|
||||
'feature_name',
|
||||
_escapeText(name),
|
||||
);
|
||||
_currentFeatureCode = _replaceVariable(
|
||||
_currentFeatureCode!,
|
||||
'tags',
|
||||
'<String>[${tags.map((e) => "'$e'").join(', ')}]',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> visitScenario(
|
||||
String featureName,
|
||||
Iterable<String> featureTags,
|
||||
String name,
|
||||
Iterable<String> tags,
|
||||
bool isFirst,
|
||||
|
@ -224,6 +229,16 @@ class FeatureFileTestGeneratorVisitor extends FeatureFileVisitor {
|
|||
'onAfter',
|
||||
isLast ? ON_AFTER_SCENARIO_RUN : 'null',
|
||||
);
|
||||
_currentScenarioCode = _replaceVariable(
|
||||
_currentScenarioCode!,
|
||||
'feature_name',
|
||||
_escapeText(featureName),
|
||||
);
|
||||
_currentScenarioCode = _replaceVariable(
|
||||
_currentScenarioCode!,
|
||||
'feature_tags',
|
||||
'<String>[${featureTags.map((e) => "'$e'").join(', ')}]',
|
||||
);
|
||||
_currentScenarioCode = _replaceVariable(
|
||||
_currentScenarioCode!,
|
||||
'scenario_name',
|
||||
|
|
|
@ -18,7 +18,6 @@ mixin _SwipeHelper
|
|||
await world.appDriver.scroll(
|
||||
finder,
|
||||
dx: offset.toDouble(),
|
||||
dy: 0,
|
||||
duration: Duration(milliseconds: 500),
|
||||
timeout: timeout,
|
||||
);
|
||||
|
@ -28,7 +27,6 @@ mixin _SwipeHelper
|
|||
|
||||
await world.appDriver.scroll(
|
||||
finder,
|
||||
dx: 0,
|
||||
dy: offset.toDouble(),
|
||||
duration: Duration(milliseconds: 500),
|
||||
timeout: timeout,
|
||||
|
@ -58,7 +56,7 @@ class SwipeOnKeyStep
|
|||
|
||||
@override
|
||||
RegExp get pattern =>
|
||||
RegExp(r'I swipe {swipe_direction} by {int} pixels on the {string}$');
|
||||
RegExp(r'I swipe {swipe_direction} by {int} pixels on the {string}');
|
||||
}
|
||||
|
||||
/// Swipes in a cardinal direction on a widget discovered by its test.
|
||||
|
|
|
@ -160,7 +160,7 @@ packages:
|
|||
name: gherkin
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.5+1"
|
||||
version: "2.0.7"
|
||||
glob:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
name: flutter_gherkin
|
||||
description: A Gherkin / Cucumber parser and test runner for Dart and Flutter
|
||||
version: 3.0.0-rc.6
|
||||
version: 3.0.0-rc.7
|
||||
homepage: https://github.com/jonsamwell/flutter_gherkin
|
||||
|
||||
environment:
|
||||
|
@ -18,7 +18,7 @@ dependencies:
|
|||
sdk: flutter
|
||||
analyzer: ">=1.7.1 <3.0.0"
|
||||
collection: ^1.15.0
|
||||
gherkin: ^2.0.5+1
|
||||
gherkin: ^2.0.7
|
||||
source_gen: ^1.1.1
|
||||
build: ^2.1.1
|
||||
glob: ^2.0.2
|
||||
|
|
Loading…
Reference in New Issue