Bugfixing for windows API (primarily switch_to_window and within_window)
This commit is contained in:
parent
adda9b0acd
commit
c157ef4e61
|
@ -363,14 +363,15 @@ module Capybara
|
|||
##
|
||||
# @overload switch_to_window(&block)
|
||||
# Switches to the first window for which given block returns a value other than false or nil.
|
||||
# If window that matches block can't be found, the window will be switched back and `WindowError` will be raised.
|
||||
# @example
|
||||
# window = switch_to_window { title == 'Page title' }
|
||||
# @return [Capybara::Window] window that has been switched to
|
||||
# @raise [Capybara::WindowError] if no window matches given block
|
||||
# @overload switch_to_window(window)
|
||||
# @param window [Capybara::Window] window that should be switched to
|
||||
# @raise [Capybara::Driver::Base#no_such_window_error] if unexistent (e.g. closed) window was passed
|
||||
#
|
||||
# @return [Capybara::Window] window that has been switched to
|
||||
# @raise [Capybara::ScopeError] if this method is invoked inside `within`,
|
||||
# `within_frame` or `within_window` methods
|
||||
# @raise [ArgumentError] if both or neither arguments were provided
|
||||
|
@ -388,14 +389,23 @@ module Capybara
|
|||
|
||||
if window
|
||||
driver.switch_to_window(window.handle)
|
||||
window
|
||||
else
|
||||
driver.window_handles.each do |handle|
|
||||
driver.switch_to_window handle
|
||||
if yield
|
||||
return Window.new(self, handle)
|
||||
original_window_handle = driver.current_window_handle
|
||||
begin
|
||||
driver.window_handles.each do |handle|
|
||||
driver.switch_to_window handle
|
||||
if yield
|
||||
return Window.new(self, handle)
|
||||
end
|
||||
end
|
||||
rescue => e
|
||||
driver.switch_to_window(original_window_handle)
|
||||
raise e
|
||||
else
|
||||
driver.switch_to_window(original_window_handle)
|
||||
raise Capybara::WindowError, "Could not find a window matching block/lambda"
|
||||
end
|
||||
raise Capybara::WindowError, "Could not find a window matching block/lambda"
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -409,6 +419,7 @@ module Capybara
|
|||
# @overload within_window(window) { do_something }
|
||||
# @param [Capybara::Window] instance of Capybara::Window class
|
||||
# that will be switched to
|
||||
# @raise [driver#no_such_window_error] if unexistent (e.g. closed) window was passed
|
||||
# @overload within_window(proc_or_lambda) { do_something }
|
||||
# @param lambda [Proc] lambda. First window for which lambda
|
||||
# returns a value other than false or nil will be switched to.
|
||||
|
@ -421,7 +432,6 @@ module Capybara
|
|||
#
|
||||
# @raise [Capybara::ScopeError] if this method is invoked inside `within`,
|
||||
# `within_frame` or `within_window` methods
|
||||
# @raise [driver#no_such_window_error] if unexistent (e.g. closed) window was passed
|
||||
# @return value returned by the block
|
||||
#
|
||||
def within_window(window_or_handle)
|
||||
|
@ -429,20 +439,20 @@ module Capybara
|
|||
original = current_window
|
||||
begin
|
||||
switch_to_window(window_or_handle) unless original == window_or_handle
|
||||
scopes.push(nil)
|
||||
scopes << nil
|
||||
yield
|
||||
ensure
|
||||
scopes.pop if scopes.last.nil? # It will be not nil if closed window has been passed
|
||||
@scopes = [nil]
|
||||
switch_to_window(original) unless original == window_or_handle
|
||||
end
|
||||
elsif window_or_handle.is_a?(Proc)
|
||||
original = current_window
|
||||
switch_to_window { window_or_handle.call }
|
||||
scopes << nil
|
||||
begin
|
||||
switch_to_window { window_or_handle.call }
|
||||
scopes.push(nil)
|
||||
yield
|
||||
ensure
|
||||
scopes.pop if scopes.last.nil?
|
||||
@scopes = [nil]
|
||||
switch_to_window(original)
|
||||
end
|
||||
else
|
||||
|
@ -451,10 +461,10 @@ module Capybara
|
|||
warn "DEPRECATION WARNING: Passing string argument to #within_window is deprecated. "\
|
||||
"Pass window object or lambda. (called from #{file_line})"
|
||||
begin
|
||||
scopes.push(nil)
|
||||
scopes << nil
|
||||
driver.within_window(window_or_handle) { yield }
|
||||
ensure
|
||||
scopes.pop
|
||||
@scopes = [nil]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -625,7 +635,7 @@ module Capybara
|
|||
end
|
||||
|
||||
def scopes
|
||||
@scopes ||= [document]
|
||||
@scopes ||= [nil]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -30,6 +30,17 @@ Capybara::SpecHelper.spec '#switch_to_window', requires: [:windows] do
|
|||
@session.switch_to_window(window)
|
||||
expect(['', 'about:blank']).to include(@session.title)
|
||||
end
|
||||
|
||||
it "should raise error when closed window is passed" do
|
||||
original_window = @session.current_window
|
||||
new_window = @session.open_new_window
|
||||
@session.switch_to_window(new_window)
|
||||
new_window.close
|
||||
@session.switch_to_window(original_window)
|
||||
expect do
|
||||
@session.switch_to_window(new_window)
|
||||
end.to raise_error(@session.driver.no_such_window_error)
|
||||
end
|
||||
end
|
||||
|
||||
context "with block" do
|
||||
|
@ -83,11 +94,21 @@ Capybara::SpecHelper.spec '#switch_to_window', requires: [:windows] do
|
|||
end
|
||||
end.to raise_error(Capybara::ScopeError, "`switch_to_window` is not supposed to be invoked from `within`'s, `within_frame`'s' or `within_window`'s' block.")
|
||||
end
|
||||
end
|
||||
|
||||
it "should raise error if window matching block wasn't found" do
|
||||
expect do
|
||||
@session.switch_to_window { @session.title == 'A title' }
|
||||
end.to raise_error(Capybara::WindowError, "Could not find a window matching block/lambda")
|
||||
it "should raise error if window matching block wasn't found" do
|
||||
original = @session.current_window
|
||||
expect do
|
||||
@session.switch_to_window { @session.title == 'A title' }
|
||||
end.to raise_error(Capybara::WindowError, "Could not find a window matching block/lambda")
|
||||
expect(@session.current_window).to eq(original)
|
||||
end
|
||||
|
||||
it "should switch to original window if error is raised inside block" do
|
||||
original = @session.switch_to_window(@session.windows[1])
|
||||
expect do
|
||||
@session.switch_to_window { raise 'error' }
|
||||
end.to raise_error(StandardError, 'error')
|
||||
expect(@session.current_window).to eq(original)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -18,7 +18,7 @@ Capybara::SpecHelper.spec '#window_opened_by', requires: [:windows] do
|
|||
it 'should raise error if value of :wait is less than timeout' do
|
||||
Capybara.using_wait_time 1 do
|
||||
expect do
|
||||
@session.window_opened_by(wait: 0.3) do
|
||||
@session.window_opened_by(wait: 0.4) do
|
||||
@session.find(:css, '#openWindowWithTimeout').click
|
||||
end
|
||||
end.to raise_error(Capybara::WindowError, zero_windows_message)
|
||||
|
@ -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
|
||||
Capybara.using_wait_time 0.1 do
|
||||
window = @session.window_opened_by(wait: 0.9) do
|
||||
window = @session.window_opened_by(wait: 1) do
|
||||
@session.find(:css, '#openWindowWithTimeout').click
|
||||
end
|
||||
expect(window).to be_instance_of(Capybara::Window)
|
||||
|
@ -37,7 +37,7 @@ Capybara::SpecHelper.spec '#window_opened_by', requires: [:windows] do
|
|||
|
||||
context 'without :wait option' do
|
||||
it 'should raise error if default_wait_time is less than timeout' do
|
||||
Capybara.using_wait_time 0.2 do
|
||||
Capybara.using_wait_time 0.4 do
|
||||
expect do
|
||||
@session.window_opened_by do
|
||||
@session.find(:css, '#openWindowWithTimeout').click
|
||||
|
@ -47,7 +47,7 @@ Capybara::SpecHelper.spec '#window_opened_by', requires: [:windows] do
|
|||
end
|
||||
|
||||
it 'should find window if default_wait_time is more than timeout' do
|
||||
Capybara.using_wait_time 0.9 do
|
||||
Capybara.using_wait_time 1 do
|
||||
window = @session.window_opened_by do
|
||||
@session.find(:css, '#openWindowWithTimeout').click
|
||||
end
|
||||
|
|
|
@ -54,7 +54,7 @@ Capybara::SpecHelper.spec Capybara::Window, requires: [:windows] do
|
|||
it 'should return false if window is closed' do
|
||||
@session.switch_to_window(@other_window)
|
||||
@other_window.close
|
||||
expect(@other_window.current?).to be_false
|
||||
expect(@other_window.current?).to eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -42,11 +42,14 @@ Capybara::SpecHelper.spec '#within_window', requires: [:windows] do
|
|||
window = (@session.windows - [@window]).first
|
||||
expect do
|
||||
@session.within_window(window) do
|
||||
raise 'some error'
|
||||
@session.within 'html' do
|
||||
raise 'some error'
|
||||
end
|
||||
end
|
||||
end.to raise_error(StandardError, 'some error')
|
||||
expect(@session.current_window).to eq(@window)
|
||||
expect(@session).to have_css('#doesNotOpenWindows')
|
||||
expect(@session.send(:scopes)).to eq([nil])
|
||||
end
|
||||
|
||||
it 'should raise error if closed window was passed' do
|
||||
|
@ -59,7 +62,9 @@ Capybara::SpecHelper.spec '#within_window', requires: [:windows] do
|
|||
raise 'should not be invoked'
|
||||
end
|
||||
end.to raise_error(@session.driver.no_such_window_error)
|
||||
expect(@session.current_window).to eq(@window)
|
||||
expect(@session).to have_css('#doesNotOpenWindows')
|
||||
expect(@session.send(:scopes)).to eq([nil])
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -86,7 +91,9 @@ Capybara::SpecHelper.spec '#within_window', requires: [:windows] do
|
|||
expect(@session).to have_css('#divInPopupOne')
|
||||
end
|
||||
end.to raise_error(Capybara::WindowError, "Could not find a window matching block/lambda")
|
||||
expect(@session.current_window).to eq(@window)
|
||||
expect(@session).to have_css('#doesNotOpenWindows')
|
||||
expect(@session.send(:scopes)).to eq([nil])
|
||||
end
|
||||
|
||||
it "returns value from the block" do
|
||||
|
@ -103,6 +110,7 @@ Capybara::SpecHelper.spec '#within_window', requires: [:windows] do
|
|||
end
|
||||
end.to raise_error(StandardError, 'some error')
|
||||
expect(@session.current_window).to eq(@window)
|
||||
expect(@session.send(:scopes)).to eq([nil])
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -110,7 +118,7 @@ Capybara::SpecHelper.spec '#within_window', requires: [:windows] do
|
|||
it "should warn" do
|
||||
expect(@session).to receive(:warn).with("DEPRECATION WARNING: Passing string argument "\
|
||||
"to #within_window is deprecated. Pass window object or lambda. "\
|
||||
"(called from #{__FILE__}:114)").and_call_original
|
||||
"(called from #{__FILE__}:122)").and_call_original
|
||||
@session.within_window('firstPopup') {}
|
||||
end
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
$('#openWindowWithTimeout').click(function(){
|
||||
setTimeout(function(){
|
||||
window.open('/popup_one', 'firstPopup');
|
||||
}, 500);
|
||||
}, 600);
|
||||
return false;
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue