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