module Watir class Window include EventuallyPresent include Waitable include Exception attr_reader :browser def initialize(browser, selector) @browser = browser @driver = browser.driver @selector = selector if selector.empty? @handle = current_window elsif selector.key? :handle @handle = selector.delete :handle else return if selector.keys.all? { |k| %i[title url index].include? k } raise ArgumentError, "invalid window selector: #{selector_string}" end end def inspect format('#<%s:0x%x located=%s>', self.class, hash * 2, !!@handle) end # # Returns window size. # # @example # size = browser.window.size # [size.width, size.height] #=> [1600, 1200] # def size use { return @driver.manage.window.size } end # # Returns window position. # # @example # position = browser.window.position # [position.x, position.y] #=> [92, 76] # def position use { return @driver.manage.window.position } end # # Resizes window to given width and height. # # @example # browser.window.resize_to 1600, 1200 # # @param [Integer] width # @param [Integer] height # def resize_to(width, height) Selenium::WebDriver::Dimension.new(Integer(width), Integer(height)).tap do |dimension| use { @driver.manage.window.size = dimension } end end # # Moves window to given x and y coordinates. # # @example # browser.window.move_to 300, 200 # # @param [Integer] x_coord # @param [Integer] y_coord # def move_to(x_coord, y_coord) Selenium::WebDriver::Point.new(Integer(x_coord), Integer(y_coord)).tap do |point| use { @driver.manage.window.position = point } end end # # Maximizes window. # # @example # browser.window.maximize # def maximize use { @driver.manage.window.maximize } end # # Returns true if window exists. # # @return [Boolean] # def exists? assert_exists true rescue NoMatchingWindowFoundException false end alias present? exists? alias exist? exists? # # Returns true if two windows are equal. # # @example # browser.window(index: 0) == browser.window(index: 1) # #=> false # # @param [Window] other # def ==(other) return false unless other.is_a?(self.class) handle == other.handle end alias eql? == def hash handle.hash ^ self.class.hash end # # Returns true if window is current. # # @example # browser.window.current? # #=> true # def current? current_window == handle end # # Closes window. # def close @browser.original_window = nil if self == @browser.original_window use { @driver.close } end # # Returns window title. # # @return [String] # def title use { return @driver.title } end # # Returns window URL. # # @return [String] # def url use { return @driver.current_url } end # # Switches to given window and executes block, then switches back. # # @example # browser.window(title: "closeable window").use do # browser.a(id: "close").click # end # def use(&blk) @browser.original_window ||= current_window wait_for_exists @driver.switch_to.window(handle, &blk) self end # # @api private # # Referenced in EventuallyPresent # def selector_string @selector.inspect end def handle @handle ||= locate end private def locate if @selector.empty? nil elsif @selector.key?(:index) @driver.window_handles[Integer(@selector[:index])] else @driver.window_handles.find { |wh| matches?(wh) } end end def assert_exists return if @driver.window_handles.include?(handle) raise(NoMatchingWindowFoundException, selector_string) end # return a handle to the currently active window if it is still open; otherwise nil def current_window @driver.window_handle rescue Selenium::WebDriver::Error::NoSuchWindowError nil end def matches?(handle) @driver.switch_to.window(handle) do matches_title = @selector[:title].nil? || @browser.title =~ /#{@selector[:title]}/ matches_url = @selector[:url].nil? || @browser.url =~ /#{@selector[:url]}/ matches_title && matches_url end rescue Selenium::WebDriver::Error::NoSuchWindowError, Selenium::WebDriver::Error::NoSuchDriverError # the window may disappear while we're iterating. false end def wait_for_exists return assert_exists unless Watir.relaxed_locate? begin wait_until(&:exists?) rescue Wait::TimeoutError raise NoMatchingWindowFoundException, selector_string end end end # Window end # Watir