feat(screenshots): added ability to include a pre-defined hook that attached screenshot to the world if a step fails

This commit is contained in:
Jon Samwell 2019-06-21 08:14:51 +10:00
parent 98c956bc18
commit 704b7f9cf2
9 changed files with 102 additions and 14 deletions

View File

@ -1,3 +1,7 @@
## [1.0.3] - 21/06/2019
* Added ability to include a hook (see `AttachScreenhotOnFailedStepHook`) that takes a screenshot after a failed step. If using the json reporter it include the screenshot in the report that can then be used to generate a HTML report.
* Updated to latest dart_gherkin lib
## [1.0.2] - 05/06/2019
* Fixed analysis suggestions

View File

@ -56,6 +56,8 @@ Available as a Dart package https://pub.dartlang.org/packages/flutter_gherkin
- [Assertions](#assertions)
- [Tags](#tags)
- [Hooks](#hooks)
- [Attachements](#attachments)
- [Screenshot on step failure](#screenshot)
- [Reporting](#reporting)
- [Flutter](#flutter)
- [Restarting the app before each test](#restarting-the-app-before-each-test)
@ -269,12 +271,65 @@ Future<void> main() {
#### hooks
Hooks are custom bits of code that can be run at certain points with the test run such as before or after a scenario. Place instances of any custom `Hook` class instance in this collection. They will then be run at the defined points with the test run. See [Hooks](#hooks).
Hooks are custom bits of code that can be run at certain points with the test run such as before or after a scenario. Place instances of any custom `Hook` class instance in this collection. They will then be run at the defined points with the test run.
#### attachments
Attachment are pieces of data you can attach to a running scenario. This could be simple bits of textual data or even image like a screenshot. These attachments can then be used by reporters to provide more contextual information. For example when a step fails some contextual information could be attached to the scenario which is then used by a reporter to display why the step failed.
Attachments would typically be attached via a `Hook` for example `onAfterStep`.
```
import 'package:gherkin/gherkin.dart';
class AttachScreenhotOnFailedStepHook extends Hook {
/// Run after a step has executed
@override
Future<void> onAfterStep(World world, String step, StepResult stepResult) async {
if (stepResult.result == StepExecutionResult.fail) {
world.attach('Some info.','text/plain');
world.attach('{"some", "JSON"}}', 'application/json');
}
}
}
```
##### screenshot
To take a screenshot on a step failing you can used the pre-defined hook `AttachScreenhotOnFailedStepHook` and include it in the hook configuration of the tests config. This hook will take a screenshot and add it as an attachment to the scenerio. If the `JsonReporter` is being used the screenshot will be embedded in the report which can be used to generate a HTML report which will ultimately display the screenshot under the failed step.
```
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';
import 'steps/tap_button_n_times_step.dart';
Future<void> main() {
final config = FlutterTestConfiguration()
..features = [Glob(r"test_driver/features/**.feature")]
..reporters = [
ProgressReporter(),
TestRunSummaryReporter(),
JsonReporter(path: './report.json')
]
..hooks = [HookExample(), AttachScreenhotOnFailedStepHook()]
..stepDefinitions = [TapButtonNTimesStep(), GivenIPickAColour()]
..customStepParameterDefinitions = [ColourParameter()]
..restartAppBetweenScenarios = true
..targetAppPath = "test_driver/app.dart"
..exitAfterTestRun = true; // set to false if debugging to exit cleanly
return GherkinRunner().execute(config);
}
```
#### reporters
*Required*
Reporters are classes that are able to report on the status of the test run. This could be a simple as merely logging scenario result to the console. There are a number of built-in reporter:
- `StdoutReporter` : Logs all messages from the test run to the standard output (console).

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,5 @@
import 'package:example/main.dart' as app;
// ignore: avoid_relative_lib_imports
import '../lib/main.dart' as app;
import 'package:flutter_driver/driver_extension.dart';
void main() {

View File

@ -15,7 +15,9 @@ Future<void> main() {
TestRunSummaryReporter(),
JsonReporter(path: './report.json')
] // you can include the "StdoutReporter()" without the message level parameter for verbose log information
..hooks = [HookExample()]
..hooks = [
HookExample()
] // you can include "AttachScreenhotOnFailedStepHook()" to take a screenshot of each step failure and attach it to the world object
..stepDefinitions = [TapButtonNTimesStep(), GivenIPickAColour()]
..customStepParameterDefinitions = [ColourParameter()]
..restartAppBetweenScenarios = true

View File

@ -11,3 +11,6 @@ export 'src/flutter/steps/then_expect_element_to_have_value_step.dart';
export 'src/flutter/steps/when_fill_field_step.dart';
export 'src/flutter/steps/when_pause_step.dart';
export 'src/flutter/steps/when_tap_widget_step.dart';
// Hooks
export 'src/flutter/hooks/attach_screenshot_on_failed_step_hook.dart';

View File

@ -0,0 +1,23 @@
import 'dart:convert';
import 'package:gherkin/gherkin.dart';
import 'package:meta/meta.dart';
import '../flutter_world.dart';
class AttachScreenhotOnFailedStepHook extends Hook {
@override
Future<void> onAfterStep(
World world, String step, StepResult stepResult) async {
if (stepResult.result == StepExecutionResult.fail) {
final screenshotData = await takeScreenshot(world);
world.attach(screenshotData, 'image/png', step);
}
}
@protected
Future<String> takeScreenshot(World world) async {
final bytes = await (world as FlutterWorld).driver.screenshot();
return base64Encode(bytes);
}
}

View File

@ -104,7 +104,7 @@ packages:
name: gherkin
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
version: "1.0.3"
glob:
dependency: "direct main"
description:
@ -183,7 +183,7 @@ packages:
source: hosted
version: "0.12.5"
meta:
dependency: transitive
dependency: "direct main"
description:
name: meta
url: "https://pub.dartlang.org"
@ -232,7 +232,7 @@ packages:
source: hosted
version: "1.6.2"
pedantic:
dependency: "direct main"
dependency: transitive
description:
name: pedantic
url: "https://pub.dartlang.org"
@ -417,6 +417,6 @@ packages:
name: yaml
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.15"
version: "2.1.16"
sdks:
dart: ">=2.2.0 <3.0.0"

View File

@ -1,6 +1,6 @@
name: flutter_gherkin
description: A Gherkin / Cucumber parser and test runner for Dart and Flutter
version: 1.0.2
version: 1.0.3
author: Jon Samwell <jonsamwell@gmail.com>
homepage: https://github.com/jonsamwell/flutter_gherkin
@ -15,10 +15,10 @@ dependencies:
flutter_driver:
sdk: flutter
glob: ^1.1.7
pedantic: ^1.5.0
gherkin: ^1.0.0
meta: ^1.1.6
gherkin: ^1.0.3
dev_dependencies:
test: 1.6.1
test: any
flutter: