cucumber/cucumber-js — pull request #189 by simondean (2014-05-28 23:19:48+00:00)
Title: Support attachments, also known as embeddings

Hi. This pull request implements:

- #124 Embedding screenshots in JSON and HTML reports
- #129 success and failed properties in after and around hooks
- #179 Hooks as steps
- #159 Callback.fail() not supported in hooks.

It also fixes:
- #110 Errors within Before and After hooks should make the scenario fail
- #181 visitRow function is unused

The pull request includes several new cucumber tests under `features/` in the codebase which provide examples of i) how attachments can be used from hooks and from step definitions, ii) how hooks are now reported as steps by the JSON formatter and iii) how you can fail a step using callback("fail") and callback.fail().

Here's a quick example of how the hooks appear as steps in the JSON (taken from `features/hooks.feature`):

``` json
[
{
"id": "some-feature",
"name": "some feature",
"description": "",
"line": 1,
"keyword": "Feature",
"uri": "/features/a.feature",
"elements": [
{
"name": "I've declared one step and it is passing",
"id": "some-feature;i've-declared-one-step-and-it-is-passing",
"line": 3,
"keyword": "Scenario",
"description": "",
"type": "scenario",
"steps": [
{
"name": "scenario",
"keyword": "Around ",
"result": {
"duration": "",
"status": "passed"
},
"match": {}
},
{
"name": "scenario",
"keyword": "Before ",
"result": {
"duration": "",
"status": "passed"
},
"match": {}
},
{
"name": "This step is passing",
"line": 4,
"keyword": "Given ",
"result": {
"duration": "",
"status": "passed"
},
"match": {}
},
{
"name": "scenario",
"keyword": "After ",
"result": {
"duration": "",
"status": "passed"
},
"match": {}
},
{
"name": "scenario",
"keyword": "Around ",
"result": {
"duration": "",
"status": "passed"
},
"match": {}
}
]
}
]
}
]
```

Here's an example of how to attach an attachment from a before hook (these attachment examples are taken from `features/attachments.feature`):

``` javascript
var hooks = function () {
this.Before(function(scenario, callback) {
scenario.attach("text");
callback();
});
};

module.exports = hooks;
```

Attaching from an around hook:

``` javascript
var hooks = function () {
this.Around(function(scenario, runScenario) {
scenario.attach("text");

runScenario(function(scenario, callback) {
scenario.attach("more text");
callback();
});
});
};

module.exports = hooks;
```

I've implemented #179 "Hooks as steps" as part of this pull request to avoid over complicating the way reporters/listeners/formatters work when attaching from a hook. See the getCurrentStep method in https://github.com/cucumber/gherkin/blob/master/java/src/main/java/gherkin/formatter/JSONFormatter.java to contrast with the other way this could have been implemented (Gerkin's Java JSONFormatter has to rewind time to earlier steps in order to add attachments to the last step that executed/failed).