nimboids-capybara 1.1.2
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 +289 -0
- data/README.rdoc +722 -0
- data/lib/capybara.rb +252 -0
- data/lib/capybara/cucumber.rb +28 -0
- data/lib/capybara/driver/base.rb +64 -0
- data/lib/capybara/driver/node.rb +74 -0
- data/lib/capybara/dsl.rb +168 -0
- data/lib/capybara/node/actions.rb +162 -0
- data/lib/capybara/node/base.rb +63 -0
- data/lib/capybara/node/document.rb +25 -0
- data/lib/capybara/node/element.rb +201 -0
- data/lib/capybara/node/finders.rb +197 -0
- data/lib/capybara/node/matchers.rb +417 -0
- data/lib/capybara/node/simple.rb +132 -0
- data/lib/capybara/rack_test/browser.rb +121 -0
- data/lib/capybara/rack_test/driver.rb +80 -0
- data/lib/capybara/rack_test/form.rb +80 -0
- data/lib/capybara/rack_test/node.rb +105 -0
- data/lib/capybara/rails.rb +17 -0
- data/lib/capybara/rspec.rb +26 -0
- data/lib/capybara/rspec/features.rb +22 -0
- data/lib/capybara/rspec/matchers.rb +154 -0
- data/lib/capybara/selector.rb +89 -0
- data/lib/capybara/selenium/driver.rb +163 -0
- data/lib/capybara/selenium/node.rb +91 -0
- data/lib/capybara/server.rb +90 -0
- data/lib/capybara/session.rb +321 -0
- data/lib/capybara/spec/driver.rb +301 -0
- data/lib/capybara/spec/fixtures/capybara.jpg +3 -0
- data/lib/capybara/spec/fixtures/test_file.txt +1 -0
- data/lib/capybara/spec/public/test.js +43 -0
- data/lib/capybara/spec/session.rb +154 -0
- data/lib/capybara/spec/session/all_spec.rb +78 -0
- data/lib/capybara/spec/session/attach_file_spec.rb +73 -0
- data/lib/capybara/spec/session/check_spec.rb +65 -0
- data/lib/capybara/spec/session/choose_spec.rb +26 -0
- data/lib/capybara/spec/session/click_button_spec.rb +304 -0
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +36 -0
- data/lib/capybara/spec/session/click_link_spec.rb +119 -0
- data/lib/capybara/spec/session/current_host_spec.rb +68 -0
- data/lib/capybara/spec/session/current_url_spec.rb +15 -0
- data/lib/capybara/spec/session/fill_in_spec.rb +125 -0
- data/lib/capybara/spec/session/find_button_spec.rb +18 -0
- data/lib/capybara/spec/session/find_by_id_spec.rb +18 -0
- data/lib/capybara/spec/session/find_field_spec.rb +26 -0
- data/lib/capybara/spec/session/find_link_spec.rb +19 -0
- data/lib/capybara/spec/session/find_spec.rb +149 -0
- data/lib/capybara/spec/session/first_spec.rb +105 -0
- data/lib/capybara/spec/session/has_button_spec.rb +32 -0
- data/lib/capybara/spec/session/has_content_spec.rb +106 -0
- data/lib/capybara/spec/session/has_css_spec.rb +243 -0
- data/lib/capybara/spec/session/has_field_spec.rb +192 -0
- data/lib/capybara/spec/session/has_link_spec.rb +37 -0
- data/lib/capybara/spec/session/has_select_spec.rb +129 -0
- data/lib/capybara/spec/session/has_selector_spec.rb +129 -0
- data/lib/capybara/spec/session/has_table_spec.rb +96 -0
- data/lib/capybara/spec/session/has_xpath_spec.rb +123 -0
- data/lib/capybara/spec/session/headers.rb +19 -0
- data/lib/capybara/spec/session/javascript.rb +289 -0
- data/lib/capybara/spec/session/response_code.rb +19 -0
- data/lib/capybara/spec/session/select_spec.rb +113 -0
- data/lib/capybara/spec/session/text_spec.rb +19 -0
- data/lib/capybara/spec/session/uncheck_spec.rb +21 -0
- data/lib/capybara/spec/session/unselect_spec.rb +61 -0
- data/lib/capybara/spec/session/within_spec.rb +178 -0
- data/lib/capybara/spec/test_app.rb +142 -0
- data/lib/capybara/spec/views/buttons.erb +4 -0
- data/lib/capybara/spec/views/fieldsets.erb +29 -0
- data/lib/capybara/spec/views/form.erb +365 -0
- data/lib/capybara/spec/views/frame_one.erb +8 -0
- data/lib/capybara/spec/views/frame_two.erb +8 -0
- data/lib/capybara/spec/views/header_links.erb +7 -0
- data/lib/capybara/spec/views/host_links.erb +12 -0
- data/lib/capybara/spec/views/popup_one.erb +8 -0
- data/lib/capybara/spec/views/popup_two.erb +8 -0
- data/lib/capybara/spec/views/postback.erb +13 -0
- data/lib/capybara/spec/views/tables.erb +122 -0
- data/lib/capybara/spec/views/with_html.erb +78 -0
- data/lib/capybara/spec/views/with_html_entities.erb +1 -0
- data/lib/capybara/spec/views/with_js.erb +48 -0
- data/lib/capybara/spec/views/with_scope.erb +36 -0
- data/lib/capybara/spec/views/with_simple_html.erb +1 -0
- data/lib/capybara/spec/views/within_frames.erb +10 -0
- data/lib/capybara/spec/views/within_popups.erb +25 -0
- data/lib/capybara/util/save_and_open_page.rb +44 -0
- data/lib/capybara/util/timeout.rb +27 -0
- data/lib/capybara/version.rb +3 -0
- data/spec/basic_node_spec.rb +77 -0
- data/spec/capybara_spec.rb +46 -0
- data/spec/driver/rack_test_driver_spec.rb +89 -0
- data/spec/driver/selenium_driver_spec.rb +50 -0
- data/spec/dsl_spec.rb +253 -0
- data/spec/fixtures/selenium_driver_rspec_failure.rb +8 -0
- data/spec/fixtures/selenium_driver_rspec_success.rb +8 -0
- data/spec/rspec/features_spec.rb +45 -0
- data/spec/rspec/matchers_spec.rb +495 -0
- data/spec/rspec_spec.rb +53 -0
- data/spec/save_and_open_page_spec.rb +155 -0
- data/spec/server_spec.rb +89 -0
- data/spec/session/rack_test_session_spec.rb +55 -0
- data/spec/session/selenium_session_spec.rb +26 -0
- data/spec/spec_helper.rb +30 -0
- data/spec/string_spec.rb +77 -0
- data/spec/timeout_spec.rb +28 -0
- metadata +346 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'capybara'
|
|
2
|
+
require 'capybara/dsl'
|
|
3
|
+
|
|
4
|
+
Capybara.app = Rack::Builder.new do
|
|
5
|
+
map "/" do
|
|
6
|
+
if Rails.version.to_f >= 3.0
|
|
7
|
+
run Rails.application
|
|
8
|
+
else # Rails 2
|
|
9
|
+
use Rails::Rack::Static
|
|
10
|
+
run ActionController::Dispatcher.new
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end.to_app
|
|
14
|
+
|
|
15
|
+
Capybara.asset_root = Rails.root.join('public')
|
|
16
|
+
Capybara.save_and_open_page_path = Rails.root.join('tmp/capybara')
|
|
17
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require 'capybara'
|
|
2
|
+
require 'capybara/dsl'
|
|
3
|
+
require 'rspec/core'
|
|
4
|
+
require 'capybara/rspec/matchers'
|
|
5
|
+
require 'capybara/rspec/features'
|
|
6
|
+
|
|
7
|
+
RSpec.configure do |config|
|
|
8
|
+
config.include Capybara::DSL, :type => :request
|
|
9
|
+
config.include Capybara::DSL, :type => :acceptance
|
|
10
|
+
config.include Capybara::RSpecMatchers, :type => :request
|
|
11
|
+
config.include Capybara::RSpecMatchers, :type => :acceptance
|
|
12
|
+
# The before and after blocks must run instantaneously, because Capybara
|
|
13
|
+
# might not actually be used in all examples where it's included.
|
|
14
|
+
config.after do
|
|
15
|
+
if self.class.include?(Capybara::DSL)
|
|
16
|
+
Capybara.reset_sessions!
|
|
17
|
+
Capybara.use_default_driver
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
config.before do
|
|
21
|
+
if self.class.include?(Capybara::DSL)
|
|
22
|
+
Capybara.current_driver = Capybara.javascript_driver if example.metadata[:js]
|
|
23
|
+
Capybara.current_driver = example.metadata[:driver] if example.metadata[:driver]
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Capybara
|
|
2
|
+
module Features
|
|
3
|
+
def self.included(base)
|
|
4
|
+
base.instance_eval do
|
|
5
|
+
alias :background :before
|
|
6
|
+
alias :scenario :it
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.feature(*args, &block)
|
|
13
|
+
options = if args.last.is_a?(Hash) then args.pop else {} end
|
|
14
|
+
options[:capybara_feature] = true
|
|
15
|
+
options[:type] = :request
|
|
16
|
+
options[:caller] ||= caller
|
|
17
|
+
args.push(options)
|
|
18
|
+
|
|
19
|
+
describe(*args, &block)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
RSpec.configuration.include Capybara::Features, :capybara_feature => true
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
module Capybara
|
|
2
|
+
module RSpecMatchers
|
|
3
|
+
class HaveSelector
|
|
4
|
+
def initialize(*args)
|
|
5
|
+
@args = args
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def matches?(actual)
|
|
9
|
+
@actual = wrap(actual)
|
|
10
|
+
@actual.has_selector?(*@args)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def does_not_match?(actual)
|
|
14
|
+
@actual = wrap(actual)
|
|
15
|
+
@actual.has_no_selector?(*@args)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def failure_message_for_should
|
|
19
|
+
if normalized.failure_message
|
|
20
|
+
normalized.failure_message.call(@actual, normalized)
|
|
21
|
+
else
|
|
22
|
+
"expected #{selector_name} to return something"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def failure_message_for_should_not
|
|
27
|
+
"expected #{selector_name} not to return anything"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def description
|
|
31
|
+
"has #{selector_name}"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def selector_name
|
|
35
|
+
name = "#{normalized.name} #{normalized.locator.inspect}"
|
|
36
|
+
name << " with text #{normalized.options[:text].inspect}" if normalized.options[:text]
|
|
37
|
+
name
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def wrap(actual)
|
|
41
|
+
if actual.respond_to?("has_selector?")
|
|
42
|
+
actual
|
|
43
|
+
else
|
|
44
|
+
Capybara.string(actual.to_s)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def normalized
|
|
49
|
+
@normalized ||= Capybara::Selector.normalize(*@args)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
class HaveMatcher
|
|
54
|
+
attr_reader :name, :locator, :options, :failure_message, :actual
|
|
55
|
+
|
|
56
|
+
def initialize(name, locator, options={}, &block)
|
|
57
|
+
@name = name
|
|
58
|
+
@locator = locator
|
|
59
|
+
@options = options
|
|
60
|
+
@failure_message = block
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def arguments
|
|
64
|
+
if options.empty? then [locator] else [locator, options] end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def matches?(actual)
|
|
68
|
+
@actual = wrap(actual)
|
|
69
|
+
@actual.send(:"has_#{name}?", *arguments)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def does_not_match?(actual)
|
|
73
|
+
@actual = wrap(actual)
|
|
74
|
+
@actual.send(:"has_no_#{name}?", *arguments)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def failure_message_for_should
|
|
78
|
+
if failure_message
|
|
79
|
+
failure_message.call(actual, self)
|
|
80
|
+
else
|
|
81
|
+
"expected #{selector_name} to return something"
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def failure_message_for_should_not
|
|
86
|
+
"expected #{selector_name} not to return anything"
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def description
|
|
90
|
+
"has #{selector_name}"
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def selector_name
|
|
94
|
+
selector_name = "#{name} #{locator.inspect}"
|
|
95
|
+
selector_name << " with text #{options[:text].inspect}" if options[:text]
|
|
96
|
+
selector_name
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def wrap(actual)
|
|
100
|
+
if actual.respond_to?("has_selector?")
|
|
101
|
+
actual
|
|
102
|
+
else
|
|
103
|
+
Capybara.string(actual.to_s)
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def have_selector(*args)
|
|
109
|
+
HaveSelector.new(*args)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def have_xpath(xpath, options={})
|
|
113
|
+
HaveMatcher.new(:xpath, xpath, options)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def have_css(css, options={})
|
|
117
|
+
HaveMatcher.new(:css, css, options)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def have_content(text)
|
|
121
|
+
HaveMatcher.new(:content, text.to_s) do |page, matcher|
|
|
122
|
+
%(expected there to be content #{matcher.locator.inspect} in #{page.text.inspect})
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def have_link(locator, options={})
|
|
127
|
+
HaveMatcher.new(:link, locator, options)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def have_button(locator)
|
|
131
|
+
HaveMatcher.new(:button, locator)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def have_field(locator, options={})
|
|
135
|
+
HaveMatcher.new(:field, locator, options)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def have_checked_field(locator)
|
|
139
|
+
HaveMatcher.new(:checked_field, locator)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def have_unchecked_field(locator)
|
|
143
|
+
HaveMatcher.new(:unchecked_field, locator)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def have_select(locator, options={})
|
|
147
|
+
HaveMatcher.new(:select, locator, options)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def have_table(locator, options={})
|
|
151
|
+
HaveMatcher.new(:table, locator, options)
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
module Capybara
|
|
2
|
+
class Selector
|
|
3
|
+
attr_reader :name
|
|
4
|
+
|
|
5
|
+
class Normalized
|
|
6
|
+
attr_accessor :selector, :locator, :options, :xpaths
|
|
7
|
+
|
|
8
|
+
def failure_message; selector.failure_message; end
|
|
9
|
+
def name; selector.name; end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
class << self
|
|
13
|
+
def all
|
|
14
|
+
@selectors ||= {}
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def add(name, &block)
|
|
18
|
+
all[name.to_sym] = Capybara::Selector.new(name.to_sym, &block)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def remove(name)
|
|
22
|
+
all.delete(name.to_sym)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def normalize(*args)
|
|
26
|
+
normalized = Normalized.new
|
|
27
|
+
normalized.options = if args.last.is_a?(Hash) then args.pop else {} end
|
|
28
|
+
|
|
29
|
+
if args[1]
|
|
30
|
+
normalized.selector = all[args[0]]
|
|
31
|
+
normalized.locator = args[1]
|
|
32
|
+
else
|
|
33
|
+
normalized.selector = all.values.find { |s| s.match?(args[0]) }
|
|
34
|
+
normalized.locator = args[0]
|
|
35
|
+
end
|
|
36
|
+
normalized.selector ||= all[Capybara.default_selector]
|
|
37
|
+
|
|
38
|
+
xpath = normalized.selector.call(normalized.locator)
|
|
39
|
+
if xpath.respond_to?(:to_xpaths)
|
|
40
|
+
normalized.xpaths = xpath.to_xpaths
|
|
41
|
+
else
|
|
42
|
+
normalized.xpaths = [xpath.to_s].flatten
|
|
43
|
+
end
|
|
44
|
+
normalized
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def initialize(name, &block)
|
|
49
|
+
@name = name
|
|
50
|
+
instance_eval(&block)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def xpath(&block)
|
|
54
|
+
@xpath = block if block
|
|
55
|
+
@xpath
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def match(&block)
|
|
59
|
+
@match = block if block
|
|
60
|
+
@match
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def failure_message(&block)
|
|
64
|
+
@failure_message = block if block
|
|
65
|
+
@failure_message
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def call(locator)
|
|
69
|
+
@xpath.call(locator)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def match?(locator)
|
|
73
|
+
@match and @match.call(locator)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
Capybara.add_selector(:xpath) do
|
|
79
|
+
xpath { |xpath| xpath }
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
Capybara.add_selector(:css) do
|
|
83
|
+
xpath { |css| XPath.css(css) }
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
Capybara.add_selector(:id) do
|
|
87
|
+
xpath { |id| XPath.descendant[XPath.attr(:id) == id.to_s] }
|
|
88
|
+
match { |value| value.is_a?(Symbol) }
|
|
89
|
+
end
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
require 'selenium-webdriver'
|
|
2
|
+
|
|
3
|
+
class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|
4
|
+
DEFAULT_OPTIONS = {
|
|
5
|
+
:resynchronize => false,
|
|
6
|
+
:resynchronization_timeout => 10,
|
|
7
|
+
:browser => :firefox
|
|
8
|
+
}
|
|
9
|
+
SPECIAL_OPTIONS = [:browser, :resynchronize, :resynchronization_timeout]
|
|
10
|
+
|
|
11
|
+
attr_reader :app, :rack_server, :options
|
|
12
|
+
|
|
13
|
+
def browser
|
|
14
|
+
unless @browser
|
|
15
|
+
@browser = Selenium::WebDriver.for(options[:browser], options.reject { |key,val| SPECIAL_OPTIONS.include?(key) })
|
|
16
|
+
|
|
17
|
+
main = Process.pid
|
|
18
|
+
at_exit do
|
|
19
|
+
# Store the exit status of the test run since it goes away after calling the at_exit proc...
|
|
20
|
+
@exit_status = $!.status if $!.is_a?(SystemExit)
|
|
21
|
+
quit if Process.pid == main
|
|
22
|
+
exit @exit_status if @exit_status # Force exit with stored status
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
@browser
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def initialize(app, options={})
|
|
29
|
+
@app = app
|
|
30
|
+
@options = DEFAULT_OPTIONS.merge(options)
|
|
31
|
+
@rack_server = Capybara::Server.new(@app)
|
|
32
|
+
@rack_server.boot if Capybara.run_server
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def visit(path)
|
|
36
|
+
browser.navigate.to(url(path))
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def source
|
|
40
|
+
browser.page_source
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def body
|
|
44
|
+
browser.page_source
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def current_url
|
|
48
|
+
browser.current_url
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def find(selector)
|
|
52
|
+
browser.find_elements(:xpath, selector).map { |node| Capybara::Selenium::Node.new(self, node) }
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def wait?; true; end
|
|
56
|
+
|
|
57
|
+
def resynchronize
|
|
58
|
+
if options[:resynchronize]
|
|
59
|
+
load_wait_for_ajax_support
|
|
60
|
+
yield
|
|
61
|
+
Capybara.timeout(options[:resynchronization_timeout], self, "failed to resynchronize, ajax request timed out") do
|
|
62
|
+
evaluate_script("!window.capybaraRequestsOutstanding")
|
|
63
|
+
end
|
|
64
|
+
else
|
|
65
|
+
yield
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def execute_script(script)
|
|
70
|
+
browser.execute_script script
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def evaluate_script(script)
|
|
74
|
+
browser.execute_script "return #{script}"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def reset!
|
|
78
|
+
# Use instance variable directly so we avoid starting the browser just to reset the session
|
|
79
|
+
if @browser
|
|
80
|
+
begin
|
|
81
|
+
@browser.manage.delete_all_cookies
|
|
82
|
+
rescue Selenium::WebDriver::Error::UnhandledError => e
|
|
83
|
+
# delete_all_cookies fails when we've previously gone
|
|
84
|
+
# to about:blank, so we rescue this error and do nothing
|
|
85
|
+
# instead.
|
|
86
|
+
end
|
|
87
|
+
@browser.navigate.to('about:blank')
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def within_frame(frame_id)
|
|
92
|
+
old_window = browser.window_handle
|
|
93
|
+
browser.switch_to.frame(frame_id)
|
|
94
|
+
yield
|
|
95
|
+
browser.switch_to.window old_window
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def find_window( selector )
|
|
99
|
+
original_handle = browser.window_handle
|
|
100
|
+
browser.window_handles.each do |handle|
|
|
101
|
+
browser.switch_to.window handle
|
|
102
|
+
if( selector == browser.execute_script("return window.name") ||
|
|
103
|
+
browser.title.include?(selector) ||
|
|
104
|
+
browser.current_url.include?(selector) ||
|
|
105
|
+
(selector == handle) )
|
|
106
|
+
browser.switch_to.window original_handle
|
|
107
|
+
return handle
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
raise Capybara::ElementNotFound, "Could not find a window identified by #{selector}"
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def within_window(selector, &blk)
|
|
114
|
+
handle = find_window( selector )
|
|
115
|
+
browser.switch_to.window(handle, &blk)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def quit
|
|
119
|
+
@browser.quit
|
|
120
|
+
rescue Errno::ECONNREFUSED
|
|
121
|
+
# Browser must have already gone
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def invalid_element_errors
|
|
125
|
+
[Selenium::WebDriver::Error::ObsoleteElementError]
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
private
|
|
129
|
+
|
|
130
|
+
def load_wait_for_ajax_support
|
|
131
|
+
browser.execute_script <<-JS
|
|
132
|
+
window.capybaraRequestsOutstanding = 0;
|
|
133
|
+
(function() { // Overriding XMLHttpRequest
|
|
134
|
+
var oldXHR = window.XMLHttpRequest;
|
|
135
|
+
|
|
136
|
+
function newXHR() {
|
|
137
|
+
var realXHR = new oldXHR();
|
|
138
|
+
|
|
139
|
+
window.capybaraRequestsOutstanding++;
|
|
140
|
+
realXHR.addEventListener("readystatechange", function() {
|
|
141
|
+
if( realXHR.readyState == 4 ) {
|
|
142
|
+
setTimeout( function() {
|
|
143
|
+
window.capybaraRequestsOutstanding--;
|
|
144
|
+
if(window.capybaraRequestsOutstanding < 0) {
|
|
145
|
+
window.capybaraRequestsOutstanding = 0;
|
|
146
|
+
}
|
|
147
|
+
}, 500 );
|
|
148
|
+
}
|
|
149
|
+
}, false);
|
|
150
|
+
|
|
151
|
+
return realXHR;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
window.XMLHttpRequest = newXHR;
|
|
155
|
+
})();
|
|
156
|
+
JS
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def url(path)
|
|
160
|
+
rack_server.url(path)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
end
|