cucumber 3.0.0.pre.1 → 3.0.0.pre.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.cucumberproignore +6 -0
- data/.rubocop.yml +13 -0
- data/.rubocop_todo.yml +1075 -0
- data/.travis.yml +42 -8
- data/CONTRIBUTING.md +8 -1
- data/Gemfile +16 -10
- data/History.md +96 -36
- data/README.md +12 -3
- data/Rakefile +12 -2
- data/appveyor.yml +26 -0
- data/cucumber.gemspec +15 -10
- data/cucumber.yml +9 -10
- data/examples/i18n/Rakefile +1 -1
- data/examples/i18n/ar/features/step_definitions/calculator_steps.rb +2 -2
- data/examples/i18n/ar/lib/calculator.rb +2 -2
- data/examples/i18n/bg/features/step_definitions/calculator_steps.rb +6 -6
- data/examples/i18n/ca/features/step_definitions/calculator_steps.rb +4 -4
- data/examples/i18n/ca/lib/calculadora.rb +2 -2
- data/examples/i18n/cs/features/step_definitions/calculator_steps.rb +4 -4
- data/examples/i18n/cs/lib/calculator.rb +3 -3
- data/examples/i18n/da/features/step_definitions/lommeregner_steps.rb +4 -4
- data/examples/i18n/da/lib/lommeregner.rb +2 -2
- data/examples/i18n/de/features/step_definitions/calculator_steps.rb +4 -4
- data/examples/i18n/de/lib/calculator.rb +2 -2
- data/examples/i18n/el/features/step_definitions/calculator_steps.rb +5 -5
- data/examples/i18n/el/lib/calculator.rb +2 -2
- data/examples/i18n/en-lol/features/step_definitions/cucumbrz_steps.rb +4 -4
- data/examples/i18n/en-lol/lib/basket.rb +2 -2
- data/examples/i18n/en-lol/lib/belly.rb +2 -2
- data/examples/i18n/en/features/step_definitions/calculator_steps.rb +4 -4
- data/examples/i18n/en/lib/calculator.rb +2 -2
- data/examples/i18n/eo/features/step_definitions/calculator_steps.rb +4 -4
- data/examples/i18n/eo/lib/calculator.rb +2 -2
- data/examples/i18n/es/features/step_definitions/calculador_steps.rb +5 -5
- data/examples/i18n/es/lib/calculador.rb +2 -2
- data/examples/i18n/et/features/step_definitions/kalkulaator_steps.rb +4 -4
- data/examples/i18n/et/lib/kalkulaator.rb +3 -3
- data/examples/i18n/fi/features/step_definitions/laskin_steps.rb +3 -3
- data/examples/i18n/fi/lib/laskin.rb +1 -1
- data/examples/i18n/fr/features/step_definitions/calculatrice_steps.rb +8 -8
- data/examples/i18n/fr/features/support/env.rb +1 -1
- data/examples/i18n/fr/lib/calculatrice.rb +2 -2
- data/examples/i18n/he/features/step_definitions/calculator_steps.rb +4 -4
- data/examples/i18n/he/lib/calculator.rb +1 -1
- data/examples/i18n/hi/features/step_definitions/calculator_steps.rb +3 -3
- data/examples/i18n/hi/lib/calculator.rb +1 -1
- data/examples/i18n/ht/features/step_definitions/kalkilatris_steps.rb +4 -4
- data/examples/i18n/ht/lib/kalkilatris.rb +2 -2
- data/examples/i18n/hu/features/step_definitions/calculator_steps.rb +4 -4
- data/examples/i18n/hu/lib/calculator.rb +1 -1
- data/examples/i18n/id/features/step_definitions/calculator_steps.rb +4 -4
- data/examples/i18n/id/lib/calculator.rb +2 -2
- data/examples/i18n/it/features/step_definitions/calcolatrice_steps.rb +4 -4
- data/examples/i18n/it/lib/calcolatrice.rb +3 -3
- data/examples/i18n/ja/features/step_definitions/calculator_steps.rb +3 -3
- data/examples/i18n/ja/features/support/env.rb +1 -1
- data/examples/i18n/ja/lib/calculator.rb +2 -2
- data/examples/i18n/ko/features/step_definitions/calculator_steps.rb +4 -4
- data/examples/i18n/ko/lib/calculator.rb +2 -2
- data/examples/i18n/lt/features/step_definitions/calculator_steps.rb +4 -4
- data/examples/i18n/lt/lib/calculator.rb +2 -2
- data/examples/i18n/lv/features/step_definitions/calculator_steps.rb +4 -4
- data/examples/i18n/lv/lib/calculator.rb +2 -2
- data/examples/i18n/no/features/step_definitions/kalkulator_steps.rb +3 -3
- data/examples/i18n/no/features/support/env.rb +1 -1
- data/examples/i18n/no/lib/kalkulator.rb +2 -2
- data/examples/i18n/pl/features/step_definitions/calculator_steps.rb +4 -4
- data/examples/i18n/pl/lib/calculator.rb +2 -2
- data/examples/i18n/pt/features/step_definitions/calculadora_steps.rb +3 -3
- data/examples/i18n/pt/features/support/env.rb +1 -1
- data/examples/i18n/pt/lib/calculadora.rb +1 -1
- data/examples/i18n/ro/features/step_definitions/calculator_steps.rb +5 -5
- data/examples/i18n/ro/lib/calculator.rb +1 -1
- data/examples/i18n/ru/features/step_definitions/calculator_steps.rb +5 -5
- data/examples/i18n/sk/features/step_definitions/calculator_steps.rb +4 -4
- data/examples/i18n/sk/lib/calculator.rb +2 -2
- data/examples/i18n/sr-Cyrl/features/step_definitions/calculator_steps.rb +3 -3
- data/examples/i18n/sr-Cyrl/features/support/env.rb +1 -1
- data/examples/i18n/sr-Cyrl/lib/calculator.rb +2 -2
- data/examples/i18n/sr-Latn/features/step_definitions/calculator_steps.rb +4 -4
- data/examples/i18n/sr-Latn/lib/calculator.rb +2 -2
- data/examples/i18n/sv/features/step_definitions/kalkulator_steps.rb +3 -3
- data/examples/i18n/sv/lib/kalkulator.rb +2 -2
- data/examples/i18n/tr/features/step_definitions/hesap_makinesi_adimlari.rb +4 -4
- data/examples/i18n/tr/lib/hesap_makinesi.rb +2 -2
- data/examples/i18n/uk/features/step_definitions/calculator_steps.rb +4 -4
- data/examples/i18n/uz/features/step_definitions/calculator_steps.rb +4 -4
- data/examples/i18n/zh-CN/features/step_definitions/calculator_steps.rb +5 -5
- data/examples/i18n/zh-CN/lib/calculator.rb +2 -2
- data/examples/i18n/zh-TW/features/step_definitions/calculator_steps.rb +4 -4
- data/examples/i18n/zh-TW/lib/calculator.rb +2 -2
- data/examples/rspec_doubles/features/step_definitions/calvin_steps.rb +3 -3
- data/examples/sinatra/features/step_definitions/add_steps.rb +4 -4
- data/examples/tcl/features/step_definitions/fib_steps.rb +2 -2
- data/examples/test_unit/features/step_definitions/test_unit_steps.rb +4 -4
- data/examples/watir/features/step_definitions/search_steps.rb +3 -3
- data/examples/watir/features/support/screenshots.rb +5 -5
- data/features/docs/api/list_step_defs_as_json.feature +21 -7
- data/features/docs/api/listen_for_events.feature +1 -1
- data/features/docs/api/run_cli_main_with_existing_runtime.feature +1 -0
- data/features/docs/cli/dry_run.feature +3 -0
- data/features/docs/cli/execute_with_tag_filter.feature +4 -4
- data/features/docs/cli/fail_fast.feature +2 -0
- data/features/docs/{gherkin/language_help.feature → cli/i18n.feature} +6 -6
- data/features/docs/cli/randomize.feature +2 -2
- data/features/docs/cli/retry_failing_tests.feature +28 -3
- data/features/docs/cli/run_scenarios_matching_name.feature +1 -0
- data/features/docs/cli/specifying_multiple_formatters.feature +3 -0
- data/features/docs/cli/strict_mode.feature +6 -0
- data/features/docs/defining_steps/nested_steps.feature +5 -1
- data/features/docs/defining_steps/nested_steps_i18n.feature +1 -0
- data/features/docs/defining_steps/nested_steps_with_second_arg.feature +2 -0
- data/features/docs/defining_steps/printing_messages.feature +1 -1
- data/features/docs/defining_steps/skip_scenario.feature +1 -0
- data/features/docs/defining_steps/snippets.feature +18 -18
- data/features/docs/events/gherkin_source_read_event.feature +43 -0
- data/features/docs/events/step_activated_event.feature +36 -0
- data/features/docs/events/step_definition_registered_event.feature +29 -0
- data/features/docs/events/test_case_finished_event.feature +35 -0
- data/features/docs/events/test_case_starting_event.feature +54 -0
- data/features/docs/events/test_run_finished_event.feature +40 -0
- data/features/docs/events/test_run_starting_event.feature +41 -0
- data/features/docs/events/test_step_finished_event.feature +47 -0
- data/features/docs/events/test_step_starting_event.feature +43 -0
- data/features/docs/exception_in_after_hook.feature +3 -2
- data/features/docs/exception_in_after_step_hook.feature +2 -0
- data/features/docs/exception_in_around_hook.feature +2 -0
- data/features/docs/exception_in_before_hook.feature +3 -1
- data/features/docs/extending_cucumber/custom_formatter.feature +21 -1
- data/features/docs/formatters/json_formatter.feature +4 -4
- data/features/docs/formatters/junit_formatter.feature +7 -6
- data/features/docs/formatters/pretty_formatter.feature +1 -0
- data/features/docs/formatters/progress_formatter.feature +1 -0
- data/features/docs/formatters/rerun_formatter.feature +2 -0
- data/features/docs/formatters/summary_formatter.feature +1 -0
- data/features/docs/formatters/usage_formatter.feature +3 -0
- data/features/docs/getting_started.feature +2 -1
- data/features/docs/gherkin/background.feature +5 -5
- data/features/docs/gherkin/doc_strings.feature +2 -0
- data/features/docs/gherkin/expand_option_for_outlines.feature +1 -0
- data/features/docs/gherkin/outlines.feature +4 -0
- data/features/docs/gherkin/unicode_table.feature +1 -0
- data/features/docs/gherkin/using_descriptions.feature +1 -0
- data/features/docs/gherkin/using_star_notation.feature +1 -1
- data/features/docs/post_configuration_hook.feature +1 -1
- data/features/docs/rake_task.feature +5 -0
- data/features/docs/raketask.feature +3 -1
- data/features/docs/work_in_progress.feature +5 -2
- data/features/docs/writing_support_code/after_step_hooks.feature +3 -1
- data/features/docs/writing_support_code/around_hooks.feature +6 -0
- data/features/docs/writing_support_code/before_hook.feature +1 -0
- data/features/docs/writing_support_code/hook_order.feature +3 -1
- data/features/docs/writing_support_code/parameter_types.feature +75 -0
- data/features/docs/writing_support_code/tagged_hooks.feature +1 -1
- data/features/lib/step_definitions/aruba_steps.rb +4 -10
- data/features/lib/step_definitions/cli_steps.rb +2 -2
- data/features/lib/step_definitions/cucumber_steps.rb +8 -12
- data/features/lib/step_definitions/iso-8859-1_steps.rb +2 -2
- data/features/lib/step_definitions/json_steps.rb +1 -1
- data/features/lib/step_definitions/junit_steps.rb +1 -1
- data/features/lib/step_definitions/language_steps.rb +2 -2
- data/features/lib/step_definitions/profile_steps.rb +6 -6
- data/features/lib/step_definitions/retry_steps.rb +3 -3
- data/features/lib/step_definitions/ruby_steps.rb +1 -1
- data/features/lib/support/env.rb +1 -1
- data/features/lib/support/fake_wire_server.rb +7 -2
- data/features/lib/support/feature_factory.rb +1 -1
- data/features/lib/support/normalise_output.rb +13 -12
- data/features/lib/support/parameter_types.rb +8 -0
- data/gem_tasks/contributors.rake +9 -6
- data/gem_tasks/environment.rake +1 -5
- data/gem_tasks/examples.rake +1 -1
- data/gem_tasks/fix_cr_lf.rake +1 -1
- data/gem_tasks/flog.rake +2 -2
- data/gem_tasks/rspec.rake +1 -1
- data/lib/autotest/cucumber_mixin.rb +15 -15
- data/lib/autotest/discover.rb +2 -2
- data/lib/cucumber/cli/configuration.rb +7 -13
- data/lib/cucumber/cli/main.rb +6 -6
- data/lib/cucumber/cli/options.rb +163 -126
- data/lib/cucumber/cli/profile_loader.rb +24 -20
- data/lib/cucumber/configuration.rb +12 -17
- data/lib/cucumber/constantize.rb +1 -1
- data/lib/cucumber/core_ext/string.rb +1 -1
- data/lib/cucumber/deprecate.rb +1 -1
- data/lib/cucumber/events.rb +11 -1
- data/lib/cucumber/events/gherkin_source_read.rb +17 -0
- data/lib/cucumber/events/{step_match.rb → step_activated.rb} +2 -2
- data/lib/cucumber/events/step_definition_registered.rb +1 -1
- data/lib/cucumber/events/test_case_finished.rb +18 -0
- data/lib/cucumber/events/test_case_starting.rb +15 -0
- data/lib/cucumber/events/test_run_starting.rb +16 -0
- data/lib/cucumber/events/test_step_finished.rb +20 -0
- data/lib/cucumber/events/test_step_starting.rb +17 -0
- data/lib/cucumber/filters.rb +1 -0
- data/lib/cucumber/filters/activate_steps.rb +1 -1
- data/lib/cucumber/filters/broadcast_test_run_starting_event.rb +27 -0
- data/lib/cucumber/filters/retry.rb +1 -1
- data/lib/cucumber/filters/tag_limits.rb +3 -3
- data/lib/cucumber/filters/tag_limits/verifier.rb +1 -1
- data/lib/cucumber/formatter/ansicolor.rb +8 -11
- data/lib/cucumber/formatter/backtrace_filter.rb +19 -7
- data/lib/cucumber/formatter/console.rb +16 -19
- data/lib/cucumber/formatter/console_counts.rb +8 -21
- data/lib/cucumber/formatter/console_issues.rb +30 -9
- data/lib/cucumber/formatter/duration.rb +1 -1
- data/lib/cucumber/formatter/fail_fast.rb +1 -1
- data/lib/cucumber/formatter/html.rb +168 -242
- data/lib/cucumber/formatter/html_builder.rb +110 -0
- data/lib/cucumber/formatter/inline-js.js +30 -0
- data/lib/cucumber/formatter/interceptor.rb +2 -2
- data/lib/cucumber/formatter/json.rb +12 -12
- data/lib/cucumber/formatter/junit.rb +11 -11
- data/lib/cucumber/formatter/legacy_api/adapter.rb +27 -27
- data/lib/cucumber/formatter/legacy_api/ast.rb +16 -20
- data/lib/cucumber/formatter/legacy_api/results.rb +6 -8
- data/lib/cucumber/formatter/pretty.rb +17 -17
- data/lib/cucumber/formatter/progress.rb +11 -12
- data/lib/cucumber/formatter/rerun.rb +1 -1
- data/lib/cucumber/formatter/steps.rb +1 -1
- data/lib/cucumber/formatter/unicode.rb +1 -1
- data/lib/cucumber/formatter/usage.rb +12 -12
- data/lib/cucumber/gherkin/formatter/ansi_escapes.rb +1 -1
- data/lib/cucumber/gherkin/formatter/escaping.rb +1 -1
- data/lib/cucumber/{rb_support/rb_dsl.rb → glue/dsl.rb} +44 -17
- data/lib/cucumber/glue/hook.rb +43 -0
- data/lib/cucumber/glue/invoke_in_world.rb +70 -0
- data/lib/cucumber/glue/proto_world.rb +225 -0
- data/lib/cucumber/{rb_support/rb_language.rb → glue/registry_and_more.rb} +45 -86
- data/lib/cucumber/{rb_support → glue}/snippet.rb +62 -25
- data/lib/cucumber/glue/step_definition.rb +143 -0
- data/lib/cucumber/glue/world_factory.rb +23 -0
- data/lib/cucumber/hooks.rb +4 -4
- data/lib/cucumber/multiline_argument.rb +2 -2
- data/lib/cucumber/multiline_argument/data_table.rb +40 -178
- data/lib/cucumber/multiline_argument/data_table/diff_matrices.rb +158 -0
- data/lib/cucumber/platform.rb +3 -5
- data/lib/cucumber/rake/task.rb +11 -11
- data/lib/cucumber/rspec/disable_option_parser.rb +1 -1
- data/lib/cucumber/rspec/doubles.rb +1 -1
- data/lib/cucumber/running_test_case.rb +2 -2
- data/lib/cucumber/runtime.rb +46 -34
- data/lib/cucumber/runtime/after_hooks.rb +1 -1
- data/lib/cucumber/runtime/for_programming_languages.rb +1 -36
- data/lib/cucumber/runtime/support_code.rb +19 -15
- data/lib/cucumber/runtime/user_interface.rb +4 -11
- data/lib/cucumber/step_argument.rb +0 -2
- data/lib/cucumber/step_definition_light.rb +1 -0
- data/lib/cucumber/step_match.rb +16 -15
- data/lib/cucumber/step_match_search.rb +2 -3
- data/lib/cucumber/term/ansicolor.rb +1 -1
- data/lib/cucumber/version +1 -1
- data/lib/simplecov_setup.rb +1 -1
- data/scripts/invite-collaborator +40 -0
- data/scripts/update-history +83 -0
- data/spec/cucumber/cli/configuration_spec.rb +95 -97
- data/spec/cucumber/cli/main_spec.rb +7 -7
- data/spec/cucumber/cli/options_spec.rb +112 -78
- data/spec/cucumber/cli/profile_loader_spec.rb +24 -5
- data/spec/cucumber/cli/rerun_spec.rb +20 -20
- data/spec/cucumber/configuration_spec.rb +47 -47
- data/spec/cucumber/constantize_spec.rb +2 -2
- data/spec/cucumber/events_spec.rb +9 -0
- data/spec/cucumber/file_specs_spec.rb +25 -25
- data/spec/cucumber/filters/activate_steps_spec.rb +16 -16
- data/spec/cucumber/filters/gated_receiver_spec.rb +6 -6
- data/spec/cucumber/filters/retry_spec.rb +22 -9
- data/spec/cucumber/filters/tag_limits/test_case_index_spec.rb +11 -11
- data/spec/cucumber/filters/tag_limits/verifier_spec.rb +14 -14
- data/spec/cucumber/filters/tag_limits_spec.rb +8 -8
- data/spec/cucumber/formatter/ansicolor_spec.rb +9 -9
- data/spec/cucumber/formatter/backtrace_filter_spec.rb +32 -0
- data/spec/cucumber/formatter/console_counts_spec.rb +1 -1
- data/spec/cucumber/formatter/duration_spec.rb +3 -3
- data/spec/cucumber/formatter/fail_fast_spec.rb +21 -21
- data/spec/cucumber/formatter/html_spec.rb +58 -58
- data/spec/cucumber/formatter/json_spec.rb +44 -46
- data/spec/cucumber/formatter/junit_spec.rb +43 -45
- data/spec/cucumber/formatter/legacy_api/adapter_spec.rb +43 -43
- data/spec/cucumber/formatter/pretty_spec.rb +107 -107
- data/spec/cucumber/formatter/progress_spec.rb +20 -20
- data/spec/cucumber/formatter/rerun_spec.rb +1 -1
- data/spec/cucumber/formatter/spec_helper.rb +6 -5
- data/spec/cucumber/{rb_support/rb_world_spec.rb → glue/proto_world_spec.rb} +20 -5
- data/spec/cucumber/glue/registry_and_more_spec.rb +213 -0
- data/spec/cucumber/{rb_support → glue}/snippet_spec.rb +61 -25
- data/spec/cucumber/glue/step_definition_spec.rb +207 -0
- data/spec/cucumber/hooks_spec.rb +3 -3
- data/spec/cucumber/multiline_argument/data_table_spec.rb +177 -133
- data/spec/cucumber/project_initializer_spec.rb +10 -10
- data/spec/cucumber/rake/forked_spec.rb +10 -10
- data/spec/cucumber/rake/task_spec.rb +20 -20
- data/spec/cucumber/running_test_case_spec.rb +35 -35
- data/spec/cucumber/runtime/for_programming_languages_spec.rb +1 -30
- data/spec/cucumber/runtime_spec.rb +2 -2
- data/spec/cucumber/step_argument_spec.rb +5 -5
- data/spec/cucumber/step_match_search_spec.rb +31 -41
- data/spec/cucumber/step_match_spec.rb +33 -33
- data/spec/cucumber/world/pending_spec.rb +10 -10
- metadata +117 -47
- data/features/docs/formatters/debug_formatter.feature +0 -47
- data/features/docs/writing_support_code/transforms.feature +0 -98
- data/features/lib/step_definitions/wire_steps.rb +0 -59
- data/gem_tasks/cucumber.rake +0 -26
- data/lib/cucumber/core_ext/instance_exec.rb +0 -71
- data/lib/cucumber/formatter/debug.rb +0 -36
- data/lib/cucumber/rb_support/rb_hook.rb +0 -20
- data/lib/cucumber/rb_support/rb_step_definition.rb +0 -132
- data/lib/cucumber/rb_support/rb_transform.rb +0 -60
- data/lib/cucumber/rb_support/rb_world.rb +0 -171
- data/spec/cucumber/core_ext/instance_exec_spec.rb +0 -5
- data/spec/cucumber/formatter/debug_spec.rb +0 -65
- data/spec/cucumber/rb_support/rb_language_spec.rb +0 -321
- data/spec/cucumber/rb_support/rb_step_definition_spec.rb +0 -200
- data/spec/cucumber/rb_support/rb_transform_spec.rb +0 -47
@@ -4,13 +4,25 @@ require 'cucumber/platform'
|
|
4
4
|
|
5
5
|
module Cucumber
|
6
6
|
module Formatter
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
@backtrace_filters = %w(
|
8
|
+
/vendor/rails
|
9
|
+
lib/cucumber
|
10
|
+
bin/cucumber:
|
11
|
+
lib/rspec
|
12
|
+
gems/
|
13
|
+
minitest
|
14
|
+
test/unit
|
15
|
+
.gem/ruby
|
16
|
+
lib/ruby/
|
17
|
+
bin/bundle
|
18
|
+
)
|
19
|
+
|
20
|
+
if ::Cucumber::JRUBY
|
21
|
+
@backtrace_filters << 'org/jruby/'
|
12
22
|
end
|
13
23
|
|
24
|
+
BACKTRACE_FILTER_PATTERNS = Regexp.new(@backtrace_filters.join('|'))
|
25
|
+
|
14
26
|
class BacktraceFilter
|
15
27
|
def initialize(exception)
|
16
28
|
@exception = exception
|
@@ -20,10 +32,10 @@ module Cucumber
|
|
20
32
|
return @exception if ::Cucumber.use_full_backtrace
|
21
33
|
|
22
34
|
pwd_pattern = /#{::Regexp.escape(::Dir.pwd)}\//m
|
23
|
-
backtrace = @exception.backtrace.map { |line| line.gsub(pwd_pattern,
|
35
|
+
backtrace = @exception.backtrace.map { |line| line.gsub(pwd_pattern, './') }
|
24
36
|
|
25
37
|
filtered = (backtrace || []).reject do |line|
|
26
|
-
|
38
|
+
line =~ BACKTRACE_FILTER_PATTERNS
|
27
39
|
end
|
28
40
|
|
29
41
|
if ::ENV['CUCUMBER_TRUNCATE_OUTPUT']
|
@@ -32,11 +32,11 @@ module Cucumber
|
|
32
32
|
|
33
33
|
def format_step(keyword, step_match, status, source_indent)
|
34
34
|
comment = if source_indent
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
35
|
+
c = ('# ' + step_match.location.to_s).indent(source_indent)
|
36
|
+
format_string(c, :comment)
|
37
|
+
else
|
38
|
+
''
|
39
|
+
end
|
40
40
|
|
41
41
|
format = format_for(status, :param)
|
42
42
|
line = keyword + step_match.format_args(format) + comment
|
@@ -102,10 +102,10 @@ module Cucumber
|
|
102
102
|
end
|
103
103
|
|
104
104
|
def exception_message_string(e, indent)
|
105
|
-
message = "#{e.message} (#{e.class})".dup.force_encoding(
|
105
|
+
message = "#{e.message} (#{e.class})".dup.force_encoding('UTF-8')
|
106
106
|
message = linebreaks(message, ENV['CUCUMBER_TRUNCATE_OUTPUT'].to_i)
|
107
107
|
|
108
|
-
|
108
|
+
"#{message}\n#{e.backtrace.join("\n")}".indent(indent)
|
109
109
|
end
|
110
110
|
|
111
111
|
# http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/10655
|
@@ -116,13 +116,11 @@ module Cucumber
|
|
116
116
|
|
117
117
|
def collect_snippet_data(test_step, result)
|
118
118
|
# collect snippet data for undefined steps
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
end
|
125
|
-
end
|
119
|
+
return if hook?(test_step)
|
120
|
+
keyword = test_step.source.last.actual_keyword(@previous_step_keyword)
|
121
|
+
@previous_step_keyword = keyword
|
122
|
+
return unless result.undefined?
|
123
|
+
@snippets_input << Console::SnippetData.new(keyword, test_step.source.last)
|
126
124
|
end
|
127
125
|
|
128
126
|
def print_snippets(options)
|
@@ -157,7 +155,7 @@ module Cucumber
|
|
157
155
|
def do_print_passing_wip(passed_messages)
|
158
156
|
if passed_messages.any?
|
159
157
|
@io.puts format_string("\nThe --wip switch was used, so I didn't expect anything to pass. These scenarios passed:", :failed)
|
160
|
-
print_element_messages(passed_messages, :passed,
|
158
|
+
print_element_messages(passed_messages, :passed, 'scenarios')
|
161
159
|
else
|
162
160
|
@io.puts format_string("\nThe --wip switch was used, so the failures were expected. All is good.\n", :passed)
|
163
161
|
end
|
@@ -210,7 +208,6 @@ module Cucumber
|
|
210
208
|
end
|
211
209
|
|
212
210
|
def do_print_profile_information(profiles)
|
213
|
-
profiles_sentence = ''
|
214
211
|
profiles_sentence = profiles.size == 1 ? profiles.first :
|
215
212
|
"#{profiles[0...-1].join(', ')} and #{profiles.last}"
|
216
213
|
|
@@ -233,11 +230,11 @@ module Cucumber
|
|
233
230
|
end
|
234
231
|
|
235
232
|
def element_messages(elements, status)
|
236
|
-
|
233
|
+
elements.map do |element|
|
237
234
|
if status == :failed
|
238
|
-
|
235
|
+
exception_message_string(element.exception, 0)
|
239
236
|
else
|
240
|
-
|
237
|
+
linebreaks(element.backtrace_line, ENV['CUCUMBER_TRUNCATE_OUTPUT'].to_i)
|
241
238
|
end
|
242
239
|
end
|
243
240
|
end
|
@@ -6,43 +6,30 @@ module Cucumber
|
|
6
6
|
include Console
|
7
7
|
|
8
8
|
def initialize(config)
|
9
|
-
@
|
10
|
-
@test_step_summary = Core::Test::Result::Summary.new
|
11
|
-
|
12
|
-
config.on_event :test_case_finished do |event|
|
13
|
-
event.result.describe_to @test_case_summary
|
14
|
-
end
|
15
|
-
|
16
|
-
config.on_event :test_step_finished do |event|
|
17
|
-
event.result.describe_to @test_step_summary if from_gherkin?(event.test_step)
|
18
|
-
end
|
9
|
+
@summary = Core::Report::Summary.new(config.event_bus)
|
19
10
|
end
|
20
11
|
|
21
12
|
def to_s
|
22
13
|
[
|
23
|
-
[scenario_count, status_counts(@
|
24
|
-
[step_count, status_counts(@
|
14
|
+
[scenario_count, status_counts(@summary.test_cases)].compact.join(' '),
|
15
|
+
[step_count, status_counts(@summary.test_steps)].compact.join(' ')
|
25
16
|
].join("\n")
|
26
17
|
end
|
27
18
|
|
28
19
|
private
|
29
20
|
|
30
|
-
def from_gherkin?(test_step)
|
31
|
-
test_step.source.last.location.file.match(/\.feature$/)
|
32
|
-
end
|
33
|
-
|
34
21
|
def scenario_count
|
35
|
-
count = @
|
36
|
-
"#{count} scenario" + (count == 1 ?
|
22
|
+
count = @summary.test_cases.total
|
23
|
+
"#{count} scenario" + (count == 1 ? '' : 's')
|
37
24
|
end
|
38
25
|
|
39
26
|
def step_count
|
40
|
-
count = @
|
41
|
-
"#{count} step" + (count == 1 ?
|
27
|
+
count = @summary.test_steps.total
|
28
|
+
"#{count} step" + (count == 1 ? '' : 's')
|
42
29
|
end
|
43
30
|
|
44
31
|
def status_counts(summary)
|
45
|
-
counts =
|
32
|
+
counts = Core::Test::Result::TYPES.map { |status|
|
46
33
|
count = summary.total(status)
|
47
34
|
[status, count]
|
48
35
|
}.select { |status, count|
|
@@ -6,28 +6,49 @@ module Cucumber
|
|
6
6
|
include Console
|
7
7
|
|
8
8
|
def initialize(config)
|
9
|
-
@
|
9
|
+
@previous_test_case = nil
|
10
|
+
@issues = Hash.new { |h, k| h[k] = [] }
|
10
11
|
@config = config
|
11
12
|
@config.on_event(:test_case_finished) do |event|
|
12
|
-
|
13
|
+
if event.test_case != @previous_test_case
|
14
|
+
@previous_test_case = event.test_case
|
15
|
+
@issues[event.result.to_sym] << event.test_case unless event.result.ok?(@config.strict?)
|
16
|
+
elsif event.result.passed?
|
17
|
+
@issues[:flaky] << event.test_case unless Core::Test::Result::Flaky.ok?(@config.strict?)
|
18
|
+
@issues[:failed].delete(event.test_case)
|
19
|
+
end
|
13
20
|
end
|
14
21
|
end
|
15
22
|
|
16
23
|
def to_s
|
17
|
-
return if @
|
18
|
-
result =
|
19
|
-
|
20
|
-
format_string("cucumber #{profiles_string}" + failure.location, :failed) + source
|
21
|
-
}
|
22
|
-
result.join("\n")
|
24
|
+
return if @issues.empty?
|
25
|
+
result = Core::Test::Result::TYPES.map { |type| scenario_listing(type, @issues[type]) }
|
26
|
+
result.flatten.join("\n")
|
23
27
|
end
|
24
28
|
|
25
29
|
def any?
|
26
|
-
@
|
30
|
+
@issues.any?
|
27
31
|
end
|
28
32
|
|
29
33
|
private
|
30
34
|
|
35
|
+
def scenario_listing(type, test_cases)
|
36
|
+
return [] if test_cases.empty?
|
37
|
+
[ format_string("#{type_heading(type)} Scenarios:", type) ] + test_cases.map { |test_case|
|
38
|
+
source = @config.source? ? format_string(" # #{test_case.keyword}: #{test_case.name}", :comment) : ''
|
39
|
+
format_string("cucumber #{profiles_string}" + test_case.location, type) + source
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
def type_heading(type)
|
44
|
+
case type
|
45
|
+
when :failed
|
46
|
+
'Failing'
|
47
|
+
else
|
48
|
+
type.to_s.slice(0, 1).capitalize + type.to_s.slice(1..-1)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
31
52
|
def profiles_string
|
32
53
|
return if @config.custom_profiles.empty?
|
33
54
|
@config.custom_profiles.map { |profile| "-p #{profile}" }.join(' ') + ' '
|
@@ -9,7 +9,7 @@ module Cucumber
|
|
9
9
|
|
10
10
|
def initialize(configuration)
|
11
11
|
configuration.on_event :test_case_finished do |event|
|
12
|
-
|
12
|
+
_test_case, result = *event.attributes
|
13
13
|
Cucumber.wants_to_quit = true unless result.ok?(configuration.strict?)
|
14
14
|
end
|
15
15
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require 'erb'
|
3
|
-
require 'builder'
|
4
3
|
require 'cucumber/formatter/duration'
|
5
4
|
require 'cucumber/formatter/io'
|
5
|
+
require 'cucumber/formatter/html_builder'
|
6
6
|
require 'pathname'
|
7
7
|
|
8
8
|
module Cucumber
|
@@ -14,174 +14,142 @@ module Cucumber
|
|
14
14
|
Cucumber::Core::Ast::Scenario => 'scenario',
|
15
15
|
Cucumber::Core::Ast::ScenarioOutline => 'scenario outline'
|
16
16
|
}
|
17
|
+
|
17
18
|
AST_DATA_TABLE = LegacyApi::Ast::MultilineArg::DataTable
|
18
19
|
|
19
20
|
include ERB::Util # for the #h method
|
20
21
|
include Duration
|
21
22
|
include Io
|
22
23
|
|
24
|
+
attr_reader :builder
|
25
|
+
private :builder
|
26
|
+
|
23
27
|
def initialize(runtime, path_or_io, options)
|
24
28
|
@io = ensure_io(path_or_io)
|
25
29
|
@runtime = runtime
|
26
30
|
@options = options
|
27
31
|
@buffer = {}
|
28
|
-
@builder =
|
32
|
+
@builder = HtmlBuilder.new(target: @io, indent: 0)
|
29
33
|
@feature_number = 0
|
30
34
|
@scenario_number = 0
|
31
35
|
@step_number = 0
|
32
36
|
@header_red = nil
|
33
37
|
@delayed_messages = []
|
34
|
-
@
|
35
|
-
@text_id = 0
|
36
|
-
@inside_outline = false
|
38
|
+
@inside_outline = false
|
37
39
|
@previous_step_keyword = nil
|
38
40
|
end
|
39
41
|
|
40
42
|
def embed(src, mime_type, label)
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
embed_image(src, label)
|
48
|
-
when /^text\/plain/
|
49
|
-
embed_text(src, label)
|
43
|
+
if image?(mime_type)
|
44
|
+
src = src_is_file_or_data?(src) ? src : "data:#{standardize_mime_type(mime_type)},#{src}"
|
45
|
+
|
46
|
+
builder.embed_image(src: set_path(src), label: label, id: next_id(:img))
|
47
|
+
else
|
48
|
+
builder.embed_text(src: src, label: label, id: next_id(:text))
|
50
49
|
end
|
51
50
|
end
|
52
51
|
|
53
|
-
def
|
54
|
-
id = "img_#{@img_id}"
|
55
|
-
@img_id += 1
|
52
|
+
def set_path(src)
|
56
53
|
if @io.respond_to?(:path) and File.file?(src)
|
57
54
|
out_dir = Pathname.new(File.dirname(File.absolute_path(@io.path)))
|
58
55
|
src = Pathname.new(File.absolute_path(src)).relative_path_from(out_dir)
|
59
|
-
end
|
60
|
-
@builder.span(:class => 'embed') do |pre|
|
61
|
-
pre << %{<a href="" onclick="img=document.getElementById('#{id}'); img.style.display = (img.style.display == 'none' ? 'block' : 'none');return false">#{label}</a><br>
|
62
|
-
<img id="#{id}" style="display: none" src="#{src}"/>}
|
63
56
|
end
|
57
|
+
|
58
|
+
src
|
64
59
|
end
|
65
60
|
|
66
|
-
def
|
67
|
-
|
68
|
-
@text_id += 1
|
69
|
-
@builder.span(:class => 'embed') do |pre|
|
70
|
-
pre << %{<a id="#{id}" href="#{src}" title="#{label}">#{label}</a>}
|
71
|
-
end
|
61
|
+
def standardize_mime_type(mime_type)
|
62
|
+
mime_type =~ /;base[0-9]+$/ ? mime_type : mime_type + ';base64'
|
72
63
|
end
|
73
64
|
|
65
|
+
def src_is_file_or_data?(src)
|
66
|
+
File.file?(src) or src =~ /^data:image\/(png|gif|jpg|jpeg);base64,/
|
67
|
+
end
|
68
|
+
|
69
|
+
def image?(mime_type)
|
70
|
+
mime_type =~ /^image\/(png|gif|jpg|jpeg)/
|
71
|
+
end
|
74
72
|
|
75
73
|
def before_features(features)
|
76
74
|
@step_count = features && features.step_count || 0 #TODO: Make this work with core!
|
77
75
|
|
78
|
-
|
79
|
-
|
80
|
-
:DOCTYPE,
|
81
|
-
:html,
|
82
|
-
:PUBLIC,
|
83
|
-
'-//W3C//DTD XHTML 1.0 Strict//EN',
|
84
|
-
'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'
|
85
|
-
)
|
86
|
-
|
87
|
-
@builder << '<html xmlns ="http://www.w3.org/1999/xhtml">'
|
88
|
-
@builder.head do
|
89
|
-
@builder.meta('http-equiv' => 'Content-Type', :content => 'text/html;charset=utf-8')
|
90
|
-
@builder.title 'Cucumber'
|
91
|
-
inline_css
|
92
|
-
inline_js
|
93
|
-
end
|
94
|
-
@builder << '<body>'
|
95
|
-
@builder << "<!-- Step count #{@step_count}-->"
|
96
|
-
@builder << '<div class="cucumber">'
|
97
|
-
@builder.div(:id => 'cucumber-header') do
|
98
|
-
@builder.div(:id => 'label') do
|
99
|
-
@builder.h1('Cucumber Features')
|
100
|
-
end
|
101
|
-
@builder.div(:id => 'summary') do
|
102
|
-
@builder.p('',:id => 'totals')
|
103
|
-
@builder.p('',:id => 'duration')
|
104
|
-
@builder.div(:id => 'expand-collapse') do
|
105
|
-
@builder.p('Expand All', :id => 'expander')
|
106
|
-
@builder.p('Collapse All', :id => 'collapser')
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
76
|
+
builder.build_document!
|
77
|
+
builder.format_features! features
|
110
78
|
end
|
111
79
|
|
112
80
|
def after_features(features)
|
113
81
|
print_stats(features)
|
114
|
-
|
115
|
-
|
116
|
-
|
82
|
+
builder << '</div>'
|
83
|
+
builder << '</body>'
|
84
|
+
builder << '</html>'
|
117
85
|
end
|
118
86
|
|
119
|
-
def before_feature(
|
87
|
+
def before_feature(_feature)
|
120
88
|
@exceptions = []
|
121
|
-
|
89
|
+
builder << '<div class="feature">'
|
122
90
|
end
|
123
91
|
|
124
|
-
def after_feature(
|
125
|
-
|
92
|
+
def after_feature(_feature)
|
93
|
+
builder << '</div>'
|
126
94
|
end
|
127
95
|
|
128
|
-
def before_comment(
|
129
|
-
|
96
|
+
def before_comment(_comment)
|
97
|
+
builder << '<pre class="comment">'
|
130
98
|
end
|
131
99
|
|
132
|
-
def after_comment(
|
133
|
-
|
100
|
+
def after_comment(_comment)
|
101
|
+
builder << '</pre>'
|
134
102
|
end
|
135
103
|
|
136
104
|
def comment_line(comment_line)
|
137
|
-
|
138
|
-
|
105
|
+
builder.text!(comment_line)
|
106
|
+
builder.br
|
139
107
|
end
|
140
108
|
|
141
|
-
def after_tags(
|
109
|
+
def after_tags(_tags)
|
142
110
|
@tag_spacer = nil
|
143
111
|
end
|
144
112
|
|
145
113
|
def tag_name(tag_name)
|
146
|
-
|
114
|
+
builder.text!(@tag_spacer) if @tag_spacer
|
147
115
|
@tag_spacer = ' '
|
148
|
-
|
116
|
+
builder.span(tag_name, :class => 'tag')
|
149
117
|
end
|
150
118
|
|
151
119
|
def feature_name(keyword, name)
|
152
120
|
lines = name.split(/\r?\n/)
|
153
121
|
return if lines.empty?
|
154
|
-
|
155
|
-
|
122
|
+
builder.h2 do |h2|
|
123
|
+
builder.span(keyword + ': ' + lines[0], :class => 'val')
|
156
124
|
end
|
157
|
-
|
125
|
+
builder.p(:class => 'narrative') do
|
158
126
|
lines[1..-1].each do |line|
|
159
|
-
|
160
|
-
|
127
|
+
builder.text!(line.strip)
|
128
|
+
builder.br
|
161
129
|
end
|
162
130
|
end
|
163
131
|
end
|
164
132
|
|
165
|
-
def before_test_case(
|
133
|
+
def before_test_case(_test_case)
|
166
134
|
@previous_step_keyword = nil
|
167
135
|
end
|
168
136
|
|
169
|
-
def before_background(
|
137
|
+
def before_background(_background)
|
170
138
|
@in_background = true
|
171
|
-
|
139
|
+
builder << '<div class="background">'
|
172
140
|
end
|
173
141
|
|
174
|
-
def after_background(
|
142
|
+
def after_background(_background)
|
175
143
|
@in_background = nil
|
176
|
-
|
144
|
+
builder << '</div>'
|
177
145
|
end
|
178
146
|
|
179
|
-
def background_name(keyword, name,
|
147
|
+
def background_name(keyword, name, _file_colon_line, _source_indent)
|
180
148
|
@listing_background = true
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
149
|
+
builder.h3(:id => "background_#{@scenario_number}") do |h3|
|
150
|
+
builder.span(keyword, :class => 'keyword')
|
151
|
+
builder.text!(' ')
|
152
|
+
builder.span(name, :class => 'val')
|
185
153
|
end
|
186
154
|
end
|
187
155
|
|
@@ -189,22 +157,22 @@ module Cucumber
|
|
189
157
|
@scenario_number+=1
|
190
158
|
@scenario_red = false
|
191
159
|
css_class = AST_CLASSES[feature_element.class]
|
192
|
-
|
160
|
+
builder << "<div class='#{css_class}'>"
|
193
161
|
@in_scenario_outline = feature_element.class == Cucumber::Core::Ast::ScenarioOutline
|
194
162
|
end
|
195
163
|
|
196
|
-
def after_feature_element(
|
164
|
+
def after_feature_element(_feature_element)
|
197
165
|
unless @in_scenario_outline
|
198
166
|
print_messages
|
199
|
-
|
167
|
+
builder << '</ol>'
|
200
168
|
end
|
201
|
-
|
169
|
+
builder << '</div>'
|
202
170
|
@in_scenario_outline = nil
|
203
171
|
end
|
204
172
|
|
205
|
-
def scenario_name(keyword, name, file_colon_line,
|
206
|
-
|
207
|
-
|
173
|
+
def scenario_name(keyword, name, file_colon_line, _source_indent)
|
174
|
+
builder.span(:class => 'scenario_file') do
|
175
|
+
builder << file_colon_line
|
208
176
|
end
|
209
177
|
@listing_background = false
|
210
178
|
scenario_id = "scenario_#{@scenario_number}"
|
@@ -213,48 +181,48 @@ module Cucumber
|
|
213
181
|
scenario_id += "_#{@outline_row}"
|
214
182
|
@scenario_red = false
|
215
183
|
end
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
184
|
+
builder.h3(:id => scenario_id) do
|
185
|
+
builder.span(keyword + ':', :class => 'keyword')
|
186
|
+
builder.text!(' ')
|
187
|
+
builder.span(name, :class => 'val')
|
220
188
|
end
|
221
189
|
end
|
222
190
|
|
223
|
-
def before_outline_table(
|
191
|
+
def before_outline_table(_outline_table)
|
224
192
|
@inside_outline = true
|
225
193
|
@outline_row = 0
|
226
|
-
|
194
|
+
builder << '<table>'
|
227
195
|
end
|
228
196
|
|
229
|
-
def after_outline_table(
|
230
|
-
|
197
|
+
def after_outline_table(_outline_table)
|
198
|
+
builder << '</table>'
|
231
199
|
@outline_row = nil
|
232
200
|
@inside_outline = false
|
233
201
|
end
|
234
202
|
|
235
|
-
def before_examples(
|
236
|
-
|
203
|
+
def before_examples(_examples)
|
204
|
+
builder << '<div class="examples">'
|
237
205
|
end
|
238
206
|
|
239
|
-
def after_examples(
|
240
|
-
|
207
|
+
def after_examples(_examples)
|
208
|
+
builder << '</div>'
|
241
209
|
end
|
242
210
|
|
243
211
|
def examples_name(keyword, name)
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
212
|
+
builder.h4 do
|
213
|
+
builder.span(keyword, :class => 'keyword')
|
214
|
+
builder.text!(' ')
|
215
|
+
builder.span(name, :class => 'val')
|
248
216
|
end
|
249
217
|
end
|
250
218
|
|
251
|
-
def before_steps(
|
252
|
-
|
219
|
+
def before_steps(_steps)
|
220
|
+
builder << '<ol>'
|
253
221
|
end
|
254
222
|
|
255
|
-
def after_steps(
|
223
|
+
def after_steps(_steps)
|
256
224
|
print_messages
|
257
|
-
|
225
|
+
builder << '</ol>' if @in_background or @in_scenario_outline
|
258
226
|
end
|
259
227
|
|
260
228
|
def before_step(step)
|
@@ -264,11 +232,11 @@ module Cucumber
|
|
264
232
|
@step = step
|
265
233
|
end
|
266
234
|
|
267
|
-
def after_step(
|
235
|
+
def after_step(_step)
|
268
236
|
move_progress
|
269
237
|
end
|
270
238
|
|
271
|
-
def before_step_result(
|
239
|
+
def before_step_result(_keyword, step_match, _multiline_arg, status, exception, _source_indent, background, _file_colon_line)
|
272
240
|
@step_match = step_match
|
273
241
|
@hide_this_step = false
|
274
242
|
if exception
|
@@ -285,10 +253,10 @@ module Cucumber
|
|
285
253
|
@status = status
|
286
254
|
return if @hide_this_step
|
287
255
|
set_scenario_color(status)
|
288
|
-
|
256
|
+
builder << "<li id='#{@step_id}' class='step #{status}'>"
|
289
257
|
end
|
290
258
|
|
291
|
-
def after_step_result(keyword, step_match,
|
259
|
+
def after_step_result(keyword, step_match, _multiline_arg, status, _exception, _source_indent, _background, _file_colon_line)
|
292
260
|
return if @hide_this_step
|
293
261
|
# print snippet for undefined steps
|
294
262
|
unless outline_step?(@step)
|
@@ -296,17 +264,17 @@ module Cucumber
|
|
296
264
|
@previous_step_keyword = keyword
|
297
265
|
end
|
298
266
|
if status == :undefined
|
299
|
-
|
300
|
-
# TODO: snippet text should be an event sent to the formatter so we don't
|
267
|
+
builder.pre do |pre|
|
268
|
+
# TODO: snippet text should be an event sent to the formatter so we don't
|
301
269
|
# have this couping to the runtime.
|
302
|
-
pre << @runtime.snippet_text(keyword,step_match.instance_variable_get(
|
270
|
+
pre << @runtime.snippet_text(keyword,step_match.instance_variable_get('@name') || '', @step.multiline_arg)
|
303
271
|
end
|
304
272
|
end
|
305
|
-
|
273
|
+
builder << '</li>'
|
306
274
|
print_messages
|
307
275
|
end
|
308
276
|
|
309
|
-
def step_name(keyword, step_match, status,
|
277
|
+
def step_name(keyword, step_match, status, _source_indent, background, _file_colon_line)
|
310
278
|
background_in_scenario = background && !@listing_background
|
311
279
|
@skip_step = background_in_scenario
|
312
280
|
|
@@ -315,7 +283,7 @@ module Cucumber
|
|
315
283
|
end
|
316
284
|
end
|
317
285
|
|
318
|
-
def exception(exception,
|
286
|
+
def exception(exception, _status)
|
319
287
|
return if @hide_this_step
|
320
288
|
print_messages
|
321
289
|
build_exception_detail(exception)
|
@@ -329,21 +297,21 @@ module Cucumber
|
|
329
297
|
def before_multiline_arg(multiline_arg)
|
330
298
|
return if @hide_this_step || @skip_step
|
331
299
|
if AST_DATA_TABLE === multiline_arg
|
332
|
-
|
300
|
+
builder << '<table>'
|
333
301
|
end
|
334
302
|
end
|
335
303
|
|
336
304
|
def after_multiline_arg(multiline_arg)
|
337
305
|
return if @hide_this_step || @skip_step
|
338
306
|
if AST_DATA_TABLE === multiline_arg
|
339
|
-
|
307
|
+
builder << '</table>'
|
340
308
|
end
|
341
309
|
end
|
342
310
|
|
343
311
|
def doc_string(string)
|
344
312
|
return if @hide_this_step
|
345
|
-
|
346
|
-
|
313
|
+
builder.pre(:class => 'val') do |pre|
|
314
|
+
builder << h(string).gsub("\n", '
')
|
347
315
|
end
|
348
316
|
end
|
349
317
|
|
@@ -351,17 +319,17 @@ module Cucumber
|
|
351
319
|
@row_id = table_row.dom_id
|
352
320
|
@col_index = 0
|
353
321
|
return if @hide_this_step
|
354
|
-
|
322
|
+
builder << "<tr class='step' id='#{@row_id}'>"
|
355
323
|
end
|
356
324
|
|
357
325
|
def after_table_row(table_row)
|
358
326
|
return if @hide_this_step
|
359
327
|
print_table_row_messages
|
360
|
-
|
328
|
+
builder << '</tr>'
|
361
329
|
if table_row.exception
|
362
|
-
|
363
|
-
|
364
|
-
|
330
|
+
builder.tr do
|
331
|
+
builder.td(:colspan => @col_index.to_s, :class => 'failed') do
|
332
|
+
builder.pre do |pre|
|
365
333
|
pre << h(format_exception(table_row.exception))
|
366
334
|
end
|
367
335
|
end
|
@@ -392,16 +360,16 @@ module Cucumber
|
|
392
360
|
|
393
361
|
def puts(message)
|
394
362
|
@delayed_messages << message
|
395
|
-
|
363
|
+
#builder.pre(message, :class => 'message')
|
396
364
|
end
|
397
365
|
|
398
366
|
def print_messages
|
399
367
|
return if @delayed_messages.empty?
|
400
368
|
|
401
|
-
|
369
|
+
#builder.ol do
|
402
370
|
@delayed_messages.each do |ann|
|
403
|
-
|
404
|
-
|
371
|
+
builder.li(:class => 'step message') do
|
372
|
+
builder << ann
|
405
373
|
end
|
406
374
|
end
|
407
375
|
#end
|
@@ -411,8 +379,8 @@ module Cucumber
|
|
411
379
|
def print_table_row_messages
|
412
380
|
return if @delayed_messages.empty?
|
413
381
|
|
414
|
-
|
415
|
-
|
382
|
+
builder.td(:class => 'message') do
|
383
|
+
builder << @delayed_messages.join(', ')
|
416
384
|
end
|
417
385
|
empty_messages
|
418
386
|
end
|
@@ -421,7 +389,7 @@ module Cucumber
|
|
421
389
|
@delayed_messages = []
|
422
390
|
end
|
423
391
|
|
424
|
-
def after_test_case(
|
392
|
+
def after_test_case(_test_case, result)
|
425
393
|
if result.failed? and not @scenario_red
|
426
394
|
set_scenario_color_failed
|
427
395
|
end
|
@@ -429,34 +397,44 @@ module Cucumber
|
|
429
397
|
|
430
398
|
protected
|
431
399
|
|
400
|
+
def next_id(type)
|
401
|
+
@indices ||= Hash.new { 0 }
|
402
|
+
@indices[type] += 1
|
403
|
+
"#{type}_#{@indices[:type]}"
|
404
|
+
end
|
405
|
+
|
432
406
|
def build_exception_detail(exception)
|
433
407
|
backtrace = Array.new
|
434
|
-
|
408
|
+
|
409
|
+
builder.div(:class => 'message') do
|
435
410
|
message = exception.message
|
411
|
+
|
436
412
|
if defined?(RAILS_ROOT) && message.include?('Exception caught')
|
437
413
|
matches = message.match(/Showing <i>(.+)<\/i>(?:.+) #(\d+)/)
|
438
414
|
backtrace += ["#{RAILS_ROOT}/#{matches[1]}:#{matches[2]}"] if matches
|
439
415
|
matches = message.match(/<code>([^(\/)]+)<\//m)
|
440
|
-
message = matches ? matches[1] :
|
416
|
+
message = matches ? matches[1] : ''
|
441
417
|
end
|
442
418
|
|
443
419
|
unless exception.instance_of?(RuntimeError)
|
444
420
|
message = "#{message} (#{exception.class})"
|
445
421
|
end
|
446
422
|
|
447
|
-
|
448
|
-
|
423
|
+
builder.pre do
|
424
|
+
builder.text!(message)
|
449
425
|
end
|
450
426
|
end
|
451
|
-
|
452
|
-
|
427
|
+
|
428
|
+
builder.div(:class => 'backtrace') do
|
429
|
+
builder.pre do
|
453
430
|
backtrace = exception.backtrace
|
454
431
|
backtrace.delete_if { |x| x =~ /\/gems\/(cucumber|rspec)/ }
|
455
|
-
|
432
|
+
builder << backtrace_line(backtrace.join("\n"))
|
456
433
|
end
|
457
434
|
end
|
435
|
+
|
458
436
|
extra = extra_failure_content(backtrace)
|
459
|
-
|
437
|
+
builder << extra unless extra == ''
|
460
438
|
end
|
461
439
|
|
462
440
|
def set_scenario_color(status)
|
@@ -469,31 +447,31 @@ module Cucumber
|
|
469
447
|
end
|
470
448
|
|
471
449
|
def set_scenario_color_failed
|
472
|
-
|
473
|
-
|
450
|
+
builder.script do
|
451
|
+
builder.text!("makeRed('cucumber-header');") unless @header_red
|
474
452
|
@header_red = true
|
475
|
-
scenario_or_background = @in_background ?
|
476
|
-
|
453
|
+
scenario_or_background = @in_background ? 'background' : 'scenario'
|
454
|
+
builder.text!("makeRed('#{scenario_or_background}_#{@scenario_number}');") unless @scenario_red
|
477
455
|
@scenario_red = true
|
478
456
|
if @options[:expand] and @inside_outline
|
479
|
-
|
457
|
+
builder.text!("makeRed('#{scenario_or_background}_#{@scenario_number}_#{@outline_row}');")
|
480
458
|
end
|
481
459
|
end
|
482
460
|
end
|
483
461
|
|
484
462
|
def set_scenario_color_pending
|
485
|
-
|
486
|
-
|
487
|
-
scenario_or_background = @in_background ?
|
488
|
-
|
463
|
+
builder.script do
|
464
|
+
builder.text!("makeYellow('cucumber-header');") unless @header_red
|
465
|
+
scenario_or_background = @in_background ? 'background' : 'scenario'
|
466
|
+
builder.text!("makeYellow('#{scenario_or_background}_#{@scenario_number}');") unless @scenario_red
|
489
467
|
end
|
490
468
|
end
|
491
469
|
|
492
|
-
def build_step(keyword, step_match,
|
470
|
+
def build_step(keyword, step_match, _status)
|
493
471
|
step_name = step_match.format_args(lambda{|param| %{<span class="param">#{param}</span>}})
|
494
|
-
|
495
|
-
|
496
|
-
|
472
|
+
builder.div(:class => 'step_name') do |div|
|
473
|
+
builder.span(keyword, :class => 'keyword')
|
474
|
+
builder.span(:class => 'step val') do |name|
|
497
475
|
name << h(step_name).gsub(/<span class="(.*?)">/, '<span class="\1">').gsub(/<\/span>/, '</span>')
|
498
476
|
end
|
499
477
|
end
|
@@ -505,77 +483,23 @@ module Cucumber
|
|
505
483
|
end
|
506
484
|
end
|
507
485
|
|
508
|
-
|
509
|
-
|
510
|
-
|
486
|
+
builder.div(:class => 'step_file') do |div|
|
487
|
+
builder.span do
|
488
|
+
builder << step_file
|
511
489
|
end
|
512
490
|
end
|
513
491
|
end
|
514
492
|
|
515
493
|
def build_cell(cell_type, value, attributes)
|
516
|
-
|
517
|
-
|
518
|
-
|
494
|
+
builder.__send__(cell_type, attributes) do
|
495
|
+
builder.div do
|
496
|
+
builder.span(value,:class => 'step param')
|
519
497
|
end
|
520
498
|
end
|
521
499
|
end
|
522
500
|
|
523
|
-
def inline_css
|
524
|
-
@builder.style(:type => 'text/css') do
|
525
|
-
@builder << File.read(File.dirname(__FILE__) + '/cucumber.css')
|
526
|
-
end
|
527
|
-
end
|
528
|
-
|
529
|
-
def inline_js
|
530
|
-
@builder.script(:type => 'text/javascript') do
|
531
|
-
@builder << inline_jquery
|
532
|
-
@builder << inline_js_content
|
533
|
-
end
|
534
|
-
end
|
535
|
-
|
536
|
-
def inline_jquery
|
537
|
-
File.read(File.dirname(__FILE__) + '/jquery-min.js')
|
538
|
-
end
|
539
|
-
|
540
|
-
def inline_js_content
|
541
|
-
<<-EOF
|
542
|
-
|
543
|
-
SCENARIOS = "h3[id^='scenario_'],h3[id^=background_]";
|
544
|
-
|
545
|
-
$(document).ready(function() {
|
546
|
-
$(SCENARIOS).css('cursor', 'pointer');
|
547
|
-
$(SCENARIOS).click(function() {
|
548
|
-
$(this).siblings().toggle(250);
|
549
|
-
});
|
550
|
-
|
551
|
-
$("#collapser").css('cursor', 'pointer');
|
552
|
-
$("#collapser").click(function() {
|
553
|
-
$(SCENARIOS).siblings().hide();
|
554
|
-
});
|
555
|
-
|
556
|
-
$("#expander").css('cursor', 'pointer');
|
557
|
-
$("#expander").click(function() {
|
558
|
-
$(SCENARIOS).siblings().show();
|
559
|
-
});
|
560
|
-
})
|
561
|
-
|
562
|
-
function moveProgressBar(percentDone) {
|
563
|
-
$("cucumber-header").css('width', percentDone +"%");
|
564
|
-
}
|
565
|
-
function makeRed(element_id) {
|
566
|
-
$('#'+element_id).css('background', '#C40D0D');
|
567
|
-
$('#'+element_id).css('color', '#FFFFFF');
|
568
|
-
}
|
569
|
-
function makeYellow(element_id) {
|
570
|
-
$('#'+element_id).css('background', '#FAF834');
|
571
|
-
$('#'+element_id).css('color', '#000000');
|
572
|
-
}
|
573
|
-
|
574
|
-
EOF
|
575
|
-
end
|
576
|
-
|
577
501
|
def move_progress
|
578
|
-
|
502
|
+
builder << " <script type=\"text/javascript\">moveProgressBar('#{percent_done}');</script>"
|
579
503
|
end
|
580
504
|
|
581
505
|
def percent_done
|
@@ -587,10 +511,10 @@ module Cucumber
|
|
587
511
|
end
|
588
512
|
|
589
513
|
def format_exception(exception)
|
590
|
-
([
|
514
|
+
([exception.message.to_s] + exception.backtrace).join("\n")
|
591
515
|
end
|
592
516
|
|
593
|
-
|
517
|
+
def backtrace_line(line)
|
594
518
|
if ENV['TM_PROJECT_DIRECTORY']
|
595
519
|
line.gsub(/^([^:]*\.(?:rb|feature|haml)):(\d*).*$/) do
|
596
520
|
"<a href=\"txmt://open?url=file://#{File.expand_path($1)}&line=#{$2}\">#{$1}:#{$2}</a> "
|
@@ -601,17 +525,17 @@ module Cucumber
|
|
601
525
|
end
|
602
526
|
|
603
527
|
def print_stats(features)
|
604
|
-
|
605
|
-
|
528
|
+
builder << "<script type=\"text/javascript\">document.getElementById('duration').innerHTML = \"Finished in <strong>#{format_duration(features.duration)} seconds</strong>\";</script>"
|
529
|
+
builder << "<script type=\"text/javascript\">document.getElementById('totals').innerHTML = \"#{print_stat_string(features)}\";</script>"
|
606
530
|
end
|
607
531
|
|
608
|
-
def print_stat_string(
|
532
|
+
def print_stat_string(_features)
|
609
533
|
string = String.new
|
610
|
-
string << dump_count(@runtime.scenarios.length,
|
534
|
+
string << dump_count(@runtime.scenarios.length, 'scenario')
|
611
535
|
scenario_count = print_status_counts{|status| @runtime.scenarios(status)}
|
612
536
|
string << scenario_count if scenario_count
|
613
|
-
string <<
|
614
|
-
string << dump_count(@runtime.steps.length,
|
537
|
+
string << '<br />'
|
538
|
+
string << dump_count(@runtime.steps.length, 'step')
|
615
539
|
step_count = print_status_counts{|status| @runtime.steps(status)}
|
616
540
|
string << step_count if step_count
|
617
541
|
end
|
@@ -619,26 +543,28 @@ module Cucumber
|
|
619
543
|
def print_status_counts
|
620
544
|
counts = [:failed, :skipped, :undefined, :pending, :passed].map do |status|
|
621
545
|
elements = yield status
|
622
|
-
elements.any? ? "#{elements.length} #{status
|
546
|
+
elements.any? ? "#{elements.length} #{status}" : nil
|
623
547
|
end.compact
|
624
548
|
return " (#{counts.join(', ')})" if counts.any?
|
625
549
|
end
|
626
550
|
|
627
551
|
def dump_count(count, what, state=nil)
|
628
|
-
[count, state, "#{what}#{count == 1 ? '' : 's'}"].compact.join(
|
629
|
-
end
|
630
|
-
|
631
|
-
def create_builder(io)
|
632
|
-
Builder::XmlMarkup.new(:target => io, :indent => 0)
|
552
|
+
[count, state, "#{what}#{count == 1 ? '' : 's'}"].compact.join(' ')
|
633
553
|
end
|
634
554
|
|
635
|
-
def outline_step?(
|
555
|
+
def outline_step?(_step)
|
636
556
|
not @step.step.respond_to?(:actual_keyword)
|
637
557
|
end
|
638
558
|
|
639
559
|
class SnippetExtractor #:nodoc:
|
640
|
-
class NullConverter; def convert(code,
|
641
|
-
|
560
|
+
class NullConverter; def convert(code, _pre); code; end; end #:nodoc:
|
561
|
+
|
562
|
+
begin
|
563
|
+
require 'syntax/convertors/html'
|
564
|
+
@@converter = Syntax::Convertors::HTML.for_syntax 'ruby'
|
565
|
+
rescue LoadError
|
566
|
+
@@converter = NullConverter.new
|
567
|
+
end
|
642
568
|
|
643
569
|
def snippet(error)
|
644
570
|
raw_code, line = snippet_for(error[0])
|