capybara 2.0.0.beta2 → 2.0.0.beta4
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/History.txt +30 -1
- data/README.md +52 -31
- data/lib/capybara.rb +1 -0
- data/lib/capybara/driver/base.rb +1 -1
- data/lib/capybara/driver/node.rb +1 -0
- data/lib/capybara/dsl.rb +12 -5
- data/lib/capybara/helpers.rb +33 -0
- data/lib/capybara/node/actions.rb +4 -2
- data/lib/capybara/node/base.rb +52 -1
- data/lib/capybara/node/element.rb +0 -12
- data/lib/capybara/node/finders.rb +1 -1
- data/lib/capybara/node/matchers.rb +57 -47
- data/lib/capybara/node/simple.rb +4 -0
- data/lib/capybara/query.rb +11 -11
- data/lib/capybara/rack_test/browser.rb +14 -15
- data/lib/capybara/rack_test/driver.rb +2 -2
- data/lib/capybara/rack_test/node.rb +15 -2
- data/lib/capybara/result.rb +7 -19
- data/lib/capybara/rspec.rb +7 -4
- data/lib/capybara/rspec/features.rb +4 -1
- data/lib/capybara/rspec/matchers.rb +8 -3
- data/lib/capybara/selector.rb +1 -2
- data/lib/capybara/selenium/driver.rb +2 -2
- data/lib/capybara/selenium/node.rb +9 -7
- data/lib/capybara/session.rb +47 -31
- data/lib/capybara/spec/fixtures/another_test_file.txt +1 -0
- data/lib/capybara/spec/public/test.js +1 -1
- data/lib/capybara/spec/session/all_spec.rb +60 -62
- data/lib/capybara/spec/session/assert_selector.rb +123 -0
- data/lib/capybara/spec/session/attach_file_spec.rb +72 -58
- data/lib/capybara/spec/session/body_spec.rb +21 -0
- data/lib/capybara/spec/session/check_spec.rb +67 -50
- data/lib/capybara/spec/session/choose_spec.rb +32 -21
- data/lib/capybara/spec/session/click_button_spec.rb +261 -221
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +40 -30
- data/lib/capybara/spec/session/click_link_spec.rb +95 -81
- data/lib/capybara/spec/session/current_url_spec.rb +70 -60
- data/lib/capybara/spec/session/evaluate_script_spec.rb +6 -0
- data/lib/capybara/spec/session/execute_script_spec.rb +7 -0
- data/lib/capybara/spec/session/fill_in_spec.rb +118 -92
- data/lib/capybara/spec/session/find_button_spec.rb +16 -14
- data/lib/capybara/spec/session/find_by_id_spec.rb +16 -14
- data/lib/capybara/spec/session/find_field_spec.rb +23 -21
- data/lib/capybara/spec/session/find_link_spec.rb +15 -14
- data/lib/capybara/spec/session/find_spec.rb +96 -91
- data/lib/capybara/spec/session/first_spec.rb +53 -55
- data/lib/capybara/spec/session/has_button_spec.rb +22 -24
- data/lib/capybara/spec/session/has_css_spec.rb +190 -205
- data/lib/capybara/spec/session/has_field_spec.rb +167 -169
- data/lib/capybara/spec/session/has_link_spec.rb +26 -29
- data/lib/capybara/spec/session/has_select_spec.rb +175 -176
- data/lib/capybara/spec/session/has_selector_spec.rb +94 -100
- data/lib/capybara/spec/session/has_table_spec.rb +22 -26
- data/lib/capybara/spec/session/has_text_spec.rb +159 -132
- data/lib/capybara/spec/session/has_xpath_spec.rb +100 -96
- data/lib/capybara/spec/session/headers.rb +4 -17
- data/lib/capybara/spec/session/html_spec.rb +15 -0
- data/lib/capybara/spec/session/node_spec.rb +172 -82
- data/lib/capybara/spec/session/reset_session_spec.rb +42 -0
- data/lib/capybara/spec/session/response_code.rb +4 -17
- data/lib/capybara/spec/session/save_page_spec.rb +46 -0
- data/lib/capybara/spec/session/screenshot.rb +8 -24
- data/lib/capybara/spec/session/select_spec.rb +100 -89
- data/lib/capybara/spec/session/source_spec.rb +12 -0
- data/lib/capybara/spec/session/text_spec.rb +15 -17
- data/lib/capybara/spec/session/uncheck_spec.rb +22 -17
- data/lib/capybara/spec/session/unselect_spec.rb +57 -52
- data/lib/capybara/spec/session/visit_spec.rb +58 -60
- data/lib/capybara/spec/session/within_frame_spec.rb +24 -26
- data/lib/capybara/spec/session/within_spec.rb +119 -121
- data/lib/capybara/spec/session/within_window_spec.rb +29 -31
- data/lib/capybara/spec/spec_helper.rb +84 -0
- data/lib/capybara/spec/test_app.rb +5 -3
- data/lib/capybara/spec/views/form.erb +1 -0
- data/lib/capybara/spec/views/with_html.erb +6 -1
- data/lib/capybara/spec/views/with_js.erb +1 -0
- data/lib/capybara/version.rb +1 -1
- data/spec/basic_node_spec.rb +2 -2
- data/spec/capybara_spec.rb +9 -0
- data/spec/dsl_spec.rb +22 -10
- data/spec/rack_test_spec.rb +28 -23
- data/spec/result_spec.rb +51 -0
- data/spec/rspec/features_spec.rb +19 -0
- data/spec/rspec/matchers_spec.rb +6 -0
- data/spec/rspec_spec.rb +1 -1
- data/spec/selenium_spec.rb +11 -25
- data/spec/server_spec.rb +2 -2
- data/spec/spec_helper.rb +1 -46
- metadata +41 -98
- data/lib/capybara/spec/session.rb +0 -183
- data/lib/capybara/spec/session/javascript.rb +0 -290
- data/lib/capybara/util/save_and_open_page.rb +0 -45
- data/spec/save_and_open_page_spec.rb +0 -155
data/lib/capybara/node/simple.rb
CHANGED
data/lib/capybara/query.rb
CHANGED
|
@@ -11,7 +11,7 @@ module Capybara
|
|
|
11
11
|
@options[:visible] = Capybara.ignore_hidden_elements
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
if args[
|
|
14
|
+
if args[0].is_a?(Symbol)
|
|
15
15
|
@selector = Selector.all[args[0]]
|
|
16
16
|
@locator = args[1]
|
|
17
17
|
else
|
|
@@ -35,21 +35,21 @@ module Capybara
|
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
def matches_filters?(node)
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
node.unsynchronized do
|
|
39
|
+
if options[:text]
|
|
40
|
+
regexp = options[:text].is_a?(Regexp) ? options[:text] : Regexp.escape(options[:text])
|
|
41
|
+
return false if not node.text.match(regexp)
|
|
42
|
+
end
|
|
43
|
+
return false if options[:visible] and not node.visible?
|
|
44
|
+
selector.custom_filters.each do |name, block|
|
|
45
|
+
return false if options.has_key?(name) and not block.call(node, options[name])
|
|
46
|
+
end
|
|
47
|
+
true
|
|
41
48
|
end
|
|
42
|
-
return false if options[:visible] and not node.visible?
|
|
43
|
-
selector.custom_filters.each do |name, block|
|
|
44
|
-
return false if options.has_key?(name) and not block.call(node, options[name])
|
|
45
|
-
end
|
|
46
|
-
true
|
|
47
49
|
end
|
|
48
50
|
|
|
49
51
|
def matches_count?(count)
|
|
50
52
|
case
|
|
51
|
-
when count.zero?
|
|
52
|
-
false
|
|
53
53
|
when options[:between]
|
|
54
54
|
options[:between] === count
|
|
55
55
|
when options[:count]
|
|
@@ -45,22 +45,18 @@ class Capybara::RackTest::Browser
|
|
|
45
45
|
new_uri = URI.parse(path)
|
|
46
46
|
method.downcase! unless method.is_a? Symbol
|
|
47
47
|
|
|
48
|
-
if
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
new_uri.path = request_path if path.start_with?("?")
|
|
49
|
+
new_uri.path = request_path.sub(%r(/[^/]*$), '/') + new_uri.path unless new_uri.path.start_with?('/')
|
|
50
|
+
new_uri.scheme ||= @current_scheme
|
|
51
|
+
new_uri.host ||= @current_host
|
|
52
|
+
new_uri.port ||= @current_port unless new_uri.default_port == @current_port
|
|
52
53
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
elsif not path.start_with?('/')
|
|
57
|
-
path = request_path.sub(%r(/[^/]*$), '/') + path
|
|
58
|
-
end
|
|
59
|
-
path = current_host + path
|
|
60
|
-
end
|
|
54
|
+
@current_scheme = new_uri.scheme
|
|
55
|
+
@current_host = new_uri.host
|
|
56
|
+
@current_port = new_uri.port
|
|
61
57
|
|
|
62
58
|
reset_cache!
|
|
63
|
-
send(method,
|
|
59
|
+
send(method, new_uri.to_s, attributes, env.merge(options[:headers] || {}))
|
|
64
60
|
end
|
|
65
61
|
|
|
66
62
|
def current_url
|
|
@@ -70,14 +66,17 @@ class Capybara::RackTest::Browser
|
|
|
70
66
|
end
|
|
71
67
|
|
|
72
68
|
def reset_host!
|
|
73
|
-
|
|
69
|
+
uri = URI.parse(Capybara.app_host || Capybara.default_host)
|
|
70
|
+
@current_scheme = uri.scheme
|
|
71
|
+
@current_host = uri.host
|
|
72
|
+
@current_port = uri.port
|
|
74
73
|
end
|
|
75
74
|
|
|
76
75
|
def reset_cache!
|
|
77
76
|
@dom = nil
|
|
78
77
|
end
|
|
79
78
|
|
|
80
|
-
def
|
|
79
|
+
def html
|
|
81
80
|
dom.to_xml
|
|
82
81
|
end
|
|
83
82
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
class Capybara::RackTest::Node < Capybara::Driver::Node
|
|
2
2
|
def text
|
|
3
|
-
|
|
3
|
+
Capybara::Helpers.normalize_whitespace(unnormalized_text)
|
|
4
4
|
end
|
|
5
5
|
|
|
6
6
|
def [](name)
|
|
@@ -12,6 +12,9 @@ class Capybara::RackTest::Node < Capybara::Driver::Node
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def set(value)
|
|
15
|
+
if (Array === value) && !self[:multiple]
|
|
16
|
+
raise ArgumentError.new "Value cannot be an Array when 'multiple' attribute is not present. Not a #{value.class}"
|
|
17
|
+
end
|
|
15
18
|
if tag_name == 'input' and type == 'radio'
|
|
16
19
|
other_radios_xpath = XPath.generate { |x| x.anywhere(:input)[x.attr(:name).equals(self[:name])] }.to_s
|
|
17
20
|
driver.dom.xpath(other_radios_xpath).each { |node| node.remove_attribute("checked") }
|
|
@@ -29,7 +32,17 @@ class Capybara::RackTest::Node < Capybara::Driver::Node
|
|
|
29
32
|
# Firefox, allowing no input
|
|
30
33
|
value = value[0...self[:maxlength].to_i]
|
|
31
34
|
end
|
|
32
|
-
|
|
35
|
+
if Array === value #Assert multiple attribute is present
|
|
36
|
+
value.each do |v|
|
|
37
|
+
new_native = native.clone
|
|
38
|
+
new_native.remove_attribute('value')
|
|
39
|
+
native.add_next_sibling(new_native)
|
|
40
|
+
new_native['value'] = v.to_s
|
|
41
|
+
end
|
|
42
|
+
native.remove
|
|
43
|
+
else
|
|
44
|
+
native['value'] = value.to_s
|
|
45
|
+
end
|
|
33
46
|
elsif tag_name == "textarea"
|
|
34
47
|
native.content = value.to_s
|
|
35
48
|
end
|
data/lib/capybara/result.rb
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
require 'forwardable'
|
|
2
|
+
|
|
1
3
|
module Capybara
|
|
2
4
|
class Result
|
|
3
5
|
include Enumerable
|
|
6
|
+
extend Forwardable
|
|
4
7
|
|
|
5
8
|
def initialize(elements, query)
|
|
6
9
|
@elements = elements
|
|
@@ -9,31 +12,21 @@ module Capybara
|
|
|
9
12
|
@query = query
|
|
10
13
|
end
|
|
11
14
|
|
|
12
|
-
|
|
13
|
-
@result.each(&block)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def first
|
|
17
|
-
@result.first
|
|
18
|
-
end
|
|
15
|
+
def_delegators :@result, :each, :[], :at, :size, :count, :length, :first, :last, :empty?
|
|
19
16
|
|
|
20
17
|
def matches_count?
|
|
21
18
|
@query.matches_count?(@result.size)
|
|
22
19
|
end
|
|
23
20
|
|
|
24
21
|
def find!
|
|
25
|
-
raise find_error if @result.
|
|
22
|
+
raise find_error if @result.size != 1
|
|
26
23
|
@result.first
|
|
27
24
|
end
|
|
28
25
|
|
|
29
|
-
def size; @result.size; end
|
|
30
|
-
alias_method :length, :size
|
|
31
|
-
alias_method :count, :size
|
|
32
|
-
|
|
33
26
|
def find_error
|
|
34
|
-
if @result.
|
|
27
|
+
if @result.size == 0
|
|
35
28
|
Capybara::ElementNotFound.new("Unable to find #{@query.description}")
|
|
36
|
-
elsif @result.
|
|
29
|
+
elsif @result.size > 1
|
|
37
30
|
Capybara::Ambiguous.new("Ambiguous match, found #{size} elements matching #{@query.description}")
|
|
38
31
|
end
|
|
39
32
|
end
|
|
@@ -66,11 +59,6 @@ module Capybara
|
|
|
66
59
|
"expected not to find #{@query.description}, but there #{declension("was", "were")} #{count} #{declension("match", "matches")}"
|
|
67
60
|
end
|
|
68
61
|
|
|
69
|
-
def empty?
|
|
70
|
-
@result.empty?
|
|
71
|
-
end
|
|
72
|
-
def [](key); @result[key]; end
|
|
73
|
-
|
|
74
62
|
private
|
|
75
63
|
|
|
76
64
|
def declension(singular, plural, count=count)
|
data/lib/capybara/rspec.rb
CHANGED
|
@@ -5,10 +5,8 @@ require 'capybara/rspec/matchers'
|
|
|
5
5
|
require 'capybara/rspec/features'
|
|
6
6
|
|
|
7
7
|
RSpec.configure do |config|
|
|
8
|
-
config.include Capybara::DSL, :type => :
|
|
9
|
-
config.include Capybara::
|
|
10
|
-
config.include Capybara::RSpecMatchers, :type => :request
|
|
11
|
-
config.include Capybara::RSpecMatchers, :type => :acceptance
|
|
8
|
+
config.include Capybara::DSL, :type => :feature
|
|
9
|
+
config.include Capybara::RSpecMatchers, :type => :feature
|
|
12
10
|
# The before and after blocks must run instantaneously, because Capybara
|
|
13
11
|
# might not actually be used in all examples where it's included.
|
|
14
12
|
config.after do
|
|
@@ -24,3 +22,8 @@ RSpec.configure do |config|
|
|
|
24
22
|
end
|
|
25
23
|
end
|
|
26
24
|
end
|
|
25
|
+
|
|
26
|
+
# Override default rack_test driver to respect data-method attributes.
|
|
27
|
+
Capybara.register_driver :rack_test do |app|
|
|
28
|
+
Capybara::RackTest::Driver.new(app, :respect_data_method => true)
|
|
29
|
+
end
|
|
@@ -4,6 +4,9 @@ module Capybara
|
|
|
4
4
|
base.instance_eval do
|
|
5
5
|
alias :background :before
|
|
6
6
|
alias :scenario :it
|
|
7
|
+
alias :xscenario :xit
|
|
8
|
+
alias :given :let
|
|
9
|
+
alias :given! :let!
|
|
7
10
|
end
|
|
8
11
|
end
|
|
9
12
|
end
|
|
@@ -12,7 +15,7 @@ end
|
|
|
12
15
|
def self.feature(*args, &block)
|
|
13
16
|
options = if args.last.is_a?(Hash) then args.pop else {} end
|
|
14
17
|
options[:capybara_feature] = true
|
|
15
|
-
options[:type] = :
|
|
18
|
+
options[:type] = :feature
|
|
16
19
|
options[:caller] ||= caller
|
|
17
20
|
args.push(options)
|
|
18
21
|
|
|
@@ -48,15 +48,15 @@ module Capybara
|
|
|
48
48
|
end
|
|
49
49
|
|
|
50
50
|
def failure_message_for_should
|
|
51
|
-
"expected there to be text #{text
|
|
51
|
+
"expected there to be text #{format(text)} in #{format(@actual.text)}"
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
def failure_message_for_should_not
|
|
55
|
-
"expected there not to be text #{text
|
|
55
|
+
"expected there not to be text #{format(text)} in #{format(@actual.text)}"
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
def description
|
|
59
|
-
"have text #{text
|
|
59
|
+
"have text #{format(text)}"
|
|
60
60
|
end
|
|
61
61
|
|
|
62
62
|
def wrap(actual)
|
|
@@ -66,6 +66,11 @@ module Capybara
|
|
|
66
66
|
Capybara.string(actual.to_s)
|
|
67
67
|
end
|
|
68
68
|
end
|
|
69
|
+
|
|
70
|
+
def format(text)
|
|
71
|
+
text = Capybara::Helpers.normalize_whitespace(text) unless text.is_a? Regexp
|
|
72
|
+
text.inspect
|
|
73
|
+
end
|
|
69
74
|
end
|
|
70
75
|
|
|
71
76
|
def have_selector(*args)
|
data/lib/capybara/selector.rb
CHANGED
|
@@ -72,7 +72,6 @@ end
|
|
|
72
72
|
|
|
73
73
|
Capybara.add_selector(:id) do
|
|
74
74
|
xpath { |id| XPath.descendant[XPath.attr(:id) == id.to_s] }
|
|
75
|
-
match { |value| value.is_a?(Symbol) }
|
|
76
75
|
end
|
|
77
76
|
|
|
78
77
|
Capybara.add_selector(:field) do
|
|
@@ -95,7 +94,7 @@ end
|
|
|
95
94
|
Capybara.add_selector(:link) do
|
|
96
95
|
xpath { |locator| XPath::HTML.link(locator) }
|
|
97
96
|
filter(:href) do |node, href|
|
|
98
|
-
node.first(:xpath, XPath.axis(:self)[XPath.attr(:href).equals(href)])
|
|
97
|
+
node.first(:xpath, XPath.axis(:self)[XPath.attr(:href).equals(href.to_s)])
|
|
99
98
|
end
|
|
100
99
|
end
|
|
101
100
|
|
|
@@ -38,7 +38,7 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|
|
38
38
|
browser.page_source
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
-
def
|
|
41
|
+
def html
|
|
42
42
|
browser.page_source
|
|
43
43
|
end
|
|
44
44
|
|
|
@@ -113,6 +113,6 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|
|
113
113
|
end
|
|
114
114
|
|
|
115
115
|
def invalid_element_errors
|
|
116
|
-
[Selenium::WebDriver::Error::
|
|
116
|
+
[Selenium::WebDriver::Error::StaleElementReferenceError, Selenium::WebDriver::Error::UnhandledError]
|
|
117
117
|
end
|
|
118
118
|
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
class Capybara::Selenium::Node < Capybara::Driver::Node
|
|
2
2
|
def text
|
|
3
|
-
|
|
3
|
+
# Selenium doesn't normalize Unicode whitespace.
|
|
4
|
+
Capybara::Helpers.normalize_whitespace(native.text)
|
|
4
5
|
end
|
|
5
6
|
|
|
6
7
|
def [](name)
|
|
@@ -18,12 +19,18 @@ class Capybara::Selenium::Node < Capybara::Driver::Node
|
|
|
18
19
|
end
|
|
19
20
|
|
|
20
21
|
def set(value)
|
|
22
|
+
tag_name = self.tag_name
|
|
23
|
+
type = self[:type]
|
|
24
|
+
if (Array === value) && !self[:multiple]
|
|
25
|
+
raise ArgumentError.new "Value cannot be an Array when 'multiple' attribute is not present. Not a #{value.class}"
|
|
26
|
+
end
|
|
21
27
|
if tag_name == 'input' and type == 'radio'
|
|
22
28
|
click
|
|
23
29
|
elsif tag_name == 'input' and type == 'checkbox'
|
|
24
30
|
click if value ^ native.attribute('checked').to_s.eql?("true")
|
|
25
31
|
elsif tag_name == 'input' and type == 'file'
|
|
26
|
-
|
|
32
|
+
path_names = value.to_s.empty? ? [] : value
|
|
33
|
+
native.send_keys(*path_names)
|
|
27
34
|
elsif tag_name == 'textarea' or tag_name == 'input'
|
|
28
35
|
native.send_keys(("\b" * native[:value].size) + value.to_s)
|
|
29
36
|
end
|
|
@@ -74,9 +81,4 @@ private
|
|
|
74
81
|
def select_node
|
|
75
82
|
find('./ancestor::select').first
|
|
76
83
|
end
|
|
77
|
-
|
|
78
|
-
def type
|
|
79
|
-
self[:type]
|
|
80
|
-
end
|
|
81
|
-
|
|
82
84
|
end
|
data/lib/capybara/session.rb
CHANGED
|
@@ -29,19 +29,18 @@ module Capybara
|
|
|
29
29
|
:click_link_or_button, :click_button, :click_link, :field_labeled,
|
|
30
30
|
:fill_in, :find, :find_button, :find_by_id, :find_field, :find_link,
|
|
31
31
|
:has_content?, :has_text?, :has_css?, :has_no_content?, :has_no_text?,
|
|
32
|
-
:has_no_css?, :has_no_xpath?, :resolve,
|
|
33
|
-
:
|
|
34
|
-
:
|
|
35
|
-
:
|
|
36
|
-
:
|
|
37
|
-
:
|
|
38
|
-
:assert_selector, :assert_no_selector
|
|
32
|
+
:has_no_css?, :has_no_xpath?, :resolve, :has_xpath?, :select, :uncheck,
|
|
33
|
+
:has_link?, :has_no_link?, :has_button?, :has_no_button?, :has_field?,
|
|
34
|
+
:has_no_field?, :has_checked_field?, :has_unchecked_field?,
|
|
35
|
+
:has_no_table?, :has_table?, :unselect, :has_select?, :has_no_select?,
|
|
36
|
+
:has_selector?, :has_no_selector?, :click_on, :has_no_checked_field?,
|
|
37
|
+
:has_no_unchecked_field?, :query, :assert_selector, :assert_no_selector
|
|
39
38
|
]
|
|
40
39
|
SESSION_METHODS = [
|
|
41
40
|
:body, :html, :current_url, :current_host, :evaluate_script, :source,
|
|
42
|
-
:visit, :within, :within_fieldset, :within_table,
|
|
43
|
-
:
|
|
44
|
-
:
|
|
41
|
+
:visit, :within, :within_fieldset, :within_table, :within_frame,
|
|
42
|
+
:within_window, :current_path, :save_page, :save_and_open_page,
|
|
43
|
+
:save_screenshot, :reset_session!, :response_headers, :status_code
|
|
45
44
|
]
|
|
46
45
|
DSL_METHODS = NODE_METHODS + SESSION_METHODS
|
|
47
46
|
|
|
@@ -101,10 +100,10 @@ module Capybara
|
|
|
101
100
|
|
|
102
101
|
##
|
|
103
102
|
#
|
|
104
|
-
# @return [String] A snapshot of the
|
|
103
|
+
# @return [String] A snapshot of the DOM of the current document, as it looks right now (potentially modified by JavaScript).
|
|
105
104
|
#
|
|
106
105
|
def html
|
|
107
|
-
driver.
|
|
106
|
+
driver.html
|
|
108
107
|
end
|
|
109
108
|
|
|
110
109
|
##
|
|
@@ -150,14 +149,22 @@ module Capybara
|
|
|
150
149
|
# session.visit('/foo')
|
|
151
150
|
# session.visit('http://google.com')
|
|
152
151
|
#
|
|
153
|
-
# For drivers which can run against an external application, such as
|
|
152
|
+
# For drivers which can run against an external application, such as the selenium driver
|
|
154
153
|
# giving an absolute URL will navigate to that page. This allows testing applications
|
|
155
|
-
# running on remote servers. For these drivers, setting Capybara.app_host will make the
|
|
154
|
+
# running on remote servers. For these drivers, setting {Capybara.app_host} will make the
|
|
156
155
|
# remote server the default. For example:
|
|
157
156
|
#
|
|
158
157
|
# Capybara.app_host = 'http://google.com'
|
|
159
158
|
# session.visit('/') # visits the google homepage
|
|
160
159
|
#
|
|
160
|
+
# If {Capybara.always_include_port} is set to true and this session is running against
|
|
161
|
+
# a rack application, then the port that the rack application is running on will automatically
|
|
162
|
+
# be inserted into the URL. Supposing the app is running on port `4567`, doing something like:
|
|
163
|
+
#
|
|
164
|
+
# visit("http://google.com/test")
|
|
165
|
+
#
|
|
166
|
+
# Will actually navigate to `http://google.com:4567/test`.
|
|
167
|
+
#
|
|
161
168
|
# @param [String] url The URL to navigate to
|
|
162
169
|
#
|
|
163
170
|
def visit(url)
|
|
@@ -203,11 +210,7 @@ module Capybara
|
|
|
203
210
|
# @raise [Capybara::ElementNotFound] If the scope can't be found before time expires
|
|
204
211
|
#
|
|
205
212
|
def within(*args)
|
|
206
|
-
new_scope = if args.
|
|
207
|
-
args.first
|
|
208
|
-
else
|
|
209
|
-
find(*args)
|
|
210
|
-
end
|
|
213
|
+
new_scope = if args.first.is_a?(Capybara::Node::Base) then args.first else find(*args) end
|
|
211
214
|
begin
|
|
212
215
|
scopes.push(new_scope)
|
|
213
216
|
yield
|
|
@@ -293,16 +296,31 @@ module Capybara
|
|
|
293
296
|
|
|
294
297
|
##
|
|
295
298
|
#
|
|
296
|
-
# Save a snapshot of the page
|
|
299
|
+
# Save a snapshot of the page.
|
|
297
300
|
#
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
+
# @param [String] path The path to where it should be saved [optional]
|
|
302
|
+
#
|
|
303
|
+
def save_page(path=nil)
|
|
304
|
+
path ||= "capybara-#{Time.new.strftime("%Y%m%d%H%M%S")}#{rand(10**10)}.html"
|
|
305
|
+
path = File.expand_path(path, Capybara.save_and_open_page_path) if Capybara.save_and_open_page_path
|
|
306
|
+
|
|
307
|
+
FileUtils.mkdir_p(File.dirname(path))
|
|
308
|
+
|
|
309
|
+
File.open(path,'w') { |f| f.write(body) }
|
|
310
|
+
path
|
|
301
311
|
end
|
|
302
312
|
|
|
313
|
+
##
|
|
314
|
+
#
|
|
315
|
+
# Save a snapshot of the page and open it in a browser for inspection
|
|
316
|
+
#
|
|
317
|
+
# @param [String] path The path to where it should be saved [optional]
|
|
318
|
+
#
|
|
303
319
|
def save_and_open_page(file_name=nil)
|
|
304
|
-
require
|
|
305
|
-
|
|
320
|
+
require "launchy"
|
|
321
|
+
Launchy.open(save_page(file_name))
|
|
322
|
+
rescue LoadError
|
|
323
|
+
warn "Please install the launchy gem to open page with save_and_open_page"
|
|
306
324
|
end
|
|
307
325
|
|
|
308
326
|
##
|
|
@@ -320,12 +338,10 @@ module Capybara
|
|
|
320
338
|
end
|
|
321
339
|
|
|
322
340
|
NODE_METHODS.each do |method|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
end
|
|
328
|
-
RUBY
|
|
341
|
+
define_method method do |*args, &block|
|
|
342
|
+
@touched = true
|
|
343
|
+
current_node.send(method, *args, &block)
|
|
344
|
+
end
|
|
329
345
|
end
|
|
330
346
|
|
|
331
347
|
def inspect
|