cucumber 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +3 -0
- data/License.txt +20 -0
- data/Manifest.txt +152 -0
- data/README.txt +42 -0
- data/Rakefile +4 -0
- data/TODO.txt +26 -0
- data/bin/cucumber +4 -0
- data/config/hoe.rb +69 -0
- data/config/requirements.rb +15 -0
- data/cucumber.yml +1 -0
- data/examples/calculator/Rakefile +6 -0
- data/examples/calculator/cucumber.yml +1 -0
- data/examples/calculator/features/addition.feature +16 -0
- data/examples/calculator/features/division.feature +10 -0
- data/examples/calculator/features/steps/calculator_steps.rb +31 -0
- data/examples/calculator/lib/calculator.rb +16 -0
- data/examples/calculator_ruby_features/Rakefile +6 -0
- data/examples/calculator_ruby_features/features/addition.rb +23 -0
- data/examples/calculator_ruby_features/features/steps/calculator_steps.rb +43 -0
- data/examples/calculatrice_francaise_avec_soit_scenario/Rakefile +6 -0
- data/examples/calculatrice_francaise_avec_soit_scenario/features/addition.feature +13 -0
- data/examples/calculatrice_francaise_avec_soit_scenario/features/calculatrice_steps.rb +31 -0
- data/examples/cs/README.textile +22 -0
- data/examples/cs/Rakefile +12 -0
- data/examples/cs/features/hello.feature +11 -0
- data/examples/cs/features/steps/hello_steps.rb +25 -0
- data/examples/cs/features/steps/tree_steps.rb +14 -0
- data/examples/cs/features/tree.feature +9 -0
- data/examples/cs/src/Hello.cs +18 -0
- data/examples/danish_calculator/Rakefile +6 -0
- data/examples/danish_calculator/features/steps/kalkulator_steps.rb +22 -0
- data/examples/danish_calculator/features/summering.feature +17 -0
- data/examples/danish_calculator/lib/kalkulator.rb +11 -0
- data/examples/estonian_calculator/Rakefile +6 -0
- data/examples/estonian_calculator/features/kalkulaator_steps.rb +35 -0
- data/examples/estonian_calculator/features/liitmine.feature +16 -0
- data/examples/java/README.textile +22 -0
- data/examples/java/Rakefile +12 -0
- data/examples/java/features/hello.feature +11 -0
- data/examples/java/features/steps/hello_steps.rb +25 -0
- data/examples/java/features/steps/tree_steps.rb +14 -0
- data/examples/java/features/tree.feature +9 -0
- data/examples/java/src/cucumber/demo/Hello.java +16 -0
- data/examples/norwegian_calculator/Rakefile +6 -0
- data/examples/norwegian_calculator/features/steps/kalkulator_steps.rb +22 -0
- data/examples/norwegian_calculator/features/summering.feature +17 -0
- data/examples/norwegian_calculator/lib/kalkulator.rb +11 -0
- data/examples/portuguese_calculator/Rakefile +6 -0
- data/examples/portuguese_calculator/features/adicao.feature +10 -0
- data/examples/portuguese_calculator/features/calculadora_steps.rb +31 -0
- data/examples/selenium/Rakefile +6 -0
- data/examples/selenium/features/search.feature +9 -0
- data/examples/selenium/features/steps/stories_steps.rb +41 -0
- data/examples/spanish_calculator/Rakefile +6 -0
- data/examples/spanish_calculator/features/adicion.feature +17 -0
- data/examples/spanish_calculator/features/steps/calculador_steps.rb +22 -0
- data/examples/spanish_calculator/lib/Calculador.rb +11 -0
- data/examples/tickets/Rakefile +4 -0
- data/examples/tickets/features/steps/tickets_steps.rb +5 -0
- data/examples/tickets/features/tickets.feature +7 -0
- data/examples/watir/Rakefile +6 -0
- data/examples/watir/features/search.feature +9 -0
- data/examples/watir/features/steps/stories_steps.rb +51 -0
- data/features/see_features.feature +8 -0
- data/features/steps/features_steps.rb +9 -0
- data/gem_tasks/deployment.rake +34 -0
- data/gem_tasks/environment.rake +7 -0
- data/gem_tasks/features.rake +6 -0
- data/gem_tasks/fix_cr_lf.rake +10 -0
- data/gem_tasks/flog.rake +4 -0
- data/gem_tasks/gemspec.rake +6 -0
- data/gem_tasks/rspec.rake +21 -0
- data/gem_tasks/treetop.rake +27 -0
- data/generators/cucumber/cucumber_generator.rb +27 -0
- data/generators/cucumber/templates/common_webrat.rb +51 -0
- data/generators/cucumber/templates/cucumber +2 -0
- data/generators/cucumber/templates/cucumber.rake +7 -0
- data/generators/cucumber/templates/env.rb +8 -0
- data/generators/feature/feature_generator.rb +17 -0
- data/generators/feature/templates/feature.erb +27 -0
- data/generators/feature/templates/steps.erb +22 -0
- data/lib/cucumber.rb +32 -0
- data/lib/cucumber/cli.rb +163 -0
- data/lib/cucumber/core_ext/proc.rb +43 -0
- data/lib/cucumber/core_ext/string.rb +22 -0
- data/lib/cucumber/executor.rb +120 -0
- data/lib/cucumber/formatters.rb +1 -0
- data/lib/cucumber/formatters/ansicolor.rb +90 -0
- data/lib/cucumber/formatters/cucumber.css +132 -0
- data/lib/cucumber/formatters/cucumber.js +11 -0
- data/lib/cucumber/formatters/html_formatter.rb +125 -0
- data/lib/cucumber/formatters/jquery.js +32 -0
- data/lib/cucumber/formatters/pretty_formatter.rb +126 -0
- data/lib/cucumber/formatters/progress_formatter.rb +42 -0
- data/lib/cucumber/languages.yml +83 -0
- data/lib/cucumber/rails/rspec.rb +12 -0
- data/lib/cucumber/rails/world.rb +75 -0
- data/lib/cucumber/rake/task.rb +75 -0
- data/lib/cucumber/step_methods.rb +45 -0
- data/lib/cucumber/step_mother.rb +82 -0
- data/lib/cucumber/tree.rb +18 -0
- data/lib/cucumber/tree/feature.rb +53 -0
- data/lib/cucumber/tree/features.rb +21 -0
- data/lib/cucumber/tree/given_scenario.rb +13 -0
- data/lib/cucumber/tree/scenario.rb +110 -0
- data/lib/cucumber/tree/step.rb +123 -0
- data/lib/cucumber/tree/table.rb +26 -0
- data/lib/cucumber/tree/top_down_visitor.rb +23 -0
- data/lib/cucumber/treetop_parser/feature.treetop.erb +159 -0
- data/lib/cucumber/treetop_parser/feature_da.rb +1214 -0
- data/lib/cucumber/treetop_parser/feature_de.rb +1214 -0
- data/lib/cucumber/treetop_parser/feature_en.rb +1214 -0
- data/lib/cucumber/treetop_parser/feature_es.rb +1214 -0
- data/lib/cucumber/treetop_parser/feature_et.rb +1214 -0
- data/lib/cucumber/treetop_parser/feature_fr.rb +1214 -0
- data/lib/cucumber/treetop_parser/feature_no.rb +1214 -0
- data/lib/cucumber/treetop_parser/feature_parser.rb +32 -0
- data/lib/cucumber/treetop_parser/feature_pt.rb +1214 -0
- data/lib/cucumber/treetop_parser/feature_ru.rb +1214 -0
- data/lib/cucumber/treetop_parser/feature_se.rb +1214 -0
- data/lib/cucumber/version.rb +9 -0
- data/script/console +10 -0
- data/script/console.cmd +1 -0
- data/script/destroy +14 -0
- data/script/destroy.cmd +1 -0
- data/script/generate +14 -0
- data/script/generate.cmd +1 -0
- data/script/txt2html +74 -0
- data/script/txt2html.cmd +1 -0
- data/setup.rb +1585 -0
- data/spec/cucumber/cli_spec.rb +36 -0
- data/spec/cucumber/core_ext/proc_spec.rb +39 -0
- data/spec/cucumber/core_ext/string_spec.rb +34 -0
- data/spec/cucumber/executor_spec.rb +131 -0
- data/spec/cucumber/formatters/ansicolor_spec.rb +23 -0
- data/spec/cucumber/formatters/features.html +269 -0
- data/spec/cucumber/formatters/html_formatter_spec.rb +59 -0
- data/spec/cucumber/formatters/pretty_formatter_spec.rb +17 -0
- data/spec/cucumber/formatters/progress_formatter_spec.rb +44 -0
- data/spec/cucumber/sell_cucumbers.feature +9 -0
- data/spec/cucumber/step_mother_spec.rb +53 -0
- data/spec/cucumber/tree/scenario_spec.rb +15 -0
- data/spec/cucumber/treetop_parser/empty_feature.feature +4 -0
- data/spec/cucumber/treetop_parser/empty_scenario.feature +9 -0
- data/spec/cucumber/treetop_parser/feature_parser_spec.rb +73 -0
- data/spec/cucumber/treetop_parser/fit_scenario.feature +7 -0
- data/spec/cucumber/treetop_parser/given_scenario.feature +9 -0
- data/spec/cucumber/treetop_parser/multiple_tables.feature +27 -0
- data/spec/cucumber/treetop_parser/spaces.feature +10 -0
- data/spec/cucumber/treetop_parser/with_comments.feature +6 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +23 -0
- metadata +259 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module Cucumber
|
|
2
|
+
class ArityMismatchError < StandardError
|
|
3
|
+
end
|
|
4
|
+
|
|
5
|
+
module CoreExt
|
|
6
|
+
# Proc extension that allows a proc to be called in the context of any object.
|
|
7
|
+
# Also makes it possible to tack a name onto a Proc.
|
|
8
|
+
module CallIn
|
|
9
|
+
attr_accessor :name
|
|
10
|
+
|
|
11
|
+
def call_in(obj, *args)
|
|
12
|
+
obj.extend(mod)
|
|
13
|
+
a = arity == -1 ? 0 : arity
|
|
14
|
+
if self != StepMother::PENDING && args.length != a
|
|
15
|
+
# We have to manually raise when the block has arity -1 (no pipes)
|
|
16
|
+
raise ArityMismatchError.new("expected #{arity == -1 ? 0 : arity} block argument(s), got #{args.length}")
|
|
17
|
+
else
|
|
18
|
+
obj.__send__(meth, *args)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def arity2
|
|
23
|
+
arity == -1 ? 0 : arity
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def backtrace_line
|
|
27
|
+
to_s.match(/[\d\w]+@(.*)>/)[1] + ":in `#{name}'"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def meth
|
|
31
|
+
@meth ||= "__cucumber_#{object_id}"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def mod
|
|
35
|
+
p = self
|
|
36
|
+
m = meth
|
|
37
|
+
@mod ||= Module.new do
|
|
38
|
+
define_method(m, &p)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
class String
|
|
2
|
+
def gzub(regexp, format=nil, &proc)
|
|
3
|
+
md = match(regexp)
|
|
4
|
+
raise "#{self.inspect} doesn't match #{regexp.inspect}" if md.nil?
|
|
5
|
+
|
|
6
|
+
s = dup
|
|
7
|
+
pos = 0
|
|
8
|
+
md.captures.each_with_index do |m, n|
|
|
9
|
+
replacement = if block_given?
|
|
10
|
+
proc.call(m)
|
|
11
|
+
else
|
|
12
|
+
format % m
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
if md.offset(n+1)[0]
|
|
16
|
+
s[md.offset(n+1)[0] + pos, m.length] = replacement
|
|
17
|
+
pos += replacement.length - m.length
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
s
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
require 'cucumber/core_ext/proc'
|
|
2
|
+
|
|
3
|
+
module Cucumber
|
|
4
|
+
class Executor
|
|
5
|
+
attr_reader :failed
|
|
6
|
+
|
|
7
|
+
def line=(line)
|
|
8
|
+
@line = line
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def initialize(formatter, step_mother)
|
|
12
|
+
@formatter = formatter
|
|
13
|
+
@world_proc = lambda do
|
|
14
|
+
world = Object.new
|
|
15
|
+
world.extend(Spec::Matchers) if defined?(Spec::Matchers)
|
|
16
|
+
world
|
|
17
|
+
end
|
|
18
|
+
@before_scenario_procs = []
|
|
19
|
+
@after_scenario_procs = []
|
|
20
|
+
@after_step_procs = []
|
|
21
|
+
@step_mother = step_mother
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def register_world_proc(&proc)
|
|
25
|
+
@world_proc = proc
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def register_before_scenario_proc(&proc)
|
|
29
|
+
proc.extend(CoreExt::CallIn)
|
|
30
|
+
@before_scenario_procs << proc
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def register_after_scenario_proc(&proc)
|
|
34
|
+
proc.extend(CoreExt::CallIn)
|
|
35
|
+
@after_scenario_procs << proc
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def register_after_step_proc(&proc)
|
|
39
|
+
proc.extend(CoreExt::CallIn)
|
|
40
|
+
@after_step_procs << proc
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def visit_features(features)
|
|
44
|
+
raise "Line number can only be specified when there is 1 feature. There were #{features.length}." if @line && features.length != 1
|
|
45
|
+
@formatter.visit_features(features) if @formatter.respond_to?(:visit_features)
|
|
46
|
+
features.accept(self)
|
|
47
|
+
@formatter.dump
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def visit_feature(feature)
|
|
51
|
+
feature.accept(self)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def visit_header(header)
|
|
55
|
+
@formatter.header_executing(header) if @formatter.respond_to?(:header_executing)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def visit_row_scenario(scenario)
|
|
59
|
+
visit_scenario(scenario)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def visit_regular_scenario(scenario)
|
|
63
|
+
visit_scenario(scenario)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def visit_scenario(scenario)
|
|
67
|
+
if @line.nil? || scenario.at_line?(@line)
|
|
68
|
+
@error = nil
|
|
69
|
+
@pending = nil
|
|
70
|
+
@world = @world_proc.call
|
|
71
|
+
@formatter.scenario_executing(scenario) if @formatter.respond_to?(:scenario_executing)
|
|
72
|
+
@before_scenario_procs.each{|p| p.call_in(@world, *[])}
|
|
73
|
+
scenario.accept(self)
|
|
74
|
+
@after_scenario_procs.each{|p| p.call_in(@world, *[])}
|
|
75
|
+
@formatter.scenario_executed(scenario) if @formatter.respond_to?(:scenario_executed)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def visit_row_step(step)
|
|
80
|
+
visit_step(step)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def visit_regular_step(step)
|
|
84
|
+
visit_step(step)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def visit_step(step)
|
|
88
|
+
unless @pending || @error
|
|
89
|
+
begin
|
|
90
|
+
regexp, args, proc = step.regexp_args_proc(@step_mother)
|
|
91
|
+
step.execute_in(@world, regexp, args, proc)
|
|
92
|
+
@after_step_procs.each{|p| p.call_in(@world, *[])}
|
|
93
|
+
@formatter.step_passed(step, regexp, args)
|
|
94
|
+
rescue Pending
|
|
95
|
+
record_pending_step(step, regexp, args)
|
|
96
|
+
rescue => e
|
|
97
|
+
@failed = true
|
|
98
|
+
@error = step.error = e
|
|
99
|
+
@formatter.step_failed(step, regexp, args)
|
|
100
|
+
end
|
|
101
|
+
else
|
|
102
|
+
begin
|
|
103
|
+
regexp, args, proc = step.regexp_args_proc(@step_mother)
|
|
104
|
+
step.execute_in(@world, regexp, args, proc)
|
|
105
|
+
@formatter.step_skipped(step, regexp, args)
|
|
106
|
+
rescue Pending
|
|
107
|
+
record_pending_step(step, regexp, args)
|
|
108
|
+
rescue Exception
|
|
109
|
+
@formatter.step_skipped(step, regexp, args)
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def record_pending_step(step, regexp, args)
|
|
115
|
+
@pending = true
|
|
116
|
+
@formatter.step_pending(step, regexp, args)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
end
|
|
120
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
%w{html pretty progress}.each{|n| require "cucumber/formatters/#{n}_formatter"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
require 'term/ansicolor'
|
|
2
|
+
begin
|
|
3
|
+
require 'Win32/Console/ANSI' if PLATFORM =~ /mswin|mingw/
|
|
4
|
+
rescue LoadError
|
|
5
|
+
STDERR.puts "You must gem install win32console to get coloured output on this ruby platform (#{PLATFORM})"
|
|
6
|
+
::Term::ANSIColor.coloring = false
|
|
7
|
+
end
|
|
8
|
+
::Term::ANSIColor.coloring = false if !STDOUT.tty?
|
|
9
|
+
|
|
10
|
+
module Cucumber
|
|
11
|
+
module Formatters
|
|
12
|
+
# Adds ANSI color support to formatters.
|
|
13
|
+
# You can define your own colours by defining CUCUMBER_COLORS in your shell. Example:
|
|
14
|
+
#
|
|
15
|
+
# CUCUMBER_COLORS=pending=black,on_yellow:failed=dark,magenta:failed_param=bold,red
|
|
16
|
+
#
|
|
17
|
+
# The string must be a series of key=value pairs where:
|
|
18
|
+
#
|
|
19
|
+
# * Each key=value pair is separated by a colon (:)
|
|
20
|
+
# * Each key must be one of:
|
|
21
|
+
# ** passed
|
|
22
|
+
# ** passed_param
|
|
23
|
+
# ** failed
|
|
24
|
+
# ** failed_param
|
|
25
|
+
# ** skipped
|
|
26
|
+
# ** skipped_param
|
|
27
|
+
# ** pending
|
|
28
|
+
# * Each value must be a comma-separated string composed of:
|
|
29
|
+
# ** bold
|
|
30
|
+
# ** dark
|
|
31
|
+
# ** italic
|
|
32
|
+
# ** underline
|
|
33
|
+
# ** underscore
|
|
34
|
+
# ** blink
|
|
35
|
+
# ** rapid_blink
|
|
36
|
+
# ** negative
|
|
37
|
+
# ** concealed
|
|
38
|
+
# ** strikethrough
|
|
39
|
+
# ** black
|
|
40
|
+
# ** red
|
|
41
|
+
# ** green
|
|
42
|
+
# ** yellow
|
|
43
|
+
# ** blue
|
|
44
|
+
# ** magenta
|
|
45
|
+
# ** cyan
|
|
46
|
+
# ** white
|
|
47
|
+
# ** on_black
|
|
48
|
+
# ** on_red
|
|
49
|
+
# ** on_green
|
|
50
|
+
# ** on_yellow
|
|
51
|
+
# ** on_blue
|
|
52
|
+
# ** on_magenta
|
|
53
|
+
# ** on_cyan
|
|
54
|
+
# ** on_white
|
|
55
|
+
#
|
|
56
|
+
module ANSIColor
|
|
57
|
+
include ::Term::ANSIColor
|
|
58
|
+
|
|
59
|
+
# Params are underlined bold, except in windows, which doesn't support underline. Use non-bold colour.
|
|
60
|
+
param = PLATFORM =~ /mswin|mingw/ ? '' : 'underline,bold,'
|
|
61
|
+
|
|
62
|
+
# Default aliases
|
|
63
|
+
ALIASES = {
|
|
64
|
+
:passed => 'bold,green',
|
|
65
|
+
:passed_param => "#{param}green",
|
|
66
|
+
:failed => 'bold,red',
|
|
67
|
+
:failed_param => "#{param}red",
|
|
68
|
+
:skipped => 'bold,cyan',
|
|
69
|
+
:skipped_param => "#{param}cyan",
|
|
70
|
+
:pending => 'bold,yellow' # No pending_param
|
|
71
|
+
}
|
|
72
|
+
if ENV['CUCUMBER_COLORS']
|
|
73
|
+
ENV['CUCUMBER_COLORS'].split(':').each do |pair|
|
|
74
|
+
a = pair.split('=')
|
|
75
|
+
ALIASES[a[0].to_sym] = a[1]
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
ALIASES.each do |m, color_string|
|
|
80
|
+
colors = color_string.split(",").reverse
|
|
81
|
+
define_method(m) do |*s|
|
|
82
|
+
::Term::ANSIColor.coloring = false if ENV['CUCUMBER_COLORS_DISABLED'] == '1'
|
|
83
|
+
clear + colors.inject(s[0]) do |memo, color|
|
|
84
|
+
s[0].nil? ? __send__(color) + memo.to_s : __send__(color, memo.to_s)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
body {
|
|
2
|
+
background: #fff;
|
|
3
|
+
font-size: 80%;
|
|
4
|
+
margin:0pt;
|
|
5
|
+
padding:0pt;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
#container {
|
|
9
|
+
background:white none repeat scroll 0%;
|
|
10
|
+
font-family:Helvetica,Arial,sans-serif;
|
|
11
|
+
margin:0pt auto;
|
|
12
|
+
position:relative;
|
|
13
|
+
text-align:left;
|
|
14
|
+
top:1.0em;
|
|
15
|
+
width:78em;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
span {
|
|
19
|
+
font-weight: bold;
|
|
20
|
+
text-decoration: underline;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
dl {
|
|
24
|
+
font: normal 11px "Lucida Grande", Helvetica, sans-serif;
|
|
25
|
+
margin-left: 5px;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
dl.new {
|
|
29
|
+
border-left: 5px solid #444444;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
dl.pending {
|
|
33
|
+
border-left: 5px solid #FAF834;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
dl.failed {
|
|
37
|
+
border-left: 5px solid #C20000;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
dl.passed {
|
|
41
|
+
border-left: 5px solid #65C400;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
dt {
|
|
45
|
+
color: #fff;
|
|
46
|
+
padding: 3px;
|
|
47
|
+
font-weight: bold;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
dl.new > dt {
|
|
51
|
+
background: #444444;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
dl.pending > dt {
|
|
55
|
+
color: #131313;
|
|
56
|
+
background: #FAF834;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
dl.failed > dt {
|
|
60
|
+
background: #C20000;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
dl.passed > dt {
|
|
64
|
+
background: #65C400;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
dd {
|
|
68
|
+
margin: 0px 0px 0px 0px;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
dd p, pre {
|
|
72
|
+
padding: 5px;
|
|
73
|
+
margin-top: 0;
|
|
74
|
+
margin-bottom: 5px;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
dl.passed > dd > p, li.passed {
|
|
78
|
+
background: #DBFFB4; color: #3D7700;
|
|
79
|
+
border-bottom: 1px solid #65C400;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
dl.failed > dd > p, li.failed {
|
|
83
|
+
color: #C20000; background: #FFFBD3;
|
|
84
|
+
border-bottom: 1px solid #C20000;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
dl.pending > dd > p, li.pending {
|
|
88
|
+
color: #131313; background: #FCFB98;
|
|
89
|
+
border-bottom: 1px solid #FAF834;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
dl.new > dd > p, li.new {
|
|
93
|
+
color: #444444; background: #DDDDDD;
|
|
94
|
+
border-bottom: 1px solid #444444;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
span.param, span.param_editor {
|
|
98
|
+
font-weight: bold;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
input {
|
|
102
|
+
width: 100%;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
ul {
|
|
106
|
+
padding: 0px;
|
|
107
|
+
list-style: none;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
ul > li {
|
|
111
|
+
margin: 5px 0px 5px 5px;
|
|
112
|
+
padding: 3px 3px 3px 5px;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
div.auto_complete ul {
|
|
116
|
+
list-style-type: none;
|
|
117
|
+
border: 2px solid #F0F0F0;
|
|
118
|
+
margin: 0px;
|
|
119
|
+
padding: 0px;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
div.auto_complete ul li {
|
|
123
|
+
background-color: white;
|
|
124
|
+
list-style-type: none;
|
|
125
|
+
display: block;
|
|
126
|
+
margin: 0;
|
|
127
|
+
padding: 2px;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
div.auto_complete ul li.selected {
|
|
131
|
+
color: #444444; background: #DDDDDD;
|
|
132
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
function stepPassed(id) {
|
|
2
|
+
$("#"+id).removeClass("new").addClass("passed");
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
function stepPending(id) {
|
|
6
|
+
$("#"+id).removeClass("new").addClass("pending");
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function stepFailed(id, message, backtrace) {
|
|
10
|
+
$("#"+id).removeClass("new").addClass("failed").append("<div>" + message + "</div>").append("<pre>" + backtrace + "</pre>");
|
|
11
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
module Cucumber
|
|
2
|
+
module Formatters
|
|
3
|
+
class HtmlFormatter
|
|
4
|
+
def initialize(io, step_mother)
|
|
5
|
+
@io = io
|
|
6
|
+
@step_mother = step_mother
|
|
7
|
+
@errors = []
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def visit_features(features)
|
|
11
|
+
# IMPORTANT NOTICE ABOUT JQUERY BELOW. THE ORIGINAL BACKSLASHES (\) HAVE
|
|
12
|
+
# BEEN REPLACED BY DOUBLE BACKSLASHES (\\) IN THIS FILE TO MAKE SURE THEY
|
|
13
|
+
# ARE PRINTED PROPERLY WITH ONLY ONE BACKSLASH (\).
|
|
14
|
+
@io.puts(<<-HTML)
|
|
15
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
16
|
+
<!DOCTYPE html
|
|
17
|
+
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
|
18
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
|
19
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
|
20
|
+
<head>
|
|
21
|
+
<title>#{Cucumber.language['feature']}</title>
|
|
22
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
23
|
+
<meta http-equiv="Expires" content="-1" />
|
|
24
|
+
<meta http-equiv="Pragma" content="no-cache" />
|
|
25
|
+
<script type="text/javascript">
|
|
26
|
+
#{IO.read(File.dirname(__FILE__) + '/jquery.js')}
|
|
27
|
+
#{IO.read(File.dirname(__FILE__) + '/cucumber.js')}
|
|
28
|
+
</script>
|
|
29
|
+
<style>
|
|
30
|
+
#{IO.read(File.dirname(__FILE__) + '/cucumber.css')}
|
|
31
|
+
</style>
|
|
32
|
+
</head>
|
|
33
|
+
<body>
|
|
34
|
+
<div id="container">
|
|
35
|
+
HTML
|
|
36
|
+
features.accept(self)
|
|
37
|
+
@io.puts %{ </div>}
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def visit_feature(feature)
|
|
41
|
+
@io.puts %{ <dl class="feature new">}
|
|
42
|
+
feature.accept(self)
|
|
43
|
+
@io.puts %{ </dd>}
|
|
44
|
+
@io.puts %{ </dl>}
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def visit_header(header)
|
|
48
|
+
header = header.gsub(/\n/, "<br />\n")
|
|
49
|
+
@io.puts %{ <dt>#{header}}
|
|
50
|
+
@io.puts %{ </dt>}
|
|
51
|
+
@io.puts %{ <dd>}
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def visit_regular_scenario(scenario)
|
|
55
|
+
@io.puts %{ <dl class="new">}
|
|
56
|
+
@io.puts %{ <dt>#{Cucumber.language['scenario']}: #{scenario.name}</dt>}
|
|
57
|
+
@io.puts %{ <dd>}
|
|
58
|
+
@io.puts %{ <ul>}
|
|
59
|
+
scenario.accept(self)
|
|
60
|
+
@io.puts %{ </ul>}
|
|
61
|
+
@io.puts %{ </dd>}
|
|
62
|
+
@io.puts %{ </dl>}
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def visit_row_scenario(scenario)
|
|
66
|
+
@io.puts %{ <dl class="new">}
|
|
67
|
+
@io.puts %{ <dt>#{Cucumber.language['scenario']}: #{scenario.name}</dt>}
|
|
68
|
+
@io.puts %{ <dd>}
|
|
69
|
+
@io.puts %{ <table>}
|
|
70
|
+
@io.puts %{ <thead>}
|
|
71
|
+
@io.puts %{ <tr>}
|
|
72
|
+
@io.puts %{ <th>COL 1</th>}
|
|
73
|
+
@io.puts %{ <th>COL 2</th>}
|
|
74
|
+
@io.puts %{ </tr>}
|
|
75
|
+
@io.puts %{ </thead>}
|
|
76
|
+
@io.puts %{ <tbody>}
|
|
77
|
+
scenario.accept(self)
|
|
78
|
+
@io.puts %{ </tbody>}
|
|
79
|
+
@io.puts %{ </table>}
|
|
80
|
+
@io.puts %{ </dd>}
|
|
81
|
+
@io.puts %{ </dl>}
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def visit_row_step(step)
|
|
85
|
+
_, args, _ = step.regexp_args_proc(@step_mother)
|
|
86
|
+
args.each do |arg|
|
|
87
|
+
@io.puts %{ <td id="#{step.id}"><span>#{arg}</span></td>}
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def visit_regular_step(step)
|
|
92
|
+
regexp, _, _ = step.regexp_args_proc(@step_mother)
|
|
93
|
+
@io.puts %{ <li class="new" id="#{step.id}">#{step.keyword} #{step.format(regexp, '<span>%s</span>')}</li>}
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def step_passed(step, regexp, args)
|
|
97
|
+
print_javascript_tag("stepPassed(#{step.id})")
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def step_failed(step, regexp, args)
|
|
101
|
+
@errors << step.error
|
|
102
|
+
print_javascript_tag("stepFailed(#{step.id}, #{step.error.message.inspect}, #{step.error.backtrace.join("\n").inspect})")
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def step_pending(step, regexp, args)
|
|
106
|
+
print_javascript_tag("stepPending(#{step.id})")
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def step_skipped(step, regexp, args)
|
|
110
|
+
# noop
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def print_javascript_tag(js)
|
|
114
|
+
@io.puts %{ <script type="text/javascript">#{js}</script>}
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def dump
|
|
118
|
+
@io.puts <<-HTML
|
|
119
|
+
</body>
|
|
120
|
+
</html>
|
|
121
|
+
HTML
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|