The test case gets retried 3 times and the other steps will get skipped
This commit is contained in:
parent
61146d84b2
commit
3772e89b9c
|
@ -10,7 +10,8 @@ import 'package:source_gen/source_gen.dart';
|
|||
|
||||
class NoOpReporter extends Reporter {}
|
||||
|
||||
class GherkinSuiteTestGenerator extends GeneratorForAnnotation<GherkinTestSuite> {
|
||||
class GherkinSuiteTestGenerator
|
||||
extends GeneratorForAnnotation<GherkinTestSuite> {
|
||||
static const String TEMPLATE = '''
|
||||
class _CustomGherkinIntegrationTestRunner extends GherkinIntegrationTestRunner {
|
||||
_CustomGherkinIntegrationTestRunner(
|
||||
|
@ -45,14 +46,21 @@ void executeTestSuite(
|
|||
_languageService.initialise(
|
||||
annotation.read('featureDefaultLanguage').literalValue.toString(),
|
||||
);
|
||||
final idx = annotation.read('executionOrder').objectValue.getField('index')!.toIntValue()!;
|
||||
final idx = annotation
|
||||
.read('executionOrder')
|
||||
.objectValue
|
||||
.getField('index')!
|
||||
.toIntValue()!;
|
||||
final executionOrder = ExecutionOrder.values[idx];
|
||||
final featureFiles = annotation
|
||||
.read('featurePaths')
|
||||
.listValue
|
||||
.map((path) => Glob(path.toStringValue()!))
|
||||
.map(
|
||||
(glob) => glob.listSync().map((entity) => File(entity.path).readAsStringSync()).toList(),
|
||||
(glob) => glob
|
||||
.listSync()
|
||||
.map((entity) => File(entity.path).readAsStringSync())
|
||||
.toList(),
|
||||
)
|
||||
.reduce((value, element) => value..addAll(element));
|
||||
|
||||
|
@ -80,7 +88,10 @@ void executeTestSuite(
|
|||
}
|
||||
}
|
||||
|
||||
return TEMPLATE.replaceAll('{{feature_functions}}', featureExecutionFunctionsBuilder.toString()).replaceAll(
|
||||
return TEMPLATE
|
||||
.replaceAll('{{feature_functions}}',
|
||||
featureExecutionFunctionsBuilder.toString())
|
||||
.replaceAll(
|
||||
'{{features_to_execute}}',
|
||||
featuresToExecute.toString(),
|
||||
);
|
||||
|
@ -123,20 +134,22 @@ class FeatureFileTestGeneratorVisitor extends FeatureFileVisitor {
|
|||
runScenario(
|
||||
'{{scenario_name}}',
|
||||
{{tags}},
|
||||
(TestDependencies dependencies) async {
|
||||
[
|
||||
{{steps}}
|
||||
},
|
||||
],
|
||||
{{onBefore}}
|
||||
{{onAfter}}
|
||||
);
|
||||
''';
|
||||
static const String STEP_TEMPLATE = '''
|
||||
await runStep(
|
||||
(TestDependencies dependencies, bool hasToSkip) async {
|
||||
return await runStep(
|
||||
'{{step_name}}',
|
||||
{{step_multi_line_strings}},
|
||||
{{step_table}},
|
||||
dependencies,
|
||||
);
|
||||
hasToSkip
|
||||
);}
|
||||
''';
|
||||
static const String ON_BEFORE_SCENARIO_RUN = '''
|
||||
onBefore: () async => onBeforeRunFeature('{{feature_name}}', {{feature_tags}},),
|
||||
|
@ -151,6 +164,7 @@ class FeatureFileTestGeneratorVisitor extends FeatureFileVisitor {
|
|||
String? _currentScenarioCode;
|
||||
final StringBuffer _scenarioBuffer = StringBuffer();
|
||||
final StringBuffer _stepBuffer = StringBuffer();
|
||||
final _steps = [];
|
||||
|
||||
Future<String> generateTests(
|
||||
int id,
|
||||
|
@ -207,7 +221,6 @@ class FeatureFileTestGeneratorVisitor extends FeatureFileVisitor {
|
|||
Iterable<String> tags,
|
||||
bool isFirst,
|
||||
bool isLast,
|
||||
String path,
|
||||
) async {
|
||||
_flushScenario();
|
||||
_currentScenarioCode = _replaceVariable(
|
||||
|
@ -266,6 +279,7 @@ class FeatureFileTestGeneratorVisitor extends FeatureFileVisitor {
|
|||
);
|
||||
|
||||
_stepBuffer.writeln(code);
|
||||
_steps.add(code);
|
||||
}
|
||||
|
||||
void _flushFeature() {
|
||||
|
@ -285,11 +299,11 @@ class FeatureFileTestGeneratorVisitor extends FeatureFileVisitor {
|
|||
|
||||
void _flushScenario() {
|
||||
if (_currentScenarioCode != null) {
|
||||
if (_stepBuffer.isNotEmpty) {
|
||||
if (_steps.isNotEmpty) {
|
||||
_currentScenarioCode = _replaceVariable(
|
||||
_currentScenarioCode!,
|
||||
'steps',
|
||||
_stepBuffer.toString(),
|
||||
_steps.join(','),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ class FlutterAppRunnerHook extends Hook {
|
|||
TestConfiguration config,
|
||||
String scenario,
|
||||
Iterable<Tag> tags,
|
||||
bool failed,
|
||||
) async {
|
||||
final flutterConfig = _castConfig(config);
|
||||
haveRunFirstScenario = true;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import 'dart:math';
|
||||
|
||||
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';
|
||||
|
@ -135,7 +137,8 @@ abstract class GherkinIntegrationTestRunner {
|
|||
void runScenario(
|
||||
String name,
|
||||
Iterable<String>? tags,
|
||||
Future<void> Function(TestDependencies dependencies) runTest, {
|
||||
List<Future<StepResult> Function(TestDependencies dependencies, bool skip)>
|
||||
steps, {
|
||||
Future<void> Function()? onBefore,
|
||||
Future<void> Function()? onAfter,
|
||||
}) {
|
||||
|
@ -146,6 +149,7 @@ abstract class GherkinIntegrationTestRunner {
|
|||
if (onBefore != null) {
|
||||
await onBefore();
|
||||
}
|
||||
var failed = false;
|
||||
|
||||
final debugInformation = RunnableDebugInformation('', 0, name);
|
||||
final scenarioTags =
|
||||
|
@ -181,14 +185,26 @@ abstract class GherkinIntegrationTestRunner {
|
|||
scenarioTags,
|
||||
),
|
||||
);
|
||||
|
||||
await runTest(dependencies);
|
||||
var hasToSkip = false;
|
||||
for (int i = 0; i < steps.length; i++) {
|
||||
try {
|
||||
final result = await steps[i](dependencies, hasToSkip);
|
||||
if (_isNegativeResult(result.result)) {
|
||||
failed = true;
|
||||
hasToSkip = true;
|
||||
}
|
||||
} catch (e) {
|
||||
failed = true;
|
||||
hasToSkip = true;
|
||||
// rethrow;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
await reporter.onScenarioFinished(
|
||||
ScenarioFinishedMessage(
|
||||
name,
|
||||
debugInformation,
|
||||
true,
|
||||
!failed,
|
||||
),
|
||||
);
|
||||
|
||||
|
@ -196,6 +212,7 @@ abstract class GherkinIntegrationTestRunner {
|
|||
configuration,
|
||||
name,
|
||||
scenarioTags,
|
||||
!failed,
|
||||
);
|
||||
|
||||
if (onAfter != null) {
|
||||
|
@ -254,12 +271,8 @@ abstract class GherkinIntegrationTestRunner {
|
|||
}
|
||||
|
||||
@protected
|
||||
Future<StepResult> runStep(
|
||||
String step,
|
||||
Iterable<String> multiLineStrings,
|
||||
dynamic table,
|
||||
TestDependencies dependencies,
|
||||
) async {
|
||||
Future<StepResult> runStep(String step, Iterable<String> multiLineStrings,
|
||||
dynamic table, TestDependencies dependencies, bool hasToSkip) async {
|
||||
final executable = _executableSteps!.firstWhereOrNull(
|
||||
(s) => s.expression.isMatch(step),
|
||||
);
|
||||
|
@ -283,28 +296,43 @@ abstract class GherkinIntegrationTestRunner {
|
|||
multiLineStrings,
|
||||
);
|
||||
|
||||
final result = await executable.step.run(
|
||||
dependencies.world,
|
||||
reporter,
|
||||
configuration.defaultTimeout,
|
||||
parameters,
|
||||
);
|
||||
StepResult? result;
|
||||
|
||||
if (hasToSkip) {
|
||||
result = new StepResult(
|
||||
0, StepExecutionResult.skipped, "Previous step(s) failed.");
|
||||
} else {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
result = await executable.step.run(
|
||||
dependencies.world,
|
||||
reporter,
|
||||
configuration.defaultTimeout,
|
||||
parameters,
|
||||
);
|
||||
if (!_isNegativeResult(result.result)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
await _onAfterStepRun(
|
||||
step,
|
||||
result,
|
||||
result!,
|
||||
dependencies,
|
||||
);
|
||||
|
||||
if (result.result == StepExecutionResult.fail) {
|
||||
throw TestFailure('Step: $step \n\n${result.resultReason}');
|
||||
} else if (result is ErroredStepResult) {
|
||||
throw result.exception;
|
||||
if (result is ErroredStepResult) {
|
||||
// result.resultReason = result.exception.toString();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool _isNegativeResult(StepExecutionResult result) {
|
||||
return result == StepExecutionResult.error ||
|
||||
result == StepExecutionResult.fail ||
|
||||
result == StepExecutionResult.timeout;
|
||||
}
|
||||
|
||||
@protected
|
||||
void cleanupScenarioRun(TestDependencies dependencies) {
|
||||
_safeInvokeFuture(
|
||||
|
|
Loading…
Reference in New Issue