diff --git a/lib/src/flutter/code_generation/generators/gherkin_suite_test_generator.dart b/lib/src/flutter/code_generation/generators/gherkin_suite_test_generator.dart index fb7176f..ac714d0 100644 --- a/lib/src/flutter/code_generation/generators/gherkin_suite_test_generator.dart +++ b/lib/src/flutter/code_generation/generators/gherkin_suite_test_generator.dart @@ -8,7 +8,18 @@ import 'package:glob/glob.dart'; import 'package:glob/list_local_fs.dart'; import 'package:source_gen/source_gen.dart'; -class NoOpReporter extends Reporter {} +class NoOpReporter extends MessageReporter { + @override + Future message(String message, MessageLevel level) async { + if(level == MessageLevel.info || level == MessageLevel.debug) { + print(message); + }else if(level == MessageLevel.warning) { + print('\x1B[33m$message\x1B[0m'); + }else if(level == MessageLevel.error) { + print('\x1B[31m$message\x1B[0m'); + } + } +} class GherkinSuiteTestGenerator extends GeneratorForAnnotation { @@ -52,16 +63,12 @@ void executeTestSuite( .getField('index')! .toIntValue()!; final executionOrder = ExecutionOrder.values[idx]; - final featureFiles = annotation + final featureFiles = annotation .read('featurePaths') .listValue .map((path) => Glob(path.toStringValue()!)) - .map( - (glob) => glob - .listSync() - .map((entity) => File(entity.path).readAsStringSync()) - .toList(), - ) + .map((glob) => + glob.listSync().map((entity) => File(entity.path)).toList()) .reduce((value, element) => value..addAll(element)); if (executionOrder == ExecutionOrder.random) { @@ -73,11 +80,11 @@ void executeTestSuite( final featuresToExecute = new StringBuffer(); var id = 0; - for (var featureFileContent in featureFiles) { + for (var featureFile in featureFiles) { final code = await generator.generate( id++, - featureFileContent, - '', + featureFile.readAsStringSync(), + featureFile.absolute.path, _languageService, _reporter, ); @@ -104,7 +111,7 @@ class FeatureFileTestGenerator { String featureFileContents, String path, LanguageService languageService, - Reporter reporter, + MessageReporter reporter, ) async { final visitor = FeatureFileTestGeneratorVisitor(); @@ -148,14 +155,14 @@ class FeatureFileTestGeneratorVisitor extends FeatureFileVisitor { {{step_multi_line_strings}}, {{step_table}}, dependencies, - hasToSkip + hasToSkip, );} '''; static const String ON_BEFORE_SCENARIO_RUN = ''' onBefore: () async => onBeforeRunFeature('{{feature_name}}', {{feature_tags}},), '''; static const String ON_AFTER_SCENARIO_RUN = ''' - onAfter: () async => onAfterRunFeature('{{feature_name}}',), + onAfter: () async => onAfterRunFeature('{{feature_name}}', '{{path}}'), '''; final StringBuffer _buffer = StringBuffer(); @@ -171,7 +178,7 @@ class FeatureFileTestGeneratorVisitor extends FeatureFileVisitor { String featureFileContents, String path, LanguageService languageService, - Reporter reporter, + MessageReporter reporter, ) async { _id = id; await visit( @@ -214,14 +221,9 @@ class FeatureFileTestGeneratorVisitor extends FeatureFileVisitor { } @override - Future visitScenario( - String featureName, - Iterable featureTags, - String name, - Iterable tags, - bool isFirst, - bool isLast, - ) async { + Future visitScenario(String featureName, Iterable featureTags, + String name, Iterable tags, String path, + {required bool isFirst, required bool isLast}) async { _flushScenario(); _currentScenarioCode = _replaceVariable( SCENARIO_TEMPLATE, @@ -238,6 +240,11 @@ class FeatureFileTestGeneratorVisitor extends FeatureFileVisitor { 'feature_name', _escapeText(featureName), ); + _currentScenarioCode = _replaceVariable( + _currentScenarioCode!, + 'path', + _escapeText(path), + ); _currentScenarioCode = _replaceVariable( _currentScenarioCode!, 'feature_tags', diff --git a/lib/src/flutter/configuration/flutter_test_configuration.dart b/lib/src/flutter/configuration/flutter_test_configuration.dart index 46764f2..920589e 100644 --- a/lib/src/flutter/configuration/flutter_test_configuration.dart +++ b/lib/src/flutter/configuration/flutter_test_configuration.dart @@ -24,32 +24,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:gherkin/gherkin.dart'; class FlutterTestConfiguration extends TestConfiguration { - - /// ~~The path(s) to all the features.~~ - /// ~~All three [Pattern]s are supported: [RegExp], [String], [Glob].~~ - /// - /// Instead of using this variable, give the features in the `@GherkinTestSuite(features: [])` option. - @deprecated - Iterable features = const []; - - /// ~~The execution order of features - this default to random to avoid any inter-test dependencies~~ - /// - /// Instead of using this variable, give the executionOrder in the `@GherkinTestSuite(executionOrder: ExecutionOrder.random)` option. - @deprecated - ExecutionOrder order = ExecutionOrder.random; - - /// ~~Lists feature files paths, which match [features] patterns.~~ - /// - /// Instead of using this variable, give the features in the `@GherkinTestSuite(features: [])` option. - @deprecated - FeatureFileMatcher featureFileMatcher = const IoFeatureFileAccessor(); - - /// ~~The feature file reader.~~ - /// ~~Takes files/resources paths from [featureFileIndexer] and returns their content as String.~~ - /// - /// Instead of using this variable, give the features in the `@GherkinTestSuite(features: [])` option. - @deprecated - FeatureFileReader featureFileReader = const IoFeatureFileAccessor(); /// Enable semantics in a test by creating a [SemanticsHandle]. /// See: [testWidgets] and [WidgetController.ensureSemantics]. @@ -63,7 +37,6 @@ class FlutterTestConfiguration extends TestConfiguration { String targetAppPath = 'test_driver/integration_test_driver.dart', }) { return FlutterTestConfiguration() - ..features = [RegExp(featurePath)] ..reporters = [ StdoutReporter(MessageLevel.error), ProgressReporter(), diff --git a/lib/src/flutter/hooks/app_runner_hook.dart b/lib/src/flutter/hooks/app_runner_hook.dart index 4cc21cc..248fe6f 100644 --- a/lib/src/flutter/hooks/app_runner_hook.dart +++ b/lib/src/flutter/hooks/app_runner_hook.dart @@ -39,7 +39,7 @@ class FlutterAppRunnerHook extends Hook { TestConfiguration config, String scenario, Iterable tags, - bool failed, + {bool? passed,} ) async { final flutterConfig = _castConfig(config); haveRunFirstScenario = true; diff --git a/lib/src/flutter/runners/gherkin_integration_test_runner.dart b/lib/src/flutter/runners/gherkin_integration_test_runner.dart index 84c8327..1b7496c 100644 --- a/lib/src/flutter/runners/gherkin_integration_test_runner.dart +++ b/lib/src/flutter/runners/gherkin_integration_test_runner.dart @@ -1,8 +1,4 @@ -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'; import 'package:gherkin/gherkin.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -24,14 +20,14 @@ abstract class GherkinIntegrationTestRunner { TagExpressionEvaluator(); final TestConfiguration configuration; final Future Function(World world) appMainFunction; - Reporter? _reporter; + AggregatedReporter _reporter = new AggregatedReporter(); Hook? _hook; Iterable? _executableSteps; Iterable? _customParameters; IntegrationTestWidgetsFlutterBinding? _binding; - Reporter get reporter => _reporter!; + AggregatedReporter get reporter => _reporter; Hook get hook => _hook!; LiveTestWidgetsFlutterBindingFramePolicy? get framePolicy => null; @@ -42,7 +38,7 @@ abstract class GherkinIntegrationTestRunner { this.appMainFunction, ) { configuration.prepare(); - _reporter = _registerReporters(configuration.reporters); + _registerReporters(configuration.reporters); _hook = _registerHooks(configuration.hooks); _customParameters = _registerCustomParameters(configuration.customStepParameterDefinitions); @@ -66,7 +62,7 @@ abstract class GherkinIntegrationTestRunner { ); _safeInvokeFuture(() async => await hook.onBeforeRun(configuration)); - _safeInvokeFuture(() async => await reporter.onTestRunStarted()); + _safeInvokeFuture(() async => await reporter.test.onStarted.maybeCall()); onRun(); } @@ -74,7 +70,7 @@ abstract class GherkinIntegrationTestRunner { void onRun(); void onRunComplete() { - _safeInvokeFuture(() async => await reporter.onTestRunFinished()); + _safeInvokeFuture(() async => await reporter.test.onFinished.maybeCall()); _safeInvokeFuture(() async => await hook.onAfterRun(configuration)); setTestResultData(_binding!); _safeInvokeFuture(() async => await reporter.dispose()); @@ -82,7 +78,7 @@ abstract class GherkinIntegrationTestRunner { void setTestResultData(IntegrationTestWidgetsFlutterBinding binding) { if (reporter is SerializableReporter) { - final json = (reporter as SerializableReporter).toJson(); + final json = (reporter as SerializableReporter).serialize(); binding.reportData = {'gherkin_reports': json}; } } @@ -109,12 +105,11 @@ abstract class GherkinIntegrationTestRunner { final debugInformation = RunnableDebugInformation('', 0, name); final featureTags = (tags ?? Iterable.empty()).map((t) => Tag(t.toString(), 0)); - await reporter.onFeatureStarted( - StartedMessage( - Target.feature, - name, - debugInformation, - featureTags, + await reporter.feature.onStarted.maybeCall( + FeatureMessage( + name: name, + context: debugInformation, + tags: featureTags.toList(), ), ); } @@ -122,13 +117,14 @@ abstract class GherkinIntegrationTestRunner { @protected Future onAfterRunFeature( String name, + String path ) async { - final debugInformation = RunnableDebugInformation('', 0, name); - await reporter.onFeatureFinished( - FinishedMessage( - Target.feature, - name, - debugInformation, + final debugInformation = RunnableDebugInformation(path, 0, name); + await reporter.test.onFinished.maybeCall( + TestMessage( + target: Target.feature, + name: name, + context: debugInformation, ), ); } @@ -138,7 +134,7 @@ abstract class GherkinIntegrationTestRunner { String name, Iterable? tags, List Function(TestDependencies dependencies, bool skip,)> - steps, { + steps, String path, { Future Function()? onBefore, Future Function()? onAfter, }) { @@ -151,7 +147,7 @@ abstract class GherkinIntegrationTestRunner { } var failed = false; - final debugInformation = RunnableDebugInformation('', 0, name); + final debugInformation = RunnableDebugInformation(path, 0, name); final scenarioTags = (tags ?? Iterable.empty()).map((t) => Tag(t.toString(), 0)); final dependencies = await createTestDependencies( @@ -177,12 +173,11 @@ abstract class GherkinIntegrationTestRunner { scenarioTags, ); - await reporter.onScenarioStarted( - StartedMessage( - Target.scenario, - name, - debugInformation, - scenarioTags, + await reporter.scenario.onStarted.maybeCall( + ScenarioMessage( + name: name, + context: debugInformation, + tags: scenarioTags.toList(), ), ); var hasToSkip = false; @@ -200,11 +195,11 @@ abstract class GherkinIntegrationTestRunner { } } } finally { - await reporter.onScenarioFinished( - ScenarioFinishedMessage( - name, - debugInformation, - !failed, + await reporter.scenario.onFinished.maybeCall( + ScenarioMessage( + name: name, + context: debugInformation, + hasPassed: !failed, ), ); @@ -212,7 +207,7 @@ abstract class GherkinIntegrationTestRunner { configuration, name, scenarioTags, - !failed, + passed: !failed, ); if (onAfter != null) { @@ -300,7 +295,7 @@ abstract class GherkinIntegrationTestRunner { if (hasToSkip) { result = new StepResult( - 0, StepExecutionResult.skipped, "Previous step(s) failed."); + 0, StepExecutionResult.skipped, resultReason: "Previous step(s) failed."); } else { for (int i = 0; i < this.configuration.stepMaxRetries + 1; i++) { result = await executable.step.run( @@ -345,13 +340,10 @@ abstract class GherkinIntegrationTestRunner { ); } - Reporter _registerReporters(Iterable? reporters) { - final reporter = AggregatedReporter(); + void _registerReporters(Iterable? reporters) { if (reporters != null) { - reporters.forEach((r) => reporter.addReporter(r)); + reporters.forEach((r) => _reporter.addReporter(r)); } - - return reporter; } Hook _registerHooks(Iterable? hooks) { @@ -429,12 +421,12 @@ abstract class GherkinIntegrationTestRunner { result, ); - await reporter.onStepFinished( - StepFinishedMessage( - step, - RunnableDebugInformation('', 0, step), - result, - dependencies.attachmentManager.getAttachmentsForContext(step), + await reporter.step.onStarted.maybeCall( + StepMessage( + name: step, + context: RunnableDebugInformation('', 0, step), + result: result, + attachments: dependencies.attachmentManager.getAttachmentsForContext(step).toList(), ), ); } @@ -446,10 +438,10 @@ abstract class GherkinIntegrationTestRunner { Iterable multiLineStrings, ) async { await hook.onBeforeStep(world, step); - await reporter.onStepStarted( - StepStartedMessage( - step, - RunnableDebugInformation('', 0, step), + await reporter.step.onStarted.maybeCall( + StepMessage( + name: step, + context: RunnableDebugInformation('', 0, step), table: table, multilineString: multiLineStrings.isNotEmpty ? multiLineStrings.first : null, diff --git a/lib/src/flutter/steps/then_expect_element_to_have_value_step.dart b/lib/src/flutter/steps/then_expect_element_to_have_value_step.dart index b1bf22c..c0c175f 100644 --- a/lib/src/flutter/steps/then_expect_element_to_have_value_step.dart +++ b/lib/src/flutter/steps/then_expect_element_to_have_value_step.dart @@ -22,7 +22,7 @@ StepDefinitionGeneric ThenExpectElementToHaveValue() { context.expect(text, value); } catch (e) { - await context.reporter.message('Step error: $e', MessageLevel.error); + // await context.reporter('Step error: $e', MessageLevel.error); rethrow; } }, diff --git a/pubspec.lock b/pubspec.lock index 06031d1..df06d64 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -21,7 +21,7 @@ packages: name: archive url: "https://pub.dartlang.org" source: hosted - version: "3.1.2" + version: "3.1.11" args: dependency: transitive description: @@ -35,7 +35,7 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.8.1" + version: "2.8.2" boolean_selector: dependency: transitive description: @@ -63,7 +63,7 @@ packages: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.2.0" charcode: dependency: transitive description: @@ -98,7 +98,7 @@ packages: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.15.0" + version: "1.16.0" convert: dependency: transitive description: @@ -126,7 +126,7 @@ packages: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.3.0" file: dependency: transitive description: @@ -160,7 +160,7 @@ packages: name: gherkin url: "https://pub.dartlang.org" source: hosted - version: "2.0.8" + version: "3.0.0" glob: dependency: "direct main" description: @@ -193,7 +193,14 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.10" + version: "0.12.11" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.4" meta: dependency: "direct dev" description: @@ -214,7 +221,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.0" + version: "1.8.1" pedantic: dependency: "direct dev" description: @@ -228,14 +235,14 @@ packages: name: platform url: "https://pub.dartlang.org" source: hosted - version: "3.0.0" + version: "3.1.0" process: dependency: transitive description: name: process url: "https://pub.dartlang.org" source: hosted - version: "4.2.3" + version: "4.2.4" pub_semver: dependency: transitive description: @@ -268,7 +275,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.1" + version: "1.8.2" stack_trace: dependency: transitive description: @@ -310,7 +317,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.2" + version: "0.4.9" typed_data: dependency: transitive description: @@ -318,20 +325,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.0" + uuid: + dependency: transitive + description: + name: uuid + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.6" vector_math: dependency: transitive description: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.1.2" vm_service: dependency: transitive description: name: vm_service url: "https://pub.dartlang.org" source: hosted - version: "7.1.1" + version: "8.2.2" watcher: dependency: transitive description: @@ -354,5 +368,5 @@ packages: source: hosted version: "3.1.0" sdks: - dart: ">=2.14.0 <3.0.0" + dart: ">=2.17.0-0 <3.0.0" flutter: ">=2.2.0" diff --git a/pubspec.yaml b/pubspec.yaml index 2823f68..5c14074 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -18,7 +18,7 @@ dependencies: sdk: flutter analyzer: ">=1.7.1 <3.0.0" collection: ^1.15.0 - gherkin: ^2.0.8 + gherkin: ^3.0.0 source_gen: ^1.1.1 build: ^2.1.1 glob: ^2.0.2