mirror of
https://github.com/teamcapybara/capybara.git
synced 2022-11-09 12:08:07 -05:00
146 lines
4 KiB
Ruby
146 lines
4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Capybara
|
|
##
|
|
# The {Window} class represents a browser window.
|
|
#
|
|
# You can get an instance of the class by calling either of:
|
|
#
|
|
# * {Capybara::Session#windows}
|
|
# * {Capybara::Session#current_window}
|
|
# * {Capybara::Session#window_opened_by}
|
|
# * {Capybara::Session#switch_to_window}
|
|
#
|
|
# Note that some drivers (e.g. Selenium) support getting size of/resizing/closing only
|
|
# current window. So if you invoke such method for:
|
|
#
|
|
# * window that is current, Capybara will make 2 Selenium method invocations
|
|
# (get handle of current window + get size/resize/close).
|
|
# * window that is not current, Capybara will make 4 Selenium method invocations
|
|
# (get handle of current window + switch to given handle + get size/resize/close + switch to original handle)
|
|
#
|
|
class Window
|
|
# @return [String] a string that uniquely identifies window within session
|
|
attr_reader :handle
|
|
|
|
# @return [Capybara::Session] session that this window belongs to
|
|
attr_reader :session
|
|
|
|
# @api private
|
|
def initialize(session, handle)
|
|
@session = session
|
|
@driver = session.driver
|
|
@handle = handle
|
|
end
|
|
|
|
##
|
|
# @return [Boolean] whether the window is not closed
|
|
def exists?
|
|
@driver.window_handles.include?(@handle)
|
|
end
|
|
|
|
##
|
|
# @return [Boolean] whether the window is closed
|
|
def closed?
|
|
!exists?
|
|
end
|
|
|
|
##
|
|
# @return [Boolean] whether this window is the window in which commands are being executed
|
|
def current?
|
|
@driver.current_window_handle == @handle
|
|
rescue @driver.no_such_window_error
|
|
false
|
|
end
|
|
|
|
##
|
|
# Close window.
|
|
#
|
|
# If this method was called for window that is current, then after calling this method
|
|
# future invocations of other Capybara methods should raise
|
|
# {Capybara::Driver::Base#no_such_window_error session.driver.no_such_window_error} until another window will be switched to.
|
|
#
|
|
# @!macro about_current
|
|
# If this method was called for window that is not current, then after calling this method
|
|
# current window should remain the same as it was before calling this method.
|
|
#
|
|
def close
|
|
@driver.close_window(handle)
|
|
end
|
|
|
|
##
|
|
# Get window size.
|
|
#
|
|
# @macro about_current
|
|
# @return [Array<(Integer, Integer)>] an array with width and height
|
|
#
|
|
def size
|
|
@driver.window_size(handle)
|
|
end
|
|
|
|
##
|
|
# Resize window.
|
|
#
|
|
# @macro about_current
|
|
# @param width [String] the new window width in pixels
|
|
# @param height [String] the new window height in pixels
|
|
#
|
|
def resize_to(width, height)
|
|
wait_for_stable_size { @driver.resize_window_to(handle, width, height) }
|
|
end
|
|
|
|
##
|
|
# Maximize window.
|
|
#
|
|
# If a particular driver (e.g. headless driver) doesn't have concept of maximizing it
|
|
# may not support this method.
|
|
#
|
|
# @macro about_current
|
|
#
|
|
def maximize
|
|
wait_for_stable_size { @driver.maximize_window(handle) }
|
|
end
|
|
|
|
##
|
|
# Fullscreen window.
|
|
#
|
|
# If a particular driver doesn't have concept of fullscreen it may not support this method.
|
|
#
|
|
# @macro about_current
|
|
#
|
|
def fullscreen
|
|
@driver.fullscreen_window(handle)
|
|
end
|
|
|
|
def eql?(other)
|
|
other.is_a?(self.class) && @session == other.session && @handle == other.handle
|
|
end
|
|
alias_method :==, :eql?
|
|
|
|
def hash
|
|
@session.hash ^ @handle.hash
|
|
end
|
|
|
|
def inspect
|
|
"#<Window @handle=#{@handle.inspect}>"
|
|
end
|
|
|
|
private
|
|
|
|
def wait_for_stable_size(seconds = session.config.default_max_wait_time)
|
|
res = yield if block_given?
|
|
timer = Capybara::Helpers.timer(expire_in: seconds)
|
|
loop do
|
|
prev_size = size
|
|
sleep 0.025
|
|
return res if prev_size == size
|
|
break if timer.expired?
|
|
end
|
|
raise Capybara::WindowError, "Window size not stable within #{seconds} seconds."
|
|
end
|
|
|
|
def raise_unless_current(what)
|
|
raise Capybara::WindowError, "#{what} not current window is not possible." unless current?
|
|
end
|
|
end
|
|
end
|