From 7f146d3c465c14984876bf51945971e28b73628b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Rasmusson?= Date: Sun, 22 Jun 2014 13:34:23 +0200 Subject: [PATCH 1/9] Support embedding images directly in html files --- lib/cucumber/formatter/html.rb | 3 +++ spec/cucumber/formatter/html_spec.rb | 33 +++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/lib/cucumber/formatter/html.rb b/lib/cucumber/formatter/html.rb index ef5d6b05e5..7209a557fb 100644 --- a/lib/cucumber/formatter/html.rb +++ b/lib/cucumber/formatter/html.rb @@ -28,6 +28,9 @@ def initialize(runtime, path_or_io, options) def embed(src, mime_type, label) case(mime_type) when /^image\/(png|gif|jpg|jpeg)/ + unless File.file?(src) or src =~ /^data:image\/(png|gif|jpg|jpeg);base64,/ + src = "data:" + mime_type + ";base64," + src + end embed_image(src, label) end end diff --git a/spec/cucumber/formatter/html_spec.rb b/spec/cucumber/formatter/html_spec.rb index 15b7dfb2a8..5b76113138 100644 --- a/spec/cucumber/formatter/html_spec.rb +++ b/spec/cucumber/formatter/html_spec.rb @@ -235,7 +235,10 @@ module Formatter describe "with a step that embeds a snapshot" do define_steps do - Given(/snap/) { embed('snapshot.jpeg', 'image/jpeg') } + Given(/snap/) { + File.should_receive(:file?).with('snapshot.jpeg').and_return(true) + embed('snapshot.jpeg', 'image/jpeg') + } end define_feature(<<-FEATURE) @@ -247,6 +250,34 @@ module Formatter it { @doc.css('.embed img').first.attributes['src'].to_s.should == "snapshot.jpeg" } end + describe "with a step that embeds a snapshot content manually" do + define_steps do + Given(/snap/) { embed('data:image/png;base64,YWJj', 'image/png') } + end + + define_feature(<<-FEATURE) + Feature: + Scenario: + Given snap + FEATURE + + it { @doc.css('.embed img').first.attributes['src'].to_s.should == "data:image/png;base64,YWJj" } + end + + describe "with a step that embeds a snapshot content" do + define_steps do + Given(/snap/) { embed('YWJj', 'image/png') } + end + + define_feature(<<-FEATURE) + Feature: + Scenario: + Given snap + FEATURE + + it { @doc.css('.embed img').first.attributes['src'].to_s.should == "data:image/png;base64,YWJj" } + end + describe "with an undefined Given step then an undefined And step" do define_feature(<<-FEATURE) Feature: From f39bf4eddaea1c0aa1618556a88a8859f9ccc846 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Rasmusson?= Date: Sun, 22 Jun 2014 19:55:58 +0200 Subject: [PATCH 2/9] Prefer encoding included in mime-type when embedding images direcly --- lib/cucumber/formatter/html.rb | 3 ++- spec/cucumber/formatter/html_spec.rb | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/cucumber/formatter/html.rb b/lib/cucumber/formatter/html.rb index 7209a557fb..850e875e7a 100644 --- a/lib/cucumber/formatter/html.rb +++ b/lib/cucumber/formatter/html.rb @@ -29,7 +29,8 @@ def embed(src, mime_type, label) case(mime_type) when /^image\/(png|gif|jpg|jpeg)/ unless File.file?(src) or src =~ /^data:image\/(png|gif|jpg|jpeg);base64,/ - src = "data:" + mime_type + ";base64," + src + type = mime_type =~ /;base[0-9]+$/ ? mime_type : mime_type + ";base64" + src = "data:" + type + "," + src end embed_image(src, label) end diff --git a/spec/cucumber/formatter/html_spec.rb b/spec/cucumber/formatter/html_spec.rb index 5b76113138..0de8ebbd67 100644 --- a/spec/cucumber/formatter/html_spec.rb +++ b/spec/cucumber/formatter/html_spec.rb @@ -266,7 +266,7 @@ module Formatter describe "with a step that embeds a snapshot content" do define_steps do - Given(/snap/) { embed('YWJj', 'image/png') } + Given(/snap/) { embed('YWJj', 'image/png;base64') } end define_feature(<<-FEATURE) From 18cb9a6b5487b144efdd362ec2eee5e88ee9e61e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Rasmusson?= Date: Sun, 29 Jun 2014 20:02:55 +0200 Subject: [PATCH 3/9] Regression test for scenario outlines in the JSON formatter --- features/json_formatter.feature | 82 +++++++++++++++++++++ features/step_definitions/cucumber_steps.rb | 6 +- 2 files changed, 86 insertions(+), 2 deletions(-) diff --git a/features/json_formatter.feature b/features/json_formatter.feature index f722dd422f..b4c4ed8bf0 100644 --- a/features/json_formatter.feature +++ b/features/json_formatter.feature @@ -72,6 +72,19 @@ Feature: JSON output formatter And I print from step definition """ + And a file named "features/outline.feature" with: + """ + Feature: An outline feature + + Scenario Outline: outline + Given a step + + Examples: examples + | type | + | passing | + | failing | + + """ # Need to investigate why this won't pass in-process. error_message doesn't get det? @spawn @@ -405,4 +418,73 @@ Feature: JSON output formatter } ] + """ + @spawn + Scenario: scenario outline + When I run `cucumber --format json features/outline.feature` + Then it should fail with JSON: + """ + [ + { + "uri": "features/outline.feature", + "id": "an-outline-feature", + "keyword": "Feature", + "name": "An outline feature", + "line": 1, + "description": "", + "elements": [ + { + "id": "an-outline-feature;outline", + "keyword": "Scenario Outline", + "name": "outline", + "line": 3, + "description": "", + "type": "scenario_outline", + "steps": [ + { + "keyword": "Given ", + "name": "a step", + "line": 4, + "match": { + "location": "features/step_definitions/steps.rb:1" + } + } + ], + "examples": [ + { + "keyword": "Examples", + "name": "examples", + "line": 6, + "description": "", + "id": "an-outline-feature;outline;examples", + "rows": [ + { + "cells": [ + "type" + ], + "line": 7, + "id": "an-outline-feature;outline;examples;1" + }, + { + "cells": [ + "passing" + ], + "line": 8, + "id": "an-outline-feature;outline;examples;2" + }, + { + "cells": [ + "failing" + ], + "line": 9, + "id": "an-outline-feature;outline;examples;3" + } + ] + } + ] + } + ] + } + ] + """ diff --git a/features/step_definitions/cucumber_steps.rb b/features/step_definitions/cucumber_steps.rb index 6941ade74b..22f701d0d7 100644 --- a/features/step_definitions/cucumber_steps.rb +++ b/features/step_definitions/cucumber_steps.rb @@ -17,8 +17,10 @@ actual.each do |feature| feature['elements'].each do |scenario| scenario['steps'].each do |step| - step['result']['duration'].should be >= 0 - step['result']['duration'] = 1 + if step['result'] + step['result']['duration'].should be >= 0 + step['result']['duration'] = 1 + end end end end From 02eb585ea9e12cfe1f3aefc3fe2f879658fd6fe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Rasmusson?= Date: Sun, 29 Jun 2014 20:08:19 +0200 Subject: [PATCH 4/9] Test for the new outline expand feature for the JSON formatter --- features/json_formatter.feature | 64 +++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/features/json_formatter.feature b/features/json_formatter.feature index b4c4ed8bf0..ae3ac0f222 100644 --- a/features/json_formatter.feature +++ b/features/json_formatter.feature @@ -487,4 +487,68 @@ Feature: JSON output formatter } ] + """ + @spawn + Scenario: scenario outline expanded + When I run `cucumber --expand --format json features/outline.feature` + Then it should fail with JSON: + """ + [ + { + "uri": "features/outline.feature", + "id": "an-outline-feature", + "keyword": "Feature", + "name": "An outline feature", + "line": 1, + "description": "", + "elements": [ + { + "id": "an-outline-feature;outline;examples;2", + "keyword": "Scenario Outline", + "name": "outline", + "line": 8, + "description": "", + "type": "scenario", + "steps": [ + { + "keyword": "Given ", + "name": "a passing step", + "line": 4, + "match": { + "location": "features/step_definitions/steps.rb:1" + }, + "result": { + "status": "passed", + "duration": 1 + } + } + ] + }, + { + "id": "an-outline-feature;outline;examples;3", + "keyword": "Scenario Outline", + "name": "outline", + "line": 9, + "description": "", + "type": "scenario", + "steps": [ + { + "keyword": "Given ", + "name": "a failing step", + "line": 4, + "match": { + "location": "features/step_definitions/steps.rb:5" + }, + "result": { + "status": "failed", + "error_message" : " (RuntimeError)\n./features/step_definitions/steps.rb:6:in `/a failing step/'\nfeatures/outline.feature:4:in `Given a step'", + "duration": 1 + } + } + ] + } + ] + } + ] + """ From 1740b65ebf3eb9fe8f96de4e9b60f2ac478f1e76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Rasmusson?= Date: Sun, 29 Jun 2014 20:17:58 +0200 Subject: [PATCH 5/9] Add new outline expand feature to the JSON formatter --- .../formatter/gherkin_formatter_adapter.rb | 82 +++++++++++++++++-- lib/cucumber/formatter/json.rb | 2 +- 2 files changed, 77 insertions(+), 7 deletions(-) diff --git a/lib/cucumber/formatter/gherkin_formatter_adapter.rb b/lib/cucumber/formatter/gherkin_formatter_adapter.rb index ba116ad294..05f51a9690 100644 --- a/lib/cucumber/formatter/gherkin_formatter_adapter.rb +++ b/lib/cucumber/formatter/gherkin_formatter_adapter.rb @@ -6,9 +6,10 @@ module Formatter # Adapts Cucumber formatter events to Gherkin formatter events # This class will disappear when Cucumber is based on Gherkin's model. class GherkinFormatterAdapter - def initialize(gherkin_formatter, print_empty_match) + def initialize(gherkin_formatter, print_empty_match, options) @gf = gherkin_formatter @print_empty_match = print_empty_match + @options = options end def before_feature(feature) @@ -28,14 +29,42 @@ def before_feature_element(feature_element) @gf.scenario(feature_element.gherkin_statement) when Ast::ScenarioOutline @outline = true - @gf.scenario_outline(feature_element.gherkin_statement) + if @options[:expand] + @current_scenario_hash = to_hash(feature_element.gherkin_statement) + else + @gf.scenario_outline(feature_element.gherkin_statement) + end else raise "Bad type: #{feature_element.class}" end end + def scenario_name(keyword, name, file_colon_line, source_indent) + if @outline and @options[:expand] + @example_row = @example_row ? @example_row + 1 : 0 + if in_instantiated_scenario? + example_row_hash = @current_example_rows[@example_row].to_hash + scenario = Gherkin::Formatter::Model::Scenario.new( + @current_scenario_hash['comments'], + @current_scenario_hash['tags'], + @current_scenario_hash['keyword'], + @current_scenario_hash['name'], + @current_scenario_hash['description'], + example_row_hash['line'], + example_row_hash['id']) + @gf.scenario(scenario) + end + end + end + def before_step(step) - @gf.step(step.gherkin_statement) + unless @outline and @options[:expand] + @gf.step(step.gherkin_statement) + else + if in_instantiated_scenario? + @current_step_hash = to_hash(step.gherkin_statement) + end + end if @print_empty_match if(@outline) match = Gherkin::Formatter::Model::Match.new(step.gherkin_statement.outline_args, nil) @@ -55,23 +84,50 @@ def before_step_result(keyword, step_match, multiline_arg, status, exception, so # Trick the formatter to believe that's what was printed previously so we get arg highlights on #result @gf.instance_variable_set('@match', match) else - @gf.match(match) + unless @outline and @options[:expand] + @gf.match(match) + end end error_message = exception ? "#{exception.message} (#{exception.class})\n#{exception.backtrace.join("\n")}" : nil unless @outline @gf.result(Gherkin::Formatter::Model::Result.new(status, nil, error_message)) + else + if @options[:expand] and in_instantiated_scenario? + @current_match = match + @current_result = Gherkin::Formatter::Model::Result.new(status, nil, error_message) + end + end + end + + def step_name(keyword, step_match, status, source_indent, background, file_colon_line) + if @outline and @options[:expand] and in_instantiated_scenario? + @gf.step(Gherkin::Formatter::Model::Step.new( + @current_step_hash['comments'], + @current_step_hash['keyword'], + step_match.format_args(), + @current_step_hash['line'], + @current_step_hash['rows'], + @current_step_hash['doc_string'])) + @gf.match(@current_match) + @gf.result(@current_result) end end def before_examples(examples) - @gf.examples(examples.gherkin_statement) + unless @options[:expand] + @gf.examples(examples.gherkin_statement) + else + @current_example_rows = to_hash(examples.gherkin_statement)['rows'] + end end #used for capturing duration def after_step(step) step_finish = (Time.now - @step_time) - @gf.append_duration(step_finish) + unless @outline and @options[:expand] and not in_instantiated_scenario? + @gf.append_duration(step_finish) + end end def after_feature(feature) @@ -93,6 +149,20 @@ def embed(file, mime_type, label) def puts(message) @gf.write(message) end + + private + + def in_instantiated_scenario? + @example_row > 0 + end + + def to_hash(gherkin_statement) + if defined?(JRUBY_VERSION) + gherkin_statement.toMap() + else + gherkin_statement.to_hash + end + end end end end diff --git a/lib/cucumber/formatter/json.rb b/lib/cucumber/formatter/json.rb index bdc7124395..a2e720ec4d 100644 --- a/lib/cucumber/formatter/json.rb +++ b/lib/cucumber/formatter/json.rb @@ -11,7 +11,7 @@ class Json < GherkinFormatterAdapter def initialize(runtime, io, options) @io = ensure_io(io, "json") - super(Gherkin::Formatter::JSONFormatter.new(@io), false) + super(Gherkin::Formatter::JSONFormatter.new(@io), false, options) end end end From 3a4f8f69444fe94c0216bfb444ea000cfe4db7e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Rasmusson?= Date: Mon, 30 Jun 2014 16:08:31 +0200 Subject: [PATCH 6/9] Handle more than one Examples table in a Scenario Outline --- features/json_formatter.feature | 65 ++++++++++++++++--- .../formatter/gherkin_formatter_adapter.rb | 43 ++++++------ 2 files changed, 80 insertions(+), 28 deletions(-) diff --git a/features/json_formatter.feature b/features/json_formatter.feature index ae3ac0f222..e9fbb25d77 100644 --- a/features/json_formatter.feature +++ b/features/json_formatter.feature @@ -79,11 +79,15 @@ Feature: JSON output formatter Scenario Outline: outline Given a step - Examples: examples + Examples: examples1 | type | | passing | | failing | + Examples: examples2 + | type | + | passing | + """ # Need to investigate why this won't pass in-process. error_message doesn't get det? @@ -453,31 +457,54 @@ Feature: JSON output formatter "examples": [ { "keyword": "Examples", - "name": "examples", + "name": "examples1", "line": 6, "description": "", - "id": "an-outline-feature;outline;examples", + "id": "an-outline-feature;outline;examples1", "rows": [ { "cells": [ "type" ], "line": 7, - "id": "an-outline-feature;outline;examples;1" + "id": "an-outline-feature;outline;examples1;1" }, { "cells": [ "passing" ], "line": 8, - "id": "an-outline-feature;outline;examples;2" + "id": "an-outline-feature;outline;examples1;2" }, { "cells": [ "failing" ], "line": 9, - "id": "an-outline-feature;outline;examples;3" + "id": "an-outline-feature;outline;examples1;3" + } + ] + }, + { + "keyword": "Examples", + "name": "examples2", + "line": 11, + "description": "", + "id": "an-outline-feature;outline;examples2", + "rows": [ + { + "cells": [ + "type" + ], + "line": 12, + "id": "an-outline-feature;outline;examples2;1" + }, + { + "cells": [ + "passing" + ], + "line": 13, + "id": "an-outline-feature;outline;examples2;2" } ] } @@ -503,7 +530,7 @@ Feature: JSON output formatter "description": "", "elements": [ { - "id": "an-outline-feature;outline;examples;2", + "id": "an-outline-feature;outline;examples1;2", "keyword": "Scenario Outline", "name": "outline", "line": 8, @@ -525,7 +552,7 @@ Feature: JSON output formatter ] }, { - "id": "an-outline-feature;outline;examples;3", + "id": "an-outline-feature;outline;examples1;3", "keyword": "Scenario Outline", "name": "outline", "line": 9, @@ -546,6 +573,28 @@ Feature: JSON output formatter } } ] + }, + { + "id": "an-outline-feature;outline;examples2;2", + "keyword": "Scenario Outline", + "name": "outline", + "line": 13, + "description": "", + "type": "scenario", + "steps": [ + { + "keyword": "Given ", + "name": "a passing step", + "line": 4, + "match": { + "location": "features/step_definitions/steps.rb:1" + }, + "result": { + "status": "passed", + "duration": 1 + } + } + ] } ] } diff --git a/lib/cucumber/formatter/gherkin_formatter_adapter.rb b/lib/cucumber/formatter/gherkin_formatter_adapter.rb index 05f51a9690..15b165c7ee 100644 --- a/lib/cucumber/formatter/gherkin_formatter_adapter.rb +++ b/lib/cucumber/formatter/gherkin_formatter_adapter.rb @@ -30,6 +30,7 @@ def before_feature_element(feature_element) when Ast::ScenarioOutline @outline = true if @options[:expand] + @in_instantiated_scenario = false @current_scenario_hash = to_hash(feature_element.gherkin_statement) else @gf.scenario_outline(feature_element.gherkin_statement) @@ -41,19 +42,23 @@ def before_feature_element(feature_element) def scenario_name(keyword, name, file_colon_line, source_indent) if @outline and @options[:expand] - @example_row = @example_row ? @example_row + 1 : 0 - if in_instantiated_scenario? - example_row_hash = @current_example_rows[@example_row].to_hash - scenario = Gherkin::Formatter::Model::Scenario.new( - @current_scenario_hash['comments'], - @current_scenario_hash['tags'], - @current_scenario_hash['keyword'], - @current_scenario_hash['name'], - @current_scenario_hash['description'], - example_row_hash['line'], - example_row_hash['id']) - @gf.scenario(scenario) + return if not @in_instantiated_scenario + if @new_example_table + @example_row = 1 + @new_example_table = false + else + @example_row += 1 end + example_row_hash = @current_example_rows[@example_row].to_hash + scenario = Gherkin::Formatter::Model::Scenario.new( + @current_scenario_hash['comments'], + @current_scenario_hash['tags'], + @current_scenario_hash['keyword'], + @current_scenario_hash['name'], + @current_scenario_hash['description'], + example_row_hash['line'], + example_row_hash['id']) + @gf.scenario(scenario) end end @@ -61,7 +66,7 @@ def before_step(step) unless @outline and @options[:expand] @gf.step(step.gherkin_statement) else - if in_instantiated_scenario? + if @in_instantiated_scenario @current_step_hash = to_hash(step.gherkin_statement) end end @@ -93,7 +98,7 @@ def before_step_result(keyword, step_match, multiline_arg, status, exception, so unless @outline @gf.result(Gherkin::Formatter::Model::Result.new(status, nil, error_message)) else - if @options[:expand] and in_instantiated_scenario? + if @options[:expand] and @in_instantiated_scenario @current_match = match @current_result = Gherkin::Formatter::Model::Result.new(status, nil, error_message) end @@ -101,7 +106,7 @@ def before_step_result(keyword, step_match, multiline_arg, status, exception, so end def step_name(keyword, step_match, status, source_indent, background, file_colon_line) - if @outline and @options[:expand] and in_instantiated_scenario? + if @outline and @options[:expand] and @in_instantiated_scenario @gf.step(Gherkin::Formatter::Model::Step.new( @current_step_hash['comments'], @current_step_hash['keyword'], @@ -118,6 +123,8 @@ def before_examples(examples) unless @options[:expand] @gf.examples(examples.gherkin_statement) else + @in_instantiated_scenario = true + @new_example_table = true @current_example_rows = to_hash(examples.gherkin_statement)['rows'] end end @@ -125,7 +132,7 @@ def before_examples(examples) #used for capturing duration def after_step(step) step_finish = (Time.now - @step_time) - unless @outline and @options[:expand] and not in_instantiated_scenario? + unless @outline and @options[:expand] and not @in_instantiated_scenario @gf.append_duration(step_finish) end end @@ -152,10 +159,6 @@ def puts(message) private - def in_instantiated_scenario? - @example_row > 0 - end - def to_hash(gherkin_statement) if defined?(JRUBY_VERSION) gherkin_statement.toMap() From 5c127d5331504d218a2d37723e1320d6f8446c02 Mon Sep 17 00:00:00 2001 From: Matt Wynne Date: Tue, 5 Aug 2014 12:01:52 +0100 Subject: [PATCH 7/9] Pin to non-buggy jruby version Conflicts: .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 73c6ed8aba..c8cd211a7e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ rvm: - 2.0.0 - 1.9.3 - 1.8.7 - - jruby + - jruby-1.7.12 # whitelist branches: From 6f0de4d83d869d3eaf6bad388317edbb7709b123 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Rasmusson?= Date: Sat, 21 Jun 2014 16:36:26 +0200 Subject: [PATCH 8/9] Support embedding data directly in gherkin formatters. --- features/json_formatter.feature | 59 +++++++++++++++++++ .../formatter/gherkin_formatter_adapter.rb | 6 +- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/features/json_formatter.feature b/features/json_formatter.feature index e9fbb25d77..3e6464673a 100644 --- a/features/json_formatter.feature +++ b/features/json_formatter.feature @@ -54,6 +54,11 @@ Feature: JSON output formatter Given /^I print from step definition/ do puts "from step definition" end + + Given /^I embed data directly/ do + data = "abc" + embed data, "mime-type" + end """ And a file named "features/embed.feature" with: """ @@ -89,6 +94,14 @@ Feature: JSON output formatter | passing | """ + And a file named "features/embed_data_directly.feature" with: + """ + Feature: An embed data directly feature + + Scenario: + Given I embed data directly + + """ # Need to investigate why this won't pass in-process. error_message doesn't get det? @spawn @@ -422,6 +435,52 @@ Feature: JSON output formatter } ] + """ + Scenario: embedding data directly + When I run `cucumber -b --format json features/embed_data_directly.feature` + Then it should pass with JSON: + """ + [ + { + "uri": "features/embed_data_directly.feature", + "id": "an-embed-data-directly-feature", + "keyword": "Feature", + "name": "An embed data directly feature", + "line": 1, + "description": "", + "elements": [ + { + "id": "an-embed-data-directly-feature;", + "keyword": "Scenario", + "name": "", + "line": 3, + "description": "", + "type": "scenario", + "steps": [ + { + "keyword": "Given ", + "name": "I embed data directly", + "line": 4, + "embeddings": [ + { + "mime_type": "mime-type", + "data": "YWJj" + } + ], + "match": { + "location": "features/step_definitions/steps.rb:38" + }, + "result": { + "status": "passed", + "duration": 1 + } + } + ] + } + ] + } + ] + """ @spawn Scenario: scenario outline diff --git a/lib/cucumber/formatter/gherkin_formatter_adapter.rb b/lib/cucumber/formatter/gherkin_formatter_adapter.rb index 15b165c7ee..497032757e 100644 --- a/lib/cucumber/formatter/gherkin_formatter_adapter.rb +++ b/lib/cucumber/formatter/gherkin_formatter_adapter.rb @@ -146,7 +146,11 @@ def after_features(features) end def embed(file, mime_type, label) - data = File.open(file, 'rb') { |f| f.read } + if File.file?(file) + data = File.open(file, 'rb') { |f| f.read } + else + data = file + end if defined?(JRUBY_VERSION) data = data.to_java_bytes end From ffc692b609c9050953e29533453e7ceb4b7875db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Rasmusson?= Date: Sun, 22 Jun 2014 20:26:19 +0200 Subject: [PATCH 9/9] Decode base64 data before sending it to a gherkin formatter The gherkin JSON formatter will encode the data it receives before inserting it into the json file. When supporting embedding images in html files, the data sent to the embed method need to be base64 encoded. Unless decoded before sent to the gherkin JSON formatter, the base64 encoding will be applied twice. --- features/json_formatter.feature | 4 ++-- lib/cucumber/formatter/gherkin_formatter_adapter.rb | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/features/json_formatter.feature b/features/json_formatter.feature index 3e6464673a..63d1ee1b2b 100644 --- a/features/json_formatter.feature +++ b/features/json_formatter.feature @@ -56,8 +56,8 @@ Feature: JSON output formatter end Given /^I embed data directly/ do - data = "abc" - embed data, "mime-type" + data = "YWJj" + embed data, "mime-type;base64" end """ And a file named "features/embed.feature" with: diff --git a/lib/cucumber/formatter/gherkin_formatter_adapter.rb b/lib/cucumber/formatter/gherkin_formatter_adapter.rb index 497032757e..9f0d7843be 100644 --- a/lib/cucumber/formatter/gherkin_formatter_adapter.rb +++ b/lib/cucumber/formatter/gherkin_formatter_adapter.rb @@ -149,7 +149,12 @@ def embed(file, mime_type, label) if File.file?(file) data = File.open(file, 'rb') { |f| f.read } else - data = file + if mime_type =~ /;base64$/ + mime_type = mime_type[0..-8] + data = Base64.decode64(file) + else + data = file + end end if defined?(JRUBY_VERSION) data = data.to_java_bytes