kelp 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/History.md +8 -0
- data/examples/sinatra_app/features/checkbox.feature +10 -1
- data/examples/sinatra_app/features/checkbox_fail.feature +1 -1
- data/examples/sinatra_app/features/dropdown.feature +4 -1
- data/examples/sinatra_app/features/dropdown_fail.feature +1 -1
- data/examples/sinatra_app/features/field.feature +11 -1
- data/examples/sinatra_app/features/field_fail.feature +6 -1
- data/examples/sinatra_app/features/navigation.feature +38 -0
- data/examples/sinatra_app/features/navigation_fail.feature +26 -0
- data/examples/sinatra_app/features/visibility.feature +3 -3
- data/examples/sinatra_app/features/visibility_fail.feature +1 -1
- data/features/kelp_step_definitions.feature +47 -8
- data/kelp.gemspec +1 -1
- data/lib/kelp/checkbox.rb +0 -1
- data/lib/kelp/dropdown.rb +1 -1
- data/lib/kelp/exceptions.rb +4 -0
- data/lib/kelp/field.rb +51 -23
- data/lib/kelp/navigation.rb +34 -4
- data/lib/kelp/scoping.rb +15 -3
- data/rails_generators/kelp/templates/web_steps.rb +7 -6
- data/spec/field_spec.rb +52 -0
- data/spec/navigation_spec.rb +5 -5
- data/spec/visibility_spec.rb +1 -1
- metadata +6 -5
- data/examples/sinatra_app/features/web_steps.rb +0 -4
data/Gemfile.lock
CHANGED
data/History.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Feature: Checkboxes
|
2
2
|
|
3
3
|
Background:
|
4
|
-
Given I
|
4
|
+
Given I am on "/form"
|
5
5
|
|
6
6
|
Scenario: Checkbox should be checked
|
7
7
|
Then the "Like" checkbox next to "Apple" should be checked
|
@@ -10,3 +10,12 @@ Feature: Checkboxes
|
|
10
10
|
Scenario: Checkbox should not be checked
|
11
11
|
Then the "Like" checkbox next to "Banana" should be unchecked
|
12
12
|
And the "Like" checkbox next to "Banana" should not be checked
|
13
|
+
|
14
|
+
Scenario: Check a checkbox
|
15
|
+
When I check "I like salami"
|
16
|
+
Then the "I like salami" checkbox should be checked
|
17
|
+
|
18
|
+
Scenario: Uncheck a checkbox
|
19
|
+
When I uncheck "I like cheese"
|
20
|
+
Then the "I like cheese" checkbox should be unchecked
|
21
|
+
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Feature: Dropdowns
|
2
2
|
|
3
3
|
Background:
|
4
|
-
Given I
|
4
|
+
Given I am on "/form"
|
5
5
|
|
6
6
|
Scenario: Dropdown should equal
|
7
7
|
Then the "Height" dropdown should equal "Average"
|
@@ -30,4 +30,7 @@ Feature: Dropdowns
|
|
30
30
|
| Dwarf |
|
31
31
|
| Behemoth |
|
32
32
|
|
33
|
+
Scenario: Select a value from a dropdown
|
34
|
+
When I select "Tall" from "Height"
|
35
|
+
Then the "Height" dropdown should equal "Tall"
|
33
36
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Feature: Fields
|
2
2
|
|
3
3
|
Background:
|
4
|
-
Given I
|
4
|
+
Given I am on "/form"
|
5
5
|
|
6
6
|
|
7
7
|
Scenario: Field should be empty
|
@@ -20,6 +20,16 @@ Feature: Fields
|
|
20
20
|
| Message | Your message goes here |
|
21
21
|
|
22
22
|
|
23
|
+
Scenario: Field should contain
|
24
|
+
Then the "First name" field should contain ""
|
25
|
+
And the "Message" field should contain "Your message goes here"
|
26
|
+
|
27
|
+
|
28
|
+
Scenario: Field should not contain
|
29
|
+
When I fill in "First name" with "Adam"
|
30
|
+
Then the "First name" field should not contain "Jamie"
|
31
|
+
|
32
|
+
|
23
33
|
Scenario: Fill in single fields by label
|
24
34
|
When I fill in "First name" with "Adam"
|
25
35
|
And I fill in "Savage" for "Last name"
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Feature: Field failure test
|
2
2
|
|
3
3
|
Background:
|
4
|
-
Given I
|
4
|
+
Given I am on "/form"
|
5
5
|
|
6
6
|
|
7
7
|
Scenario: Field should be empty (FAIL)
|
@@ -19,6 +19,11 @@ Feature: Field failure test
|
|
19
19
|
Then the "First name" field should contain "Alexy"
|
20
20
|
|
21
21
|
|
22
|
+
Scenario: Field should not contain (FAIL)
|
23
|
+
When I fill in "First name" with "Ivan"
|
24
|
+
Then the "First name" field should not contain "Ivan"
|
25
|
+
|
26
|
+
|
22
27
|
Scenario: Fill in a single field (FAIL)
|
23
28
|
When I fill in "Middle name" with "Fyodorovitch"
|
24
29
|
|
@@ -0,0 +1,38 @@
|
|
1
|
+
Feature: Navigation
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given I am on "/home"
|
5
|
+
|
6
|
+
|
7
|
+
Scenario: Go to page, should be on page
|
8
|
+
When I go to "/form"
|
9
|
+
Then I should be on "/form"
|
10
|
+
|
11
|
+
|
12
|
+
Scenario: Follow a link
|
13
|
+
When I follow "About Us"
|
14
|
+
Then I should be on "/about"
|
15
|
+
|
16
|
+
|
17
|
+
Scenario: Follow a link within a scope
|
18
|
+
When I follow "About Us" within "#links"
|
19
|
+
Then I should be on "/about"
|
20
|
+
|
21
|
+
|
22
|
+
Scenario: Follow a link next to something else
|
23
|
+
When I follow "Edit" next to "Eric"
|
24
|
+
Then I should be on "/edit1"
|
25
|
+
|
26
|
+
|
27
|
+
Scenario: Press a button
|
28
|
+
When I go to "/form"
|
29
|
+
And I press "Submit person form"
|
30
|
+
Then I should be on "/thanks"
|
31
|
+
|
32
|
+
|
33
|
+
Scenario: Press a button within a scope
|
34
|
+
When I am on "/form"
|
35
|
+
And I press "Save preferences" within "#preferences_form"
|
36
|
+
Then I should be on "/thanks"
|
37
|
+
|
38
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
Feature: Navigation failures
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given I am on "/home"
|
5
|
+
|
6
|
+
|
7
|
+
Scenario: Should be on page (FAIL)
|
8
|
+
When I go to "/form"
|
9
|
+
Then I should be on "home"
|
10
|
+
|
11
|
+
|
12
|
+
Scenario: Follow a link (FAIL)
|
13
|
+
When I follow "Bogus link"
|
14
|
+
|
15
|
+
|
16
|
+
Scenario: Follow a bad link next to existing text (FAIL)
|
17
|
+
When I follow "555" next to "Eric"
|
18
|
+
|
19
|
+
|
20
|
+
Scenario: Follow a link next to nonexistent text (FAIL)
|
21
|
+
When I follow "Edit" next to "Ramses"
|
22
|
+
|
23
|
+
|
24
|
+
Scenario: Press a button (FAIL)
|
25
|
+
When I press "Big red button"
|
26
|
+
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Feature: Visibility
|
2
2
|
|
3
3
|
Background:
|
4
|
-
Given I
|
4
|
+
Given I am on "/home"
|
5
5
|
|
6
6
|
|
7
7
|
Scenario: Should or shouldn't see text
|
@@ -122,13 +122,13 @@ Feature: Visibility
|
|
122
122
|
|
123
123
|
|
124
124
|
Scenario: Should or shouldn't see button
|
125
|
-
When I
|
125
|
+
When I go to "/form"
|
126
126
|
Then I should see a "Submit person form" button
|
127
127
|
But I should not see a "Submit animal form" button
|
128
128
|
|
129
129
|
|
130
130
|
Scenario: Should or shouldn't see button within a scope
|
131
|
-
When I
|
131
|
+
When I go to "/form"
|
132
132
|
Then I should see a "Submit person form" button within "#person_form"
|
133
133
|
But I should not see a "Submit person form" button within "#preferences_form"
|
134
134
|
|
@@ -10,8 +10,8 @@ Feature: Kelp Step Definitions
|
|
10
10
|
When I run cucumber on "checkbox.feature"
|
11
11
|
Then the results should include:
|
12
12
|
"""
|
13
|
-
|
14
|
-
|
13
|
+
4 scenarios (4 passed)
|
14
|
+
12 steps (12 passed)
|
15
15
|
"""
|
16
16
|
|
17
17
|
Scenario: Checkbox failure test
|
@@ -32,8 +32,8 @@ Feature: Kelp Step Definitions
|
|
32
32
|
When I run cucumber on "dropdown.feature"
|
33
33
|
Then the results should include:
|
34
34
|
"""
|
35
|
-
|
36
|
-
|
35
|
+
4 scenarios (4 passed)
|
36
|
+
14 steps (14 passed)
|
37
37
|
"""
|
38
38
|
|
39
39
|
Scenario: Dropdown failure test
|
@@ -59,14 +59,17 @@ Feature: Kelp Step Definitions
|
|
59
59
|
Scenario: Dropdown should not include multiple values (FAIL)
|
60
60
|
Expected 'Height' dropdown to not include: ["Tiny", "Average", "Tall", "Enormous"]
|
61
61
|
Did include: ["Average", "Tall"] (Kelp::Unexpected)
|
62
|
+
|
63
|
+
5 scenarios (5 failed)
|
64
|
+
10 steps (5 failed, 5 passed)
|
62
65
|
"""
|
63
66
|
|
64
67
|
Scenario: Field test
|
65
68
|
When I run cucumber on "field.feature"
|
66
69
|
Then the results should include:
|
67
70
|
"""
|
68
|
-
|
69
|
-
|
71
|
+
9 scenarios (9 passed)
|
72
|
+
36 steps (36 passed)
|
70
73
|
"""
|
71
74
|
|
72
75
|
Scenario: Field failure test
|
@@ -83,14 +86,18 @@ Feature: Kelp Step Definitions
|
|
83
86
|
Expected 'First name' to contain 'Alexy'
|
84
87
|
Got 'Dmitry' (Kelp::Unexpected)
|
85
88
|
|
89
|
+
Scenario: Field should not contain (FAIL)
|
90
|
+
Did not expect 'First name' to contain 'Ivan'
|
91
|
+
Got 'Ivan' (Kelp::Unexpected)
|
92
|
+
|
86
93
|
Scenario: Fill in a single field (FAIL)
|
87
94
|
No field with id, name, or label 'Middle name' found (Kelp::FieldNotFound)
|
88
95
|
|
89
96
|
Scenario: Fill in multiple fields (FAIL)
|
90
97
|
Field 'Height' has no option 'Diminutive' (Kelp::OptionNotFound)
|
91
98
|
|
92
|
-
|
93
|
-
|
99
|
+
6 scenarios (6 failed)
|
100
|
+
16 steps (6 failed, 10 passed)
|
94
101
|
"""
|
95
102
|
|
96
103
|
Scenario: Visibility test
|
@@ -141,3 +148,35 @@ Feature: Kelp Step Definitions
|
|
141
148
|
16 steps (8 failed, 8 passed)
|
142
149
|
"""
|
143
150
|
|
151
|
+
Scenario: Navigation test
|
152
|
+
When I run cucumber on "navigation.feature"
|
153
|
+
Then the results should include:
|
154
|
+
"""
|
155
|
+
6 scenarios (6 passed)
|
156
|
+
20 steps (20 passed)
|
157
|
+
"""
|
158
|
+
|
159
|
+
Scenario: Navigation failure test
|
160
|
+
When I run cucumber on "navigation_fail.feature"
|
161
|
+
Then the results should include:
|
162
|
+
"""
|
163
|
+
Scenario: Should be on page (FAIL)
|
164
|
+
Expected to be on page: 'home'
|
165
|
+
Actually on page: '/form' (Kelp::Unexpected)
|
166
|
+
|
167
|
+
Scenario: Follow a link (FAIL)
|
168
|
+
No link with title, id or text 'Bogus link' found (Kelp::MissingLink)
|
169
|
+
|
170
|
+
Scenario: Follow a bad link next to existing text (FAIL)
|
171
|
+
No link with title, id or text '555' found in the same row as 'Eric' (Kelp::MissingLink)
|
172
|
+
|
173
|
+
Scenario: Follow a link next to nonexistent text (FAIL)
|
174
|
+
No table row found containing 'Edit' and 'Ramses' (Kelp::MissingRow)
|
175
|
+
|
176
|
+
Scenario: Press a button (FAIL)
|
177
|
+
No button with value, id or text 'Big red button' found (Kelp::MissingButton)
|
178
|
+
|
179
|
+
5 scenarios (5 failed)
|
180
|
+
11 steps (5 failed, 6 passed)
|
181
|
+
"""
|
182
|
+
|
data/kelp.gemspec
CHANGED
data/lib/kelp/checkbox.rb
CHANGED
@@ -22,7 +22,6 @@ module Kelp
|
|
22
22
|
def checkbox_should_be_checked(checkbox, scope={})
|
23
23
|
in_scope(scope) do
|
24
24
|
field_checked = find_field(checkbox)['checked']
|
25
|
-
puts field_checked.inspect
|
26
25
|
if !field_checked
|
27
26
|
raise Kelp::Unexpected,
|
28
27
|
"Expected '#{checkbox}' to be checked, but it is unchecked."
|
data/lib/kelp/dropdown.rb
CHANGED
@@ -35,7 +35,7 @@ module Kelp
|
|
35
35
|
rescue Capybara::ElementNotFound
|
36
36
|
# FIXME: Find a way to support multiple-selection dropdowns
|
37
37
|
if field.value.class == Array
|
38
|
-
raise
|
38
|
+
raise NotImplementedError, "Multiple-selection dropdowns are not supported"
|
39
39
|
end
|
40
40
|
field_value = xpath_sanitize(field.value)
|
41
41
|
selected = field.find(:xpath, ".//option[@value=#{field_value}]")
|
data/lib/kelp/exceptions.rb
CHANGED
@@ -3,5 +3,9 @@ module Kelp
|
|
3
3
|
class Unexpected < KelpError; end
|
4
4
|
class FieldNotFound < KelpError; end
|
5
5
|
class OptionNotFound < KelpError; end
|
6
|
+
class MissingLink < KelpError; end
|
7
|
+
class MissingButton < KelpError; end
|
8
|
+
class MissingRow < KelpError; end
|
9
|
+
class InvalidScope < KelpError; end
|
6
10
|
end
|
7
11
|
|
data/lib/kelp/field.rb
CHANGED
@@ -31,7 +31,7 @@ module Kelp
|
|
31
31
|
begin
|
32
32
|
select(value, :from => field)
|
33
33
|
rescue Capybara::ElementNotFound => err
|
34
|
-
# The select method may raise ElementNotFound in two cases:
|
34
|
+
# The `select` method may raise ElementNotFound in two cases:
|
35
35
|
# (1) The given field does not exist, in which case try a text field
|
36
36
|
if err.message =~ /no select box with id, name, or label/
|
37
37
|
begin
|
@@ -178,6 +178,28 @@ module Kelp
|
|
178
178
|
end
|
179
179
|
|
180
180
|
|
181
|
+
# Return the string value found in the given field.
|
182
|
+
# If the field is `nil`, return the empty string.
|
183
|
+
#
|
184
|
+
# @param [String] field
|
185
|
+
# Capybara locator for the field (name, id, or label text)
|
186
|
+
#
|
187
|
+
# @return [String]
|
188
|
+
# The value found in the given field
|
189
|
+
#
|
190
|
+
# @since 0.2.1
|
191
|
+
#
|
192
|
+
def field_value(field)
|
193
|
+
element = find_field(field)
|
194
|
+
value = (element.tag_name == 'textarea') ? element.text : element.value
|
195
|
+
# If field value is an Array, take the first item
|
196
|
+
if value.class == Array
|
197
|
+
value = value.first
|
198
|
+
end
|
199
|
+
return value.to_s
|
200
|
+
end
|
201
|
+
|
202
|
+
|
181
203
|
# Verify that the given field contains the given value.
|
182
204
|
#
|
183
205
|
# @param [String] field
|
@@ -192,37 +214,43 @@ module Kelp
|
|
192
214
|
#
|
193
215
|
def field_should_contain(field, value, scope={})
|
194
216
|
in_scope(scope) do
|
195
|
-
|
196
|
-
# (text, single-select, multi-select)
|
197
|
-
element = find_field(field)
|
198
|
-
field_value = (element.tag_name == 'textarea') ? element.text : element.value
|
199
|
-
# If field value is an Array, take the first item
|
200
|
-
if field_value.class == Array
|
201
|
-
field_value = field_value.first
|
202
|
-
end
|
217
|
+
actual = field_value(field)
|
203
218
|
# Escape any problematic characters in the expected value
|
204
|
-
|
219
|
+
expect = Regexp.escape(value)
|
205
220
|
# Match actual to expected
|
206
|
-
if !(
|
221
|
+
if !(actual =~ /#{expect}/)
|
207
222
|
raise Kelp::Unexpected,
|
208
|
-
"Expected '#{field}' to contain '#{
|
209
|
-
"\nGot '#{
|
223
|
+
"Expected '#{field}' to contain '#{expect}'" + \
|
224
|
+
"\nGot '#{actual}'"
|
210
225
|
end
|
211
226
|
end
|
212
227
|
end
|
213
228
|
|
214
229
|
|
230
|
+
# Verify that the given field does not contain the given value.
|
231
|
+
#
|
232
|
+
# @param [String] field
|
233
|
+
# Capybara locator for the field (name, id, or label text)
|
234
|
+
# @param [String] value
|
235
|
+
# Value you expect to not see in the text field
|
236
|
+
# @param [Hash] scope
|
237
|
+
# Scoping keywords as understood by {#in_scope}
|
238
|
+
#
|
239
|
+
# @raise [Kelp::Unexpected]
|
240
|
+
# If the given field contains `value`
|
241
|
+
#
|
215
242
|
def field_should_not_contain(field, value, scope={})
|
216
|
-
|
217
|
-
|
218
|
-
#
|
219
|
-
|
220
|
-
#
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
243
|
+
in_scope(scope) do
|
244
|
+
actual = field_value(field)
|
245
|
+
# Escape any problematic characters in the expected value
|
246
|
+
expect_not = Regexp.escape(value)
|
247
|
+
# Match actual to expected
|
248
|
+
if (actual =~ /#{expect_not}/)
|
249
|
+
raise Kelp::Unexpected,
|
250
|
+
"Did not expect '#{field}' to contain '#{expect_not}'" + \
|
251
|
+
"\nGot '#{actual}'"
|
252
|
+
end
|
253
|
+
end
|
226
254
|
end
|
227
255
|
|
228
256
|
|
data/lib/kelp/navigation.rb
CHANGED
@@ -2,6 +2,7 @@ require 'uri'
|
|
2
2
|
require 'cgi'
|
3
3
|
require 'kelp/scoping'
|
4
4
|
require 'kelp/xpath'
|
5
|
+
require 'kelp/exceptions'
|
5
6
|
|
6
7
|
module Kelp
|
7
8
|
# This module defines helper methods for navigating a webpage, including
|
@@ -25,7 +26,12 @@ module Kelp
|
|
25
26
|
#
|
26
27
|
def follow(link, scope={})
|
27
28
|
in_scope(scope) do
|
28
|
-
|
29
|
+
begin
|
30
|
+
click_link(link)
|
31
|
+
rescue Capybara::ElementNotFound
|
32
|
+
raise Kelp::MissingLink,
|
33
|
+
"No link with title, id or text '#{link}' found"
|
34
|
+
end
|
29
35
|
end
|
30
36
|
end
|
31
37
|
|
@@ -42,7 +48,12 @@ module Kelp
|
|
42
48
|
#
|
43
49
|
def press(button, scope={})
|
44
50
|
in_scope(scope) do
|
45
|
-
|
51
|
+
begin
|
52
|
+
click_button(button)
|
53
|
+
rescue Capybara::ElementNotFound
|
54
|
+
raise Kelp::MissingButton,
|
55
|
+
"No button with value, id or text '#{button}' found"
|
56
|
+
end
|
46
57
|
end
|
47
58
|
end
|
48
59
|
|
@@ -58,8 +69,27 @@ module Kelp
|
|
58
69
|
# Other content that must be in the same row
|
59
70
|
#
|
60
71
|
def click_link_in_row(link, text)
|
61
|
-
|
62
|
-
|
72
|
+
begin
|
73
|
+
row = find(:xpath, xpath_row_containing([link, text]))
|
74
|
+
rescue Capybara::ElementNotFound
|
75
|
+
raise Kelp::MissingRow,
|
76
|
+
"No table row found containing '#{link}' and '#{text}'"
|
77
|
+
end
|
78
|
+
begin
|
79
|
+
row.click_link(link)
|
80
|
+
rescue Capybara::ElementNotFound
|
81
|
+
raise Kelp::MissingLink,
|
82
|
+
"No link with title, id or text '#{link}' found in the same row as '#{text}'"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
def go_to_page(page_name_or_path)
|
88
|
+
if defined? path_to
|
89
|
+
visit path_to(page_name_or_path)
|
90
|
+
else
|
91
|
+
visit page_name_or_path
|
92
|
+
end
|
63
93
|
end
|
64
94
|
|
65
95
|
|
data/lib/kelp/scoping.rb
CHANGED
@@ -3,6 +3,18 @@ module Kelp
|
|
3
3
|
# verifications on a webpage.
|
4
4
|
#
|
5
5
|
module Scoping
|
6
|
+
# Wrapper for Capybara's `within`, but raises Kelp::InvalidScope
|
7
|
+
# instead of Capybara::ElementNotFound
|
8
|
+
def kelp_within(kind, selector=nil)
|
9
|
+
begin
|
10
|
+
within(kind, selector) { yield }
|
11
|
+
rescue Capybara::ElementNotFound
|
12
|
+
raise Kelp::InvalidScope,
|
13
|
+
"Scope '#{selector || kind}' not found on page"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
6
18
|
# Execute a block of code within a given scope. If `locator` begins with
|
7
19
|
# `/` or `./`, then it's assumed to be an XPath selector; otherwise, it's
|
8
20
|
# assumed to be a CSS selector.
|
@@ -11,13 +23,13 @@ module Kelp
|
|
11
23
|
# Use the selector_for method if it's defined. This may be provided
|
12
24
|
# by features/support/selectors.rb, generated by cucumber-rails.
|
13
25
|
if defined? selector_for
|
14
|
-
|
26
|
+
kelp_within(*selector_for(locator)) { yield }
|
15
27
|
# Otherwise, fall back on the Capybara locator syntax (CSS or XPath)
|
16
28
|
else
|
17
29
|
if locator =~ /\.?\//
|
18
|
-
|
30
|
+
kelp_within(:xpath, locator) { yield }
|
19
31
|
else
|
20
|
-
|
32
|
+
kelp_within(:css, locator) { yield }
|
21
33
|
end
|
22
34
|
end
|
23
35
|
else
|
@@ -26,7 +26,8 @@ World(Kelp::Visibility)
|
|
26
26
|
|
27
27
|
# Patterns shared by step definitions
|
28
28
|
I = /(?:|I )/
|
29
|
-
TEXT = /"([^\"]
|
29
|
+
TEXT = /"([^\"]*)"/
|
30
|
+
PAGE = /"?([^\"]+)"?/
|
30
31
|
REGEX = /\/([^\/]*)\//
|
31
32
|
WITHIN = /(?: within "?([^\"]+)"?)?/
|
32
33
|
ELEMENT = /(?:field|checkbox|dropdown|button)/
|
@@ -46,8 +47,8 @@ ELEMENT = /(?:field|checkbox|dropdown|button)/
|
|
46
47
|
# When I go to my account page
|
47
48
|
# And I go to "/logout"
|
48
49
|
#
|
49
|
-
Given /^#{I}(am on|go to)
|
50
|
-
|
50
|
+
Given /^#{I}(?:am on|go to) #{PAGE}$/ do |page_name|
|
51
|
+
go_to_page(page_name)
|
51
52
|
end
|
52
53
|
|
53
54
|
|
@@ -89,7 +90,7 @@ end
|
|
89
90
|
|
90
91
|
# Verify that the current path name matches that of the given page.
|
91
92
|
#
|
92
|
-
Then /^#{I}should be on
|
93
|
+
Then /^#{I}should be on #{PAGE}$/ do |page_name|
|
93
94
|
should_be_on_page(page_name)
|
94
95
|
end
|
95
96
|
|
@@ -256,11 +257,11 @@ end
|
|
256
257
|
# Then I should see a "Save" button
|
257
258
|
# But I should not see a "Delete" button
|
258
259
|
#
|
259
|
-
Then /^#{I}should see
|
260
|
+
Then /^#{I}should see an? #{TEXT} button#{WITHIN}$/ do |button, selector|
|
260
261
|
should_see_button(button, :within => selector)
|
261
262
|
end
|
262
263
|
|
263
|
-
Then /^#{I}should not see
|
264
|
+
Then /^#{I}should not see an? #{TEXT} button#{WITHIN}$/ do |button, selector|
|
264
265
|
should_not_see_button(button, :within => selector)
|
265
266
|
end
|
266
267
|
|
data/spec/field_spec.rb
CHANGED
@@ -102,6 +102,58 @@ describe Kelp::Field, "field_should_contain" do
|
|
102
102
|
end
|
103
103
|
|
104
104
|
|
105
|
+
describe Kelp::Field, "field_should_not_contain" do
|
106
|
+
before(:each) do
|
107
|
+
visit('/form')
|
108
|
+
end
|
109
|
+
|
110
|
+
context "passes when" do
|
111
|
+
context "field with id" do
|
112
|
+
it "has a different value" do
|
113
|
+
fill_in "first_name", :with => "Brian"
|
114
|
+
field_should_not_contain "first_name", "Stewie"
|
115
|
+
end
|
116
|
+
|
117
|
+
it "is empty" do
|
118
|
+
field_should_not_contain "first_name", "Stewie"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
context "field with label" do
|
123
|
+
it "has a different value" do
|
124
|
+
fill_in "First name", :with => "Brian"
|
125
|
+
field_should_not_contain "First name", "Stewie"
|
126
|
+
end
|
127
|
+
|
128
|
+
it "is empty" do
|
129
|
+
field_should_not_contain "First name", "Stewie"
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
context "fails when" do
|
135
|
+
context "field with id" do
|
136
|
+
it "has the given value" do
|
137
|
+
fill_in "first_name", :with => "Judith"
|
138
|
+
lambda do
|
139
|
+
field_should_not_contain "first_name", "Judith"
|
140
|
+
end.should raise_error(Kelp::Unexpected)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
context "field with label" do
|
145
|
+
it "has the given value" do
|
146
|
+
fill_in "First name", :with => "Judith"
|
147
|
+
lambda do
|
148
|
+
field_should_not_contain "First name", "Judith"
|
149
|
+
end.should raise_error(Kelp::Unexpected)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
|
105
157
|
describe Kelp::Field, "fields_should_contain" do
|
106
158
|
before(:each) do
|
107
159
|
visit('/form')
|
data/spec/navigation_spec.rb
CHANGED
@@ -21,13 +21,13 @@ describe Kelp::Navigation, "follow" do
|
|
21
21
|
it "link does not exist" do
|
22
22
|
lambda do
|
23
23
|
follow "About Them"
|
24
|
-
end.should raise_error(
|
24
|
+
end.should raise_error(Kelp::MissingLink)
|
25
25
|
end
|
26
26
|
|
27
27
|
it "link is not within the scope" do
|
28
28
|
lambda do
|
29
29
|
follow "About Us", :within => "#invalid_scope"
|
30
|
-
end.should raise_error(
|
30
|
+
end.should raise_error(Kelp::InvalidScope)
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
@@ -53,13 +53,13 @@ describe Kelp::Navigation, "press" do
|
|
53
53
|
it "button does not exist" do
|
54
54
|
lambda do
|
55
55
|
press "Poke"
|
56
|
-
end.should raise_error(
|
56
|
+
end.should raise_error(Kelp::MissingButton)
|
57
57
|
end
|
58
58
|
|
59
59
|
it "button exists but is not within the scope" do
|
60
60
|
lambda do
|
61
61
|
press "Submit message", :within => "#greeting"
|
62
|
-
end.should raise_error(
|
62
|
+
end.should raise_error(Kelp::MissingButton)
|
63
63
|
end
|
64
64
|
end
|
65
65
|
end
|
@@ -81,7 +81,7 @@ describe Kelp::Navigation, "click_link_in_row" do
|
|
81
81
|
it "link does not exist in the row" do
|
82
82
|
lambda do
|
83
83
|
click_link_in_row "Frob", "Eric"
|
84
|
-
end.should raise_error(
|
84
|
+
end.should raise_error(Kelp::MissingRow)
|
85
85
|
end
|
86
86
|
end
|
87
87
|
end
|
data/spec/visibility_spec.rb
CHANGED
@@ -113,7 +113,7 @@ describe Kelp::Visibility, "should_see" do
|
|
113
113
|
it "is given a nonexistent XPath scope" do
|
114
114
|
lambda do
|
115
115
|
should_see "Goodbye world", :within => "//div[@id='nonexistent']"
|
116
|
-
end.should raise_error(
|
116
|
+
end.should raise_error(Kelp::InvalidScope)
|
117
117
|
end
|
118
118
|
end
|
119
119
|
|
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:
|
4
|
+
hash: 21
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
9
|
+
- 1
|
10
|
+
version: 0.2.1
|
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-05-
|
18
|
+
date: 2011-05-12 00:00:00 -06:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -145,10 +145,11 @@ files:
|
|
145
145
|
- examples/sinatra_app/features/dropdown_fail.feature
|
146
146
|
- examples/sinatra_app/features/field.feature
|
147
147
|
- examples/sinatra_app/features/field_fail.feature
|
148
|
+
- examples/sinatra_app/features/navigation.feature
|
149
|
+
- examples/sinatra_app/features/navigation_fail.feature
|
148
150
|
- examples/sinatra_app/features/support/env.rb
|
149
151
|
- examples/sinatra_app/features/visibility.feature
|
150
152
|
- examples/sinatra_app/features/visibility_fail.feature
|
151
|
-
- examples/sinatra_app/features/web_steps.rb
|
152
153
|
- examples/sinatra_app/views/about.erb
|
153
154
|
- examples/sinatra_app/views/edit1.erb
|
154
155
|
- examples/sinatra_app/views/edit2.erb
|