kelp 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore CHANGED
@@ -1,8 +1,10 @@
1
1
  *.swp
2
2
  .bundle
3
3
  coverage
4
+ coverage.data
4
5
  docs/_build
5
6
  .rvmrc
6
7
  doc
7
8
  .yardoc
8
9
  examples/sinatra_app/features/step_definitions
10
+ pkg
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- kelp (0.1.5)
4
+ kelp (0.1.6)
5
5
  capybara (>= 0.4.0)
6
6
 
7
7
  GEM
data/History.md CHANGED
@@ -1,6 +1,14 @@
1
1
  Kelp History
2
2
  ============
3
3
 
4
+ 0.1.6
5
+ -----
6
+
7
+ - Improved generated step definitions in kelp_steps.rb, fixed some bugs therein
8
+ - Expanded cucumber self-tests for generated step definitions
9
+ - Fixed bug with field_should_be_empty; now works with textarea
10
+
11
+
4
12
  0.1.5
5
13
  -----
6
14
 
data/README.md CHANGED
@@ -94,6 +94,20 @@ See the
94
94
  for more information.
95
95
 
96
96
 
97
+ Rails generator
98
+ ---------------
99
+
100
+ Kelp provides a generator for Rails 2.x projects, to quickly add some generic
101
+ step definitions. Simply run:
102
+
103
+ $ script/generate kelp
104
+
105
+ This will create `features/step_definitions/kelp_steps.rb` with some example
106
+ step definitions using Kelp's helper methods.
107
+
108
+ A Rails 3.x generator is not currently provided. Contributions are welcome!
109
+
110
+
97
111
  Development
98
112
  -----------
99
113
 
@@ -122,24 +136,26 @@ then [submit a pull request](http://github.com/wapcaplet/kelp/pulls).
122
136
  Testing
123
137
  -------
124
138
 
125
- Kelp comes with a `Rakefile`, so you can run the RSpec tests like so:
139
+ Kelp comes with a `Rakefile`, so you can run the RSpec tests and generate an
140
+ [rcov](http://eigenclass.org/hiki.rb?rcov) coverage report via:
126
141
 
127
142
  $ rake spec
128
143
 
129
- You can also generate an [rcov](http://eigenclass.org/hiki.rb?rcov)
130
- coverage report via:
144
+ This will write an HTML report to `coverage/index.html`. Finally, there are
145
+ some Cucumber self-tests included, mainly for testing the `kelp_steps.rb`
146
+ file used by the Rails generator. Run via:
131
147
 
132
- $ rake rcov
148
+ $ rake cucumber
133
149
 
134
- This will write an HTML report to `coverage/index.html`.
150
+ This self-test is a single scenario that exercises scenarios in
151
+ `examples/sinatra_app/features`, and ensures that they perform as expected.
135
152
 
136
153
 
137
154
  Future plans
138
155
  ------------
139
156
 
140
- * Write Cucumber integration tests
157
+ * Generator for Rails 3
141
158
  * Support other stuff besides Capybara
142
- * Turn the project into a proper Rails plugin, with generators
143
159
 
144
160
 
145
161
  Copyright
data/Rakefile CHANGED
@@ -1,16 +1,39 @@
1
1
  require 'rubygems'
2
2
  require 'rspec/core/rake_task'
3
+ require 'cucumber/rake/task'
3
4
 
4
- RSpec::Core::RakeTask.new do |spec|
5
- spec.pattern = 'spec/**/*_spec.rb'
6
- spec.rspec_opts = ['--color', '--format doc']
5
+ desc "Run RSpec tests with coverage analysis"
6
+ RSpec::Core::RakeTask.new(:spec) do |t|
7
+ t.pattern = 'spec/**/*_spec.rb'
8
+ t.rspec_opts = ['--color', '--format doc']
9
+ t.rcov = true
10
+ t.rcov_opts = [
11
+ '--exclude /.gem/,/gems/,spec,features,examples',
12
+ '--include lib/**/*.rb',
13
+ '--aggregate coverage.data',
14
+ ]
7
15
  end
8
16
 
9
- desc "Generate RCov coverage report"
10
- RSpec::Core::RakeTask.new(:rcov) do |spec|
11
- spec.pattern = 'spec/**/*_spec.rb'
12
- spec.rspec_opts = ['--color', '--format doc']
13
- spec.rcov = true
14
- spec.rcov_opts = %w{--exclude osx\/objc,gems\/,spec\/,features\/}
17
+ desc "Run Cucumber tests with coverage analysis"
18
+ Cucumber::Rake::Task.new(:cucumber) do |t|
19
+ t.cucumber_opts = [
20
+ "--format pretty",
21
+ "--tags ~@wip",
22
+ ]
23
+ t.rcov = true
24
+ t.rcov_opts = [
25
+ '--exclude /.gem/,/gems/,spec,features,examples',
26
+ '--include lib/**/*.rb',
27
+ '--aggregate coverage.data',
28
+ ]
15
29
  end
16
30
 
31
+ desc "Run RSpec and Cucumber tests with coverage analysis"
32
+ task :all do |t|
33
+ rm 'coverage.data' if File.exist?('coverage.data')
34
+ Rake::Task['rcov:spec'].invoke
35
+ Rake::Task['rcov:cucumber'].invoke
36
+ end
37
+
38
+ task :default => ['all']
39
+
@@ -0,0 +1,12 @@
1
+ Feature: Checkboxes
2
+
3
+ Background:
4
+ Given I visit "/form"
5
+
6
+ Scenario: Checkbox should be checked
7
+ Then the "Like" checkbox next to "Apple" should be checked
8
+ And the "Like" checkbox next to "Apple" should not be unchecked
9
+
10
+ Scenario: Checkbox should not be checked
11
+ Then the "Like" checkbox next to "Banana" should be unchecked
12
+ And the "Like" checkbox next to "Banana" should not be checked
@@ -17,6 +17,12 @@ Feature: Dropdowns
17
17
  | Single 'quotes' |
18
18
  | "Double" quotes |
19
19
  | 'Single' and "Double" quotes |
20
+ And the "Favorite Colors" dropdown should include:
21
+ """
22
+ Red
23
+ Green
24
+ Blue
25
+ """
20
26
 
21
27
  Scenario: Dropdown should not include
22
28
  Then the "Height" dropdown should not include "Midget"
@@ -0,0 +1,18 @@
1
+ Feature: Fields
2
+
3
+ Background:
4
+ Given I visit "/form"
5
+
6
+ Scenario: Field should be empty
7
+ Then the "First name" field should be empty
8
+ And the "First name" field within "#person_form" should be empty
9
+ And the "Last name" field should be empty
10
+ And the "Last name" field within "#person_form" should be empty
11
+
12
+ Scenario: Fields should contain
13
+ Then the fields should contain:
14
+ | First name | |
15
+ | Last name | |
16
+ | Weight | Light |
17
+ | Height | Average |
18
+ | Message | Your message goes here |
@@ -11,6 +11,7 @@ Feature: Visibility
11
11
  And I should not see the following:
12
12
  | Goodbye cruel world |
13
13
 
14
+
14
15
  Scenario: Should or shouldn't see in same row
15
16
  Then I should see a table row containing:
16
17
  | Eric | Edit |
@@ -26,3 +27,9 @@ Feature: Visibility
26
27
  | John | Delete |
27
28
  | Terry | Delete |
28
29
 
30
+
31
+ Scenario: Should or shouldn't see next to
32
+ Then I should see "Edit" next to "John"
33
+ And I should not see "Delete" next to "John"
34
+
35
+
@@ -13,6 +13,10 @@
13
13
  <label for="last_name">Last name</label>
14
14
  <input id="last_name" type="text" />
15
15
  </p>
16
+ <p>
17
+ <label for="biography">Life story</label>
18
+ <textarea id="biography" cols="80" rows="10" />
19
+ </p>
16
20
  <p>
17
21
  <label for="height">Height</label>
18
22
  <select id="height">
@@ -53,6 +57,10 @@
53
57
  <label for="like_salami">I like salami</label>
54
58
  <input id="like_salami" type="checkbox" />
55
59
  </p>
60
+ <p>
61
+ <label for="message">Message</label>
62
+ <input id="message" type="text" value="Your message goes here" />
63
+ </p>
56
64
  <p><input type="submit" value="Submit" /></p>
57
65
  </form>
58
66
  </div>
@@ -68,16 +76,18 @@
68
76
  <form action="/thanks" method="get">
69
77
  <table>
70
78
  <tr>
71
- <td><label for="check_a">Apple</label></td>
72
- <td><input id="check_a" type="checkbox"/></td>
73
- </tr>
74
- <tr>
75
- <td><label for="check_b">Banana</label></td>
76
- <td><input id="check_b" type="checkbox"/></td>
79
+ <th>Apple</th>
80
+ <td>
81
+ <label for="like_apple">Like</label>
82
+ <input id="like_apple" type="checkbox" checked="checked"/>
83
+ </td>
77
84
  </tr>
78
85
  <tr>
79
- <td><label for="check_c">Carrot</label></td>
80
- <td><input id="check_c" type="checkbox"/></td>
86
+ <th>Banana</th>
87
+ <td>
88
+ <label for="like_banana">Like</label>
89
+ <input id="like_banana" type="checkbox"/>
90
+ </td>
81
91
  </tr>
82
92
  </table>
83
93
  </form>
@@ -3,12 +3,38 @@ Feature: Kelp Step Definitions
3
3
  As a Kelp developer
4
4
  I want to be sure the step definitions Kelp provides work correctly
5
5
 
6
- Scenario: Regression test
7
- Given a sinatra application with the latest Kelp step definitions
8
- When I run "cucumber features -q --no-color" in the sinatra app
6
+ Background:
7
+ Given the latest Kelp step definitions
8
+
9
+ Scenario: Checkbox test
10
+ When I run cucumber on "checkbox.feature"
11
+ Then the results should be:
12
+ """
13
+ 2 scenarios (2 passed)
14
+ 6 steps (6 passed)
15
+ """
16
+
17
+ Scenario: Dropdown test
18
+ When I run cucumber on "dropdown.feature"
19
+ Then the results should be:
20
+ """
21
+ 3 scenarios (3 passed)
22
+ 11 steps (11 passed)
23
+ """
24
+
25
+ Scenario: Field test
26
+ When I run cucumber on "field.feature"
27
+ Then the results should be:
28
+ """
29
+ 2 scenarios (2 passed)
30
+ 7 steps (7 passed)
31
+ """
32
+
33
+ Scenario: Visibility test
34
+ When I run cucumber on "visibility.feature"
9
35
  Then the results should be:
10
36
  """
11
- 5 scenarios (5 passed)
12
- 18 steps (18 passed)
37
+ 3 scenarios (3 passed)
38
+ 11 steps (11 passed)
13
39
  """
14
40
 
@@ -2,8 +2,8 @@
2
2
 
3
3
  require 'fileutils'
4
4
 
5
- Given /^a (\w+) application with the latest Kelp step definitions$/ do |platform|
6
- app_dir = File.join(root_dir, 'examples', "#{platform}_app")
5
+ Given /^the latest Kelp step definitions$/ do
6
+ app_dir = File.join(root_dir, 'examples', "sinatra_app")
7
7
  installed_steps = File.join(app_dir, 'features', 'step_definitions', 'kelp_steps.rb')
8
8
  latest_steps = File.join(root_dir, 'rails_generators', 'kelp', 'templates', 'kelp_steps.rb')
9
9
  # Remove the installed kelp_steps.rb, if any, then install the latest one
@@ -12,15 +12,23 @@ Given /^a (\w+) application with the latest Kelp step definitions$/ do |platform
12
12
  FileUtils.cp_r(latest_steps, installed_steps)
13
13
  end
14
14
 
15
- When /^I run "(.+)" in the (\w+) app$/ do |command, platform|
16
- command.gsub!('cucumber', "#{Cucumber::RUBY_BINARY} #{Cucumber::BINARY}")
17
- app_dir = File.join(root_dir, 'examples', "#{platform}_app")
15
+
16
+ When /^I run cucumber on "(.+)"$/ do |feature|
17
+ cucumber = "#{Cucumber::RUBY_BINARY} #{Cucumber::BINARY}"
18
+ opts = "-q --no-color"
19
+ command = "#{cucumber} #{opts} features/#{feature}"
20
+ app_dir = File.join(root_dir, 'examples', "sinatra_app")
18
21
  Dir.chdir(app_dir) do
19
22
  @output = `#{command}`
20
23
  end
21
24
  end
22
25
 
26
+
23
27
  Then /^the results should be:$/ do |expected_results|
24
- @output.should include(expected_results)
28
+ if !@output.include?(expected_results)
29
+ got = @output.collect {|line| " #{line}"}.join
30
+ want = expected_results.collect {|line| " #{line}"}.join
31
+ raise("Expected:\n#{want}\nGot:\n#{got}")
32
+ end
25
33
  end
26
34
 
data/kelp.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "kelp"
5
- s.version = "0.1.5"
5
+ s.version = "0.1.6"
6
6
  s.summary = "Cucumber helper methods"
7
7
  s.description = <<-EOS
8
8
  Kelp is a collection of helper methods for Cucumber to ease the process of
data/lib/kelp/field.rb CHANGED
@@ -57,12 +57,12 @@ module Kelp
57
57
 
58
58
 
59
59
  # Verify that the given field is empty or nil.
60
- def field_should_be_empty(field)
61
- _field = nice_find_field(field)
62
- if _field.nil? || _field.value.nil?
63
- return true
64
- else
65
- raise RuntimeError, "Expected field '#{field}' to be empty, but value is '#{_field.value}'"
60
+ def field_should_be_empty(field, scope={})
61
+ in_scope(scope) do
62
+ _field = nice_find_field(field)
63
+ if !(_field.nil? || _field.value.nil? || _field.value == '')
64
+ raise RuntimeError, "Expected field '#{field}' to be empty, but value is '#{_field.value}'"
65
+ end
66
66
  end
67
67
  end
68
68
 
data/lib/kelp/scoping.rb CHANGED
@@ -3,9 +3,9 @@ module Kelp
3
3
  # verifications on a webpage.
4
4
  #
5
5
  module Scoping
6
- # Execute a block of code within a given scope.
7
- # `locator` may be in css or xpath form, depending on what type
8
- # is set in Capybara.default_locator.
6
+ # Execute a block of code within a given scope. If `locator` begins with
7
+ # `/` or `./`, then it's assumed to be an XPath selector; otherwise, it's
8
+ # assumed to be a CSS selector.
9
9
  def scope_within(locator)
10
10
  if locator
11
11
  # Use the selector_for method if it's defined
@@ -15,7 +15,11 @@ module Kelp
15
15
  # and fall back on the Capybara locator syntax (CSS or XPath)
16
16
  else
17
17
  locator.gsub!(/^"(.*?)"$/, '\1')
18
- within(locator) { yield }
18
+ if locator =~ /\.?\//
19
+ within(:xpath, locator) { yield }
20
+ else
21
+ within(:css, locator) { yield }
22
+ end
19
23
  end
20
24
  else
21
25
  yield
@@ -14,11 +14,30 @@
14
14
  #
15
15
 
16
16
  require 'kelp'
17
- World(Kelp::Visibility)
17
+ World(Kelp::Attribute)
18
+ World(Kelp::Checkbox)
18
19
  World(Kelp::Dropdown)
20
+ World(Kelp::Field)
21
+ World(Kelp::Navigation)
22
+ World(Kelp::Scoping)
23
+ World(Kelp::Visibility)
24
+
25
+ module KelpStepHelper
26
+ # Convert a Cucumber::Ast::Table or multiline string into
27
+ # a list of strings
28
+ def listify(items)
29
+ if items.class == Cucumber::Ast::Table
30
+ strings = items.raw.flatten
31
+ else
32
+ strings = items.split(/[\r\n]+/)
33
+ end
34
+ end
35
+ end
36
+ World(KelpStepHelper)
19
37
 
20
38
  SHOULD_OR_NOT = /(should|should not)/
21
39
  WITHIN = /(?: within "([^\"]+)")?/
40
+ ELEMENT = /(?:field|checkbox|dropdown|button)/
22
41
  STR = /([^\"]+)/
23
42
 
24
43
  # Verify the presence or absence of multiple text strings in the page,
@@ -30,23 +49,19 @@ STR = /([^\"]+)/
30
49
  # `items` may be a Cucumber table, or a multi-line string. Examples:
31
50
  #
32
51
  # Then I should see the following:
33
- # | First thing |
34
- # | Next thing |
35
- # | Last thing |
52
+ # | Apple crumble |
53
+ # | Banana cream pie |
54
+ # | Cherry tart |
36
55
  #
37
56
  # Then I should see the following:
38
57
  # """
39
- # First thing
40
- # Next thing
41
- # Last thing
58
+ # Bacon & Eggs
59
+ # Biscuits & Gravy
60
+ # Hash Browns
42
61
  # """
43
62
  #
44
63
  Then /^I #{SHOULD_OR_NOT} see the following#{WITHIN}:$/ do |expect, selector, items|
45
- if items.class == Cucumber::Ast::Table
46
- strings = items.raw.flatten
47
- else
48
- strings = items.split("\n")
49
- end
64
+ strings = listify(items)
50
65
  if expect == 'should'
51
66
  should_see strings, :within => selector
52
67
  else
@@ -58,6 +73,15 @@ end
58
73
  # Verify that one or more table rows containing the correct values exist (or do
59
74
  # not exist). Rows do not need to match exactly, and fields do not need to be
60
75
  # in the same order.
76
+ #
77
+ # Examples:
78
+ #
79
+ # Then I should see table rows containing:
80
+ # | Eric | Edit |
81
+ # | John | Edit |
82
+ # And I should not see a table row containing:
83
+ # | Eric | Delete |
84
+ #
61
85
  Then /^I #{SHOULD_OR_NOT} see (?:a table row|table rows)#{WITHIN} containing:$/ do |expect, selector, rows|
62
86
  rows.raw.each do |fields|
63
87
  if expect == 'should'
@@ -72,12 +96,22 @@ end
72
96
  # Verify that a dropdown has a given value selected. This verifies the visible
73
97
  # value shown to the user, rather than the value attribute of the selected
74
98
  # option element.
99
+ #
100
+ # Examples:
101
+ #
102
+ # Then the "Height" dropdown should equal "Average"
103
+ #
75
104
  Then /^the "#{STR}" dropdown#{WITHIN} should equal "#{STR}"$/ do |dropdown, selector, value|
76
105
  dropdown_should_equal(dropdown, value, :within => selector)
77
106
  end
78
107
 
79
108
 
80
109
  # Verify that a dropdown includes or doesn't include the given value.
110
+ #
111
+ # Examples:
112
+ #
113
+ # Then the "Height" dropdown should include "Tall"
114
+ #
81
115
  Then /^the "#{STR}" dropdown#{WITHIN} #{SHOULD_OR_NOT} include "#{STR}"$/ do |dropdown, selector, expect, value|
82
116
  if expect == 'should'
83
117
  dropdown_should_include(dropdown, value, :within => selector)
@@ -87,9 +121,25 @@ Then /^the "#{STR}" dropdown#{WITHIN} #{SHOULD_OR_NOT} include "#{STR}"$/ do |dr
87
121
  end
88
122
 
89
123
 
90
- # Verify that a dropdown includes or doesn't include all values in the given table.
124
+ # Verify that a dropdown includes or doesn't include all values in the given
125
+ # table or multiline string.
126
+ #
127
+ # Examples:
128
+ #
129
+ # Then the "Height" dropdown should include:
130
+ # | Short |
131
+ # | Average |
132
+ # | Tall |
133
+ #
134
+ # Then the "Favorite Colors" dropdown should include:
135
+ # """
136
+ # Red
137
+ # Green
138
+ # Blue
139
+ # """
140
+ #
91
141
  Then /^the "#{STR}" dropdown#{WITHIN} #{SHOULD_OR_NOT} include:$/ do |dropdown, selector, expect, values|
92
- values.raw.flatten.each do |value|
142
+ listify(values).each do |value|
93
143
  if expect == 'should'
94
144
  dropdown_should_include(dropdown, value, :within => selector)
95
145
  else
@@ -99,30 +149,73 @@ Then /^the "#{STR}" dropdown#{WITHIN} #{SHOULD_OR_NOT} include:$/ do |dropdown,
99
149
  end
100
150
 
101
151
 
102
- # Verify that a given field is empty or nil
152
+ # Verify that a given field is empty or nil.
153
+ #
154
+ # Examples:
155
+ #
156
+ # Then the "First name" field should be empty
157
+ #
103
158
  Then /^the "#{STR}" field#{WITHIN} should be empty$/ do |field, selector|
104
- with_scope(selector) do
105
- field_should_be_empty field
106
- end
159
+ field_should_be_empty(field, :within => selector)
107
160
  end
108
161
 
109
162
 
110
163
  # Verify multiple fields in a form, optionally restricted to a given selector.
111
- # Fields may be text inputs or dropdowns
164
+ # Fields may be text inputs or dropdowns.
165
+ #
166
+ # Examples:
167
+ #
168
+ # Then the fields should contain:
169
+ # | First name | Eric |
170
+ # | Last name | Pierce |
171
+ #
112
172
  Then /^the fields#{WITHIN} should contain:$/ do |selector, fields|
113
173
  fields_should_contain_within(selector, fields.rows_hash)
114
174
  end
115
175
 
116
176
 
117
177
  # Verify that expected text exists or does not exist in the same row as
118
- # identifier text. This can be used to ensure the presence or absence of "Edit"
178
+ # some text. This can be used to ensure the presence or absence of "Edit"
119
179
  # or "Delete" links, or specific data associated with a row in a table.
120
- Then /^I #{SHOULD_OR_NOT} see "#{STR}" next to "#{STR}"#{WITHIN}$/ do |expect, expected, identifier, selector|
121
- with_scope(selector) do
180
+ #
181
+ # Examples:
182
+ #
183
+ # Then I should see "Edit" next to "John"
184
+ # And I should not see "Delete" next to "John"
185
+ #
186
+ Then /^I #{SHOULD_OR_NOT} see "#{STR}" next to "#{STR}"#{WITHIN}$/ do |expect, text, next_to, selector|
187
+ if expect == 'should'
188
+ should_see_in_same_row([text, next_to], :within => selector)
189
+ else
190
+ should_not_see_in_same_row([text, next_to], :within => selector)
191
+ end
192
+ end
193
+
194
+
195
+ # Verify that several expected text strings exist or do not exist in the same
196
+ # row as some text. Prevents multiple "should see X next to Y" calls. Similar
197
+ # to "should see a row containing", but targeted toward a specific row.
198
+ #
199
+ # Examples:
200
+ #
201
+ # Then I should see the following next to "Terry":
202
+ # | Copy |
203
+ # | Edit |
204
+ # | Delete |
205
+ #
206
+ # Then I should see the following next to "John":
207
+ # """
208
+ # Copy
209
+ # Edit
210
+ # Delete
211
+ # """
212
+ #
213
+ Then /^I #{SHOULD_OR_NOT} see the following next to "#{STR}"#{WITHIN}:$/ do |expect, next_to, selector, items|
214
+ listify(items).each do |text|
122
215
  if expect == 'should'
123
- should_see_in_same_row [expected, identifier]
216
+ should_see_in_same_row([text, next_to], :within => selector)
124
217
  else
125
- should_not_see_in_same_row [expected, identifier]
218
+ should_not_see_in_same_row([text, next_to], :within => selector)
126
219
  end
127
220
  end
128
221
  end
@@ -130,19 +223,34 @@ end
130
223
 
131
224
  # Click a link in a table row that contains the given text.
132
225
  # This can be used to click the "Edit" link for a specific record.
133
- When /^I follow "#{STR}" next to "#{STR}"$/ do |link, identifier|
134
- click_link_in_row(link, identifier)
226
+ #
227
+ # Examples:
228
+ #
229
+ # When I follow "Edit" next to "John"
230
+ #
231
+ When /^I follow "#{STR}" next to "#{STR}"$/ do |link, next_to|
232
+ click_link_in_row(link, next_to)
135
233
  end
136
234
 
137
235
 
138
- # Verify that a checkbox in a certain table row is checked or unchecked
139
- Then /^the "#{STR}" checkbox next to "#{STR}"#{WITHIN} should be (checked|unchecked)$/ do |checkbox, text, selector, state|
140
- within(:xpath, xpath_row_containing(text)) do
141
- if state == 'checked'
142
- checkbox_should_be_checked(checkbox, text, :within => selector)
236
+ # Verify that a checkbox in a certain table row is checked or unchecked.
237
+ # "should not be checked" and "should be unchecked" are equivalent, and
238
+ # "should be checked" and "should not be unchecked" are equivalent.
239
+ #
240
+ # Examples:
241
+ #
242
+ # Then the "Like" checkbox next to "Apple" should be checked
243
+ # And the "Like" checkbox next to "Banana" should be unchecked
244
+ #
245
+ Then /^the "#{STR}" checkbox next to "#{STR}"#{WITHIN} #{SHOULD_OR_NOT} be (checked|unchecked)$/ do |checkbox, next_to, selector, expect, state|
246
+
247
+ within(:xpath, xpath_row_containing(next_to)) do
248
+ if (expect == 'should' && state == 'checked') || (expect == 'should not' && state == 'unchecked')
249
+ checkbox_should_be_checked(checkbox, :within => selector)
143
250
  else
144
- checkbox_should_not_be_checked(checkbox, text, :within => selector)
251
+ checkbox_should_not_be_checked(checkbox, :within => selector)
145
252
  end
146
253
  end
147
254
  end
148
255
 
256
+
data/spec/field_spec.rb CHANGED
@@ -10,6 +10,7 @@ describe Kelp::Field, "field_should_be_empty" do
10
10
  it "is empty" do
11
11
  field_should_be_empty "first_name"
12
12
  field_should_be_empty "last_name"
13
+ field_should_be_empty "biography"
13
14
  end
14
15
  end
15
16
 
@@ -17,6 +18,7 @@ describe Kelp::Field, "field_should_be_empty" do
17
18
  it "is empty" do
18
19
  field_should_be_empty "First name"
19
20
  field_should_be_empty "Last name"
21
+ field_should_be_empty "Life story"
20
22
  end
21
23
  end
22
24
  end
@@ -19,9 +19,13 @@ describe Kelp::Visibility, "should_see" do
19
19
  ]
20
20
  end
21
21
 
22
- it "is within the scope" do
22
+ it "is within a CSS scope" do
23
23
  should_see "Hello world", :within => "#greeting"
24
24
  end
25
+
26
+ it "is within an XPath scope" do
27
+ should_see "Hello world", :within => "//div[@id='greeting']"
28
+ end
25
29
  end
26
30
 
27
31
  context "Regexp" do
@@ -29,10 +33,15 @@ describe Kelp::Visibility, "should_see" do
29
33
  should_see /(Hello|Goodbye) world/
30
34
  end
31
35
 
32
- it "matches within the scope" do
36
+ it "matches within a CSS scope" do
33
37
  should_see /(Hello|Goodbye) world/, :within => "#greeting"
34
38
  should_see /(Hello|Goodbye) world/, :within => "#farewell"
35
39
  end
40
+
41
+ it "matches within an XPath scope" do
42
+ should_see /(Hello|Goodbye) world/, :within => "//div[@id='greeting']"
43
+ should_see /(Hello|Goodbye) world/, :within => "//div[@id='farewell']"
44
+ end
36
45
  end
37
46
  end
38
47
 
@@ -54,11 +63,23 @@ describe Kelp::Visibility, "should_see" do
54
63
  end.should raise_error(RSpec::Expectations::ExpectationNotMetError)
55
64
  end
56
65
 
57
- it "is not within the scope" do
66
+ it "is not within a given CSS scope" do
58
67
  lambda do
59
68
  should_see "Goodbye world", :within => "#greeting"
60
69
  end.should raise_error(RSpec::Expectations::ExpectationNotMetError)
61
70
  end
71
+
72
+ it "is not within a given XPath scope" do
73
+ lambda do
74
+ should_see "Goodbye world", :within => "//div[@id='greeting']"
75
+ end.should raise_error(RSpec::Expectations::ExpectationNotMetError)
76
+ end
77
+
78
+ it "is given a nonexistent XPath scope" do
79
+ lambda do
80
+ should_see "Goodbye world", :within => "//div[@id='nonexistent']"
81
+ end.should raise_error(Capybara::ElementNotFound)
82
+ end
62
83
  end
63
84
 
64
85
  context "Regexp" do
@@ -97,9 +118,13 @@ describe Kelp::Visibility, "should_not_see" do
97
118
  ]
98
119
  end
99
120
 
100
- it "exists but is not within the scope" do
121
+ it "exists but is not within the given CSS scope" do
101
122
  should_not_see "Goodbye world", :within => "#greeting"
102
123
  end
124
+
125
+ it "exists but is not within the given XPath scope" do
126
+ should_not_see "Goodbye world", :within => "//div[@id='greeting']"
127
+ end
103
128
  end
104
129
 
105
130
  context "Regexp" do
@@ -139,11 +164,17 @@ describe Kelp::Visibility, "should_not_see" do
139
164
  end.should raise_error(RSpec::Expectations::ExpectationNotMetError)
140
165
  end
141
166
 
142
- it "exists within the scope" do
167
+ it "exists within the given CSS scope" do
143
168
  lambda do
144
169
  should_not_see "Hello world", :within => "#greeting"
145
170
  end.should raise_error(RSpec::Expectations::ExpectationNotMetError)
146
171
  end
172
+
173
+ it "exists within the given XPath scope" do
174
+ lambda do
175
+ should_not_see "Hello world", :within => "//div[@id='greeting']"
176
+ end.should raise_error(RSpec::Expectations::ExpectationNotMetError)
177
+ end
147
178
  end
148
179
 
149
180
  context "Regexp" do
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kelp
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 23
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 5
10
- version: 0.1.5
9
+ - 6
10
+ version: 0.1.6
11
11
  platform: ruby
12
12
  authors:
13
13
  - Eric Pierce
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-04-15 00:00:00 -06:00
18
+ date: 2011-04-20 00:00:00 -06:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -139,7 +139,9 @@ files:
139
139
  - Rakefile
140
140
  - examples/sinatra_app/app.rb
141
141
  - examples/sinatra_app/config.ru
142
+ - examples/sinatra_app/features/checkbox.feature
142
143
  - examples/sinatra_app/features/dropdown.feature
144
+ - examples/sinatra_app/features/field.feature
143
145
  - examples/sinatra_app/features/support/env.rb
144
146
  - examples/sinatra_app/features/visibility.feature
145
147
  - examples/sinatra_app/features/web_steps.rb