kelp 0.2.3 → 0.2.4
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 +2 -0
- data/.simplecov +8 -0
- data/Gemfile +1 -1
- data/History.md +8 -0
- data/README.md +31 -6
- data/Rakefile +0 -12
- data/examples/sinatra_app/features/ambiguous_field.feature +30 -0
- data/examples/sinatra_app/features/ambiguous_field_fail.feature +17 -0
- data/examples/sinatra_app/features/field.feature +2 -27
- data/examples/sinatra_app/features/support/env.rb +1 -1
- data/examples/sinatra_app/views/form.erb +0 -14
- data/examples/sinatra_app/views/form2.erb +128 -0
- data/features/kelp_step_definitions.feature +24 -2
- data/features/step_definitions/app_steps.rb +1 -1
- data/features/support/env.rb +3 -0
- data/kelp.gemspec +3 -3
- data/lib/kelp/exceptions.rb +1 -0
- data/lib/kelp/field.rb +46 -19
- data/lib/kelp/helper.rb +4 -0
- data/spec/field_spec.rb +31 -3
- data/spec/spec_helper.rb +5 -1
- data/spec/visibility_spec.rb +2 -2
- metadata +117 -122
data/.gitignore
CHANGED
data/.simplecov
ADDED
data/Gemfile
CHANGED
data/History.md
CHANGED
data/README.md
CHANGED
@@ -20,6 +20,34 @@ to report any bugs or feature requests. Visit the `#kelp` channel on
|
|
20
20
|
`irc.freenode.net` to chat.
|
21
21
|
|
22
22
|
|
23
|
+
Motivation
|
24
|
+
----------
|
25
|
+
|
26
|
+
Kelp was developed as an attempt to get away from the bad habit of nesting
|
27
|
+
steps inside one another. While Cucumber does allow this behavior, it is
|
28
|
+
frowned upon by much of the Cucumber community. It was also partly motivated by
|
29
|
+
a desire to move away from imperative steps, toward a
|
30
|
+
[more declarative style](http://automation-excellence.com/blog/declare-or-impair).
|
31
|
+
Some of Capybara's methods were perceived as being too low-level, especially
|
32
|
+
when it comes to filling in or verifying several different fields in a form, or
|
33
|
+
checking the presence or absence of multiple strings or regular expressions.
|
34
|
+
|
35
|
+
As of version 1.1.0, cucumber-rails
|
36
|
+
[no longer provides](http://aslakhellesoy.com/post/11055981222/the-training-wheels-came-off)
|
37
|
+
a generator for `web_steps.rb`; since Kelp does provide such a generator, it
|
38
|
+
may serve the niche market of cucumber-rails users who preferred to use the
|
39
|
+
imperative step definitions that it provided. Kelp's intent is not to encourage
|
40
|
+
this behavior; nearly all of the imperative steps it provides are one-liners,
|
41
|
+
which in many cases are more succinct and readable than the step definition
|
42
|
+
that wraps them.
|
43
|
+
|
44
|
+
It is this developer's opinion that imperative `web_steps.rb`-style steps can
|
45
|
+
be the easiest route to a working Cucumber scenario, but that they can also
|
46
|
+
be a fast track to unmaintainability. Consider them a starting point; the baby
|
47
|
+
steps you might take when writing your first few scenarios, before you discover
|
48
|
+
the higher-level declarative steps that need to be reusably encapsulated.
|
49
|
+
|
50
|
+
|
23
51
|
Usage
|
24
52
|
-----
|
25
53
|
|
@@ -61,10 +89,8 @@ Or even this:
|
|
61
89
|
]
|
62
90
|
end
|
63
91
|
|
64
|
-
|
65
|
-
|
66
|
-
and pressing buttons can all be easily done with Ruby code instead of nested
|
67
|
-
steps. Thus this:
|
92
|
+
Following links, filling in fields, and pressing buttons can all be easily done
|
93
|
+
with Ruby code instead of nested steps. Thus this:
|
68
94
|
|
69
95
|
When %{I follow "Login"}
|
70
96
|
And %{I fill in "Username" with "skroob"}
|
@@ -99,7 +125,7 @@ Rails generator
|
|
99
125
|
|
100
126
|
Kelp provides a generator for Rails projects, which writes step definitions
|
101
127
|
to `features/step_definitions/web_steps.rb`. This file provides all of the same
|
102
|
-
step definitions
|
128
|
+
step definitions formerly provided by
|
103
129
|
[cucumber-rails](http://github.com/aslakhellesoy/cucumber-rails), with several
|
104
130
|
enhancements. If you have made customizations to your `web_steps.rb`, they will
|
105
131
|
be overwritten! Consider yourself warned.
|
@@ -164,7 +190,6 @@ definitions perform as expected.
|
|
164
190
|
Future plans
|
165
191
|
------------
|
166
192
|
|
167
|
-
* Generator for Rails 3
|
168
193
|
* Support Webrat
|
169
194
|
|
170
195
|
|
data/Rakefile
CHANGED
@@ -6,12 +6,6 @@ desc "Run RSpec tests with coverage analysis"
|
|
6
6
|
RSpec::Core::RakeTask.new(:spec) do |t|
|
7
7
|
t.pattern = 'spec/**/*_spec.rb'
|
8
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
|
-
]
|
15
9
|
end
|
16
10
|
|
17
11
|
desc "Run Cucumber tests with coverage analysis"
|
@@ -20,12 +14,6 @@ Cucumber::Rake::Task.new(:cucumber) do |t|
|
|
20
14
|
"--format pretty",
|
21
15
|
"--tags ~@wip",
|
22
16
|
]
|
23
|
-
t.rcov = true
|
24
|
-
t.rcov_opts = [
|
25
|
-
'--exclude /.gem/,/gems/,spec,features,examples',
|
26
|
-
'--include lib/**/*.rb',
|
27
|
-
'--aggregate coverage.data',
|
28
|
-
]
|
29
17
|
end
|
30
18
|
|
31
19
|
desc "Run RSpec and Cucumber tests with coverage analysis"
|
@@ -0,0 +1,30 @@
|
|
1
|
+
Feature: Ambiguous fields
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given I am on "/form2"
|
5
|
+
|
6
|
+
|
7
|
+
Scenario: Fill in single fields within a scope
|
8
|
+
When I fill in "First name" with "Homer" within "#person_form"
|
9
|
+
And I fill in "First name" with "Marge" within "#spouse_form"
|
10
|
+
Then the "First name" field within "#person_form" should contain "Homer"
|
11
|
+
And the "First name" field within "#spouse_form" should contain "Marge"
|
12
|
+
|
13
|
+
|
14
|
+
Scenario: Fill in multiple fields by label within a scope
|
15
|
+
When I fill in the following within "#person_form":
|
16
|
+
| First name | Peter |
|
17
|
+
| Last name | Griffin |
|
18
|
+
And I fill in the following within "#spouse_form":
|
19
|
+
| First name | Lois |
|
20
|
+
| Last name | Griffin |
|
21
|
+
|
22
|
+
Then the fields within "#person_form" should contain:
|
23
|
+
| First name | Peter |
|
24
|
+
| Last name | Griffin |
|
25
|
+
And the fields within "#spouse_form" should contain:
|
26
|
+
| First name | Lois |
|
27
|
+
| Last name | Griffin |
|
28
|
+
|
29
|
+
|
30
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
Feature: Ambiguous fields failure test
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given I am on "/form2"
|
5
|
+
|
6
|
+
|
7
|
+
Scenario: Fill in single ambiguous field (FAIL)
|
8
|
+
When I fill in "First name" with "Homer"
|
9
|
+
Then the "First name" field should contain "Homer"
|
10
|
+
|
11
|
+
Scenario: Fill in multiple ambiguous fields by label (FAIL)
|
12
|
+
When I fill in the following:
|
13
|
+
| Last name | Griffin |
|
14
|
+
| First name | Peter |
|
15
|
+
Then the fields should contain:
|
16
|
+
| Last name | Griffin |
|
17
|
+
| First name | Peter |
|
@@ -6,9 +6,9 @@ Feature: Fields
|
|
6
6
|
|
7
7
|
Scenario: Field should be empty
|
8
8
|
Then the "First name" field should be empty
|
9
|
-
And the "First name" field
|
9
|
+
And the "First name" field should be empty
|
10
|
+
And the "Last name" field should be empty
|
10
11
|
And the "Last name" field should be empty
|
11
|
-
And the "Last name" field within "#person_form" should be empty
|
12
12
|
|
13
13
|
|
14
14
|
Scenario: Fields should contain
|
@@ -44,13 +44,6 @@ Feature: Fields
|
|
44
44
|
And the "last_name" field should contain "Hyneman"
|
45
45
|
|
46
46
|
|
47
|
-
Scenario: Fill in single fields within a scope
|
48
|
-
When I fill in "First name" with "Homer" within "#person_form"
|
49
|
-
And I fill in "First name" with "Marge" within "#spouse_form"
|
50
|
-
Then the "First name" field within "#person_form" should contain "Homer"
|
51
|
-
And the "First name" field within "#spouse_form" should contain "Marge"
|
52
|
-
|
53
|
-
|
54
47
|
Scenario: Fill in multiple fields by label
|
55
48
|
When I fill in the following:
|
56
49
|
| First name | Andre |
|
@@ -65,21 +58,3 @@ Feature: Fields
|
|
65
58
|
| Weight | Heavy |
|
66
59
|
| Height | Tall |
|
67
60
|
| Message | Anybody want a peanut? |
|
68
|
-
|
69
|
-
|
70
|
-
Scenario: Fill in multiple fields by label within a scope
|
71
|
-
When I fill in the following within "#person_form":
|
72
|
-
| First name | Peter |
|
73
|
-
| Last name | Griffin |
|
74
|
-
And I fill in the following within "#spouse_form":
|
75
|
-
| First name | Lois |
|
76
|
-
| Last name | Griffin |
|
77
|
-
|
78
|
-
Then the fields within "#person_form" should contain:
|
79
|
-
| First name | Peter |
|
80
|
-
| Last name | Griffin |
|
81
|
-
And the fields within "#spouse_form" should contain:
|
82
|
-
| First name | Lois |
|
83
|
-
| Last name | Griffin |
|
84
|
-
|
85
|
-
|
@@ -39,20 +39,6 @@
|
|
39
39
|
</form>
|
40
40
|
</div>
|
41
41
|
|
42
|
-
<div id="spouse_form">
|
43
|
-
<form action="/thanks" method="get">
|
44
|
-
<p>
|
45
|
-
<label for="spouse_first_name">First name</label>
|
46
|
-
<input id="spouse_first_name" type="text" />
|
47
|
-
</p>
|
48
|
-
<p>
|
49
|
-
<label for="spouse_last_name">Last name</label>
|
50
|
-
<input id="spouse_last_name" type="text" />
|
51
|
-
</p>
|
52
|
-
<p><button value="submit_spouse_form">Submit spouse form</button></p>
|
53
|
-
</form>
|
54
|
-
</div>
|
55
|
-
|
56
42
|
<div id="preferences_form">
|
57
43
|
<form action="/thanks" method="get">
|
58
44
|
<p>
|
@@ -0,0 +1,128 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head><title>Form</title></head>
|
4
|
+
<body>
|
5
|
+
<h1>Form Test</h1>
|
6
|
+
|
7
|
+
<div id="person_form">
|
8
|
+
<form action="/thanks" method="get">
|
9
|
+
<p>
|
10
|
+
<label for="first_name">First name</label>
|
11
|
+
<input id="first_name" type="text" />
|
12
|
+
</p>
|
13
|
+
<p>
|
14
|
+
<label for="last_name">Last name</label>
|
15
|
+
<input id="last_name" type="text" />
|
16
|
+
</p>
|
17
|
+
<p>
|
18
|
+
<label for="biography">Life story</label>
|
19
|
+
<textarea id="biography" cols="80" rows="10">
|
20
|
+
</textarea>
|
21
|
+
</p>
|
22
|
+
<p>
|
23
|
+
<label for="height">Height</label>
|
24
|
+
<select id="height">
|
25
|
+
<option value="short">Short</option>
|
26
|
+
<option value="average" selected="selected">Average</option>
|
27
|
+
<option value="tall" >Tall</option>
|
28
|
+
</select>
|
29
|
+
</p>
|
30
|
+
<p>
|
31
|
+
<label for="weight">Weight</label>
|
32
|
+
<select id="weight">
|
33
|
+
<option value="light">Light</option>
|
34
|
+
<option value="medium">Medium</option>
|
35
|
+
<option value="heavy">Heavy</option>
|
36
|
+
</select>
|
37
|
+
</p>
|
38
|
+
<p><button value="submit_person_form">Submit person form</button></p>
|
39
|
+
</form>
|
40
|
+
</div>
|
41
|
+
|
42
|
+
<div id="spouse_form">
|
43
|
+
<form action="/thanks" method="get">
|
44
|
+
<p>
|
45
|
+
<label for="spouse_first_name">First name</label>
|
46
|
+
<input id="spouse_first_name" type="text" />
|
47
|
+
</p>
|
48
|
+
<p>
|
49
|
+
<label for="spouse_last_name">Last name</label>
|
50
|
+
<input id="spouse_last_name" type="text" />
|
51
|
+
</p>
|
52
|
+
<p>
|
53
|
+
<label for="spouse_weight">Weight</label>
|
54
|
+
<select id="spouse_weight">
|
55
|
+
<option value="light">Light</option>
|
56
|
+
<option value="medium">Medium</option>
|
57
|
+
<option value="heavy">Heavy</option>
|
58
|
+
</select>
|
59
|
+
</p>
|
60
|
+
<p>
|
61
|
+
<label for="spouse_favorite_color">Favorite Colors</label>
|
62
|
+
<input id="spouse_favorite_color" type="text" />
|
63
|
+
</p>
|
64
|
+
<p><button value="submit_spouse_form">Submit spouse form</button></p>
|
65
|
+
</form>
|
66
|
+
</div>
|
67
|
+
|
68
|
+
<div id="preferences_form">
|
69
|
+
<form action="/thanks" method="get">
|
70
|
+
<p>
|
71
|
+
<label for="favorite_colors">Favorite Colors</label>
|
72
|
+
<select id="favorite_colors" multiple="multiple">
|
73
|
+
<option value="r">Red</option>
|
74
|
+
<option value="g">Green</option>
|
75
|
+
<option value="b">Blue</option>
|
76
|
+
</select>
|
77
|
+
</p>
|
78
|
+
<p>
|
79
|
+
<label for="like_cheese">I like cheese</label>
|
80
|
+
<input id="like_cheese" type="checkbox" checked="checked"/>
|
81
|
+
</p>
|
82
|
+
<p>
|
83
|
+
<label for="like_salami">I like salami</label>
|
84
|
+
<input id="like_salami" type="checkbox" />
|
85
|
+
</p>
|
86
|
+
<table>
|
87
|
+
<tr>
|
88
|
+
<th>Apple</th>
|
89
|
+
<td>
|
90
|
+
<label for="like_apple">Like</label>
|
91
|
+
<input id="like_apple" type="checkbox" checked="checked"/>
|
92
|
+
</td>
|
93
|
+
</tr>
|
94
|
+
<tr>
|
95
|
+
<th>Banana</th>
|
96
|
+
<td>
|
97
|
+
<label for="like_banana">Like</label>
|
98
|
+
<input id="like_banana" type="checkbox"/>
|
99
|
+
</td>
|
100
|
+
</tr>
|
101
|
+
</table>
|
102
|
+
<p>
|
103
|
+
<label for="message">Message</label>
|
104
|
+
<input id="message" type="text" value="Your message goes here" />
|
105
|
+
</p>
|
106
|
+
<p><input type="submit" value="Save preferences" /></p>
|
107
|
+
</form>
|
108
|
+
</div>
|
109
|
+
|
110
|
+
<div id="other_form">
|
111
|
+
<form action="/thanks" method="get">
|
112
|
+
<p>
|
113
|
+
<label for="quotes">Quotes</label>
|
114
|
+
<select id="quotes">
|
115
|
+
<option value="1">Single 'quotes'</option>
|
116
|
+
<option value="2">"Double" quotes</option>
|
117
|
+
<option value="3">'Single' and "Double" quotes</option>
|
118
|
+
</select>
|
119
|
+
</p>
|
120
|
+
<p><input id="readonly" type="text" disabled="disabled" /></p>
|
121
|
+
<p><input type="submit" value="Save is disabled" disabled="disabled" /></p>
|
122
|
+
</form>
|
123
|
+
</div>
|
124
|
+
|
125
|
+
</body>
|
126
|
+
</html>
|
127
|
+
|
128
|
+
|
@@ -68,8 +68,8 @@ Feature: Kelp Step Definitions
|
|
68
68
|
When I run cucumber on "field.feature"
|
69
69
|
Then the results should include:
|
70
70
|
"""
|
71
|
-
|
72
|
-
|
71
|
+
7 scenarios (7 passed)
|
72
|
+
26 steps (26 passed)
|
73
73
|
"""
|
74
74
|
|
75
75
|
Scenario: Field failure test
|
@@ -100,6 +100,28 @@ Feature: Kelp Step Definitions
|
|
100
100
|
16 steps (6 failed, 10 passed)
|
101
101
|
"""
|
102
102
|
|
103
|
+
Scenario: Ambiguous field test
|
104
|
+
When I run cucumber on "ambiguous_field.feature"
|
105
|
+
Then the results should include:
|
106
|
+
"""
|
107
|
+
2 scenarios (2 passed)
|
108
|
+
10 steps (10 passed)
|
109
|
+
"""
|
110
|
+
|
111
|
+
Scenario: Ambiguous field failure test
|
112
|
+
When I run cucumber on "ambiguous_field_fail.feature"
|
113
|
+
Then the results should include:
|
114
|
+
"""
|
115
|
+
Scenario: Fill in single ambiguous field (FAIL)
|
116
|
+
Field 'First name' is ambiguous (Kelp::AmbiguousField)
|
117
|
+
|
118
|
+
Scenario: Fill in multiple ambiguous fields by label (FAIL)
|
119
|
+
Field 'Last name' is ambiguous (Kelp::AmbiguousField)
|
120
|
+
|
121
|
+
2 scenarios (2 failed)
|
122
|
+
6 steps (2 failed, 2 skipped, 2 passed)
|
123
|
+
"""
|
124
|
+
|
103
125
|
Scenario: Visibility test
|
104
126
|
When I run cucumber on "visibility.feature"
|
105
127
|
Then the results should include:
|
@@ -28,7 +28,7 @@ end
|
|
28
28
|
# Extra lines in the results are ignored.
|
29
29
|
Then /^the results should include:$/ do |expected_lines|
|
30
30
|
# Full actual output, for error reporting
|
31
|
-
got = @output.collect {|line| " #{line}"}.join
|
31
|
+
got = @output.lines.collect {|line| " #{line}"}.join
|
32
32
|
# Remove leading whitespace and split into lines
|
33
33
|
got_lines = @output.gsub(/^\s*/, '').split("\n")
|
34
34
|
want_lines = expected_lines.gsub(/^\s*/, '').split("\n")
|
data/features/support/env.rb
CHANGED
data/kelp.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "kelp"
|
3
|
-
s.version = "0.2.
|
3
|
+
s.version = "0.2.4"
|
4
4
|
s.summary = "Cucumber helper methods"
|
5
5
|
s.description = <<-EOS
|
6
6
|
Kelp is a collection of helper methods for Cucumber to ease the process of
|
@@ -12,12 +12,12 @@ Gem::Specification.new do |s|
|
|
12
12
|
s.homepage = "http://github.com/wapcaplet/kelp"
|
13
13
|
s.platform = Gem::Platform::RUBY
|
14
14
|
|
15
|
-
s.add_dependency 'capybara', '
|
15
|
+
s.add_dependency 'capybara', '~> 2.0.1'
|
16
16
|
|
17
17
|
s.add_development_dependency 'sinatra'
|
18
18
|
s.add_development_dependency 'rspec', '>= 2.2.0'
|
19
19
|
s.add_development_dependency 'rspec-rails'
|
20
|
-
s.add_development_dependency '
|
20
|
+
s.add_development_dependency 'simplecov'
|
21
21
|
s.add_development_dependency 'webrat'
|
22
22
|
s.add_development_dependency 'cucumber'
|
23
23
|
|
data/lib/kelp/exceptions.rb
CHANGED
data/lib/kelp/field.rb
CHANGED
@@ -19,6 +19,8 @@ module Kelp
|
|
19
19
|
# @param [String] value
|
20
20
|
# Text to select from a dropdown or enter in a text box
|
21
21
|
#
|
22
|
+
# @raise [Kelp::AmbiguousField]
|
23
|
+
# If more than one field matching `field` is found
|
22
24
|
# @raise [Kelp::FieldNotFound]
|
23
25
|
# If no field matching `field` is found
|
24
26
|
# @raise [Kelp::OptionNotFound]
|
@@ -28,26 +30,16 @@ module Kelp
|
|
28
30
|
# @since 0.1.9
|
29
31
|
#
|
30
32
|
def select_or_fill(field, value)
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
if err.message =~ /no select box with id, name, or label/
|
37
|
-
begin
|
38
|
-
fill_in(field, :with => value)
|
39
|
-
rescue Capybara::ElementNotFound
|
40
|
-
raise Kelp::FieldNotFound,
|
41
|
-
"No field with id, name, or label '#{field}' found"
|
42
|
-
end
|
43
|
-
# (2) The field exists, but the value does not
|
44
|
-
elsif err.message =~ /no option with text/
|
33
|
+
case field_type(field)
|
34
|
+
when :select
|
35
|
+
begin
|
36
|
+
select(value, :from => field)
|
37
|
+
rescue Capybara::ElementNotFound
|
45
38
|
raise Kelp::OptionNotFound,
|
46
39
|
"Field '#{field}' has no option '#{value}'"
|
47
|
-
# And just in case...
|
48
|
-
else
|
49
|
-
raise
|
50
40
|
end
|
41
|
+
when :fillable_field
|
42
|
+
fill_in(field, :with => value)
|
51
43
|
end
|
52
44
|
end
|
53
45
|
|
@@ -63,7 +55,9 @@ module Kelp
|
|
63
55
|
# Text to select from a dropdown or enter in a text box, or
|
64
56
|
# `checked` or `unchecked` to operate on a checkbox
|
65
57
|
#
|
66
|
-
# @raise [Kelp::
|
58
|
+
# @raise [Kelp::AmbiguousField]
|
59
|
+
# If more than one field is found matching the given identifier
|
60
|
+
# @raise [Kelp::FieldNotFound]
|
67
61
|
# If no checkbox, dropdown, or text box is found with the given
|
68
62
|
# identifier
|
69
63
|
#
|
@@ -102,6 +96,8 @@ module Kelp
|
|
102
96
|
# @param [Hash] scope
|
103
97
|
# Scoping keywords as understood by {#in_scope}
|
104
98
|
#
|
99
|
+
# @raise [Kelp::AmbiguousField]
|
100
|
+
# If more than one field is found matching the given identifier
|
105
101
|
# @raise [Kelp::FieldNotFound]
|
106
102
|
# If no field is found matching the given identifier
|
107
103
|
#
|
@@ -125,7 +121,7 @@ module Kelp
|
|
125
121
|
# @param [Hash] scope
|
126
122
|
# Scoping keywords as understood by {#in_scope}
|
127
123
|
#
|
128
|
-
# @raise [Kelp::
|
124
|
+
# @raise [Kelp::FieldNotFound]
|
129
125
|
# If any field could not be found
|
130
126
|
#
|
131
127
|
def fill_in_fields(field_values, scope={})
|
@@ -302,5 +298,36 @@ module Kelp
|
|
302
298
|
fields_should_contain field_values, :within => selector
|
303
299
|
end
|
304
300
|
|
301
|
+
private
|
302
|
+
|
303
|
+
# Figure out whether the field locator matches a single select
|
304
|
+
# or fillable field.
|
305
|
+
#
|
306
|
+
# @param [String] field
|
307
|
+
# Capybara locator for the field (name, id, or label text)
|
308
|
+
#
|
309
|
+
# @raise [Kelp::AmbiguousField]
|
310
|
+
# If more than one field matching `field` is found
|
311
|
+
# @raise [Kelp::FieldNotFound]
|
312
|
+
# If no field matching `field` is found
|
313
|
+
#
|
314
|
+
# @return [Symbol]
|
315
|
+
# `:select` or `:fillable_field` depending on the type of element
|
316
|
+
def field_type(field)
|
317
|
+
select = all(:select, field).count
|
318
|
+
fillable = all(:fillable_field, field).count
|
319
|
+
count = select + fillable
|
320
|
+
|
321
|
+
case count
|
322
|
+
when 0
|
323
|
+
raise Kelp::FieldNotFound,
|
324
|
+
"No field with id, name, or label '#{field}' found"
|
325
|
+
when 1
|
326
|
+
return select > 0 ? :select : :fillable_field
|
327
|
+
else
|
328
|
+
raise Kelp::AmbiguousField,
|
329
|
+
"Field '#{field}' is ambiguous"
|
330
|
+
end
|
331
|
+
end
|
305
332
|
end
|
306
333
|
end
|
data/lib/kelp/helper.rb
CHANGED
@@ -7,6 +7,8 @@ module Kelp
|
|
7
7
|
def listify(items)
|
8
8
|
if items.class == Cucumber::Ast::Table
|
9
9
|
strings = items.raw.flatten
|
10
|
+
elsif items.class == Cucumber::Ast::DocString
|
11
|
+
strings = items.to_s.split(/[\r\n]+/)
|
10
12
|
else
|
11
13
|
strings = items.split(/[\r\n]+/)
|
12
14
|
end
|
@@ -17,6 +19,8 @@ module Kelp
|
|
17
19
|
# tells you which locator failed to match (instead of giving a useless
|
18
20
|
# Unable to find '#<XPath::Union:0xXXXXXXX>' message).
|
19
21
|
#
|
22
|
+
# @raise [Kelp::AmbiguousField]
|
23
|
+
# If more than one field with the given locator was found
|
20
24
|
# @raise [Kelp::FieldNotFound]
|
21
25
|
# If no field with the given locator could be found
|
22
26
|
#
|
data/spec/field_spec.rb
CHANGED
@@ -241,7 +241,7 @@ end
|
|
241
241
|
|
242
242
|
describe Kelp::Field, "fill_in_field" do
|
243
243
|
before(:each) do
|
244
|
-
visit('/
|
244
|
+
visit('/form2')
|
245
245
|
end
|
246
246
|
|
247
247
|
context "passes when" do
|
@@ -251,8 +251,8 @@ describe Kelp::Field, "fill_in_field" do
|
|
251
251
|
end
|
252
252
|
|
253
253
|
it "filling a single text field by label" do
|
254
|
-
fill_in_field "
|
255
|
-
field_should_contain "
|
254
|
+
fill_in_field "Life story", "I was born."
|
255
|
+
field_should_contain "Life story", "I was born."
|
256
256
|
end
|
257
257
|
|
258
258
|
it "checking a checkbox" do
|
@@ -275,6 +275,16 @@ describe Kelp::Field, "fill_in_field" do
|
|
275
275
|
fill_in_field_within "#person_form", "first_name", "Mel"
|
276
276
|
field_should_contain_within "#person_form", "first_name", "Mel"
|
277
277
|
end
|
278
|
+
|
279
|
+
it "dropdown is ambiguous, but scoped" do
|
280
|
+
fill_in_field_within "#person_form", "Weight", "Light"
|
281
|
+
field_should_contain_within "#person_form", "Weight", "light"
|
282
|
+
end
|
283
|
+
|
284
|
+
it "field is ambiguous, but scoped" do
|
285
|
+
fill_in_field_within "#person_form", "First name", "Mel"
|
286
|
+
field_should_contain_within "#person_form", "First name", "Mel"
|
287
|
+
end
|
278
288
|
end
|
279
289
|
|
280
290
|
context "fails when" do
|
@@ -295,6 +305,24 @@ describe Kelp::Field, "fill_in_field" do
|
|
295
305
|
fill_in_field_within "#preferences_form", "First name", "Mel"
|
296
306
|
end.should raise_error(Kelp::FieldNotFound)
|
297
307
|
end
|
308
|
+
|
309
|
+
it "dropdown is ambiguous, and unscoped" do
|
310
|
+
lambda do
|
311
|
+
fill_in_field "Weight", "Light"
|
312
|
+
end.should raise_error(Kelp::AmbiguousField)
|
313
|
+
end
|
314
|
+
|
315
|
+
it "field is ambiguous, and unscoped" do
|
316
|
+
lambda do
|
317
|
+
fill_in_field "First name", "Mel"
|
318
|
+
end.should raise_error(Kelp::AmbiguousField)
|
319
|
+
end
|
320
|
+
|
321
|
+
it "field and dropdown have same name" do
|
322
|
+
lambda do
|
323
|
+
fill_in_field "Favorite Colors", "Red"
|
324
|
+
end.should raise_error(Kelp::AmbiguousField)
|
325
|
+
end
|
298
326
|
end
|
299
327
|
end
|
300
328
|
|
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
if RUBY_VERSION >= '1.9'
|
2
|
+
require 'simplecov'
|
3
|
+
end
|
4
|
+
|
1
5
|
require 'rspec'
|
2
6
|
require 'capybara'
|
3
7
|
require 'capybara/dsl'
|
@@ -6,7 +10,7 @@ require 'kelp'
|
|
6
10
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'examples', 'sinatra_app', 'app'))
|
7
11
|
|
8
12
|
RSpec.configure do |config|
|
9
|
-
config.include Capybara
|
13
|
+
config.include Capybara::DSL
|
10
14
|
|
11
15
|
config.include Kelp::Attribute
|
12
16
|
config.include Kelp::Checkbox
|
data/spec/visibility_spec.rb
CHANGED
@@ -337,7 +337,7 @@ describe Kelp::Visibility, "should_see_button" do
|
|
337
337
|
context "passes when" do
|
338
338
|
it "an input tag with the given value exists" do
|
339
339
|
should_see_button "Save preferences"
|
340
|
-
|
340
|
+
should_not_see_button "Save is disabled"
|
341
341
|
end
|
342
342
|
|
343
343
|
it "a button tag with the given value exists" do
|
@@ -346,7 +346,7 @@ describe Kelp::Visibility, "should_see_button" do
|
|
346
346
|
|
347
347
|
it "an input tag with the given value exists within a scope" do
|
348
348
|
should_see_button "Save preferences", :within => "#preferences_form"
|
349
|
-
|
349
|
+
should_not_see_button "Save is disabled", :within => "#other_form"
|
350
350
|
end
|
351
351
|
|
352
352
|
it "a button tag with the given value exists within a scope" do
|
metadata
CHANGED
@@ -1,135 +1,138 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: kelp
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 2
|
9
|
-
- 3
|
10
|
-
version: 0.2.3
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.4
|
5
|
+
prerelease:
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Eric Pierce
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
dependencies:
|
21
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2013-06-04 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
22
15
|
name: capybara
|
23
|
-
|
24
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
25
17
|
none: false
|
26
|
-
requirements:
|
27
|
-
- -
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
|
30
|
-
segments:
|
31
|
-
- 0
|
32
|
-
- 4
|
33
|
-
- 0
|
34
|
-
version: 0.4.0
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 2.0.1
|
35
22
|
type: :runtime
|
36
|
-
version_requirements: *id001
|
37
|
-
- !ruby/object:Gem::Dependency
|
38
|
-
name: sinatra
|
39
23
|
prerelease: false
|
40
|
-
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
25
|
none: false
|
42
|
-
requirements:
|
43
|
-
- -
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 2.0.1
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: sinatra
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
49
38
|
type: :development
|
50
|
-
version_requirements: *id002
|
51
|
-
- !ruby/object:Gem::Dependency
|
52
|
-
name: rspec
|
53
39
|
prerelease: false
|
54
|
-
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
55
41
|
none: false
|
56
|
-
requirements:
|
57
|
-
- -
|
58
|
-
- !ruby/object:Gem::Version
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
64
53
|
version: 2.2.0
|
65
54
|
type: :development
|
66
|
-
version_requirements: *id003
|
67
|
-
- !ruby/object:Gem::Dependency
|
68
|
-
name: rspec-rails
|
69
55
|
prerelease: false
|
70
|
-
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
57
|
none: false
|
72
|
-
requirements:
|
73
|
-
- -
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.2.0
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rspec-rails
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
79
70
|
type: :development
|
80
|
-
version_requirements: *id004
|
81
|
-
- !ruby/object:Gem::Dependency
|
82
|
-
name: rcov
|
83
71
|
prerelease: false
|
84
|
-
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: simplecov
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
85
81
|
none: false
|
86
|
-
requirements:
|
87
|
-
- -
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
|
90
|
-
segments:
|
91
|
-
- 0
|
92
|
-
version: "0"
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
93
86
|
type: :development
|
94
|
-
version_requirements: *id005
|
95
|
-
- !ruby/object:Gem::Dependency
|
96
|
-
name: webrat
|
97
87
|
prerelease: false
|
98
|
-
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: webrat
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
99
97
|
none: false
|
100
|
-
requirements:
|
101
|
-
- -
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
|
104
|
-
segments:
|
105
|
-
- 0
|
106
|
-
version: "0"
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
107
102
|
type: :development
|
108
|
-
version_requirements: *id006
|
109
|
-
- !ruby/object:Gem::Dependency
|
110
|
-
name: cucumber
|
111
103
|
prerelease: false
|
112
|
-
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: cucumber
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
113
|
none: false
|
114
|
-
requirements:
|
115
|
-
- -
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
|
118
|
-
segments:
|
119
|
-
- 0
|
120
|
-
version: "0"
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
121
118
|
type: :development
|
122
|
-
|
123
|
-
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
description: ! " Kelp is a collection of helper methods for Cucumber to ease the
|
127
|
+
process of\n writing step definitions. It also includes a Rails generator for
|
128
|
+
generic\n step definitions building upon those helpers.\n"
|
124
129
|
email: wapcaplet88@gmail.com
|
125
130
|
executables: []
|
126
|
-
|
127
131
|
extensions: []
|
128
|
-
|
129
132
|
extra_rdoc_files: []
|
130
|
-
|
131
|
-
files:
|
133
|
+
files:
|
132
134
|
- .gitignore
|
135
|
+
- .simplecov
|
133
136
|
- .yardopts
|
134
137
|
- Gemfile
|
135
138
|
- History.md
|
@@ -138,6 +141,8 @@ files:
|
|
138
141
|
- Rakefile
|
139
142
|
- examples/sinatra_app/app.rb
|
140
143
|
- examples/sinatra_app/config.ru
|
144
|
+
- examples/sinatra_app/features/ambiguous_field.feature
|
145
|
+
- examples/sinatra_app/features/ambiguous_field_fail.feature
|
141
146
|
- examples/sinatra_app/features/checkbox.feature
|
142
147
|
- examples/sinatra_app/features/checkbox_fail.feature
|
143
148
|
- examples/sinatra_app/features/dropdown.feature
|
@@ -154,6 +159,7 @@ files:
|
|
154
159
|
- examples/sinatra_app/views/edit2.erb
|
155
160
|
- examples/sinatra_app/views/edit3.erb
|
156
161
|
- examples/sinatra_app/views/form.erb
|
162
|
+
- examples/sinatra_app/views/form2.erb
|
157
163
|
- examples/sinatra_app/views/home.erb
|
158
164
|
- examples/sinatra_app/views/thanks.erb
|
159
165
|
- features/kelp_step_definitions.feature
|
@@ -185,39 +191,28 @@ files:
|
|
185
191
|
- spec/spec_helper.rb
|
186
192
|
- spec/visibility_spec.rb
|
187
193
|
- spec/xpath_spec.rb
|
188
|
-
has_rdoc: true
|
189
194
|
homepage: http://github.com/wapcaplet/kelp
|
190
195
|
licenses: []
|
191
|
-
|
192
196
|
post_install_message:
|
193
197
|
rdoc_options: []
|
194
|
-
|
195
|
-
require_paths:
|
198
|
+
require_paths:
|
196
199
|
- lib
|
197
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
200
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
198
201
|
none: false
|
199
|
-
requirements:
|
200
|
-
- -
|
201
|
-
- !ruby/object:Gem::Version
|
202
|
-
|
203
|
-
|
204
|
-
- 0
|
205
|
-
version: "0"
|
206
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
202
|
+
requirements:
|
203
|
+
- - ! '>='
|
204
|
+
- !ruby/object:Gem::Version
|
205
|
+
version: '0'
|
206
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
207
207
|
none: false
|
208
|
-
requirements:
|
209
|
-
- -
|
210
|
-
- !ruby/object:Gem::Version
|
211
|
-
|
212
|
-
segments:
|
213
|
-
- 0
|
214
|
-
version: "0"
|
208
|
+
requirements:
|
209
|
+
- - ! '>='
|
210
|
+
- !ruby/object:Gem::Version
|
211
|
+
version: '0'
|
215
212
|
requirements: []
|
216
|
-
|
217
213
|
rubyforge_project:
|
218
|
-
rubygems_version: 1.
|
214
|
+
rubygems_version: 1.8.24
|
219
215
|
signing_key:
|
220
216
|
specification_version: 3
|
221
217
|
summary: Cucumber helper methods
|
222
218
|
test_files: []
|
223
|
-
|