chore(merge): updated merged in steps to use function based implementation
This commit is contained in:
parent
48bee80cc6
commit
b2f86e0446
|
@ -1,7 +1,6 @@
|
|||
import 'dart:async';
|
||||
import 'package:flutter_gherkin/flutter_gherkin.dart';
|
||||
import 'package:gherkin/gherkin.dart';
|
||||
import 'package:glob/glob.dart';
|
||||
import 'hooks/hook_example.dart';
|
||||
import 'steps/colour_parameter.dart';
|
||||
import 'steps/given_I_pick_a_colour_step.dart';
|
||||
|
|
|
@ -2,10 +2,8 @@ Feature: Startup
|
|||
|
||||
Scenario: should increment counter
|
||||
Given I expect the "counter" to be "0"
|
||||
#! profile "action speed"
|
||||
When I tap the "increment" button
|
||||
And I tap the "increment" button
|
||||
#! end
|
||||
Then I expect the "counter" to be "2"
|
||||
|
||||
Scenario: counter should reset when app is restarted
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,9 @@
|
|||
import 'package:gherkin/gherkin.dart';
|
||||
|
||||
enum Existence { present, absent }
|
||||
enum Existence {
|
||||
present,
|
||||
absent,
|
||||
}
|
||||
|
||||
class ExistenceParameter extends CustomParameter<Existence> {
|
||||
ExistenceParameter()
|
||||
|
@ -14,7 +17,8 @@ class ExistenceParameter extends CustomParameter<Existence> {
|
|||
case 'absent':
|
||||
return Existence.absent;
|
||||
default:
|
||||
throw ArgumentError('"present" or "absent" must be defined for this parameter');
|
||||
throw ArgumentError(
|
||||
'Value `$c` must be defined for this Existence parameter');
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
|
@ -13,33 +13,29 @@ import 'package:gherkin/gherkin.dart';
|
|||
/// Examples:
|
||||
///
|
||||
/// `Then I expect a "Row" that contains the text "X" to also contain the text "Y"`
|
||||
class SiblingContainsTextStep
|
||||
extends When3WithWorld<String, String, String, FlutterWorld> {
|
||||
@override
|
||||
Future<void> executeStep(
|
||||
String ancestorType, String leadingText, String valueText) async {
|
||||
final ancestor = await find.ancestor(
|
||||
of: find.text(leadingText),
|
||||
matching: find.byType(ancestorType),
|
||||
firstMatchOnly: true,
|
||||
);
|
||||
StepDefinitionGeneric SiblingContainsTextStep() {
|
||||
return given3<String, String, String, FlutterWorld>(
|
||||
'I expect a {string} that contains the text {string} to also contain the text {string}',
|
||||
(ancestorType, leadingText, valueText, context) async {
|
||||
final ancestor = await find.ancestor(
|
||||
of: find.text(leadingText),
|
||||
matching: find.byType(ancestorType),
|
||||
firstMatchOnly: true,
|
||||
);
|
||||
|
||||
final valueWidget = await find.descendant(
|
||||
of: ancestor,
|
||||
matching: find.text(valueText),
|
||||
firstMatchOnly: true,
|
||||
);
|
||||
final valueWidget = await find.descendant(
|
||||
of: ancestor,
|
||||
matching: find.text(valueText),
|
||||
firstMatchOnly: true,
|
||||
);
|
||||
|
||||
final isPresent = await FlutterDriverUtils.isPresent(
|
||||
world.driver,
|
||||
valueWidget,
|
||||
timeout: timeout,
|
||||
);
|
||||
final isPresent = await FlutterDriverUtils.isPresent(
|
||||
context.world.driver,
|
||||
valueWidget,
|
||||
timeout: context.configuration?.timeout ?? const Duration(seconds: 20),
|
||||
);
|
||||
|
||||
expect(isPresent, true);
|
||||
}
|
||||
|
||||
@override
|
||||
RegExp get pattern => RegExp(
|
||||
r'I expect a {string} that contains the text {string} to also contain the text {string}');
|
||||
context.expect(isPresent, true);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -8,8 +8,11 @@ import '../parameters/swipe_direction_parameter.dart';
|
|||
mixin _SwipeHelper
|
||||
on When3WithWorld<SwipeDirection, int, String, FlutterWorld> {
|
||||
@protected
|
||||
Future<void> swipeOnFinder(SerializableFinder finder,
|
||||
SwipeDirection direction, int swipeAmount) async {
|
||||
Future<void> swipeOnFinder(
|
||||
SerializableFinder finder,
|
||||
SwipeDirection direction,
|
||||
int swipeAmount,
|
||||
) async {
|
||||
if (direction == SwipeDirection.left || direction == SwipeDirection.right) {
|
||||
final offset =
|
||||
direction == SwipeDirection.right ? swipeAmount : (swipeAmount * -1);
|
||||
|
@ -47,7 +50,10 @@ class SwipeOnKeyStep
|
|||
with _SwipeHelper {
|
||||
@override
|
||||
Future<void> executeStep(
|
||||
SwipeDirection direction, int swipeAmount, String key) async {
|
||||
SwipeDirection direction,
|
||||
int swipeAmount,
|
||||
String key,
|
||||
) async {
|
||||
final finder = find.byValueKey(key);
|
||||
await swipeOnFinder(finder, direction, swipeAmount);
|
||||
}
|
||||
|
@ -67,7 +73,10 @@ class SwipeOnTextStep
|
|||
with _SwipeHelper {
|
||||
@override
|
||||
Future<void> executeStep(
|
||||
SwipeDirection direction, int swipeAmount, String text) async {
|
||||
SwipeDirection direction,
|
||||
int swipeAmount,
|
||||
String text,
|
||||
) async {
|
||||
final finder = find.text(text);
|
||||
await swipeOnFinder(finder, direction, swipeAmount);
|
||||
}
|
||||
|
|
|
@ -8,39 +8,39 @@ import 'package:gherkin/gherkin.dart';
|
|||
/// Examples:
|
||||
///
|
||||
/// `Then I tap the label that contains the text "Logout" within the "user_settings_list"`
|
||||
class TapTextWithinWidgetStep
|
||||
extends When2WithWorld<String, String, FlutterWorld> {
|
||||
@override
|
||||
Future<void> executeStep(String text, String ancestorKey) async {
|
||||
final finder = find.descendant(
|
||||
of: find.byValueKey(ancestorKey),
|
||||
matching: find.text(text),
|
||||
firstMatchOnly: true,
|
||||
);
|
||||
|
||||
final isPresent = await FlutterDriverUtils.isPresent(
|
||||
world.driver,
|
||||
finder,
|
||||
timeout: timeout * .2,
|
||||
);
|
||||
|
||||
if (!isPresent) {
|
||||
await world.driver.scrollUntilVisible(
|
||||
find.byValueKey(ancestorKey),
|
||||
find.text(text),
|
||||
dyScroll: -100.0,
|
||||
timeout: timeout * .9,
|
||||
StepDefinitionGeneric TapTextWithinWidgetStep() {
|
||||
return given2<String, String, FlutterWorld>(
|
||||
RegExp(
|
||||
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);
|
||||
final finder = find.descendant(
|
||||
of: find.byValueKey(ancestorKey),
|
||||
matching: find.text(text),
|
||||
firstMatchOnly: true,
|
||||
);
|
||||
}
|
||||
|
||||
await FlutterDriverUtils.tap(
|
||||
world.driver,
|
||||
finder,
|
||||
timeout: timeout,
|
||||
);
|
||||
}
|
||||
final isPresent = await FlutterDriverUtils.isPresent(
|
||||
context.world.driver,
|
||||
finder,
|
||||
timeout: timeout * .2,
|
||||
);
|
||||
|
||||
@override
|
||||
RegExp get pattern => RegExp(
|
||||
r'I tap the (?:button|element|label|field|text|widget) that contains the text {string} within the {string}');
|
||||
if (!isPresent) {
|
||||
await context.world.driver.scrollUntilVisible(
|
||||
find.byValueKey(ancestorKey),
|
||||
find.text(text),
|
||||
dyScroll: -100.0,
|
||||
timeout: timeout * .9,
|
||||
);
|
||||
}
|
||||
|
||||
await FlutterDriverUtils.tap(
|
||||
context.world.driver,
|
||||
finder,
|
||||
timeout: timeout,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -9,17 +9,15 @@ import 'package:gherkin/gherkin.dart';
|
|||
/// `Then I tap the element of type "MaterialButton"`
|
||||
/// `Then I tap the label of type "ListTile"`
|
||||
/// `Then I tap the field of type "TextField"`
|
||||
class TapWidgetOfTypeStep extends When1WithWorld<String, FlutterWorld> {
|
||||
@override
|
||||
Future<void> executeStep(String input1) async {
|
||||
await FlutterDriverUtils.tap(
|
||||
world.driver,
|
||||
find.byType(input1),
|
||||
timeout: timeout,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
RegExp get pattern => RegExp(
|
||||
r'I tap the (?:button|element|label|icon|field|text|widget) of type {string}$');
|
||||
StepDefinitionGeneric TapWidgetOfTypeStep() {
|
||||
return given1<String, FlutterWorld>(
|
||||
RegExp(
|
||||
r'I tap the (?:button|element|label|icon|field|text|widget) of type {string}$'),
|
||||
(input1, context) async {
|
||||
await FlutterDriverUtils.tap(
|
||||
context.world.driver,
|
||||
find.byType(input1),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -7,23 +7,20 @@ import 'package:gherkin/gherkin.dart';
|
|||
/// Examples:
|
||||
///
|
||||
/// `Then I tap the element of type "MaterialButton" within the "user_settings_list"`
|
||||
class TapWidgetOfTypeWithinStep
|
||||
extends When2WithWorld<String, String, FlutterWorld> {
|
||||
@override
|
||||
Future<void> executeStep(String widgetType, String ancestorKey) async {
|
||||
final finder = find.descendant(
|
||||
of: find.byValueKey(ancestorKey),
|
||||
matching: find.byType(widgetType),
|
||||
firstMatchOnly: true,
|
||||
);
|
||||
await FlutterDriverUtils.tap(
|
||||
world.driver,
|
||||
finder,
|
||||
timeout: timeout,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
RegExp get pattern => RegExp(
|
||||
r'I tap the (?:button|element|label|icon|field|text|widget) of type {string} within the {string}$');
|
||||
StepDefinitionGeneric TapWidgetOfTypeWithinStep() {
|
||||
return when2<String, String, FlutterWorld>(
|
||||
RegExp(
|
||||
r'I tap the (?:button|element|label|icon|field|text|widget) of type {string} within the {string}$'),
|
||||
(widgetType, ancestorKey, context) async {
|
||||
final finder = find.descendant(
|
||||
of: find.byValueKey(ancestorKey),
|
||||
matching: find.byType(widgetType),
|
||||
firstMatchOnly: true,
|
||||
);
|
||||
await FlutterDriverUtils.tap(
|
||||
context.world.driver,
|
||||
finder,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -9,19 +9,17 @@ import 'package:gherkin/gherkin.dart';
|
|||
/// `Then I tap the label that contains the text "Logout"`
|
||||
/// `Then I tap the button that contains the text "Sign up"`
|
||||
/// `Then I tap the widget that contains the text "My User Profile"`
|
||||
class TapWidgetWithTextStep extends When1WithWorld<String, FlutterWorld> {
|
||||
@override
|
||||
Future<void> executeStep(String input1) async {
|
||||
final finder = find.text(input1);
|
||||
await world.driver.scrollIntoView(finder, timeout: timeout);
|
||||
await FlutterDriverUtils.tap(
|
||||
world.driver,
|
||||
finder,
|
||||
timeout: timeout,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
RegExp get pattern => RegExp(
|
||||
r'I tap the (?:button|element|label|field|text|widget) that contains the text {string}$');
|
||||
StepDefinitionGeneric TapWidgetWithTextStep() {
|
||||
return then1<String, FlutterWorld>(
|
||||
RegExp(
|
||||
r'I tap the (?:button|element|label|field|text|widget) that contains the text {string}$'),
|
||||
(input1, context) async {
|
||||
final finder = find.text(input1);
|
||||
await context.world.driver.scrollIntoView(finder);
|
||||
await FlutterDriverUtils.tap(
|
||||
context.world.driver,
|
||||
finder,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -10,28 +10,24 @@ import '../parameters/existence_parameter.dart';
|
|||
///
|
||||
/// `Then I expect the text "Logout" to be present`
|
||||
/// `But I expect the text "Signup" to be absent`
|
||||
class TextExistsStep extends When2WithWorld<String, Existence, FlutterWorld> {
|
||||
@override
|
||||
Future<void> executeStep(String text, Existence exists) async {
|
||||
if (exists == Existence.present) {
|
||||
final isPresent = await FlutterDriverUtils.isPresent(
|
||||
world.driver,
|
||||
find.text(text),
|
||||
timeout: timeout,
|
||||
);
|
||||
StepDefinitionGeneric TextExistsStep() {
|
||||
return then2<String, Existence, FlutterWorld>(
|
||||
RegExp(r'I expect the text {string} to be {existence}$'),
|
||||
(text, exists, context) async {
|
||||
if (exists == Existence.present) {
|
||||
final isPresent = await FlutterDriverUtils.isPresent(
|
||||
context.world.driver,
|
||||
find.text(text),
|
||||
);
|
||||
|
||||
expect(isPresent, true);
|
||||
} else {
|
||||
final isAbsent = await FlutterDriverUtils.isAbsent(
|
||||
world.driver,
|
||||
find.text(text),
|
||||
timeout: timeout,
|
||||
);
|
||||
expect(isAbsent, true);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
RegExp get pattern =>
|
||||
RegExp(r'I expect the text {string} to be {existence}$');
|
||||
context.expect(isPresent, true);
|
||||
} else {
|
||||
final isAbsent = await FlutterDriverUtils.isAbsent(
|
||||
context.world.driver,
|
||||
find.text(text),
|
||||
);
|
||||
context.expect(isAbsent, true);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -10,26 +10,23 @@ import '../parameters/existence_parameter.dart';
|
|||
///
|
||||
/// `Then I expect the text "Logout" to be present within the "user_settings_list"`
|
||||
/// `But I expect the text "Signup" to be absent within the "login_screen"`
|
||||
class TextExistsWithinStep
|
||||
extends When3WithWorld<String, Existence, String, FlutterWorld> {
|
||||
@override
|
||||
Future<void> executeStep(
|
||||
String text, Existence exists, String ancestorKey) async {
|
||||
final finder = find.descendant(
|
||||
of: find.byValueKey(ancestorKey),
|
||||
matching: find.text(text),
|
||||
firstMatchOnly: true,
|
||||
);
|
||||
StepDefinitionGeneric TextExistsWithinStep() {
|
||||
return then3<String, Existence, String, FlutterWorld>(
|
||||
RegExp(
|
||||
r'I expect the text {string} to be {existence} within the {string}$'),
|
||||
(text, exists, ancestorKey, context) async {
|
||||
final finder = find.descendant(
|
||||
of: find.byValueKey(ancestorKey),
|
||||
matching: find.text(text),
|
||||
firstMatchOnly: true,
|
||||
);
|
||||
|
||||
final isPresent = await FlutterDriverUtils.isPresent(
|
||||
world.driver,
|
||||
finder,
|
||||
timeout: timeout,
|
||||
);
|
||||
expect(isPresent, exists == Existence.present);
|
||||
}
|
||||
final isPresent = await FlutterDriverUtils.isPresent(
|
||||
context.world.driver,
|
||||
finder,
|
||||
);
|
||||
|
||||
@override
|
||||
RegExp get pattern => RegExp(
|
||||
r'I expect the text {string} to be {existence} within the {string}$');
|
||||
context.expect(isPresent, exists == Existence.present);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -10,23 +10,24 @@ import '../parameters/existence_parameter.dart';
|
|||
///
|
||||
/// `Then I wait until the "login_loading_indicator" is absent`
|
||||
/// `And I wait until the "login_screen" is present`
|
||||
class WaitUntilKeyExistsStep
|
||||
extends When2WithWorld<String, Existence, FlutterWorld> {
|
||||
@override
|
||||
Future<void> executeStep(String keyString, Existence existence) async {
|
||||
await FlutterDriverUtils.waitUntil(
|
||||
world.driver,
|
||||
() {
|
||||
return existence == Existence.absent
|
||||
? FlutterDriverUtils.isAbsent(
|
||||
world.driver, find.byValueKey(keyString))
|
||||
: FlutterDriverUtils.isPresent(
|
||||
world.driver, find.byValueKey(keyString));
|
||||
},
|
||||
timeout: timeout,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
RegExp get pattern => RegExp(r'I wait until the {string} is {existence}');
|
||||
StepDefinitionGeneric WaitUntilKeyExistsStep() {
|
||||
return then2<String, Existence, FlutterWorld>(
|
||||
'I wait until the {string} is {existence}',
|
||||
(keyString, existence, context) async {
|
||||
await FlutterDriverUtils.waitUntil(
|
||||
context.world.driver,
|
||||
() {
|
||||
return existence == Existence.absent
|
||||
? FlutterDriverUtils.isAbsent(
|
||||
context.world.driver,
|
||||
find.byValueKey(keyString),
|
||||
)
|
||||
: FlutterDriverUtils.isPresent(
|
||||
context.world.driver,
|
||||
find.byValueKey(keyString),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -10,22 +10,24 @@ import '../parameters/existence_parameter.dart';
|
|||
///
|
||||
/// `Then I wait until the element of type "ProgressIndicator" is absent`
|
||||
/// `And I wait until the button of type the "MaterialButton" is present`
|
||||
class WaitUntilTypeExistsStep
|
||||
extends When2WithWorld<String, Existence, FlutterWorld> {
|
||||
@override
|
||||
Future<void> executeStep(String ofType, Existence existence) async {
|
||||
await FlutterDriverUtils.waitUntil(
|
||||
world.driver,
|
||||
() {
|
||||
return existence == Existence.absent
|
||||
? FlutterDriverUtils.isAbsent(world.driver, find.byType(ofType))
|
||||
: FlutterDriverUtils.isPresent(world.driver, find.byType(ofType));
|
||||
},
|
||||
timeout: timeout,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
RegExp get pattern => RegExp(
|
||||
r'I wait until the (?:button|element|label|icon|field|text|widget) of type {string} is {existence}');
|
||||
StepDefinitionGeneric WaitUntilTypeExistsStep() {
|
||||
return then2<String, Existence, FlutterWorld>(
|
||||
'I wait until the (?:button|element|label|icon|field|text|widget) of type {string} is {existence}',
|
||||
(ofType, existence, context) async {
|
||||
await FlutterDriverUtils.waitUntil(
|
||||
context.world.driver,
|
||||
() {
|
||||
return existence == Existence.absent
|
||||
? FlutterDriverUtils.isAbsent(
|
||||
context.world.driver,
|
||||
find.byType(ofType),
|
||||
)
|
||||
: FlutterDriverUtils.isPresent(
|
||||
context.world.driver,
|
||||
find.byType(ofType),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import 'package:gherkin/gherkin.dart';
|
|||
/// `When I tap the back widget"`
|
||||
StepDefinitionGeneric WhenTapBackButtonWidget() {
|
||||
return when1<String, FlutterWorld>(
|
||||
RegExp(r'I tap the back (?:button|element|widget)$'),
|
||||
RegExp(r'I tap the back (?:button|element|widget|icon|text)$'),
|
||||
(_, context) async {
|
||||
await FlutterDriverUtils.tap(
|
||||
context.world.driver,
|
||||
|
|
|
@ -2,6 +2,7 @@ import 'package:flutter_gherkin/flutter_gherkin.dart';
|
|||
import 'package:flutter_gherkin/src/flutter/hooks/app_runner_hook.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import 'mocks/parameter_mock.dart';
|
||||
import 'mocks/step_definition_mock.dart';
|
||||
|
||||
void main() {
|
||||
|
@ -22,19 +23,26 @@ void main() {
|
|||
|
||||
config.prepare();
|
||||
expect(config.stepDefinitions, isNotNull);
|
||||
expect(config.stepDefinitions.length, 9);
|
||||
expect(config.stepDefinitions.length, 20);
|
||||
expect(config.customStepParameterDefinitions, isNotNull);
|
||||
expect(config.customStepParameterDefinitions.length, 2);
|
||||
});
|
||||
|
||||
test('common step definition added to existing steps', () {
|
||||
final config = FlutterTestConfiguration()
|
||||
..stepDefinitions = [MockStepDefinition()];
|
||||
..stepDefinitions = [MockStepDefinition()]
|
||||
..customStepParameterDefinitions = [MockParameter()];
|
||||
expect(config.stepDefinitions.length, 1);
|
||||
|
||||
config.prepare();
|
||||
expect(config.stepDefinitions, isNotNull);
|
||||
expect(config.stepDefinitions.length, 10);
|
||||
expect(config.stepDefinitions.length, 21);
|
||||
expect(config.stepDefinitions.elementAt(0),
|
||||
(x) => x is MockStepDefinition);
|
||||
expect(config.customStepParameterDefinitions, isNotNull);
|
||||
expect(config.customStepParameterDefinitions.length, 3);
|
||||
expect(config.customStepParameterDefinitions.elementAt(0),
|
||||
(x) => x is MockParameter);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
import 'package:gherkin/gherkin.dart';
|
||||
|
||||
class MockParameter extends CustomParameter<String> {
|
||||
MockParameter()
|
||||
: super(
|
||||
'MockStringParam',
|
||||
RegExp('a'),
|
||||
(a) => 'a',
|
||||
);
|
||||
}
|
Loading…
Reference in New Issue