cucumber-rails 0.3.0 → 1.0.0

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.
Files changed (112) hide show
  1. data/.gitignore +1 -0
  2. data/.rspec +1 -0
  3. data/.rvmrc +1 -0
  4. data/Gemfile +2 -0
  5. data/Gemfile.lock +194 -0
  6. data/History.txt +101 -1
  7. data/LICENSE +22 -0
  8. data/README.md +77 -0
  9. data/Rakefile +3 -19
  10. data/config/cucumber.yml +1 -0
  11. data/cucumber-rails.gemspec +37 -101
  12. data/dev_tasks/cucumber.rake +1 -1
  13. data/dev_tasks/rspec.rake +6 -11
  14. data/features/allow_rescue.feature +63 -0
  15. data/features/capybara_javascript_drivers.feature +87 -0
  16. data/features/database_cleaner.feature +44 -0
  17. data/features/emulate_javascript.feature +34 -0
  18. data/features/inspect_query_string.feature +37 -0
  19. data/features/install_cucumber_rails.feature +16 -0
  20. data/features/mongoid.feature +53 -0
  21. data/features/multiple_databases.feature +74 -0
  22. data/features/named_selectors.feature +33 -0
  23. data/features/no_database.feature +70 -0
  24. data/features/pseduo_class_selectors.feature +24 -0
  25. data/features/rerun_profile.feature +38 -0
  26. data/features/rest_api.feature +47 -0
  27. data/features/routing.feature +18 -0
  28. data/features/select_dates.feature +99 -0
  29. data/features/step_definitions/cucumber_rails_steps.rb +80 -6
  30. data/features/support/env.rb +8 -2
  31. data/features/test_unit.feature +43 -0
  32. data/lib/cucumber/rails/capybara/javascript_emulation.rb +83 -0
  33. data/lib/cucumber/rails/capybara/select_dates_and_times.rb +50 -0
  34. data/lib/cucumber/rails/capybara.rb +6 -0
  35. data/lib/cucumber/rails/hooks/active_record.rb +14 -0
  36. data/lib/cucumber/rails/hooks/allow_rescue.rb +8 -0
  37. data/lib/cucumber/rails/hooks/database_cleaner.rb +13 -0
  38. data/lib/cucumber/rails/hooks/mail.rb +5 -0
  39. data/lib/cucumber/rails/hooks.rb +4 -0
  40. data/lib/cucumber/rails/rspec.rb +4 -6
  41. data/lib/cucumber/rails/world.rb +13 -35
  42. data/lib/cucumber/rails.rb +8 -0
  43. data/lib/cucumber/rails3/action_controller.rb +12 -0
  44. data/lib/cucumber/rails3/active_record.rb +8 -0
  45. data/lib/cucumber/rails3/application.rb +17 -0
  46. data/lib/cucumber/rails3.rb +16 -0
  47. data/lib/cucumber/web/tableish.rb +50 -9
  48. data/lib/generators/cucumber/feature/feature_generator.rb +8 -17
  49. data/lib/generators/cucumber/feature/named_arg.rb +2 -0
  50. data/{templates/feature → lib/generators/cucumber/feature/templates}/feature.erb +10 -12
  51. data/{templates/feature → lib/generators/cucumber/feature/templates}/steps.erb +1 -1
  52. data/lib/generators/cucumber/install/USAGE +15 -0
  53. data/lib/generators/cucumber/install/install_generator.rb +88 -0
  54. data/lib/generators/cucumber/install/templates/config/cucumber.yml.erb +8 -0
  55. data/lib/generators/cucumber/install/templates/step_definitions/web_steps.rb.erb +192 -0
  56. data/lib/generators/cucumber/install/templates/step_definitions/web_steps_cs.rb.erb +127 -0
  57. data/lib/generators/cucumber/install/templates/step_definitions/web_steps_da.rb.erb +105 -0
  58. data/lib/generators/cucumber/install/templates/step_definitions/web_steps_de.rb.erb +127 -0
  59. data/lib/generators/cucumber/install/templates/step_definitions/web_steps_es.rb.erb +127 -0
  60. data/lib/generators/cucumber/install/templates/step_definitions/web_steps_ja.rb.erb +140 -0
  61. data/lib/generators/cucumber/install/templates/step_definitions/web_steps_ko.rb.erb +142 -0
  62. data/lib/generators/cucumber/install/templates/step_definitions/web_steps_no.rb.erb +105 -0
  63. data/lib/generators/cucumber/install/templates/step_definitions/web_steps_pt-BR.rb.erb +132 -0
  64. data/lib/generators/cucumber/install/templates/support/_rails_each_run.rb.erb +36 -0
  65. data/lib/generators/cucumber/install/templates/support/_rails_prefork.rb.erb +1 -0
  66. data/{templates/skeleton → lib/generators/cucumber/install/templates}/support/capybara.rb +0 -4
  67. data/{templates/skeleton → lib/generators/cucumber/install/templates}/support/paths.rb +11 -5
  68. data/{templates/skeleton → lib/generators/cucumber/install/templates}/support/rails.rb.erb +2 -2
  69. data/{templates/skeleton → lib/generators/cucumber/install/templates}/support/rails_spork.rb.erb +2 -2
  70. data/lib/generators/cucumber/install/templates/support/selectors.rb +39 -0
  71. data/lib/generators/cucumber/install/templates/support/web_steps_warning.txt +19 -0
  72. data/{templates/skeleton → lib/generators/cucumber/install/templates}/tasks/cucumber.rake.erb +18 -0
  73. data/spec/cucumber/web/tableish_spec.rb +83 -6
  74. data/spec/spec_helper.rb +1 -4
  75. metadata +299 -73
  76. data/HACKING.rdoc +0 -34
  77. data/README.rdoc +0 -64
  78. data/VERSION +0 -1
  79. data/features/rails2.feature +0 -56
  80. data/features/rails3.feature +0 -52
  81. data/features/support/matchers/files.rb +0 -17
  82. data/generators/cucumber/USAGE +0 -14
  83. data/generators/cucumber/cucumber_generator.rb +0 -89
  84. data/generators/cucumber/templates/step_definitions/web_steps_ja.rb.erb +0 -136
  85. data/generators/feature/USAGE +0 -12
  86. data/generators/feature/feature_generator.rb +0 -47
  87. data/lib/cucumber/rails/action_controller.rb +0 -65
  88. data/lib/cucumber/rails/active_record.rb +0 -34
  89. data/lib/cucumber/rails/capybara_javascript_emulation.rb +0 -72
  90. data/lib/cucumber/rails/test_unit.rb +0 -9
  91. data/lib/generators/cucumber/feature/feature_base.rb +0 -29
  92. data/lib/generators/cucumber/skeleton/USAGE +0 -21
  93. data/lib/generators/cucumber/skeleton/skeleton_base.rb +0 -202
  94. data/lib/generators/cucumber/skeleton/skeleton_generator.rb +0 -64
  95. data/rvm.yml +0 -22
  96. data/spec/generators/cucumber/skeleton/skeleton_base_spec.rb +0 -84
  97. data/spec/spec.opts +0 -2
  98. data/templates/skeleton/config/cucumber.yml.erb +0 -7
  99. data/templates/skeleton/environments/cucumber.rb.erb +0 -37
  100. data/templates/skeleton/step_definitions/capybara_steps.rb.erb +0 -197
  101. data/templates/skeleton/step_definitions/web_steps_cs.rb.erb +0 -136
  102. data/templates/skeleton/step_definitions/web_steps_da.rb.erb +0 -114
  103. data/templates/skeleton/step_definitions/web_steps_de.rb.erb +0 -136
  104. data/templates/skeleton/step_definitions/web_steps_es.rb.erb +0 -136
  105. data/templates/skeleton/step_definitions/web_steps_no.rb.erb +0 -114
  106. data/templates/skeleton/step_definitions/web_steps_pt-BR.rb.erb +0 -140
  107. data/templates/skeleton/step_definitions/webrat_steps.rb.erb +0 -268
  108. data/templates/skeleton/support/_rails_each_run.rb +0 -34
  109. data/templates/skeleton/support/_rails_prefork.rb.erb +0 -10
  110. data/templates/skeleton/support/webrat.rb +0 -8
  111. /data/{templates/skeleton → lib/generators/cucumber/install/templates}/script/cucumber +0 -0
  112. /data/{templates/skeleton → lib/generators/cucumber/install/templates}/support/edit_warning.txt +0 -0
@@ -0,0 +1,99 @@
1
+ Feature: Select dates
2
+
3
+ Background: A simple calendar app
4
+ Given I have created a new Rails 3 app "rails-3-app" with cucumber-rails support
5
+
6
+ Scenario: Select date and time
7
+ Given I successfully run `bundle exec rails g scaffold appointment name:string when:datetime`
8
+ And I write to "features/create_appointment.feature" with:
9
+ """
10
+ Feature: Create appointments
11
+ Scenario: Constitution on May 17
12
+ Given I am on the new appointment page
13
+ And I fill in "Norway's constitution" for "Name"
14
+ And I select "2009-02-20 15:10:00 UTC" as the "When" date and time
15
+ And I press "Create Appointment"
16
+ Then I should see "Norway's constitution"
17
+ And I should see "2009-02-20 15:10:00 UTC"
18
+ """
19
+ When I run `bundle exec rake db:migrate`
20
+ And I run `bundle exec rake cucumber`
21
+ Then it should pass with:
22
+ """
23
+ 1 scenario (1 passed)
24
+ 6 steps (6 passed)
25
+ """
26
+
27
+ Scenario: Select date with label pointing to first select
28
+ Given I successfully run `bundle exec rails g scaffold appointment name:string when:date`
29
+ And I write to "features/create_appointment.feature" with:
30
+ """
31
+ Feature: Create appointments
32
+ Scenario: Constitution on May 17
33
+ Given I am on the new appointment page
34
+ And I fill in "Norway's constitution" for "Name"
35
+ And I select "2009-02-20" as the "When" date
36
+ And I press "Create Appointment"
37
+ Then I should see "Norway's constitution"
38
+ And I should see "2009-02-20"
39
+ """
40
+ And I write to "app/views/appointments/_form.html.erb" with:
41
+ """
42
+ <%= form_for(@appointment) do |f| %>
43
+ <div class="field">
44
+ <%= f.label :name %><br />
45
+ <%= f.text_field :name %>
46
+ </div>
47
+ <div class="field">
48
+ <%= f.label :when, :for => "appointment_when_1i" %><br />
49
+ <%= f.date_select :when %>
50
+ </div>
51
+ <div class="actions">
52
+ <%= f.submit %>
53
+ </div>
54
+ <% end %>
55
+ """
56
+ When I run `bundle exec rake db:migrate`
57
+ And I run `bundle exec rake cucumber`
58
+ Then it should pass with:
59
+ """
60
+ 1 scenario (1 passed)
61
+ 6 steps (6 passed)
62
+ """
63
+
64
+ Scenario: Select date when the order of fields is changed and label is set to the first select
65
+ Given I successfully run `bundle exec rails g scaffold appointment name:string when:date`
66
+ And I write to "features/create_appointment.feature" with:
67
+ """
68
+ Feature: Create appointments
69
+ Scenario: Constitution on May 17
70
+ Given I am on the new appointment page
71
+ And I fill in "Norway's constitution" for "Name"
72
+ And I select "2009-02-20" as the "When" date
73
+ And I press "Create Appointment"
74
+ Then I should see "Norway's constitution"
75
+ And I should see "2009-02-20"
76
+ """
77
+ And I write to "app/views/appointments/_form.html.erb" with:
78
+ """
79
+ <%= form_for(@appointment) do |f| %>
80
+ <div class="field">
81
+ <%= f.label :name %><br />
82
+ <%= f.text_field :name %>
83
+ </div>
84
+ <div class="field">
85
+ <%= f.label :when, :for => "appointment_when_2i" %><br />
86
+ <%= f.date_select :when, :order=>[:month, :day, :year] %>
87
+ </div>
88
+ <div class="actions">
89
+ <%= f.submit %>
90
+ </div>
91
+ <% end %>
92
+ """
93
+ When I run `bundle exec rake db:migrate`
94
+ And I run `bundle exec rake cucumber`
95
+ Then it should pass with:
96
+ """
97
+ 1 scenario (1 passed)
98
+ 6 steps (6 passed)
99
+ """
@@ -1,7 +1,81 @@
1
- Given /^I symlink this repo to "([^\"]*)"$/ do |target|
2
- source = File.expand_path('../../..', __FILE__)
3
- in_current_dir do
4
- target = File.expand_path(target)
5
- FileUtils.ln_s(source, target)
6
- end
1
+ Given /^I have created a new Rails 3 app "([^"]*)" with cucumber\-rails support$/ do |app_name|
2
+ steps %Q{
3
+ When I successfully run `rails new #{app_name}`
4
+ Then it should pass with:
5
+ """
6
+ README
7
+ """
8
+ And I cd to "#{app_name}"
9
+ And I append to "Gemfile" with:
10
+ """
11
+ gem "cucumber-rails", :group => :test, :path => "../../.."
12
+ gem "capybara", :group => :test
13
+ gem "rspec-rails", :group => :test
14
+ gem "database_cleaner", :group => :test
15
+ gem 'factory_girl', :group => :test
16
+
17
+ """
18
+ And I successfully run `bundle exec rails generate cucumber:install`
19
+ }
7
20
  end
21
+
22
+ Given /^a project without ActiveRecord$/ do
23
+ steps %Q{
24
+ Given I successfully run `rails new cuke-app`
25
+ And I cd to "cuke-app"
26
+ And I append to "Gemfile" with:
27
+ """
28
+ gem "cucumber-rails", :group => :test, :path => "../../.."
29
+ gem "capybara", :group => :test
30
+ gem "rspec-rails", :group => :test
31
+
32
+ """
33
+ And I successfully run `bundle exec rails generate cucumber:install`
34
+ And I overwrite "features/support/env.rb" with:
35
+ """
36
+ require 'cucumber/rails'
37
+
38
+ """
39
+
40
+ And I write to "config/application.rb" with:
41
+ """
42
+ require File.expand_path('../boot', __FILE__)
43
+
44
+ require 'action_controller/railtie'
45
+ require 'action_mailer/railtie'
46
+ require 'active_resource/railtie'
47
+ require 'rails/test_unit/railtie'
48
+
49
+ Bundler.require(:default, Rails.env) if defined?(Bundler)
50
+
51
+ module CukeApp
52
+ class Application < Rails::Application
53
+ config.encoding = "utf-8"
54
+ config.filter_parameters += [:password]
55
+ end
56
+ end
57
+
58
+ """
59
+ And I remove the file "config/database.yml"
60
+ }
61
+ end
62
+
63
+ And /^a cukes resource$/ do
64
+ steps %Q{
65
+ Given I write to "config/routes.rb" with:
66
+ """
67
+ CukeApp::Application.routes.draw do
68
+ resources :cukes
69
+ end
70
+
71
+ """
72
+ And I write to "app/controllers/cukes_controller.rb" with:
73
+ """
74
+ class CukesController < ApplicationController
75
+ def index
76
+ end
77
+ end
78
+
79
+ """
80
+ }
81
+ end
@@ -1,4 +1,10 @@
1
1
  $:.unshift(File.dirname(__FILE__) + '/../../lib')
2
2
  require 'rubygems'
3
- require 'spec'
4
- require 'aruba'
3
+ require 'bundler/setup'
4
+ require 'rspec/expectations'
5
+ require 'aruba/cucumber'
6
+
7
+ Before do
8
+ @aruba_timeout_seconds = 120 # A long time needed some times
9
+ unset_bundler_env_vars
10
+ end
@@ -0,0 +1,43 @@
1
+ Feature: Run with Test::Unit
2
+
3
+ Scenario: Delete a widget
4
+ Given I have created a new Rails 3 app "widgets" with cucumber-rails support
5
+ And I overwrite "Gemfile" with:
6
+ """
7
+ gem 'rails'
8
+ gem 'sqlite3'
9
+ gem "cucumber-rails", :group => :test, :path => "../../.."
10
+ gem "capybara", :group => :test
11
+ gem "database_cleaner", :group => :test
12
+ gem 'factory_girl', :group => :test
13
+
14
+ """
15
+ And I successfully run `rails generate scaffold widget name:string`
16
+ And I write to "features/f.feature" with:
17
+ """
18
+ Feature: Widget inventory
19
+ Scenario: Delete a widget
20
+ Given there is a widget named "wrench"
21
+ When I go to the widgets page
22
+ Then I should see "wrench"
23
+ """
24
+ And I write to "features/step_definitions/s.rb" with:
25
+ """
26
+ Given /^there is a widget named "([^"]*)"$/ do |name|
27
+ Factory(:widget, :name => name)
28
+ end
29
+ """
30
+ And I write to "features/support/factories.rb" with:
31
+ """
32
+ Factory.define :widget do |f|
33
+ f.name 'testwidget'
34
+ end
35
+ """
36
+ When I run `bundle exec rake db:migrate`
37
+ And I run `bundle exec rake cucumber`
38
+ Then it should pass with:
39
+ """
40
+ 1 scenario (1 passed)
41
+ 3 steps (3 passed)
42
+ """
43
+
@@ -0,0 +1,83 @@
1
+ module Cucumber
2
+ module Rails
3
+ module Capybara
4
+ module JavascriptEmulation
5
+ def self.included(base)
6
+ base.class_eval do
7
+ alias_method :click_without_javascript_emulation, :click
8
+ alias_method :click, :click_with_javascript_emulation
9
+ end
10
+ end
11
+
12
+ def click_with_javascript_emulation
13
+ if link_with_non_get_http_method?
14
+ ::Capybara::RackTest::Form.new(driver, js_form(element_node.document, self[:href], emulated_method)).submit(self)
15
+ else
16
+ click_without_javascript_emulation
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def js_form(document, action, emulated_method, method = 'POST')
23
+ js_form = document.create_element('form')
24
+ js_form['action'] = action
25
+ js_form['method'] = method
26
+
27
+ if emulated_method and emulated_method.downcase != method.downcase
28
+ input = document.create_element('input')
29
+ input['type'] = 'hidden'
30
+ input['name'] = '_method'
31
+ input['value'] = emulated_method
32
+ js_form.add_child(input)
33
+ end
34
+
35
+ js_form
36
+ end
37
+
38
+ def link_with_non_get_http_method?
39
+ if ::Rails.version.to_f >= 3.0
40
+ tag_name == 'a' && element_node['data-method'] && element_node['data-method'] =~ /(?:delete|put|post)/
41
+ else
42
+ tag_name == 'a' && element_node['onclick'] && element_node['onclick'] =~ /var f = document\.createElement\('form'\); f\.style\.display = 'none';/
43
+ end
44
+ end
45
+
46
+ def emulated_method
47
+ if ::Rails.version.to_f >= 3.0
48
+ element_node['data-method']
49
+ else
50
+ element_node['onclick'][/m\.setAttribute\('value', '([^']*)'\)/, 1]
51
+ end
52
+ end
53
+
54
+ def element_node
55
+ if self.respond_to? :native
56
+ self.native
57
+ else
58
+ warn "DEPRECATED: cucumber-rails loves you, just not your version of Capybara. Please update Capybara to >= 0.4.0"
59
+ self.node
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ class Capybara::RackTest::Node
68
+ include ::Cucumber::Rails::Capybara::JavascriptEmulation
69
+ end
70
+
71
+ Before('~@no-js-emulation') do
72
+ # Enable javascript emulation
73
+ ::Capybara::RackTest::Node.class_eval do
74
+ alias_method :click, :click_with_javascript_emulation
75
+ end
76
+ end
77
+
78
+ Before('@no-js-emulation') do
79
+ # Disable javascript emulation
80
+ ::Capybara::RackTest::Node.class_eval do
81
+ alias_method :click, :click_without_javascript_emulation
82
+ end
83
+ end
@@ -0,0 +1,50 @@
1
+ module Cucumber
2
+ module Rails
3
+ module Capybara
4
+ module SelectDatesAndTimes
5
+ def select_date(field, options = {})
6
+ date = Date.parse(options[:with])
7
+ base_dom_id = get_base_dom_id_from_label_tag(field)
8
+
9
+ find(:xpath, "//select[@id='#{base_dom_id}_1i']").select(date.year.to_s)
10
+ find(:xpath, "//select[@id='#{base_dom_id}_2i']").select(I18n.l date, :format => '%B')
11
+ find(:xpath, "//select[@id='#{base_dom_id}_3i']").select(date.day.to_s)
12
+ end
13
+
14
+ def select_time(field, options = {})
15
+ time = Time.zone.parse(options[:with])
16
+ base_dom_id = get_base_dom_id_from_label_tag(field)
17
+
18
+ find(:xpath, "//select[@id='#{base_dom_id}_4i']").select(time.hour.to_s.rjust(2, '0'))
19
+ find(:xpath, "//select[@id='#{base_dom_id}_5i']").select(time.min.to_s.rjust(2, '0'))
20
+ end
21
+
22
+ def select_datetime(field, options = {})
23
+ select_date(field, options)
24
+ select_time(field, options)
25
+ end
26
+
27
+ private
28
+
29
+ # @example "event_starts_at_"
30
+ def get_base_dom_id_from_label_tag(field)
31
+ find(:xpath, "//label[contains(., '#{field}')]")['for'].gsub(/(_[1-5]i)$/, '')
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ World(::Cucumber::Rails::Capybara::SelectDatesAndTimes)
39
+
40
+ When /^(?:|I )select "([^"]+)" as the "([^"]+)" time$/ do |time, selector|
41
+ select_time(selector, :with => time)
42
+ end
43
+
44
+ When /^(?:|I )select "([^"]+)" as the "([^"]+)" date$/ do |date, selector|
45
+ select_date(selector, :with => date)
46
+ end
47
+
48
+ When /^(?:|I )select "([^"]+)" as the "([^"]+)" date and time$/ do |datetime, selector|
49
+ select_datetime(selector, :with => datetime)
50
+ end
@@ -0,0 +1,6 @@
1
+ require 'capybara'
2
+ require 'capybara/rails'
3
+ require 'capybara/cucumber'
4
+ require 'capybara/session'
5
+ require 'cucumber/rails/capybara/javascript_emulation'
6
+ require 'cucumber/rails/capybara/select_dates_and_times'
@@ -0,0 +1,14 @@
1
+ if defined?(ActiveRecord::Base)
2
+ require 'cucumber/rails3/active_record'
3
+
4
+ Before('@javascript') do
5
+ # Forces all threads to share the same connection. This works on
6
+ # Capybara because it starts the web server in a thread.
7
+ ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection
8
+ end
9
+
10
+ Before('~@javascript') do
11
+ # Do not use a shared connection unless we're in a @javascript scenario
12
+ ActiveRecord::Base.shared_connection = nil
13
+ end
14
+ end
@@ -0,0 +1,8 @@
1
+ Before('@allow-rescue') do
2
+ @__orig_allow_rescue = ActionController::Base.allow_rescue
3
+ ActionController::Base.allow_rescue = true
4
+ end
5
+
6
+ After('@allow-rescue') do
7
+ ActionController::Base.allow_rescue = @__orig_allow_rescue
8
+ end
@@ -0,0 +1,13 @@
1
+ begin
2
+ require 'database_cleaner'
3
+
4
+ Before do
5
+ DatabaseCleaner.start
6
+ end
7
+
8
+ After do
9
+ DatabaseCleaner.clean
10
+ end
11
+
12
+ rescue LoadError => ignore_if_database_cleaner_not_present
13
+ end
@@ -0,0 +1,5 @@
1
+ if defined?(ActionMailer::Base)
2
+ Before do
3
+ ActionMailer::Base.deliveries = []
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ require 'cucumber/rails/hooks/active_record'
2
+ require 'cucumber/rails/hooks/database_cleaner'
3
+ require 'cucumber/rails/hooks/allow_rescue'
4
+ require 'cucumber/rails/hooks/mail'
@@ -1,13 +1,11 @@
1
1
  require 'cucumber/rails/world'
2
2
 
3
3
  begin
4
- require 'rspec/expectations'
5
- require 'rspec/rails'
4
+ require 'rspec/rails/matchers'
6
5
 
7
6
  [Cucumber::Rails::World, ActionController::Integration::Session].each do |klass|
8
7
  klass.class_eval do
9
- include Rspec::Matchers
10
- include Rspec::Rails::Matchers
8
+ include RSpec::Matchers
11
9
  end
12
10
  end
13
11
  rescue LoadError => try_rspec_1
@@ -17,7 +15,7 @@ rescue LoadError => try_rspec_1
17
15
  [Cucumber::Rails::World, ActionController::Integration::Session].each do |klass|
18
16
  klass.class_eval do
19
17
  include Spec::Matchers
20
- include Spec::Rails::Matchers
18
+ include Spec::Rails::Matchers if defined?(Spec::Rails::Matchers)
21
19
  end
22
20
  end
23
- end
21
+ end
@@ -1,43 +1,21 @@
1
- unless defined?(Test)
2
- begin
3
- require 'spec/test/unit'
4
- rescue LoadError => ignore_if_rspec_not_installed
5
- end
6
- end
7
-
8
- if defined?(ActiveRecord::Base)
9
- if Rails.version.to_f >= 3.0
10
- require 'rails/test_help'
11
- else
12
- require 'test_help'
13
- end
14
- else
15
- # I can't do rescue LoadError because in this files could be loaded
16
- # from rails gem (ie. load actionpack 2.3.5 if rubygems are not disabled)
17
- if Rails.version.to_f < 3.0
18
- require 'action_controller/test_process'
19
- require 'action_controller/integration'
20
- else
21
- require 'action_dispatch/testing/test_process'
22
- require 'action_dispatch/testing/integration'
23
- end
24
- end
25
-
26
- require 'cucumber/rails/test_unit'
27
- require 'cucumber/rails/action_controller'
28
-
29
-
30
- if (::Rails.respond_to?(:application) && !(::Rails.application.config.cache_classes)) ||
31
- (!(::Rails.respond_to?(:application)) && ::Rails.respond_to?(:configuration) && !(::Rails.configuration.cache_classes))
32
- warn "WARNING: You have set Rails' config.cache_classes to false (most likely in config/environments/cucumber.rb). This setting is known to break Cucumber's use_transactional_fixtures method. Set config.cache_classes to true if you want to use transactional fixtures. For more information see https://rspec.lighthouseapp.com/projects/16211/tickets/165."
1
+ begin
2
+ # Try to load it so we can assign @_result below if needed.
3
+ require 'test/unit/testresult'
4
+ rescue LoadError => ignore
33
5
  end
34
6
 
35
7
  module Cucumber #:nodoc:
36
- module Rails
37
- class World < ActionController::IntegrationTest
8
+ module Rails #:nodoc:
9
+ class World < ActionController::IntegrationTest #:nodoc:
10
+ include Rack::Test::Methods
38
11
  include ActiveSupport::Testing::SetupAndTeardown if ActiveSupport::Testing.const_defined?("SetupAndTeardown")
12
+
39
13
  def initialize #:nodoc:
40
- @_result = Test::Unit::TestResult.new
14
+ @_result = Test::Unit::TestResult.new if defined?(Test::Unit::TestResult)
15
+ end
16
+
17
+ if !defined?(ActiveRecord::Base)
18
+ def self.fixture_table_names; []; end # Workaround for projects that don't use ActiveRecord
41
19
  end
42
20
  end
43
21
  end
@@ -0,0 +1,8 @@
1
+ require 'rails'
2
+ require 'cucumber/rails3'
3
+
4
+ require 'cucumber/rails/world'
5
+ require 'cucumber/rails/hooks'
6
+ require 'cucumber/rails/capybara'
7
+
8
+ require 'cucumber/web/tableish'
@@ -0,0 +1,12 @@
1
+ ActionController::Base.class_eval do
2
+ cattr_accessor :allow_rescue
3
+ end
4
+
5
+ class ActionDispatch::ShowExceptions
6
+ alias __cucumber_orig_call__ call
7
+
8
+ def call(env)
9
+ env['action_dispatch.show_exceptions'] = !!ActionController::Base.allow_rescue
10
+ __cucumber_orig_call__(env)
11
+ end
12
+ end
@@ -0,0 +1,8 @@
1
+ class ActiveRecord::Base
2
+ mattr_accessor :shared_connection
3
+ @@shared_connection = nil
4
+
5
+ def self.connection
6
+ @@shared_connection || retrieve_connection
7
+ end
8
+ end
@@ -0,0 +1,17 @@
1
+ require 'rails/application'
2
+
3
+ # Make sure the ActionDispatch::ShowExceptions middleware is always enabled,
4
+ # regardless of what is in config/environments/test.rb
5
+ # Instead we are overriding ActionDispatch::ShowExceptions to be able to
6
+ # toggle whether or not exceptions are raised.
7
+ class Rails::Application
8
+ alias __cucumber_orig_initialize__ initialize!
9
+
10
+ def initialize!
11
+ ad = config.action_dispatch
12
+ def ad.show_exceptions
13
+ true
14
+ end
15
+ __cucumber_orig_initialize__
16
+ end
17
+ end
@@ -0,0 +1,16 @@
1
+ require 'cucumber/rails3/application'
2
+ ENV["RAILS_ENV"] ||= "test"
3
+ ENV["RAILS_ROOT"] ||= File.expand_path(File.dirname(caller.detect{|f| f =~ /\/env\.rb:/}) + '/../..')
4
+ require File.expand_path(ENV["RAILS_ROOT"] + '/config/environment')
5
+ require 'cucumber/rails3/action_controller'
6
+
7
+ if defined?(ActiveRecord::Base)
8
+ require 'rails/test_help'
9
+ else
10
+ require 'action_dispatch/testing/test_process'
11
+ require 'action_dispatch/testing/integration'
12
+ end
13
+
14
+ if !Rails.application.config.cache_classes
15
+ warn "WARNING: You have set Rails' config.cache_classes to false (most likely in config/environments/cucumber.rb). This setting is known to cause problems with database transactions. Set config.cache_classes to true if you want to use transactions. For more information see https://rspec.lighthouseapp.com/projects/16211/tickets/165."
16
+ end
@@ -3,7 +3,7 @@ require 'nokogiri'
3
3
  module Cucumber
4
4
  module Web
5
5
  module Tableish
6
- # This method returns an Array of Array of String, using CSS3 selectors.
6
+ # This method returns an Array of Array of String, using CSS3 selectors.
7
7
  # This is particularly handy when using Cucumber's Table#diff! method.
8
8
  #
9
9
  # The +row_selector+ argument must be a String, and picks out all the rows
@@ -51,27 +51,68 @@ module Cucumber
51
51
 
52
52
  def _tableish(html, row_selector, column_selectors) #:nodoc
53
53
  doc = Nokogiri::HTML(html)
54
- column_count = nil
55
- doc.search(row_selector).map do |row|
54
+ spans = nil
55
+ max_cols = 0
56
+
57
+ # Parse the table.
58
+ rows = doc.search(row_selector).map do |row|
56
59
  cells = case(column_selectors)
57
60
  when String
58
61
  row.search(column_selectors)
59
62
  when Proc
60
63
  column_selectors.call(row)
61
64
  end
62
- column_count ||= cells.length
63
- (0...column_count).map do |n|
64
- cell = cells[n]
65
- case(cell)
65
+
66
+ # TODO: max_cols should be sum of colspans
67
+ max_cols = [max_cols, cells.length].max
68
+
69
+ spans ||= Array.new(max_cols, 1)
70
+
71
+ cell_index = 0
72
+
73
+ cells = (0...spans.length).inject([]) do |array, n|
74
+ span = spans[n]
75
+
76
+ cell = if span > 1
77
+ row_span, col_span = 1, 1
78
+ nil
79
+ else
80
+ cell = cells[cell_index]
81
+
82
+ row_span, col_span = _parse_spans(cell)
83
+
84
+ if col_span > 1
85
+ ((n + 1)...(n + col_span)).each do |m|
86
+ spans[m] = row_span + 1
87
+ end
88
+ end
89
+
90
+ cell_index +=1
91
+ cell
92
+ end
93
+
94
+ spans[n] = row_span > 1 ? row_span : ([span - 1, 1].max)
95
+
96
+ array << case cell
66
97
  when String then cell.strip
67
98
  when nil then ''
68
99
  else cell.text.strip
69
100
  end
101
+
102
+ array
70
103
  end
104
+
105
+ cells
71
106
  end
72
107
  end
73
- end
108
+
109
+ def _parse_spans(cell)
110
+ cell.is_a?(Nokogiri::XML::Node) ?
111
+ [cell.attributes['rowspan'].to_s.to_i || 1, cell.attributes['colspan'].to_s.to_i || 1] :
112
+ [1, 1]
113
+ end
114
+ end
74
115
  end
75
116
  end
76
117
 
77
- World(Cucumber::Web::Tableish)
118
+ World(Cucumber::Web::Tableish)