Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

format: fix issues with colors support #2026

Merged
merged 15 commits into from May 5, 2022
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
Please see [CONTRIBUTING.md](https://github.com/cucumber/cucumber/blob/master/CONTRIBUTING.md) on how to contribute to Cucumber.

## [Unreleased]
### Changed
- Fix issues with colored output, support `FORCE_COLOR` environment variable as an override ([#2026](https://github.com/cucumber/cucumber-js/pull/2026))

## [8.1.2] - 2022-04-22
### Added
Expand Down
10 changes: 9 additions & 1 deletion docs/formatters.md
Expand Up @@ -39,9 +39,17 @@ This option is repeatable, so you can use it multiple times and the objects will

Some options offered by built-in formatters:

- `colorsEnabled` - if set to `false`, colors in terminal output are disabled
- `colorsEnabled` - [see below](#colored-output)
- `printAttachments` - if set to `false`, attachments won't be part of progress bars and summary reports

## Colored output

Many formatters, including the built-in ones, emit some colored output. By default, Cucumber will automatically detect the colors support of the output stream and decide whether to emit colors accordingly. This check comes via the [supports-colors](https://github.com/chalk/supports-color) library and is pretty comprehensive, including awareness of commonly-used operating systems and CI platforms that represent edge cases.

If you'd like to override the auto-detection behaviour, you can provide the `colorsEnabled` format option - either `true` to forcibly emit colors, or `false` to forcibly disable them.

It's worth noting that this option only influences output that Cucumber is in control of. Other tools in your stack such as assertion libraries might have their own way of handling colors. For this reason we'd recommend setting the `FORCE_COLOR` environment variable if you want to forcibly enable (by setting it to `1`) or disable (by setting it to `0`) colors, as a variety of tools (including Cucumber) will honour it.

## Built-in formatters

### `summary`
Expand Down
38 changes: 38 additions & 0 deletions features/colors.feature
@@ -0,0 +1,38 @@
@spawn
Feature: Colors

As a developer
I want to control when/whether the output includes colors

Background:
Given a file named "features/a.feature" with:
"""
Feature:
Scenario:
Given a step
"""
And a file named "features/step_definitions/steps.js" with:
"""
const {Given} = require('@cucumber/cucumber')
Given('a step', function() {})
"""
And a file named "cucumber.json" with:
"""
{ "default": { "format": ["summary:summary.out"] } }
"""

Scenario: no colored output by default for a file stream
When I run cucumber-js
Then the file "summary.out" doesn't contain colors

Scenario: colored output can be activated with the format option
When I run cucumber-js with `--format-options '{"colorsEnabled":true}'`
Then the file "summary.out" contains colors

Scenario: colored output can be activated with FORCE_COLOR
When I run cucumber-js with env `FORCE_COLOR=1`
Then the file "summary.out" contains colors

Scenario: FORCE_COLOR takes precedence over the format option
When I run cucumber-js with arguments `--format-options '{"colorsEnabled":false}'` and env `FORCE_COLOR=1`
Then the file "summary.out" contains colors
21 changes: 21 additions & 0 deletions features/step_definitions/file_steps.ts
@@ -1,5 +1,6 @@
import { Given, Then } from '../../'
import { expect } from 'chai'
import hasAnsi from 'has-ansi'
import { normalizeText } from '../support/helpers'
import fs from 'mz/fs'
import fsExtra from 'fs-extra'
Expand Down Expand Up @@ -50,3 +51,23 @@ Then(
expect(actualContent).to.eql(expectedContent)
}
)

Then(
'the file {string} contains colors',
async function (this: World, filePath: string) {
filePath = Mustache.render(filePath, this)
const absoluteFilePath = path.resolve(this.tmpDir, filePath)
const content = await fs.readFile(absoluteFilePath, 'utf8')
expect(hasAnsi(content)).to.be.true
}
)

Then(
"the file {string} doesn't contain colors",
async function (this: World, filePath: string) {
filePath = Mustache.render(filePath, this)
const absoluteFilePath = path.resolve(this.tmpDir, filePath)
const content = await fs.readFile(absoluteFilePath, 'utf8')
expect(hasAnsi(content)).to.be.false
}
)