2009-11-26 17:47:58 -05:00
|
|
|
module Capybara
|
2010-01-01 11:48:39 -05:00
|
|
|
|
2010-07-11 11:26:08 -04:00
|
|
|
##
|
|
|
|
#
|
2010-07-14 17:59:23 -04:00
|
|
|
# The Session class represents a single user's interaction with the system. The Session can use
|
|
|
|
# any of the underlying drivers. A session can be initialized manually like this:
|
2010-07-11 11:26:08 -04:00
|
|
|
#
|
|
|
|
# session = Capybara::Session.new(:culerity, MyRackApp)
|
|
|
|
#
|
|
|
|
# The application given as the second argument is optional. When running Capybara against an external
|
|
|
|
# page, you might want to leave it out:
|
|
|
|
#
|
|
|
|
# session = Capybara::Session.new(:culerity)
|
|
|
|
# session.visit('http://www.google.com')
|
|
|
|
#
|
|
|
|
# Session provides a number of methods for controlling the navigation of the page, such as +visit+,
|
|
|
|
# +current_path, and so on. It also delegate a number of methods to a Capybara::Document, representing
|
|
|
|
# the current HTML document. This allows interaction:
|
|
|
|
#
|
|
|
|
# session.fill_in('q', :with => 'Capybara')
|
|
|
|
# session.click_button('Search')
|
2013-11-14 12:43:36 -05:00
|
|
|
# expect(session).to have_content('Capybara')
|
2010-07-11 11:26:08 -04:00
|
|
|
#
|
|
|
|
# When using capybara/dsl, the Session is initialized automatically for you.
|
|
|
|
#
|
|
|
|
class Session
|
2011-03-25 09:22:47 -04:00
|
|
|
NODE_METHODS = [
|
2011-03-31 11:57:24 -04:00
|
|
|
:all, :first, :attach_file, :text, :check, :choose,
|
|
|
|
:click_link_or_button, :click_button, :click_link, :field_labeled,
|
|
|
|
:fill_in, :find, :find_button, :find_by_id, :find_field, :find_link,
|
2011-11-15 10:58:05 -05:00
|
|
|
:has_content?, :has_text?, :has_css?, :has_no_content?, :has_no_text?,
|
2012-07-21 16:44:10 -04:00
|
|
|
:has_no_css?, :has_no_xpath?, :resolve, :has_xpath?, :select, :uncheck,
|
|
|
|
:has_link?, :has_no_link?, :has_button?, :has_no_button?, :has_field?,
|
|
|
|
:has_no_field?, :has_checked_field?, :has_unchecked_field?,
|
|
|
|
:has_no_table?, :has_table?, :unselect, :has_select?, :has_no_select?,
|
|
|
|
:has_selector?, :has_no_selector?, :click_on, :has_no_checked_field?,
|
2014-01-29 06:45:18 -05:00
|
|
|
:has_no_unchecked_field?, :query, :assert_selector, :assert_no_selector,
|
|
|
|
:refute_selector
|
2009-12-29 22:05:38 -05:00
|
|
|
]
|
2011-03-25 09:22:47 -04:00
|
|
|
SESSION_METHODS = [
|
2013-06-20 16:40:32 -04:00
|
|
|
:body, :html, :source, :current_url, :current_host, :current_path,
|
2013-10-05 14:23:51 -04:00
|
|
|
:execute_script, :evaluate_script, :visit, :go_back, :go_forward,
|
2013-06-20 16:40:32 -04:00
|
|
|
:within, :within_fieldset, :within_table, :within_frame, :within_window,
|
|
|
|
:save_page, :save_and_open_page, :save_screenshot,
|
2014-03-21 22:09:15 -04:00
|
|
|
:save_and_open_screenshot, :reset_session!, :response_headers,
|
|
|
|
:status_code, :title, :has_title?, :has_no_title?, :current_scope
|
2011-03-25 09:22:47 -04:00
|
|
|
]
|
|
|
|
DSL_METHODS = NODE_METHODS + SESSION_METHODS
|
2010-01-11 17:14:52 -05:00
|
|
|
|
2012-07-13 08:57:43 -04:00
|
|
|
attr_reader :mode, :app, :server
|
2013-03-11 19:11:05 -04:00
|
|
|
attr_accessor :synchronized
|
2009-11-09 17:51:39 -05:00
|
|
|
|
2010-03-12 13:07:15 -05:00
|
|
|
def initialize(mode, app=nil)
|
2009-12-18 11:40:51 -05:00
|
|
|
@mode = mode
|
2009-11-26 17:47:58 -05:00
|
|
|
@app = app
|
2012-07-13 09:19:20 -04:00
|
|
|
if Capybara.run_server and @app and driver.needs_server?
|
|
|
|
@server = Capybara::Server.new(@app).boot
|
2012-12-02 01:14:42 -05:00
|
|
|
else
|
|
|
|
@server = nil
|
2012-07-13 07:29:02 -04:00
|
|
|
end
|
2012-12-02 01:30:29 -05:00
|
|
|
@touched = false
|
2009-11-16 14:13:06 -05:00
|
|
|
end
|
2010-01-01 11:48:39 -05:00
|
|
|
|
2009-11-26 17:47:58 -05:00
|
|
|
def driver
|
2010-07-29 09:20:11 -04:00
|
|
|
@driver ||= begin
|
|
|
|
unless Capybara.drivers.has_key?(mode)
|
|
|
|
other_drivers = Capybara.drivers.keys.map { |key| key.inspect }
|
|
|
|
raise Capybara::DriverNotFoundError, "no driver called #{mode.inspect} was found, available drivers: #{other_drivers.join(', ')}"
|
|
|
|
end
|
|
|
|
Capybara.drivers[mode].call(app)
|
2009-11-26 17:47:58 -05:00
|
|
|
end
|
2009-11-15 07:40:50 -05:00
|
|
|
end
|
2009-11-26 17:47:58 -05:00
|
|
|
|
2010-07-11 11:26:08 -04:00
|
|
|
##
|
|
|
|
#
|
2014-04-03 03:57:31 -04:00
|
|
|
# Reset the session (i.e. remove cookies and navigate to blank page)
|
|
|
|
#
|
|
|
|
# This method does not:
|
|
|
|
#
|
|
|
|
# * accept modal dialogs if they are present
|
|
|
|
# * clear browser cache/HTML 5 local storage/IndexedDB/Web SQL database/etc.
|
|
|
|
# * modify state of the driver/underlying browser in any other way
|
|
|
|
#
|
|
|
|
# as doing so will result in performance downsides and it's not needed to do everything from the list above for most apps.
|
|
|
|
#
|
|
|
|
# If you want to do anything from the list above on a general basis you can:
|
|
|
|
#
|
|
|
|
# * write RSpec/Cucumber/etc. after hook
|
|
|
|
# * monkeypatch this method
|
|
|
|
# * use Ruby's `prepend` method
|
2010-07-11 11:26:08 -04:00
|
|
|
#
|
2010-07-29 09:25:45 -04:00
|
|
|
def reset!
|
2013-10-20 13:29:22 -04:00
|
|
|
if @touched
|
|
|
|
driver.reset!
|
|
|
|
assert_no_selector :xpath, "/html/body/*"
|
2014-01-17 02:57:06 -05:00
|
|
|
@touched = false
|
2013-10-20 13:29:22 -04:00
|
|
|
end
|
2014-03-02 09:49:00 -05:00
|
|
|
raise_server_error!
|
|
|
|
end
|
|
|
|
alias_method :cleanup!, :reset!
|
|
|
|
alias_method :reset_session!, :reset!
|
|
|
|
|
|
|
|
##
|
|
|
|
#
|
|
|
|
# Raise errors encountered in the server
|
|
|
|
#
|
|
|
|
def raise_server_error!
|
2013-02-16 05:04:40 -05:00
|
|
|
raise @server.error if Capybara.raise_server_errors and @server and @server.error
|
2012-07-13 08:57:43 -04:00
|
|
|
ensure
|
|
|
|
@server.reset_error! if @server
|
2010-07-11 08:00:00 -04:00
|
|
|
end
|
2009-11-26 17:47:58 -05:00
|
|
|
|
2010-07-11 11:26:08 -04:00
|
|
|
##
|
|
|
|
#
|
|
|
|
# Returns a hash of response headers. Not supported by all drivers (e.g. Selenium)
|
|
|
|
#
|
2010-07-14 18:24:59 -04:00
|
|
|
# @return [Hash{String => String}] A hash of response headers.
|
2010-07-11 11:26:08 -04:00
|
|
|
#
|
2010-07-11 08:00:00 -04:00
|
|
|
def response_headers
|
|
|
|
driver.response_headers
|
2009-12-13 09:03:19 -05:00
|
|
|
end
|
|
|
|
|
2010-07-11 11:26:08 -04:00
|
|
|
##
|
|
|
|
#
|
|
|
|
# Returns the current HTTP status code as an Integer. Not supported by all drivers (e.g. Selenium)
|
|
|
|
#
|
2010-07-14 18:24:59 -04:00
|
|
|
# @return [Integer] Current HTTP status code
|
2010-07-11 11:26:08 -04:00
|
|
|
#
|
2010-07-11 08:00:00 -04:00
|
|
|
def status_code
|
|
|
|
driver.status_code
|
2009-11-24 15:45:52 -05:00
|
|
|
end
|
2009-11-07 12:56:04 -05:00
|
|
|
|
2010-07-11 11:26:08 -04:00
|
|
|
##
|
|
|
|
#
|
2012-09-09 21:05:17 -04:00
|
|
|
# @return [String] A snapshot of the DOM of the current document, as it looks right now (potentially modified by JavaScript).
|
2010-07-11 11:26:08 -04:00
|
|
|
#
|
2011-11-15 10:58:05 -05:00
|
|
|
def html
|
2012-09-09 21:05:17 -04:00
|
|
|
driver.html
|
2010-07-11 08:00:00 -04:00
|
|
|
end
|
2012-11-20 08:22:19 -05:00
|
|
|
alias_method :body, :html
|
|
|
|
alias_method :source, :html
|
2010-07-11 08:00:00 -04:00
|
|
|
|
2010-07-11 11:26:08 -04:00
|
|
|
##
|
|
|
|
#
|
2010-07-14 18:24:59 -04:00
|
|
|
# @return [String] Path of the current page, without any domain information
|
2010-07-11 11:26:08 -04:00
|
|
|
#
|
2010-07-09 21:11:54 -04:00
|
|
|
def current_path
|
2011-04-07 11:08:32 -04:00
|
|
|
path = URI.parse(current_url).path
|
|
|
|
path if path and not path.empty?
|
2010-07-09 21:11:54 -04:00
|
|
|
end
|
|
|
|
|
2011-03-11 11:01:13 -05:00
|
|
|
##
|
|
|
|
#
|
|
|
|
# @return [String] Host of the current page
|
|
|
|
#
|
|
|
|
def current_host
|
2011-03-25 05:01:59 -04:00
|
|
|
uri = URI.parse(current_url)
|
2011-04-07 10:18:11 -04:00
|
|
|
"#{uri.scheme}://#{uri.host}" if uri.host
|
2011-03-11 11:01:13 -05:00
|
|
|
end
|
|
|
|
|
2010-07-11 11:26:08 -04:00
|
|
|
##
|
|
|
|
#
|
2010-07-14 18:24:59 -04:00
|
|
|
# @return [String] Fully qualified URL of the current page
|
2010-07-11 11:26:08 -04:00
|
|
|
#
|
|
|
|
def current_url
|
|
|
|
driver.current_url
|
|
|
|
end
|
2013-02-16 03:34:30 -05:00
|
|
|
|
2013-02-06 14:36:55 -05:00
|
|
|
##
|
|
|
|
#
|
|
|
|
# @return [String] Title of the current page
|
|
|
|
#
|
|
|
|
def title
|
|
|
|
driver.title
|
|
|
|
end
|
2010-07-11 11:26:08 -04:00
|
|
|
|
|
|
|
##
|
|
|
|
#
|
|
|
|
# Navigate to the given URL. The URL can either be a relative URL or an absolute URL
|
|
|
|
# The behaviour of either depends on the driver.
|
|
|
|
#
|
|
|
|
# session.visit('/foo')
|
|
|
|
# session.visit('http://google.com')
|
|
|
|
#
|
2012-08-02 11:31:50 -04:00
|
|
|
# For drivers which can run against an external application, such as the selenium driver
|
2010-07-11 11:26:08 -04:00
|
|
|
# giving an absolute URL will navigate to that page. This allows testing applications
|
2012-08-02 11:31:50 -04:00
|
|
|
# running on remote servers. For these drivers, setting {Capybara.app_host} will make the
|
2010-07-11 11:26:08 -04:00
|
|
|
# remote server the default. For example:
|
|
|
|
#
|
|
|
|
# Capybara.app_host = 'http://google.com'
|
|
|
|
# session.visit('/') # visits the google homepage
|
|
|
|
#
|
2012-08-02 11:31:50 -04:00
|
|
|
# If {Capybara.always_include_port} is set to true and this session is running against
|
|
|
|
# a rack application, then the port that the rack application is running on will automatically
|
|
|
|
# be inserted into the URL. Supposing the app is running on port `4567`, doing something like:
|
|
|
|
#
|
|
|
|
# visit("http://google.com/test")
|
|
|
|
#
|
|
|
|
# Will actually navigate to `http://google.com:4567/test`.
|
|
|
|
#
|
2010-07-14 18:24:59 -04:00
|
|
|
# @param [String] url The URL to navigate to
|
2010-07-11 11:26:08 -04:00
|
|
|
#
|
2010-07-11 08:00:00 -04:00
|
|
|
def visit(url)
|
2014-03-02 09:49:00 -05:00
|
|
|
raise_server_error!
|
|
|
|
|
2012-07-10 04:03:05 -04:00
|
|
|
@touched = true
|
2012-07-13 07:29:02 -04:00
|
|
|
|
2012-11-14 08:29:12 -05:00
|
|
|
if url !~ /^http/ and Capybara.app_host
|
|
|
|
url = Capybara.app_host + url.to_s
|
|
|
|
end
|
|
|
|
|
2012-07-13 07:29:02 -04:00
|
|
|
if @server
|
2012-11-14 08:29:12 -05:00
|
|
|
url = "http://#{@server.host}:#{@server.port}" + url.to_s unless url =~ /^http/
|
2012-07-13 07:29:02 -04:00
|
|
|
|
|
|
|
if Capybara.always_include_port
|
|
|
|
uri = URI.parse(url)
|
|
|
|
uri.port = @server.port if uri.port == uri.default_port
|
|
|
|
url = uri.to_s
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2010-07-11 08:00:00 -04:00
|
|
|
driver.visit(url)
|
|
|
|
end
|
|
|
|
|
2013-10-05 14:23:51 -04:00
|
|
|
##
|
|
|
|
#
|
|
|
|
# Move back a single entry in the browser's history.
|
|
|
|
#
|
|
|
|
def go_back
|
|
|
|
driver.go_back
|
|
|
|
end
|
|
|
|
|
|
|
|
##
|
|
|
|
#
|
|
|
|
# Move forward a single entry in the browser's history.
|
|
|
|
#
|
|
|
|
def go_forward
|
|
|
|
driver.go_forward
|
|
|
|
end
|
|
|
|
|
2010-07-11 11:26:08 -04:00
|
|
|
##
|
|
|
|
#
|
2013-08-26 09:13:30 -04:00
|
|
|
# Executes the given block within the context of a node. `within` takes the
|
|
|
|
# same options as `find`, as well as a block. For the duration of the
|
|
|
|
# block, any command to Capybara will be handled as though it were scoped
|
|
|
|
# to the given element.
|
2010-07-11 11:26:08 -04:00
|
|
|
#
|
|
|
|
# within(:xpath, '//div[@id="delivery-address"]') do
|
|
|
|
# fill_in('Street', :with => '12 Main Street')
|
|
|
|
# end
|
|
|
|
#
|
2013-08-26 09:13:30 -04:00
|
|
|
# Just as with `find`, if multiple elements match the selector given to
|
|
|
|
# `within`, an error will be raised, and just as with `find`, this
|
|
|
|
# behaviour can be controlled through the `:match` and `:exact` options.
|
|
|
|
#
|
|
|
|
# It is possible to omit the first parameter, in that case, the selector is
|
|
|
|
# assumed to be of the type set in Capybara.default_selector.
|
2010-07-11 11:26:08 -04:00
|
|
|
#
|
|
|
|
# within('div#delivery-address') do
|
|
|
|
# fill_in('Street', :with => '12 Main Street')
|
|
|
|
# end
|
|
|
|
#
|
2013-08-26 09:13:30 -04:00
|
|
|
# Note that a lot of uses of `within` can be replaced more succinctly with
|
|
|
|
# chaining:
|
|
|
|
#
|
|
|
|
# find('div#delivery-address').fill_in('Street', :with => '12 Main Street')
|
|
|
|
#
|
2011-08-26 13:36:51 -04:00
|
|
|
# @overload within(*find_args)
|
|
|
|
# @param (see Capybara::Node::Finders#all)
|
|
|
|
#
|
|
|
|
# @overload within(a_node)
|
|
|
|
# @param [Capybara::Node::Base] a_node The node in whose scope the block should be evaluated
|
|
|
|
#
|
2013-08-26 09:13:30 -04:00
|
|
|
# @raise [Capybara::ElementNotFound] If the scope can't be found before time expires
|
2010-07-11 11:26:08 -04:00
|
|
|
#
|
2010-12-22 10:15:06 -05:00
|
|
|
def within(*args)
|
2012-07-24 03:09:02 -04:00
|
|
|
new_scope = if args.first.is_a?(Capybara::Node::Base) then args.first else find(*args) end
|
2010-02-11 15:46:31 -05:00
|
|
|
begin
|
2010-07-09 19:38:57 -04:00
|
|
|
scopes.push(new_scope)
|
2010-02-11 15:46:31 -05:00
|
|
|
yield
|
|
|
|
ensure
|
|
|
|
scopes.pop
|
|
|
|
end
|
2009-11-26 17:47:58 -05:00
|
|
|
end
|
2009-11-14 09:11:29 -05:00
|
|
|
|
2010-07-11 11:26:08 -04:00
|
|
|
##
|
|
|
|
#
|
|
|
|
# Execute the given block within the a specific fieldset given the id or legend of that fieldset.
|
|
|
|
#
|
2010-07-14 18:24:59 -04:00
|
|
|
# @param [String] locator Id or legend of the fieldset
|
2010-07-11 11:26:08 -04:00
|
|
|
#
|
2009-11-26 17:47:58 -05:00
|
|
|
def within_fieldset(locator)
|
2011-08-27 17:57:12 -04:00
|
|
|
within :fieldset, locator do
|
2009-11-26 17:47:58 -05:00
|
|
|
yield
|
|
|
|
end
|
2009-11-10 16:48:31 -05:00
|
|
|
end
|
|
|
|
|
2010-07-11 11:26:08 -04:00
|
|
|
##
|
|
|
|
#
|
|
|
|
# Execute the given block within the a specific table given the id or caption of that table.
|
|
|
|
#
|
2010-07-14 18:24:59 -04:00
|
|
|
# @param [String] locator Id or caption of the table
|
2010-07-11 11:26:08 -04:00
|
|
|
#
|
2009-11-26 17:47:58 -05:00
|
|
|
def within_table(locator)
|
2011-08-27 17:57:12 -04:00
|
|
|
within :table, locator do
|
2009-11-26 17:47:58 -05:00
|
|
|
yield
|
|
|
|
end
|
|
|
|
end
|
2010-01-01 12:29:30 -05:00
|
|
|
|
2010-07-11 11:26:08 -04:00
|
|
|
##
|
|
|
|
#
|
2013-01-08 03:40:12 -05:00
|
|
|
# Execute the given block within the given iframe using given frame name or index.
|
|
|
|
# May be supported by not all drivers. Drivers that support it, may provide additional options.
|
2010-07-11 11:26:08 -04:00
|
|
|
#
|
2013-01-08 03:40:12 -05:00
|
|
|
# @overload within_frame(index)
|
|
|
|
# @param [Integer] index index of a frame
|
|
|
|
# @overload within_frame(name)
|
|
|
|
# @param [String] name name of a frame
|
2010-07-11 11:26:08 -04:00
|
|
|
#
|
2013-01-08 03:40:12 -05:00
|
|
|
def within_frame(frame_handle)
|
2013-07-02 13:50:18 -04:00
|
|
|
scopes.push(nil)
|
2013-01-08 03:40:12 -05:00
|
|
|
driver.within_frame(frame_handle) do
|
2009-11-26 17:47:58 -05:00
|
|
|
yield
|
|
|
|
end
|
2013-07-02 13:50:18 -04:00
|
|
|
ensure
|
|
|
|
scopes.pop
|
2010-08-27 15:00:08 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
##
|
|
|
|
#
|
2010-08-28 12:50:34 -04:00
|
|
|
# Execute the given block within the given window. Only works on
|
2010-08-27 15:00:08 -04:00
|
|
|
# some drivers (e.g. Selenium)
|
|
|
|
#
|
2012-07-09 11:56:20 -04:00
|
|
|
# @param [String] handle of the window
|
2010-08-27 15:00:08 -04:00
|
|
|
#
|
2010-08-28 12:50:34 -04:00
|
|
|
def within_window(handle, &blk)
|
2013-07-02 13:50:18 -04:00
|
|
|
scopes.push(nil)
|
2010-08-28 12:50:34 -04:00
|
|
|
driver.within_window(handle, &blk)
|
2013-07-02 13:50:18 -04:00
|
|
|
ensure
|
|
|
|
scopes.pop
|
2009-11-26 17:47:58 -05:00
|
|
|
end
|
2010-01-01 12:29:30 -05:00
|
|
|
|
2010-07-11 11:26:08 -04:00
|
|
|
##
|
|
|
|
#
|
|
|
|
# Execute the given script, not returning a result. This is useful for scripts that return
|
2011-12-08 14:59:17 -05:00
|
|
|
# complex objects, such as jQuery statements. +execute_script+ should be used over
|
2010-07-11 11:26:08 -04:00
|
|
|
# +evaluate_script+ whenever possible.
|
|
|
|
#
|
2010-07-14 18:24:59 -04:00
|
|
|
# @param [String] script A string of JavaScript to execute
|
2010-07-11 11:26:08 -04:00
|
|
|
#
|
2010-07-09 19:42:59 -04:00
|
|
|
def execute_script(script)
|
2012-07-10 04:03:05 -04:00
|
|
|
@touched = true
|
2010-07-09 19:42:59 -04:00
|
|
|
driver.execute_script(script)
|
|
|
|
end
|
|
|
|
|
2010-07-11 11:26:08 -04:00
|
|
|
##
|
|
|
|
#
|
|
|
|
# Evaluate the given JavaScript and return the result. Be careful when using this with
|
|
|
|
# scripts that return complex objects, such as jQuery statements. +execute_script+ might
|
|
|
|
# be a better alternative.
|
|
|
|
#
|
2010-07-14 18:24:59 -04:00
|
|
|
# @param [String] script A string of JavaScript to evaluate
|
|
|
|
# @return [Object] The result of the evaluated JavaScript (may be driver specific)
|
2010-07-11 11:26:08 -04:00
|
|
|
#
|
2010-07-09 19:42:59 -04:00
|
|
|
def evaluate_script(script)
|
2012-07-10 04:03:05 -04:00
|
|
|
@touched = true
|
2010-07-09 19:42:59 -04:00
|
|
|
driver.evaluate_script(script)
|
|
|
|
end
|
|
|
|
|
2010-07-11 11:26:08 -04:00
|
|
|
##
|
|
|
|
#
|
2012-07-24 03:05:50 -04:00
|
|
|
# Save a snapshot of the page.
|
|
|
|
#
|
|
|
|
# @param [String] path The path to where it should be saved [optional]
|
2010-07-11 11:26:08 -04:00
|
|
|
#
|
2012-07-24 03:05:50 -04:00
|
|
|
def save_page(path=nil)
|
2014-03-21 22:09:15 -04:00
|
|
|
path ||= default_path('html')
|
2012-07-24 03:05:50 -04:00
|
|
|
|
|
|
|
FileUtils.mkdir_p(File.dirname(path))
|
|
|
|
|
2014-01-07 12:32:36 -05:00
|
|
|
File.open(path,'wb') { |f| f.write(Capybara::Helpers.inject_asset_host(body)) }
|
2012-07-24 03:05:50 -04:00
|
|
|
path
|
2011-02-12 15:18:47 -05:00
|
|
|
end
|
|
|
|
|
2012-07-24 03:05:50 -04:00
|
|
|
##
|
|
|
|
#
|
|
|
|
# Save a snapshot of the page and open it in a browser for inspection
|
|
|
|
#
|
2013-03-28 22:15:07 -04:00
|
|
|
# @param [String] file_name The path to where it should be saved [optional]
|
2012-07-24 03:05:50 -04:00
|
|
|
#
|
2012-06-08 04:24:41 -04:00
|
|
|
def save_and_open_page(file_name=nil)
|
2013-08-13 15:32:29 -04:00
|
|
|
file_name = save_page(file_name)
|
2014-03-21 22:09:15 -04:00
|
|
|
open_file(file_name)
|
2010-07-09 19:42:59 -04:00
|
|
|
end
|
|
|
|
|
2012-07-10 00:50:15 -04:00
|
|
|
##
|
|
|
|
#
|
|
|
|
# Save a screenshot of page
|
|
|
|
#
|
|
|
|
# @param [String] path A string of image path
|
|
|
|
# @option [Hash] options Options for saving screenshot
|
|
|
|
def save_screenshot(path, options={})
|
2014-03-21 22:09:15 -04:00
|
|
|
path ||= default_path('png')
|
|
|
|
|
|
|
|
FileUtils.mkdir_p(File.dirname(path))
|
|
|
|
|
2012-07-10 00:50:15 -04:00
|
|
|
driver.save_screenshot(path, options)
|
2014-03-21 22:09:15 -04:00
|
|
|
path
|
|
|
|
end
|
|
|
|
|
|
|
|
##
|
|
|
|
#
|
|
|
|
# Save a screenshot of the page and open it for inspection
|
|
|
|
#
|
|
|
|
# @param [String] file_name The path to where it should be saved [optional]
|
|
|
|
#
|
|
|
|
def save_and_open_screenshot(file_name=nil)
|
|
|
|
file_name = save_screenshot(file_name)
|
|
|
|
open_file(file_name)
|
2012-07-10 00:50:15 -04:00
|
|
|
end
|
|
|
|
|
2010-07-11 08:00:00 -04:00
|
|
|
def document
|
2011-07-13 09:39:17 -04:00
|
|
|
@document ||= Capybara::Node::Document.new(self, driver)
|
2010-07-11 08:00:00 -04:00
|
|
|
end
|
|
|
|
|
2011-03-25 09:22:47 -04:00
|
|
|
NODE_METHODS.each do |method|
|
2012-09-09 17:36:45 -04:00
|
|
|
define_method method do |*args, &block|
|
|
|
|
@touched = true
|
2013-02-17 10:19:26 -05:00
|
|
|
current_scope.send(method, *args, &block)
|
2012-09-09 17:36:45 -04:00
|
|
|
end
|
2010-07-11 08:00:00 -04:00
|
|
|
end
|
|
|
|
|
2011-07-20 16:55:06 -04:00
|
|
|
def inspect
|
|
|
|
%(#<Capybara::Session>)
|
|
|
|
end
|
|
|
|
|
2013-02-16 03:34:30 -05:00
|
|
|
def has_title?(content)
|
|
|
|
document.synchronize do
|
|
|
|
unless title.match(Capybara::Helpers.to_regexp(content))
|
|
|
|
raise ExpectationNotMet
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return true
|
|
|
|
rescue Capybara::ExpectationNotMet
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
def has_no_title?(content)
|
|
|
|
document.synchronize do
|
|
|
|
if title.match(Capybara::Helpers.to_regexp(content))
|
|
|
|
raise ExpectationNotMet
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return true
|
|
|
|
rescue Capybara::ExpectationNotMet
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
2013-02-17 10:19:26 -05:00
|
|
|
def current_scope
|
2013-07-02 13:50:18 -04:00
|
|
|
scopes.last || document
|
2009-11-26 17:47:58 -05:00
|
|
|
end
|
|
|
|
|
2013-02-17 10:19:26 -05:00
|
|
|
private
|
2013-02-19 17:57:34 -05:00
|
|
|
|
2014-03-21 22:09:15 -04:00
|
|
|
def open_file(file_name)
|
|
|
|
begin
|
|
|
|
require "launchy"
|
|
|
|
Launchy.open(file_name)
|
|
|
|
rescue LoadError
|
|
|
|
warn "File saved to #{file_name}."
|
|
|
|
warn "Please install the launchy gem to open the file automatically."
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def default_path(extension)
|
|
|
|
timestamp = Time.new.strftime("%Y%m%d%H%M%S")
|
|
|
|
path = "capybara-#{timestamp}#{rand(10**10)}.#{extension}"
|
|
|
|
File.expand_path(path, Capybara.save_and_open_page_path)
|
|
|
|
end
|
|
|
|
|
2009-11-26 17:47:58 -05:00
|
|
|
def scopes
|
2010-07-09 19:38:57 -04:00
|
|
|
@scopes ||= [document]
|
2009-11-26 17:47:58 -05:00
|
|
|
end
|
2009-11-14 09:11:29 -05:00
|
|
|
end
|
2009-11-07 09:36:58 -05:00
|
|
|
end
|