mirror of
https://github.com/teamcapybara/capybara.git
synced 2022-11-09 12:08:07 -05:00
Resize/get size/close should work for non-current window
This commit is contained in:
parent
397be95d09
commit
5096e90d6a
7 changed files with 107 additions and 61 deletions
|
@ -25,9 +25,11 @@ before_install:
|
||||||
- sudo apt-get update
|
- sudo apt-get update
|
||||||
- sudo apt-get install google-chrome-stable --force-yes
|
- sudo apt-get install google-chrome-stable --force-yes
|
||||||
- sudo chmod 1777 /dev/shm
|
- sudo chmod 1777 /dev/shm
|
||||||
- sudo apt-get install fluxbox -y --force-yes
|
- sudo apt-get install awesome -y; mkdir -p ~/.config/awesome
|
||||||
|
- echo "require('awful'); tags = {}; tags[1] = awful.tag({'name'})" > ~/.config/awesome/rc.lua
|
||||||
before_script:
|
before_script:
|
||||||
- export DISPLAY=:99.0
|
- export DISPLAY=:99.0
|
||||||
- sh -e /etc/init.d/xvfb start
|
- sh -e /etc/init.d/xvfb start
|
||||||
- fluxbox > /dev/null 2>&1 &
|
- sleep 1
|
||||||
|
- "awesome &"
|
||||||
script: "bundle exec rake travis"
|
script: "bundle exec rake travis"
|
||||||
|
|
|
@ -55,19 +55,19 @@ class Capybara::Driver::Base
|
||||||
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#current_window_handle'
|
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#current_window_handle'
|
||||||
end
|
end
|
||||||
|
|
||||||
def current_window_size
|
def window_size(handle)
|
||||||
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#window_size'
|
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#window_size'
|
||||||
end
|
end
|
||||||
|
|
||||||
def resize_current_window_to(width, height)
|
def resize_window_to(handle, width, height)
|
||||||
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#resize_window_to'
|
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#resize_window_to'
|
||||||
end
|
end
|
||||||
|
|
||||||
def maximize_current_window
|
def maximize_window(handle)
|
||||||
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#maximize_current_window'
|
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#maximize_current_window'
|
||||||
end
|
end
|
||||||
|
|
||||||
def close_current_window
|
def close_window(handle)
|
||||||
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#close_window'
|
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#close_window'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -130,21 +130,29 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
||||||
browser.window_handle
|
browser.window_handle
|
||||||
end
|
end
|
||||||
|
|
||||||
def current_window_size
|
def window_size(handle)
|
||||||
size = browser.manage.window.size
|
within_given_window(handle) do
|
||||||
[size.width, size.height]
|
size = browser.manage.window.size
|
||||||
|
[size.width, size.height]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def resize_current_window_to(width, height)
|
def resize_window_to(handle, width, height)
|
||||||
browser.manage.window.resize_to(width, height)
|
within_given_window(handle) do
|
||||||
|
browser.manage.window.resize_to(width, height)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def maximize_current_window
|
def maximize_window(handle)
|
||||||
browser.manage.window.maximize
|
within_given_window(handle) do
|
||||||
|
browser.manage.window.maximize
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def close_current_window
|
def close_window(handle)
|
||||||
browser.close
|
within_given_window(handle) do
|
||||||
|
browser.close
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def window_handles
|
def window_handles
|
||||||
|
@ -157,6 +165,7 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
||||||
|
|
||||||
def switch_to_window(handle)
|
def switch_to_window(handle)
|
||||||
browser.switch_to.window handle
|
browser.switch_to.window handle
|
||||||
|
sleep 0.05 # https://code.google.com/p/chromedriver/issues/detail?id=769
|
||||||
end
|
end
|
||||||
|
|
||||||
# @api private
|
# @api private
|
||||||
|
@ -166,11 +175,11 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
||||||
|
|
||||||
original_handle = browser.window_handle
|
original_handle = browser.window_handle
|
||||||
handles.each do |handle|
|
handles.each do |handle|
|
||||||
browser.switch_to.window handle
|
switch_to_window(handle)
|
||||||
if (locator == browser.execute_script("return window.name") ||
|
if (locator == browser.execute_script("return window.name") ||
|
||||||
browser.title.include?(locator) ||
|
browser.title.include?(locator) ||
|
||||||
browser.current_url.include?(locator))
|
browser.current_url.include?(locator))
|
||||||
browser.switch_to.window original_handle
|
switch_to_window(original_handle)
|
||||||
return handle
|
return handle
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -197,4 +206,18 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
||||||
def no_such_window_error
|
def no_such_window_error
|
||||||
Selenium::WebDriver::Error::NoSuchWindowError
|
Selenium::WebDriver::Error::NoSuchWindowError
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def within_given_window(handle)
|
||||||
|
original_handle = self.current_window_handle
|
||||||
|
if handle == original_handle
|
||||||
|
yield
|
||||||
|
else
|
||||||
|
switch_to_window(handle)
|
||||||
|
result = yield
|
||||||
|
switch_to_window(original_handle)
|
||||||
|
result
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,9 +16,10 @@ Capybara::SpecHelper.spec '#current_window', requires: [:windows] do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should be modified by switching to another window" do
|
it "should be modified by switching to another window" do
|
||||||
|
window = @session.window_opened_by { @session.find(:css, '#openWindow').click }
|
||||||
|
|
||||||
expect do
|
expect do
|
||||||
window = @session.window_opened_by { @session.find(:css, '#openWindow').click }
|
|
||||||
@session.switch_to_window(window)
|
@session.switch_to_window(window)
|
||||||
end.to change { @session.current_window }
|
end.to change { @session.current_window }.from(@window).to(window)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -27,7 +27,7 @@ Capybara::SpecHelper.spec '#window_opened_by', requires: [:windows] do
|
||||||
|
|
||||||
it 'should find window if value of :wait is more than timeout' do
|
it 'should find window if value of :wait is more than timeout' do
|
||||||
Capybara.using_wait_time 0.1 do
|
Capybara.using_wait_time 0.1 do
|
||||||
window = @session.window_opened_by(wait: 1) do
|
window = @session.window_opened_by(wait: 1.5) do
|
||||||
@session.find(:css, '#openWindowWithTimeout').click
|
@session.find(:css, '#openWindowWithTimeout').click
|
||||||
end
|
end
|
||||||
expect(window).to be_instance_of(Capybara::Window)
|
expect(window).to be_instance_of(Capybara::Window)
|
||||||
|
@ -47,7 +47,7 @@ Capybara::SpecHelper.spec '#window_opened_by', requires: [:windows] do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should find window if default_wait_time is more than timeout' do
|
it 'should find window if default_wait_time is more than timeout' do
|
||||||
Capybara.using_wait_time 1.2 do
|
Capybara.using_wait_time 1.5 do
|
||||||
window = @session.window_opened_by do
|
window = @session.window_opened_by do
|
||||||
@session.find(:css, '#openWindowWithTimeout').click
|
@session.find(:css, '#openWindowWithTimeout').click
|
||||||
end
|
end
|
||||||
|
|
|
@ -65,18 +65,22 @@ Capybara::SpecHelper.spec Capybara::Window, requires: [:windows] do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should change number of windows' do
|
it 'should switch to original window if invoked not for current window' do
|
||||||
expect do
|
expect(@session.windows.size).to eq(2)
|
||||||
@session.within_window(@other_window) do
|
expect(@session.current_window).to eq(@window)
|
||||||
@other_window.close
|
@other_window.close
|
||||||
end
|
expect(@session.windows.size).to eq(1)
|
||||||
end.to change { @session.windows.size }.from(2).to(1)
|
expect(@session.current_window).to eq(@window)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should raise error if invoked not for current window' do
|
it 'should make subsequent invocations of other methods raise no_such_window_error if invoked for current window' do
|
||||||
|
@session.switch_to_window(@other_window)
|
||||||
|
expect(@session.current_window).to eq(@other_window)
|
||||||
|
@other_window.close
|
||||||
expect do
|
expect do
|
||||||
@other_window.close
|
@session.find(:css, '#some_id')
|
||||||
end.to raise_error(Capybara::WindowError, "Closing not current window is not possible.")
|
end.to raise_error(@session.driver.no_such_window_error)
|
||||||
|
@session.switch_to_window(@window)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -85,13 +89,16 @@ Capybara::SpecHelper.spec Capybara::Window, requires: [:windows] do
|
||||||
expect(@session.current_window.size).to eq @session.evaluate_script("[window.outerWidth, window.outerHeight];")
|
expect(@session.current_window.size).to eq @session.evaluate_script("[window.outerWidth, window.outerHeight];")
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should raise error if invoked not for current window' do
|
it 'should switch to original window if invoked not for current window' do
|
||||||
@other_window = @session.window_opened_by do
|
@other_window = @session.window_opened_by do
|
||||||
@session.find(:css, '#openWindow').click
|
@session.find(:css, '#openWindow').click
|
||||||
end
|
end
|
||||||
expect do
|
size =
|
||||||
@other_window.size
|
@session.within_window @other_window do
|
||||||
end.to raise_error(Capybara::WindowError, "Getting size of not current window is not possible.")
|
@session.evaluate_script("[window.outerWidth, window.outerHeight];")
|
||||||
|
end
|
||||||
|
expect(@other_window.size).to eq(size)
|
||||||
|
expect(@session.current_window).to eq(@window)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -102,13 +109,13 @@ Capybara::SpecHelper.spec Capybara::Window, requires: [:windows] do
|
||||||
expect(@session.evaluate_script("[window.outerWidth, window.outerHeight];")).to eq([width-10, height-10])
|
expect(@session.evaluate_script("[window.outerWidth, window.outerHeight];")).to eq([width-10, height-10])
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should raise error if invoked not for current window' do
|
it 'should switch to original window if invoked not for current window' do
|
||||||
@other_window = @session.window_opened_by do
|
@other_window = @session.window_opened_by do
|
||||||
@session.find(:css, '#openWindow').click
|
@session.find(:css, '#openWindow').click
|
||||||
end
|
end
|
||||||
expect do
|
@other_window.resize_to(400, 300)
|
||||||
@other_window.resize_to(1000, 700)
|
expect(@session.current_window).to eq(@window)
|
||||||
end.to raise_error(Capybara::WindowError, "Resizing not current window is not possible.")
|
expect(@other_window.size).to eq([400, 300])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -119,17 +126,17 @@ Capybara::SpecHelper.spec Capybara::Window, requires: [:windows] do
|
||||||
window.resize_to(screen_width-100, screen_height-100)
|
window.resize_to(screen_width-100, screen_height-100)
|
||||||
expect(@session.evaluate_script("[window.outerWidth, window.outerHeight];")).to eq([screen_width-100, screen_height-100])
|
expect(@session.evaluate_script("[window.outerWidth, window.outerHeight];")).to eq([screen_width-100, screen_height-100])
|
||||||
window.maximize
|
window.maximize
|
||||||
sleep 0.6 # Selenium returns when window isn't yet fully resized
|
sleep 0.1
|
||||||
expect(@session.evaluate_script("[window.outerWidth, window.outerHeight];")).to eq([screen_width, screen_height])
|
expect(@session.evaluate_script("[window.outerWidth, window.outerHeight];")).to eq([screen_width, screen_height])
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should raise error if invoked not for current window' do
|
it 'should switch to original window if invoked not for current window' do
|
||||||
@other_window = @session.window_opened_by do
|
@other_window = @session.window_opened_by do
|
||||||
@session.find(:css, '#openWindow').click
|
@session.find(:css, '#openWindow').click
|
||||||
end
|
end
|
||||||
expect do
|
@other_window.maximize
|
||||||
@other_window.maximize
|
expect(@session.current_window).to eq(@window)
|
||||||
end.to raise_error(Capybara::WindowError, "Maximizing not current window is not possible.")
|
expect(@other_window.size).to eq(@session.evaluate_script("[window.screen.availWidth, window.screen.availHeight];"))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,8 +9,16 @@ module Capybara
|
||||||
# * {Capybara::Session#window_opened_by}
|
# * {Capybara::Session#window_opened_by}
|
||||||
# * {Capybara::Session#switch_to_window}
|
# * {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
|
class Window
|
||||||
# @return [String] a string that uniquely identifies window
|
# @return [String] a string that uniquely identifies window within session
|
||||||
attr_reader :handle
|
attr_reader :handle
|
||||||
|
|
||||||
# @return [Capybara::Session] session that this window belongs to
|
# @return [Capybara::Session] session that this window belongs to
|
||||||
|
@ -44,46 +52,51 @@ module Capybara
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Close window. Available only for current window.
|
# Close window.
|
||||||
# After calling this method future invocations of other Capybara methods should raise
|
#
|
||||||
|
# If this method was called for window that is current, then after calling this method
|
||||||
|
# future invocations of other Capybara methods should raise
|
||||||
# `session.driver.no_such_window_error` until another window will be switched to.
|
# `session.driver.no_such_window_error` until another window will be switched to.
|
||||||
# @raise [Capybara::WindowError] if invoked not for current window
|
#
|
||||||
|
# @!macro about_current
|
||||||
|
# If this method was called for window that is not current, then after calling this method
|
||||||
|
# current window shouldn remain the same as it was before calling this method.
|
||||||
#
|
#
|
||||||
def close
|
def close
|
||||||
raise_unless_current('Closing')
|
@driver.close_window(handle)
|
||||||
@driver.close_current_window
|
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Get window size. Available only for current window.
|
# Get window size.
|
||||||
|
#
|
||||||
|
# @macro about_current
|
||||||
# @return [Array<(Fixnum, Fixnum)>] an array with width and height
|
# @return [Array<(Fixnum, Fixnum)>] an array with width and height
|
||||||
# @raise [Capybara::WindowError] if invoked not for current window
|
|
||||||
#
|
#
|
||||||
def size
|
def size
|
||||||
raise_unless_current('Getting size of')
|
@driver.window_size(handle)
|
||||||
@driver.current_window_size
|
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Resize window. Available only for current window.
|
# Resize window.
|
||||||
|
#
|
||||||
|
# @macro about_current
|
||||||
# @param width [String] the new window width in pixels
|
# @param width [String] the new window width in pixels
|
||||||
# @param height [String] the new window height in pixels
|
# @param height [String] the new window height in pixels
|
||||||
# @raise [Capybara::WindowError] if invoked not for current window
|
|
||||||
#
|
#
|
||||||
def resize_to(width, height)
|
def resize_to(width, height)
|
||||||
raise_unless_current('Resizing')
|
@driver.resize_window_to(handle, width, height)
|
||||||
@driver.resize_current_window_to(width, height)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Maximize window. Available only for current window.
|
# Maximize window.
|
||||||
|
#
|
||||||
# If a particular driver (e.g. headless driver) doesn't have concept of maximizing it
|
# If a particular driver (e.g. headless driver) doesn't have concept of maximizing it
|
||||||
# may not support this method.
|
# may not support this method.
|
||||||
# @raise [Capybara::WindowError] if invoked not for current window
|
#
|
||||||
|
# @macro about_current
|
||||||
#
|
#
|
||||||
def maximize
|
def maximize
|
||||||
raise_unless_current('Maximizing')
|
@driver.maximize_window(handle)
|
||||||
@driver.maximize_current_window
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def eql?(other)
|
def eql?(other)
|
||||||
|
|
Loading…
Reference in a new issue