capybara 0.1.3 → 0.1.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/Manifest.txt +4 -4
- data/README.rdoc +9 -2
- data/lib/capybara.rb +12 -6
- data/lib/capybara/driver/base.rb +17 -0
- data/lib/capybara/driver/culerity_driver.rb +22 -10
- data/lib/capybara/driver/rack_test_driver.rb +41 -36
- data/lib/capybara/driver/selenium_driver.rb +12 -5
- data/lib/capybara/dsl.rb +6 -6
- data/lib/capybara/node.rb +9 -5
- data/lib/capybara/rails.rb +0 -4
- data/lib/capybara/server.rb +3 -0
- data/lib/capybara/session.rb +69 -81
- data/lib/capybara/xpath.rb +124 -0
- data/spec/driver/selenium_driver_spec.rb +1 -1
- data/spec/drivers_spec.rb +20 -3
- data/spec/dsl_spec.rb +4 -3
- data/spec/public/jquery-ui.js +35 -0
- data/spec/session/culerity_session_spec.rb +4 -3
- data/spec/session/rack_test_session_spec.rb +4 -3
- data/spec/session/selenium_session_spec.rb +5 -4
- data/spec/session_spec.rb +248 -49
- data/spec/test_app.rb +1 -1
- data/spec/views/form.erb +26 -3
- data/spec/views/with_js.erb +25 -0
- data/spec/xpath_spec.rb +195 -0
- metadata +6 -6
- data/lib/capybara/driver/firewatir_driver.rb +0 -66
- data/lib/capybara/driver/safariwatir_driver.rb +0 -67
- data/spec/driver/firewatir_driver_spec.rb +0 -10
- data/spec/driver/safariwarit_driver_spec.rb +0 -10
data/Manifest.txt
CHANGED
@@ -4,10 +4,9 @@ README.rdoc
|
|
4
4
|
Rakefile
|
5
5
|
lib/capybara.rb
|
6
6
|
lib/capybara/cucumber.rb
|
7
|
+
lib/capybara/driver/base.rb
|
7
8
|
lib/capybara/driver/culerity_driver.rb
|
8
|
-
lib/capybara/driver/firewatir_driver.rb
|
9
9
|
lib/capybara/driver/rack_test_driver.rb
|
10
|
-
lib/capybara/driver/safariwatir_driver.rb
|
11
10
|
lib/capybara/driver/selenium_driver.rb
|
12
11
|
lib/capybara/dsl.rb
|
13
12
|
lib/capybara/node.rb
|
@@ -15,17 +14,17 @@ lib/capybara/rails.rb
|
|
15
14
|
lib/capybara/save_and_open_page.rb
|
16
15
|
lib/capybara/server.rb
|
17
16
|
lib/capybara/session.rb
|
17
|
+
lib/capybara/xpath.rb
|
18
18
|
script/console
|
19
19
|
script/destroy
|
20
20
|
script/generate
|
21
21
|
spec/driver/culerity_driver_spec.rb
|
22
|
-
spec/driver/firewatir_driver_spec.rb
|
23
22
|
spec/driver/rack_test_driver_spec.rb
|
24
|
-
spec/driver/safariwarit_driver_spec.rb
|
25
23
|
spec/driver/selenium_driver_spec.rb
|
26
24
|
spec/drivers_spec.rb
|
27
25
|
spec/dsl_spec.rb
|
28
26
|
spec/fixtures/test_file.txt
|
27
|
+
spec/public/jquery-ui.js
|
29
28
|
spec/public/jquery.js
|
30
29
|
spec/save_and_open_page_spec.rb
|
31
30
|
spec/session/culerity_session_spec.rb
|
@@ -42,3 +41,4 @@ spec/views/with_html.erb
|
|
42
41
|
spec/views/with_js.erb
|
43
42
|
spec/views/with_scope.erb
|
44
43
|
spec/views/with_simple_html.erb
|
44
|
+
spec/xpath_spec.rb
|
data/README.rdoc
CHANGED
@@ -119,6 +119,10 @@ Querying:
|
|
119
119
|
find_button
|
120
120
|
field_labeled
|
121
121
|
|
122
|
+
Scripting:
|
123
|
+
|
124
|
+
evaluate_script – Returns the value of the executed javascript (only works on javascript supported drivers)
|
125
|
+
|
122
126
|
Debugging:
|
123
127
|
|
124
128
|
save_and_open_page
|
@@ -158,7 +162,7 @@ For ultimate control, you can instantiate and use a session manually.
|
|
158
162
|
Capybara does not try to guess what kind of selector you are going to give it,
|
159
163
|
if you want to use CSS with your 'within' declarations for example, you'll need
|
160
164
|
to do:
|
161
|
-
|
165
|
+
|
162
166
|
within(:css, 'ul li') { ... }
|
163
167
|
|
164
168
|
Alternatively you can set the default selector to CSS, which may help if you are
|
@@ -207,6 +211,9 @@ The following people have dedicated their time and effort to Capybara:
|
|
207
211
|
* Jonas Nicklas
|
208
212
|
* Dennis Rogenius
|
209
213
|
* Rob Holland
|
214
|
+
* Wincent Colaiuta
|
215
|
+
* Andrea Fazzi
|
216
|
+
* Aslak Hellesøy
|
210
217
|
|
211
218
|
== License:
|
212
219
|
|
@@ -231,4 +238,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
231
238
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
232
239
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
233
240
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
234
|
-
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
241
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/lib/capybara.rb
CHANGED
@@ -1,30 +1,36 @@
|
|
1
1
|
require 'nokogiri'
|
2
2
|
|
3
3
|
module Capybara
|
4
|
-
VERSION = '0.1.
|
4
|
+
VERSION = '0.1.4'
|
5
5
|
|
6
6
|
class CapybaraError < StandardError; end
|
7
7
|
class DriverNotFoundError < CapybaraError; end
|
8
8
|
class ElementNotFound < CapybaraError; end
|
9
|
+
class NotSupportedByDriverError < CapybaraError; end
|
9
10
|
|
10
11
|
class << self
|
11
12
|
attr_accessor :debug, :asset_root
|
12
|
-
|
13
|
+
attr_writer :default_selector
|
14
|
+
|
15
|
+
def default_selector
|
16
|
+
@default_selector ||= :xpath
|
17
|
+
end
|
18
|
+
|
13
19
|
def log(message)
|
14
20
|
puts "[capybara] #{message}" if debug
|
15
21
|
true
|
16
22
|
end
|
17
23
|
end
|
18
24
|
|
19
|
-
autoload :Server,
|
25
|
+
autoload :Server, 'capybara/server'
|
20
26
|
autoload :Session, 'capybara/session'
|
21
|
-
autoload :Node,
|
27
|
+
autoload :Node, 'capybara/node'
|
28
|
+
autoload :XPath, 'capybara/xpath'
|
22
29
|
|
23
30
|
module Driver
|
31
|
+
autoload :Base, 'capybara/driver/base'
|
24
32
|
autoload :RackTest, 'capybara/driver/rack_test_driver'
|
25
33
|
autoload :Culerity, 'capybara/driver/culerity_driver'
|
26
|
-
autoload :SafariWatir, 'capybara/driver/safariwatir_driver'
|
27
|
-
autoload :FireWatir, 'capybara/driver/firewatir_driver'
|
28
34
|
autoload :Selenium, 'capybara/driver/selenium_driver'
|
29
35
|
end
|
30
36
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
require 'culerity'
|
2
2
|
|
3
|
-
class Capybara::Driver::Culerity
|
3
|
+
class Capybara::Driver::Culerity < Capybara::Driver::Base
|
4
4
|
class Node < Capybara::Node
|
5
5
|
def text
|
6
6
|
node.text
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
def [](name)
|
10
10
|
value = if name.to_sym == :class
|
11
11
|
node.class_name
|
@@ -18,22 +18,28 @@ class Capybara::Driver::Culerity
|
|
18
18
|
def set(value)
|
19
19
|
node.set(value)
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
def select(option)
|
23
23
|
node.select(option)
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
def click
|
27
27
|
node.click
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
|
+
def drag_to(element)
|
31
|
+
node.fire_event('mousedown')
|
32
|
+
element.node.fire_event('mousemove')
|
33
|
+
element.node.fire_event('mouseup')
|
34
|
+
end
|
35
|
+
|
30
36
|
def tag_name
|
31
37
|
# FIXME: this might be the dumbest way ever of getting the tag name
|
32
38
|
# there has to be something better...
|
33
39
|
node.to_xml[/^\s*<([a-z0-9\-\:]+)/, 1]
|
34
40
|
end
|
35
41
|
end
|
36
|
-
|
42
|
+
|
37
43
|
attr_reader :app, :rack_server
|
38
44
|
|
39
45
|
def self.server
|
@@ -51,25 +57,31 @@ class Capybara::Driver::Culerity
|
|
51
57
|
@rack_server = Capybara::Server.new(@app)
|
52
58
|
@rack_server.boot
|
53
59
|
end
|
54
|
-
|
60
|
+
|
55
61
|
def visit(path)
|
56
62
|
browser.goto(url(path))
|
57
63
|
end
|
58
|
-
|
64
|
+
|
59
65
|
def body
|
60
66
|
browser.html
|
61
67
|
end
|
62
|
-
|
68
|
+
|
63
69
|
def find(selector)
|
64
70
|
browser.elements_by_xpath(selector).map { |node| Node.new(self, node) }
|
65
71
|
end
|
72
|
+
|
73
|
+
def wait?; true; end
|
74
|
+
|
75
|
+
def evaluate_script(script)
|
76
|
+
browser.execute_script "#{script}"
|
77
|
+
end
|
66
78
|
|
67
79
|
private
|
68
80
|
|
69
81
|
def url(path)
|
70
82
|
rack_server.url(path)
|
71
83
|
end
|
72
|
-
|
84
|
+
|
73
85
|
def browser
|
74
86
|
unless @_browser
|
75
87
|
@_browser = ::Culerity::RemoteBrowserProxy.new self.class.server, {:browser => :firefox, :log_level => :off}
|
@@ -1,7 +1,8 @@
|
|
1
1
|
require 'rack/test'
|
2
2
|
require 'nokogiri'
|
3
|
+
require 'cgi'
|
3
4
|
|
4
|
-
class Capybara::Driver::RackTest
|
5
|
+
class Capybara::Driver::RackTest < Capybara::Driver::Base
|
5
6
|
class Node < Capybara::Node
|
6
7
|
def text
|
7
8
|
node.text
|
@@ -59,50 +60,39 @@ class Capybara::Driver::RackTest
|
|
59
60
|
|
60
61
|
class Form < Node
|
61
62
|
def params(button)
|
62
|
-
params =
|
63
|
-
|
64
|
-
|
65
|
-
agg
|
63
|
+
params = {}
|
64
|
+
node.xpath(".//input[@type='text' or @type='hidden' or @type='password']").map do |input|
|
65
|
+
merge_param!(params, input['name'].to_s, input['value'].to_s)
|
66
66
|
end
|
67
|
-
|
68
|
-
|
69
|
-
agg
|
67
|
+
node.xpath(".//textarea").map do |textarea|
|
68
|
+
merge_param!(params, textarea['name'].to_s, textarea.text.to_s)
|
70
69
|
end
|
71
|
-
|
72
|
-
|
73
|
-
agg
|
70
|
+
node.xpath(".//input[@type='radio' or @type='checkbox']").map do |input|
|
71
|
+
merge_param!(params, input['name'].to_s, input['value'].to_s) if input['checked']
|
74
72
|
end
|
75
|
-
|
76
|
-
agg << [input['name'].to_s, input['value'].to_s] if input['checked']
|
77
|
-
agg
|
78
|
-
end
|
79
|
-
params += node.xpath(".//select").inject([]) do |agg, select|
|
73
|
+
node.xpath(".//select").map do |select|
|
80
74
|
option = select.xpath(".//option[@selected]").first
|
81
75
|
option ||= select.xpath('.//option').first
|
82
|
-
|
83
|
-
agg
|
76
|
+
merge_param!(params, select['name'].to_s, (option['value'] || option.text).to_s) if option
|
84
77
|
end
|
85
|
-
|
86
|
-
if
|
87
|
-
|
88
|
-
|
89
|
-
|
78
|
+
node.xpath(".//input[@type='file']").map do |input|
|
79
|
+
if input['value'].to_s.any?
|
80
|
+
if multipart?
|
81
|
+
merge_param!(params, input['name'].to_s, Rack::Test::UploadedFile.new(input['value'].to_s))
|
82
|
+
else
|
83
|
+
merge_param!(params, input['name'].to_s, File.basename(input['value'].to_s))
|
84
|
+
end
|
90
85
|
end
|
91
|
-
agg
|
92
|
-
end
|
93
|
-
params.push [button[:name], button[:value]] if button[:name]
|
94
|
-
if multipart?
|
95
|
-
params.inject({}) { |agg, (key, value)| agg[key] = value; agg }
|
96
|
-
else
|
97
|
-
params.map { |key, value| "#{key}=#{value}" }.join('&')
|
98
86
|
end
|
87
|
+
merge_param!(params, button[:name], button[:value]) if button[:name]
|
88
|
+
params
|
99
89
|
end
|
100
90
|
|
101
91
|
def submit(button)
|
102
92
|
if post?
|
103
|
-
driver.submit(node['action'].to_s, params(button))
|
93
|
+
driver.submit(node['action'].to_s, params(button))
|
104
94
|
else
|
105
|
-
driver.visit(node['action'].to_s
|
95
|
+
driver.visit(node['action'].to_s, params(button))
|
106
96
|
end
|
107
97
|
end
|
108
98
|
|
@@ -113,6 +103,21 @@ class Capybara::Driver::RackTest
|
|
113
103
|
def post?
|
114
104
|
self[:method] =~ /post/i
|
115
105
|
end
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
def merge_param!(params, key, value)
|
110
|
+
collection = key.sub!(/\[\]$/, '')
|
111
|
+
if collection
|
112
|
+
if params[key]
|
113
|
+
params[key] << value
|
114
|
+
else
|
115
|
+
params[key] = [value]
|
116
|
+
end
|
117
|
+
else
|
118
|
+
params[key] = value
|
119
|
+
end
|
120
|
+
end
|
116
121
|
end
|
117
122
|
|
118
123
|
include ::Rack::Test::Methods
|
@@ -125,8 +130,8 @@ class Capybara::Driver::RackTest
|
|
125
130
|
@app = app
|
126
131
|
end
|
127
132
|
|
128
|
-
def visit(path)
|
129
|
-
get(path)
|
133
|
+
def visit(path, attributes = {})
|
134
|
+
get(path, attributes)
|
130
135
|
follow_redirect! while response.redirect?
|
131
136
|
cache_body
|
132
137
|
end
|
@@ -134,9 +139,9 @@ class Capybara::Driver::RackTest
|
|
134
139
|
def submit(path, attributes)
|
135
140
|
post(path, attributes)
|
136
141
|
follow_redirect! while response.redirect?
|
137
|
-
cache_body
|
142
|
+
cache_body
|
138
143
|
end
|
139
|
-
|
144
|
+
|
140
145
|
def find(selector)
|
141
146
|
html.xpath(selector).map { |node| Node.new(self, node) }
|
142
147
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'selenium-webdriver'
|
2
2
|
|
3
|
-
class Capybara::Driver::Selenium
|
3
|
+
class Capybara::Driver::Selenium < Capybara::Driver::Base
|
4
4
|
class Node < Capybara::Node
|
5
5
|
def text
|
6
6
|
node.text
|
@@ -17,16 +17,13 @@ class Capybara::Driver::Selenium
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def set(value)
|
20
|
-
if tag_name == 'input' and %w(text password hidden file).include?(type)
|
20
|
+
if tag_name == 'textarea' or (tag_name == 'input' and %w(text password hidden file).include?(type))
|
21
21
|
node.clear
|
22
22
|
node.send_keys(value.to_s)
|
23
23
|
elsif tag_name == 'input' and type == 'radio'
|
24
24
|
node.select
|
25
25
|
elsif tag_name == 'input' and type == 'checkbox'
|
26
26
|
node.toggle
|
27
|
-
elsif tag_name == "textarea"
|
28
|
-
node.clear
|
29
|
-
node.send_keys(value.to_s)
|
30
27
|
end
|
31
28
|
end
|
32
29
|
|
@@ -38,6 +35,10 @@ class Capybara::Driver::Selenium
|
|
38
35
|
node.click
|
39
36
|
end
|
40
37
|
|
38
|
+
def drag_to(element)
|
39
|
+
node.drag_and_drop_on(element.node)
|
40
|
+
end
|
41
|
+
|
41
42
|
def tag_name
|
42
43
|
node.tag_name
|
43
44
|
end
|
@@ -80,6 +81,12 @@ class Capybara::Driver::Selenium
|
|
80
81
|
driver.find_elements(:xpath, selector).map { |node| Node.new(self, node) }
|
81
82
|
end
|
82
83
|
|
84
|
+
def wait?; true; end
|
85
|
+
|
86
|
+
def evaluate_script(script)
|
87
|
+
driver.execute_script "return #{script}"
|
88
|
+
end
|
89
|
+
|
83
90
|
private
|
84
91
|
|
85
92
|
def url(path)
|
data/lib/capybara/dsl.rb
CHANGED
@@ -12,7 +12,7 @@ module Capybara
|
|
12
12
|
@current_driver || default_driver
|
13
13
|
end
|
14
14
|
alias_method :mode, :current_driver
|
15
|
-
|
15
|
+
|
16
16
|
def javascript_driver
|
17
17
|
@javascript_driver || :selenium
|
18
18
|
end
|
@@ -24,11 +24,11 @@ module Capybara
|
|
24
24
|
def current_session
|
25
25
|
session_pool["#{current_driver}#{app.object_id}"] ||= Capybara::Session.new(current_driver, app)
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
def current_session?
|
29
29
|
session_pool.has_key?("#{current_driver}#{app.object_id}")
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
def reset_sessions!
|
33
33
|
@session_pool = nil
|
34
34
|
end
|
@@ -47,10 +47,10 @@ module Capybara
|
|
47
47
|
end
|
48
48
|
|
49
49
|
SESSION_METHODS = [
|
50
|
-
:visit, :body, :click_link, :click_button, :fill_in, :choose, :has_xpath?, :has_css?,
|
50
|
+
:visit, :body, :click_link, :click_button, :drag, :fill_in, :choose, :has_xpath?, :has_css?,
|
51
51
|
:check, :uncheck, :attach_file, :select, :has_content?, :within, :within_fieldset,
|
52
|
-
:within_table, :save_and_open_page, :find_field, :find_link, :find_button,
|
53
|
-
:field_labeled
|
52
|
+
:within_table, :save_and_open_page, :find, :find_field, :find_link, :find_button,
|
53
|
+
:field_labeled, :all, :wait_for, :evaluate_script
|
54
54
|
]
|
55
55
|
SESSION_METHODS.each do |method|
|
56
56
|
class_eval <<-RUBY, __FILE__, __LINE__+1
|
data/lib/capybara/node.rb
CHANGED
@@ -9,11 +9,11 @@ class Capybara::Node
|
|
9
9
|
def text
|
10
10
|
raise "Not implemented"
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
def [](name)
|
14
14
|
raise "Not implemented"
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
def value
|
18
18
|
self[:value]
|
19
19
|
end
|
@@ -21,7 +21,7 @@ class Capybara::Node
|
|
21
21
|
def set(value)
|
22
22
|
raise "Not implemented"
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
def select(option)
|
26
26
|
raise "Not implemented"
|
27
27
|
end
|
@@ -29,8 +29,12 @@ class Capybara::Node
|
|
29
29
|
def click
|
30
30
|
raise "Not implemented"
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
|
+
def drag_to(element)
|
34
|
+
raise "Not implemented"
|
35
|
+
end
|
36
|
+
|
33
37
|
def tag_name
|
34
38
|
raise "Not implemented"
|
35
39
|
end
|
36
|
-
end
|
40
|
+
end
|