kelp 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
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