Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Please visit [cucumber/CONTRIBUTING.md](https://github.com/cucumber/cucumber/blo
- Show failed step error details in the summary formatter output
- Fixed up JRuby examples which weren't running due to anglicisation issues (Pivoted to use English step definitions to help JRuby testing)
- Fixed up Arabic example which had some incorrect logic for step definition matching (Due to RTL nature of the language)
- Disable ANSI color by default for console formatter output written with `--out`.

## [11.1.0] - 2026-06-02
### Added
Expand Down
2 changes: 1 addition & 1 deletion lib/cucumber/cli/options.rb
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ def add_tag_limit(tag_limits, tag_name, limit)
end

def color(color)
Cucumber::Term::ANSIColor.coloring = color
Cucumber::Term::ANSIColor.coloring = (@options[:color] = color)
end

def initialize_project
Expand Down
69 changes: 51 additions & 18 deletions lib/cucumber/formatter/console.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,27 +31,31 @@ module Console
include Duration

def format_step(keyword, step_match, status, source_indent)
comment = if source_indent
c = indent("# #{step_match.location}", source_indent)
format_string(c, :comment)
else
''
end

format = format_for(status, :param)
line = keyword + step_match.format_args(format) + comment
format_string(line, status)
with_formatter_coloring do
comment = if source_indent
c = indent("# #{step_match.location}", source_indent)
format_string(c, :comment)
else
''
end

format = format_for(status, :param)
line = keyword + step_match.format_args(format) + comment
format_string(line, status)
end
end

def format_string(input, status)
fmt = format_for(status)
input.to_s.split("\n").map do |line|
if fmt.instance_of?(Proc)
fmt.call(line)
else
fmt % line
end
end.join("\n")
with_formatter_coloring do
fmt = format_for(status)
input.to_s.split("\n").map do |line|
if fmt.instance_of?(Proc)
fmt.call(line)
else
fmt % line
end
end.join("\n")
end
end

def print_elements(elements, status, kind)
Expand Down Expand Up @@ -229,6 +233,35 @@ def indent(string, padding)

FORMATS = Hash.new { |hash, format| hash[format] = method(format).to_proc }

def with_formatter_coloring
original_coloring = Cucumber::Term::ANSIColor.coloring?
Cucumber::Term::ANSIColor.coloring = formatter_coloring?
yield
ensure
Cucumber::Term::ANSIColor.coloring = original_coloring
end
Comment on lines +236 to +242

def formatter_coloring?
options = if instance_variable_defined?(:@options) && @options
@options
elsif instance_variable_defined?(:@config) && @config.respond_to?(:to_hash)
@config.to_hash
else
{}
end
return options[:color] if options.key?(:color)

io = if instance_variable_defined?(:@io)
@io
elsif instance_variable_defined?(:@config) && @config.respond_to?(:out_stream)
@config.out_stream
end
return Cucumber::Term::ANSIColor.coloring? if io.nil?
return false unless io.respond_to?(:tty?)

io.tty?
end

def format_for(*keys)
key = keys.join('_').to_sym
fmt = FORMATS[key]
Expand Down
1 change: 1 addition & 0 deletions lib/cucumber/formatter/console_counts.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class ConsoleCounts
include Console

def initialize(config)
@config = config
@summary = Core::Report::Summary.new(config.event_bus)
end

Expand Down
48 changes: 48 additions & 0 deletions spec/cucumber/formatter/console_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

require 'cucumber/configuration'
require 'cucumber/formatter/console'
require 'cucumber/step_match'

module Cucumber
module Formatter
Expand All @@ -21,6 +22,53 @@ module Formatter
res = indent(' a line', -10)
expect(res).to eq 'a line'
end

context 'when coloring console output' do
around do |example|
original_coloring = Cucumber::Term::ANSIColor.coloring?
Cucumber::Term::ANSIColor.coloring = true
example.run
ensure
Cucumber::Term::ANSIColor.coloring = original_coloring
end

it 'uses color by default when the formatter output is a tty' do
@io = instance_double(IO, tty?: true)
@options = {}

expect(format_string('undefined', :undefined)).to include("\e[33m")
end
Comment on lines +35 to +40

it 'disables color by default when the formatter output is a file' do
@io = instance_double(File, tty?: false)
@options = {}

expect(format_string('undefined', :undefined)).to eq 'undefined'
end

it 'allows explicit color to override the formatter output destination' do
@io = instance_double(File, tty?: false)
@options = { color: true }

expect(format_string('undefined', :undefined)).to include("\e[33m")
end
Comment on lines +49 to +54

it 'allows explicit no-color to override a tty output destination' do
@io = instance_double(IO, tty?: true)
@options = { color: false }

expect(format_string('undefined', :undefined)).to eq 'undefined'
end

it 'disables step argument color by default when the formatter output is a file' do
@io = instance_double(File, tty?: false)
@options = {}
step_match = instance_double(Cucumber::StepMatch)
allow(step_match).to receive(:format_args) { |format| "I have #{format.call('3')} cukes" }

expect(format_step('Given ', step_match, :passed, nil)).to eq 'Given I have 3 cukes'
end
end
end
end
end
Loading