2009-11-14 09:44:46 +00:00
|
|
|
require 'selenium-webdriver'
|
2009-11-07 15:30:16 +00:00
|
|
|
|
2011-04-11 05:24:00 +00:00
|
|
|
class Capybara::Selenium::Driver < Capybara::Driver::Base
|
2011-02-22 14:53:14 +00:00
|
|
|
DEFAULT_OPTIONS = {
|
|
|
|
:browser => :firefox
|
|
|
|
}
|
2012-02-01 13:23:17 +00:00
|
|
|
SPECIAL_OPTIONS = [:browser]
|
2011-02-22 14:53:14 +00:00
|
|
|
|
2012-07-13 11:29:02 +00:00
|
|
|
attr_reader :app, :options
|
2009-11-07 15:30:16 +00:00
|
|
|
|
2010-08-30 07:19:44 +00:00
|
|
|
def browser
|
|
|
|
unless @browser
|
2011-02-22 14:53:14 +00:00
|
|
|
@browser = Selenium::WebDriver.for(options[:browser], options.reject { |key,val| SPECIAL_OPTIONS.include?(key) })
|
2011-05-13 12:22:50 +00:00
|
|
|
|
|
|
|
main = Process.pid
|
2009-11-14 09:44:46 +00:00
|
|
|
at_exit do
|
2011-08-22 08:15:03 +00:00
|
|
|
# Store the exit status of the test run since it goes away after calling the at_exit proc...
|
|
|
|
@exit_status = $!.status if $!.is_a?(SystemExit)
|
2011-05-13 12:22:50 +00:00
|
|
|
quit if Process.pid == main
|
2011-08-22 08:15:03 +00:00
|
|
|
exit @exit_status if @exit_status # Force exit with stored status
|
2009-11-14 09:44:46 +00:00
|
|
|
end
|
|
|
|
end
|
2010-08-30 07:19:44 +00:00
|
|
|
@browser
|
2009-11-07 15:30:16 +00:00
|
|
|
end
|
|
|
|
|
2010-09-07 16:35:55 +00:00
|
|
|
def initialize(app, options={})
|
2009-11-07 15:30:16 +00:00
|
|
|
@app = app
|
2012-01-08 14:01:46 +00:00
|
|
|
@browser = nil
|
2012-01-08 14:02:24 +00:00
|
|
|
@exit_status = nil
|
2011-02-22 14:53:14 +00:00
|
|
|
@options = DEFAULT_OPTIONS.merge(options)
|
2009-11-07 15:30:16 +00:00
|
|
|
end
|
2009-11-14 09:44:46 +00:00
|
|
|
|
2009-11-07 15:30:16 +00:00
|
|
|
def visit(path)
|
2012-07-13 11:29:02 +00:00
|
|
|
browser.navigate.to(path)
|
2009-11-07 15:30:16 +00:00
|
|
|
end
|
2009-11-14 09:44:46 +00:00
|
|
|
|
2012-09-10 01:05:17 +00:00
|
|
|
def html
|
2010-01-01 19:13:54 +00:00
|
|
|
browser.page_source
|
2009-11-07 15:30:16 +00:00
|
|
|
end
|
2009-11-14 09:44:46 +00:00
|
|
|
|
2009-12-16 14:16:52 +00:00
|
|
|
def current_url
|
2010-01-01 19:13:54 +00:00
|
|
|
browser.current_url
|
2009-12-16 14:16:52 +00:00
|
|
|
end
|
|
|
|
|
2009-11-07 15:30:16 +00:00
|
|
|
def find(selector)
|
2011-04-11 05:24:00 +00:00
|
|
|
browser.find_elements(:xpath, selector).map { |node| Capybara::Selenium::Node.new(self, node) }
|
2009-11-07 15:30:16 +00:00
|
|
|
end
|
2009-12-12 20:46:08 +00:00
|
|
|
|
|
|
|
def wait?; true; end
|
2012-07-13 11:29:02 +00:00
|
|
|
def needs_server?; true; end
|
2009-11-07 15:30:16 +00:00
|
|
|
|
2010-06-29 20:41:33 +00:00
|
|
|
def execute_script(script)
|
|
|
|
browser.execute_script script
|
|
|
|
end
|
|
|
|
|
2009-12-11 21:41:12 +00:00
|
|
|
def evaluate_script(script)
|
2010-01-01 19:13:54 +00:00
|
|
|
browser.execute_script "return #{script}"
|
|
|
|
end
|
2010-01-01 21:46:05 +00:00
|
|
|
|
2012-07-10 04:50:15 +00:00
|
|
|
def save_screenshot(path, options={})
|
|
|
|
browser.save_screenshot(path)
|
|
|
|
end
|
|
|
|
|
2010-07-29 13:25:45 +00:00
|
|
|
def reset!
|
2010-09-07 16:35:09 +00:00
|
|
|
# Use instance variable directly so we avoid starting the browser just to reset the session
|
2011-04-07 15:08:32 +00:00
|
|
|
if @browser
|
2012-02-01 13:23:17 +00:00
|
|
|
begin @browser.manage.delete_all_cookies
|
2012-01-08 13:53:45 +00:00
|
|
|
rescue Selenium::WebDriver::Error::UnhandledError
|
2011-04-10 17:25:39 +00:00
|
|
|
# delete_all_cookies fails when we've previously gone
|
|
|
|
# to about:blank, so we rescue this error and do nothing
|
|
|
|
# instead.
|
|
|
|
end
|
2011-04-07 15:08:32 +00:00
|
|
|
@browser.navigate.to('about:blank')
|
|
|
|
end
|
2010-01-23 11:58:30 +00:00
|
|
|
end
|
|
|
|
|
2010-01-12 20:27:39 +00:00
|
|
|
def within_frame(frame_id)
|
2010-04-28 23:03:13 +00:00
|
|
|
old_window = browser.window_handle
|
|
|
|
browser.switch_to.frame(frame_id)
|
|
|
|
yield
|
2012-04-25 09:43:56 +00:00
|
|
|
ensure
|
2010-04-28 23:03:13 +00:00
|
|
|
browser.switch_to.window old_window
|
2010-01-12 19:40:10 +00:00
|
|
|
end
|
2010-04-28 23:03:13 +00:00
|
|
|
|
2011-02-22 14:53:14 +00:00
|
|
|
def find_window( selector )
|
|
|
|
original_handle = browser.window_handle
|
|
|
|
browser.window_handles.each do |handle|
|
|
|
|
browser.switch_to.window handle
|
|
|
|
if( selector == browser.execute_script("return window.name") ||
|
|
|
|
browser.title.include?(selector) ||
|
|
|
|
browser.current_url.include?(selector) ||
|
|
|
|
(selector == handle) )
|
|
|
|
browser.switch_to.window original_handle
|
|
|
|
return handle
|
|
|
|
end
|
|
|
|
end
|
|
|
|
raise Capybara::ElementNotFound, "Could not find a window identified by #{selector}"
|
|
|
|
end
|
|
|
|
|
|
|
|
def within_window(selector, &blk)
|
|
|
|
handle = find_window( selector )
|
2010-08-28 16:50:34 +00:00
|
|
|
browser.switch_to.window(handle, &blk)
|
2010-08-27 19:00:08 +00:00
|
|
|
end
|
|
|
|
|
2011-05-13 12:22:50 +00:00
|
|
|
def quit
|
|
|
|
@browser.quit
|
|
|
|
rescue Errno::ECONNREFUSED
|
|
|
|
# Browser must have already gone
|
|
|
|
end
|
|
|
|
|
2011-07-13 13:39:17 +00:00
|
|
|
def invalid_element_errors
|
2012-11-13 13:25:45 +00:00
|
|
|
[Selenium::WebDriver::Error::StaleElementReferenceError, Selenium::WebDriver::Error::UnhandledError, Selenium::WebDriver::Error::ElementNotVisibleError]
|
2011-07-13 13:39:17 +00:00
|
|
|
end
|
2009-11-07 15:30:16 +00:00
|
|
|
end
|