cucumber 0.5.3 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. data/History.txt +25 -0
  2. data/Rakefile +4 -3
  3. data/VERSION.yml +3 -2
  4. data/cucumber.gemspec +21 -16
  5. data/cucumber.yml +5 -3
  6. data/examples/i18n/ar/features/step_definitons/calculator_steps.rb +1 -1
  7. data/examples/i18n/bg/features/support/env.rb +1 -2
  8. data/examples/i18n/cat/features/step_definitons/calculator_steps.rb +1 -1
  9. data/examples/i18n/da/features/step_definitons/lommeregner_steps.rb +1 -1
  10. data/examples/i18n/de/features/step_definitons/calculator_steps.rb +1 -1
  11. data/examples/i18n/en-lol/features/support/env.rb +0 -1
  12. data/examples/i18n/en/features/step_definitons/calculator_steps.rb +2 -2
  13. data/examples/i18n/es/features/step_definitons/calculador_steps.rb +2 -2
  14. data/examples/i18n/et/features/step_definitions/kalkulaator_steps.rb +1 -1
  15. data/examples/i18n/fi/features/step_definitons/laskin_steps.rb +1 -1
  16. data/examples/i18n/fr/features/step_definitions/calculatrice_steps.rb +0 -6
  17. data/examples/i18n/fr/features/support/env.rb +5 -0
  18. data/examples/i18n/he/features/step_definitons/calculator_steps.rb +1 -1
  19. data/examples/i18n/he/lib/calculator.rb +1 -0
  20. data/examples/i18n/hu/features/step_definitons/calculator_steps.rb +1 -1
  21. data/examples/i18n/id/features/step_definitons/calculator_steps.rb +1 -1
  22. data/examples/i18n/it/features/step_definitons/calcolatrice_steps.rb +1 -1
  23. data/examples/i18n/ja/features/step_definitons/calculator_steps.rb +0 -5
  24. data/examples/i18n/ja/features/support/env.rb +5 -0
  25. data/examples/i18n/ko/features/step_definitons/calculator_steps.rb +1 -1
  26. data/examples/i18n/lt/features/step_definitons/calculator_steps.rb +1 -1
  27. data/examples/i18n/lv/features/step_definitons/calculator_steps.rb +1 -1
  28. data/examples/i18n/no/features/support/env.rb +1 -2
  29. data/examples/i18n/pl/features/step_definitons/calculator_steps.rb +1 -1
  30. data/examples/i18n/pl/features/support/env.rb +1 -2
  31. data/examples/i18n/pt/features/support/env.rb +1 -2
  32. data/examples/i18n/ro/features/step_definitons/calculator_steps.rb +1 -1
  33. data/examples/i18n/ru/features/support/env.rb +1 -2
  34. data/examples/i18n/se/features/step_definitons/kalkulator_steps.rb +1 -1
  35. data/examples/i18n/sk/features/step_definitons/calculator_steps.rb +1 -1
  36. data/examples/i18n/sr-latn/features/step_definitons/calculator_steps.rb +3 -3
  37. data/examples/i18n/sr/features/step_definitons/calculator_steps.rb +1 -5
  38. data/examples/i18n/sr/features/support/env.rb +5 -0
  39. data/examples/i18n/tr/features/step_definitons/hesap_makinesi_adimlari.rb +1 -1
  40. data/examples/i18n/uz/features/support/env.rb +1 -2
  41. data/examples/i18n/zh-CN/features/step_definitons/calculator_steps.rb +1 -1
  42. data/examples/i18n/zh-TW/features/step_definitons/calculator_steps.rb +1 -1
  43. data/examples/self_test/features/step_definitions/sample_steps.rb +2 -0
  44. data/examples/watir/features/support/screenshots.rb +20 -17
  45. data/features/call_many_steps.feature +2 -0
  46. data/features/cucumber_cli.feature +7 -4
  47. data/features/html_formatter.feature +1 -0
  48. data/features/html_formatter/a.html +2 -2
  49. data/features/language_help.feature +1 -0
  50. data/features/step_definitions/cucumber_steps.rb +3 -3
  51. data/features/support/env.rb +7 -5
  52. data/features/tag_logic.feature +7 -7
  53. data/features/wire_protocol.feature +1 -1
  54. data/gem_tasks/features.rake +2 -0
  55. data/lib/autotest/cucumber_mixin.rb +4 -4
  56. data/lib/cucumber/ast.rb +0 -1
  57. data/lib/cucumber/ast/feature.rb +9 -12
  58. data/lib/cucumber/ast/feature_element.rb +4 -4
  59. data/lib/cucumber/ast/features.rb +2 -2
  60. data/lib/cucumber/ast/table.rb +1 -0
  61. data/lib/cucumber/ast/tags.rb +1 -97
  62. data/lib/cucumber/cli/configuration.rb +3 -1
  63. data/lib/cucumber/cli/main.rb +20 -23
  64. data/lib/cucumber/cli/options.rb +9 -18
  65. data/lib/cucumber/filter.rb +4 -2
  66. data/lib/cucumber/formatter/console.rb +8 -28
  67. data/lib/cucumber/formatter/html.rb +1 -1
  68. data/lib/cucumber/formatter/pdf.rb +0 -4
  69. data/lib/cucumber/formatter/pretty.rb +1 -2
  70. data/lib/cucumber/formatter/progress.rb +1 -5
  71. data/lib/cucumber/formatter/rerun.rb +2 -0
  72. data/lib/cucumber/formatter/unicode.rb +6 -6
  73. data/lib/cucumber/language_support/language_methods.rb +0 -1
  74. data/lib/cucumber/parser/common.rb +16 -4
  75. data/lib/cucumber/parser/feature.rb +92 -27
  76. data/lib/cucumber/parser/feature.tt +8 -6
  77. data/lib/cucumber/parser/py_string.rb +12 -3
  78. data/lib/cucumber/parser/table.rb +12 -3
  79. data/lib/cucumber/rb_support/rb_dsl.rb +6 -6
  80. data/lib/cucumber/rb_support/rb_hook.rb +4 -5
  81. data/lib/cucumber/rb_support/rb_language.rb +1 -1
  82. data/lib/cucumber/tag_expression.rb +41 -0
  83. data/spec/cucumber/ast/feature_spec.rb +23 -2
  84. data/spec/cucumber/ast/scenario_outline_spec.rb +0 -7
  85. data/spec/cucumber/cli/options_spec.rb +3 -3
  86. data/spec/cucumber/formatter/html_spec.rb +10 -0
  87. data/spec/cucumber/formatter/spec_helper.rb +2 -1
  88. data/spec/cucumber/tag_expression_spec.rb +127 -0
  89. metadata +15 -10
  90. data/spec/cucumber/ast/tags_spec.rb +0 -29
  91. data/spec/cucumber/formatter/console_spec.rb +0 -20
@@ -1,5 +1,4 @@
1
1
  require 'cucumber/ast/comment'
2
- require 'cucumber/ast/tags'
3
2
  require 'cucumber/ast/features'
4
3
  require 'cucumber/ast/feature'
5
4
  require 'cucumber/ast/background'
@@ -2,8 +2,9 @@ module Cucumber
2
2
  module Ast
3
3
  # Represents the root node of a parsed feature.
4
4
  class Feature #:nodoc:
5
- attr_accessor :file, :language
5
+ attr_accessor :language
6
6
  attr_writer :features
7
+ attr_reader :file
7
8
  attr_reader :name
8
9
 
9
10
  def initialize(background, comment, tags, name, feature_elements)
@@ -44,21 +45,17 @@ module Cucumber
44
45
  "#{file_colon_line(line)}:in `#{step_name}'"
45
46
  end
46
47
 
48
+ def file=(file)
49
+ file = file.gsub(/\//, '\\') if Cucumber::WINDOWS && file && !ENV['CUCUMBER_FORWARD_SLASH_PATHS']
50
+ @file = file
51
+ end
52
+
47
53
  def file_colon_line(line)
48
54
  "#{@file}:#{line}"
49
55
  end
50
56
 
51
- def tag_count(tag)
52
- if @tags.respond_to?(:count)
53
- @tags.count(tag) # 1.9
54
- else
55
- @tags.select{|t| t == tag}.length # 1.8
56
- end
57
- end
58
-
59
- def feature_and_children_tag_count(tag)
60
- children_tag_count = @feature_elements.inject(0){|count, feature_element| count += feature_element.tag_count(tag)}
61
- children_tag_count + tag_count(tag)
57
+ def tag_locations(tag)
58
+ @feature_elements.select{|feature_element| feature_element.tagged_with?(tag)}
62
59
  end
63
60
 
64
61
  def short_name
@@ -1,5 +1,5 @@
1
1
  require 'enumerator'
2
- require 'cucumber/ast/tags'
2
+ require 'cucumber/tag_expression'
3
3
 
4
4
  module Cucumber
5
5
  module Ast
@@ -49,15 +49,15 @@ module Cucumber
49
49
  end
50
50
 
51
51
  def accept_hook?(hook)
52
- Tags.matches?(source_tag_names, hook.tag_name_lists)
52
+ TagExpression.parse(hook.tag_expressions).eval(source_tag_names)
53
53
  end
54
54
 
55
55
  def source_tag_names
56
56
  (@tags.tag_names + (@feature ? @feature.source_tag_names : [])).uniq
57
57
  end
58
58
 
59
- def tag_count(tag)
60
- @feature.tag_count(tag) == 0 ? @tags.count(tag) : @feature.tag_count(tag)
59
+ def tagged_with?(tag)
60
+ source_tag_names.index(tag)
61
61
  end
62
62
 
63
63
  def language
@@ -31,8 +31,8 @@ module Cucumber
31
31
  @duration = Time.now - start
32
32
  end
33
33
 
34
- def tag_count(tag)
35
- @features.inject(0){|count, feature| count += feature.feature_and_children_tag_count(tag)}
34
+ def tag_locations(tag)
35
+ @features.map{|feature| feature.tag_locations(tag)}.flatten
36
36
  end
37
37
 
38
38
  end
@@ -410,6 +410,7 @@ module Cucumber
410
410
  end
411
411
 
412
412
  def to_s(options = {}) #:nodoc:
413
+ require 'cucumber/formatter/pretty'
413
414
  options = {:color => true, :indent => 2, :prefixes => TO_S_PREFIXES}.merge(options)
414
415
  io = StringIO.new
415
416
 
@@ -1,92 +1,6 @@
1
- require 'set'
2
-
3
1
  module Cucumber
4
2
  module Ast
5
-
6
- # Holds the names of tags parsed from a feature file:
7
- #
8
- # @invoice @release_2
9
- #
10
- # This gets stored internally as <tt>["invoice", "release_2"]</tt>
11
- #
12
3
  class Tags #:nodoc:
13
- class And #:nodoc:
14
- def initialize(tag_names)
15
- if String === tag_names # They still come in as single strings on cuke4duke some times. Not sure why...
16
- raise "Commas in tags??? #{tag_names.inspect}" if tag_names =~ /,/ # just in case...
17
- tag_names = [tag_names]
18
- end
19
- @negative_tags, @positive_tags = tag_names.partition{|tag_name| Tags.exclude_tag?(tag_name)}
20
- @negative_tags = Tags.strip_negative_char(@negative_tags)
21
- end
22
-
23
- def matches?(tag_names)
24
- included?(tag_names) && !excluded?(tag_names)
25
- end
26
-
27
- private
28
-
29
- def excluded?(tag_names)
30
- (@negative_tags & tag_names).any?
31
- end
32
-
33
- def included?(tag_names)
34
- positive_tag_set = Set.new(@positive_tags)
35
- tag_names_set = Set.new(tag_names)
36
- positive_tag_set.subset?(tag_names_set)
37
- end
38
- end
39
-
40
- class Or #:nodoc:
41
- def initialize(tag_exp)
42
- @exp = tag_exp
43
- end
44
-
45
- def matches?(tag_names)
46
- @exp.inject(false){|matches, tag_exp| matches || tag_exp.matches?(tag_names)}
47
- end
48
- end
49
-
50
- class << self
51
- EXCLUDE_PATTERN = /^~/
52
-
53
- def matches?(source_tag_names, tag_name_lists)
54
- validate_tags(tag_name_lists)
55
- tag_name_lists.empty? ? true : check_if_tags_match(source_tag_names, tag_name_lists)
56
- end
57
-
58
- def exclude_tag?(tag_name)
59
- tag_name =~ EXCLUDE_PATTERN
60
- end
61
-
62
- def strip_negative_char(tag_names)
63
- tag_names.map{|name| name[1..-1]}
64
- end
65
-
66
- def parse_tags(tags_string)
67
- tags_string.split(',')
68
- end
69
-
70
- private
71
-
72
- def validate_tags(tag_name_lists)
73
- all_tag_names = tag_name_lists.flatten
74
- exclude_tag_names, include_tag_names = all_tag_names.partition{|tag_name| exclude_tag?(tag_name)}
75
- exclude_tag_names = strip_negative_char(exclude_tag_names)
76
- check_at_sign_prefix(exclude_tag_names + include_tag_names)
77
- end
78
-
79
- def check_if_tags_match(source_tag_names, tag_name_lists)
80
- tag_exp = Or.new(tag_name_lists.map{|tag_name_list| And.new(tag_name_list) })
81
- tag_exp.matches?(source_tag_names)
82
- end
83
-
84
- def check_at_sign_prefix(tag_names)
85
- tag_names.each{|tag_name| raise "Tag names must start with an @ sign. The following tag name didn't: #{tag_name.inspect}" unless tag_name[0..0] == '@'}
86
- end
87
-
88
- end
89
-
90
4
  attr_reader :tag_names
91
5
 
92
6
  def initialize(line, tag_names)
@@ -101,17 +15,7 @@ module Cucumber
101
15
  end
102
16
 
103
17
  def accept_hook?(hook)
104
- self.class.matches?(@tag_names, hook.tag_name_lists)
105
- end
106
-
107
- def count(tag)
108
- # See discussion:
109
- # http://github.com/weplay/cucumber/commit/2dc592acdf3f7c1a0c333a8164649936bb82d983
110
- if @tag_names.respond_to?(:count) && @tag_names.method(:count).arity > 0
111
- @tag_names.count(tag) # 1.9
112
- else
113
- @tag_names.select{|t| t == tag}.length # 1.8
114
- end
18
+ TagExpression.parse(hook.tag_expressions).eval(@tag_names)
115
19
  end
116
20
 
117
21
  def to_sexp
@@ -1,6 +1,7 @@
1
1
  require 'logger'
2
2
  require 'cucumber/cli/options'
3
3
  require 'cucumber/constantize'
4
+ require 'cucumber/tag_expression'
4
5
 
5
6
  module Cucumber
6
7
  module Cli
@@ -25,6 +26,7 @@ module Cucumber
25
26
  arrange_formats
26
27
  raise("You can't use both --strict and --wip") if strict? && wip?
27
28
 
29
+ @options[:tag_expression] = TagExpression.parse(@options[:tag_expressions])
28
30
  return @args.replace(@options.expanded_args_without_drb) if drb?
29
31
 
30
32
  set_environment_variables
@@ -57,7 +59,7 @@ module Cucumber
57
59
  def drb_port
58
60
  @options[:drb_port].to_i if @options[:drb_port]
59
61
  end
60
-
62
+
61
63
  def build_runner(step_mother, io)
62
64
  Ast::TreeWalker.new(step_mother, formatters(step_mother), @options, io)
63
65
  end
@@ -7,13 +7,10 @@ require 'cucumber/feature_file'
7
7
  require 'cucumber/formatter/color_io'
8
8
  require 'cucumber/cli/configuration'
9
9
  require 'cucumber/cli/drb_client'
10
- require 'cucumber/ast/tags'
11
10
 
12
11
  module Cucumber
13
12
  module Cli
14
13
  class Main
15
- FAILURE = 1
16
-
17
14
  class << self
18
15
  def step_mother
19
16
  @step_mother ||= StepMother.new
@@ -55,36 +52,36 @@ module Cucumber
55
52
 
56
53
  enable_diffing
57
54
 
55
+ tag_excess = tag_excess(features)
56
+ configuration.options[:tag_excess] = tag_excess # Hack to make it available in console.rb - later: stick on Run instance.
57
+
58
58
  runner = configuration.build_runner(step_mother, @out_stream)
59
59
  step_mother.visitor = runner # Needed to support World#announce
60
+
60
61
  runner.visit_features(features)
61
62
 
62
- failure = if exceeded_tag_limts?(features)
63
- FAILURE
64
- elsif configuration.wip?
65
- step_mother.scenarios(:passed).any?
66
- else
67
- step_mother.scenarios(:failed).any? ||
68
- (configuration.strict? && (step_mother.steps(:undefined).any? || step_mother.steps(:pending).any?))
69
- end
63
+ failure = if tag_excess.any?
64
+ true
65
+ elsif configuration.wip?
66
+ step_mother.scenarios(:passed).any?
67
+ else
68
+ step_mother.scenarios(:failed).any? ||
69
+ (configuration.strict? && (step_mother.steps(:undefined).any? || step_mother.steps(:pending).any?))
70
+ end
70
71
  rescue ProfilesNotDefinedError, YmlLoadError, ProfileNotFound => e
71
72
  @error_stream.puts e.message
72
73
  true
73
74
  end
74
75
 
75
- def exceeded_tag_limts?(features)
76
- exceeded = false
77
- configuration.options[:tag_names].each do |tag_list|
78
- tag_list.each do |tag_name, limit|
79
- if !Ast::Tags.exclude_tag?(tag_name) && limit
80
- tag_count = features.tag_count(tag_name)
81
- if tag_count > limit.to_i
82
- exceeded = true
83
- end
84
- end
76
+ def tag_excess(features)
77
+ configuration.options[:tag_expression].limits.map do |tag_name, tag_limit|
78
+ tag_locations = features.tag_locations(tag_name)
79
+ if tag_limit && (tag_locations.length > tag_limit)
80
+ [tag_name, tag_limit, tag_locations]
81
+ else
82
+ nil
85
83
  end
86
- end
87
- exceeded
84
+ end.compact
88
85
  end
89
86
 
90
87
  def configuration
@@ -1,5 +1,6 @@
1
1
  require 'cucumber/cli/profile_loader'
2
2
  require 'cucumber/formatter/ansicolor'
3
+ require 'cucumber/tag_expression'
3
4
 
4
5
  module Cucumber
5
6
  module Cli
@@ -29,7 +30,7 @@ module Cucumber
29
30
  FORMAT_HELP = (BUILTIN_FORMATS.keys.sort.map do |key|
30
31
  " #{key}#{' ' * (max - key.length)} : #{BUILTIN_FORMATS[key][1]}"
31
32
  end) + ["Use --format rerun --out features.txt to write out failing",
32
- "features. You can rerun them with cucumber @features.txt.",
33
+ "features. You can rerun them with cucumber @rerun.txt.",
33
34
  "FORMAT can also be the fully qualified class name of",
34
35
  "your own custom formatter. If the class isn't loaded,",
35
36
  "Cucumber will attempt to require a file with a relative",
@@ -102,7 +103,7 @@ module Cucumber
102
103
  opts.banner = ["Usage: cucumber [options] [ [FILE|DIR|URL][:LINE[:LINE]*] ]+", "",
103
104
  "Examples:",
104
105
  "cucumber examples/i18n/en/features",
105
- "cucumber @features.txt (See --format rerun)",
106
+ "cucumber @rerun.txt (See --format rerun)",
106
107
  "cucumber examples/i18n/it/features/somma.feature:6:98:113",
107
108
  "cucumber -s -i http://rubyurl.com/eeCl", "", "",
108
109
  ].join("\n")
@@ -163,8 +164,7 @@ module Cucumber
163
164
  "Limit WIP: Positive tags can be given a threshold to limit the",
164
165
  "number of occurrences. Example: --tags @qa:3 will fail if there",
165
166
  "are more than 3 occurrences of the @qa tag.") do |v|
166
- tag_names = parse_tags(v)
167
- @options[:tag_names] << tag_names
167
+ @options[:tag_expressions] << v
168
168
  end
169
169
  opts.on("-n NAME", "--name NAME",
170
170
  "Only execute the feature elements which match part of the given name.",
@@ -184,7 +184,7 @@ module Cucumber
184
184
  @profiles << v
185
185
  end
186
186
  opts.on(NO_PROFILE_SHORT_FLAG, NO_PROFILE_LONG_FLAG,
187
- "Disables all profile laoding to avoid using the 'default' profile.") do |v|
187
+ "Disables all profile loading to avoid using the 'default' profile.") do |v|
188
188
  @disable_profile_loading = true
189
189
  end
190
190
  opts.on("-c", "--[no-]color",
@@ -299,17 +299,8 @@ module Cucumber
299
299
  end
300
300
  end
301
301
 
302
- def parse_tags(tag_string)
303
- tag_names = Ast::Tags.parse_tags(tag_string)
304
- parse_tag_limits(tag_names)
305
- end
306
-
307
- def parse_tag_limits(tag_names)
308
- tag_names.inject({}) do |dict, tag|
309
- tag, limit = tag.split(':')
310
- dict[tag] = limit.nil? ? limit : limit.to_i
311
- dict
312
- end
302
+ def tag_filter(tag_string)
303
+ tags = TagExpression.parse(tag_string)
313
304
  end
314
305
 
315
306
  def disable_profile_loading?
@@ -348,7 +339,7 @@ module Cucumber
348
339
  @options[:require] += other_options[:require]
349
340
  @options[:excludes] += other_options[:excludes]
350
341
  @options[:name_regexps] += other_options[:name_regexps]
351
- @options[:tag_names] += other_options[:tag_names]
342
+ @options[:tag_expressions] += other_options[:tag_expressions]
352
343
  @options[:env_vars] = other_options[:env_vars].merge(@options[:env_vars])
353
344
  if @options[:paths].empty?
354
345
  @options[:paths] = other_options[:paths]
@@ -403,7 +394,7 @@ module Cucumber
403
394
  :dry_run => false,
404
395
  :formats => [],
405
396
  :excludes => [],
406
- :tag_names => [],
397
+ :tag_expressions => [],
407
398
  :name_regexps => [],
408
399
  :env_vars => {},
409
400
  :diff_enabled => true
@@ -1,9 +1,11 @@
1
+ require 'cucumber/tag_expression'
2
+
1
3
  module Cucumber
2
4
  # Filters the AST based on --tags and --name
3
5
  class Filter #:nodoc:
4
6
  def initialize(lines, options)
5
7
  @lines = lines
6
- @tag_name_lists = options[:tag_names] ? options[:tag_names].map{|tags_with_limit| tags_with_limit.keys } : []
8
+ @tag_expression = options[:tag_expression] || TagExpression.new
7
9
  @name_regexps = options[:name_regexps] || []
8
10
  end
9
11
 
@@ -27,7 +29,7 @@ module Cucumber
27
29
  end
28
30
 
29
31
  def matches_tags?(syntax_node)
30
- syntax_node.matches_tags?(@tag_name_lists)
32
+ syntax_node.matches_tags?(@tag_expression)
31
33
  end
32
34
 
33
35
  def outline_matches_names?(syntax_node)
@@ -124,34 +124,14 @@ module Cucumber
124
124
  end
125
125
  end
126
126
 
127
- def print_tag_limit_warnings(options)
128
- if @tag_occurrences
129
- first_tag = true
130
- options[:tag_names].each do |tag_list|
131
- tag_list.each do |tag_name, limit|
132
- unless Ast::Tags.exclude_tag?(tag_name)
133
- tag_frequency = @tag_occurrences[tag_name].size
134
- if limit && tag_frequency > limit
135
- @io.puts if first_tag
136
- first_tag = false
137
- @io.puts format_string("#{tag_name} occurred #{tag_frequency} times, but the limit was set to #{limit}", :failed)
138
- @tag_occurrences[tag_name].each {|location| @io.puts format_string(" #{location}", :failed)}
139
- @io.flush
140
- end
141
- end
142
- end
143
- end
144
- end
145
- end
146
-
147
- def record_tag_occurrences(feature_element, options)
148
- @tag_occurrences ||= Hash.new{|k,v| k[v] = []}
149
- options[:tag_names].each do |tag_list|
150
- tag_list.each do |tag_name, limit|
151
- if !Ast::Tags.exclude_tag?(tag_name) && feature_element.tag_count(tag_name) > 0
152
- @tag_occurrences[tag_name] << feature_element.file_colon_line
153
- end
154
- end
127
+ def print_tag_limit_warnings(features)
128
+ first_tag = true
129
+ @options[:tag_excess].each do |tag_name, tag_limit, tag_locations|
130
+ @io.puts if first_tag
131
+ first_tag = false
132
+ @io.puts format_string("#{tag_name} occurred #{tag_locations.length} times, but the limit was set to #{tag_limit}", :failed)
133
+ tag_locations.each {|tag_location| @io.puts format_string(" #{tag_location.file_colon_line}", :failed)}
134
+ @io.flush
155
135
  end
156
136
  end
157
137
 
@@ -236,7 +236,7 @@ module Cucumber
236
236
  if status == :undefined
237
237
  step_multiline_class = @step.multiline_arg ? @step.multiline_arg.class : nil
238
238
  @builder.pre do |pre|
239
- pre << @step_mother.snippet_text(keyword,step_match.instance_variable_get("@name") || '',step_multiline_class)
239
+ pre << @step_mother.snippet_text(@step.actual_keyword,step_match.instance_variable_get("@name") || '',step_multiline_class)
240
240
  end
241
241
  end
242
242
  @builder << '</li>'