Skip to content

Commit

Permalink
attachments: support attaching already-encoded base64 content (#1552)
Browse files Browse the repository at this point in the history
* add new scenario

* new notation

* implement

* documentation

* changelog

* Update CHANGELOG.md

* remove unnecessary comment

* i am bad at markdown
  • Loading branch information
davidjgoss authored Feb 2, 2021
1 parent e2731ed commit 6489d97
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 6 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Please see [CONTRIBUTING.md](https://github.com/cucumber/cucumber/blob/master/CO

### Added

- Support attachments that are already base64-encoded via a prefix on the MIME type e.g. `this.attach(base64String, 'base64:image/png')` ([#1552](https://github.com/cucumber/cucumber-js/pull/1552))

### Changed

### Deprecated
Expand Down
16 changes: 14 additions & 2 deletions docs/support_files/attachments.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,19 @@ After(function (testCase) {
});
```

If you've already got a base64-encoded string, you can prefix your mime type with `base64:` to indicate this:

```javascript
var {After, Status} = require('@cucumber/cucumber');

After(function (testCase) {
if (testCase.result.status === Status.FAILED) {
var base64String = getScreenshotOfError();
this.attach(base64String, 'base64:image/png');
}
});
```

Here is an example of saving a screenshot using [Selenium WebDriver](https://www.npmjs.com/package/selenium-webdriver)
when a scenario fails:

Expand All @@ -75,8 +88,7 @@ After(function (testCase) {
var world = this;
if (testCase.result.status === Status.FAILED) {
return webDriver.takeScreenshot().then(function(screenShot) {
// screenShot is a base-64 encoded PNG
world.attach(screenShot, 'image/png');
world.attach(screenShot, 'base64:image/png');
});
}
});
Expand Down
14 changes: 14 additions & 0 deletions features/attachments.feature
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,20 @@ Feature: Attachments
| DATA | MEDIA TYPE | MEDIA ENCODING |
| iVBORw== | image/png | BASE64 |

Scenario: Attach a string that is already base64 encoded
Given a file named "features/support/hooks.js" with:
"""
const {Before} = require('@cucumber/cucumber')
Before(function() {
this.attach(Buffer.from([137, 80, 78, 71]).toString('base64'), 'base64:image/png')
})
"""
When I run cucumber-js
Then scenario "some scenario" "Before" hook has the attachments:
| DATA | MEDIA TYPE | MEDIA ENCODING |
| iVBORw== | image/png | BASE64 |

Scenario: Attach a stream (callback)
Given a file named "features/support/hooks.js" with:
"""
Expand Down
15 changes: 11 additions & 4 deletions src/runtime/attachment_manager/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,17 @@ export default class AttachmentManager {
if (doesNotHaveValue(mediaType)) {
mediaType = 'text/plain'
}
this.createStringAttachment(data, {
encoding: messages.Attachment.ContentEncoding.IDENTITY,
contentType: mediaType,
})
if (mediaType.startsWith('base64:')) {
this.createStringAttachment(data, {
encoding: messages.Attachment.ContentEncoding.BASE64,
contentType: mediaType.replace('base64:', ''),
})
} else {
this.createStringAttachment(data, {
encoding: messages.Attachment.ContentEncoding.IDENTITY,
contentType: mediaType,
})
}
} else {
throw Error(
'Invalid attachment data: must be a buffer, readable stream, or string'
Expand Down
28 changes: 28 additions & 0 deletions src/runtime/attachment_manager/index_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,34 @@ describe('AttachmentManager', () => {
})
})

describe('with media type, already base64 encoded', () => {
it('adds the data and media', function () {
// Arrange
const attachments: IAttachment[] = []
const attachmentManager = new AttachmentManager((x) =>
attachments.push(x)
)

// Act
const result = attachmentManager.create(
Buffer.from('my string', 'utf8').toString('base64'),
'base64:text/special'
)

// Assert
expect(result).to.eql(undefined)
expect(attachments).to.eql([
{
data: 'bXkgc3RyaW5n',
media: {
contentType: 'text/special',
encoding: messages.Attachment.ContentEncoding.BASE64,
},
},
])
})
})

describe('without mime type', () => {
it('adds the data with the default mime type', function () {
// Arrange
Expand Down

0 comments on commit 6489d97

Please sign in to comment.