Workaround Safari issue with switching to parent frame

This commit is contained in:
Thomas Walpole 2019-04-04 18:18:41 -07:00
parent 7bbeac5474
commit ccf0bd4b1c
5 changed files with 41 additions and 7 deletions

View File

@ -3,7 +3,17 @@
require 'capybara/selenium/nodes/safari_node'
module Capybara::Selenium::Driver::SafariDriver
private # rubocop:disable Layout/IndentationWidth
def switch_to_frame(frame)
return super unless frame == :parent
# safaridriver/safari has an issue where switch_to_frame(:parent)
# behaves like switch_to_frame(:top)
handles = @frame_handles[current_window_handle]
browser.switch_to.default_content
handles.tap(&:pop).each { |fh| browser.switch_to.frame(fh) }
end
private
def build_node(native_node, initial_cache = {})
::Capybara::Selenium::SafariNode.new(self, native_node, initial_cache)

View File

@ -53,7 +53,20 @@ Capybara::SpecHelper.spec '#switch_to_frame', requires: [:frames] do
@session.switch_to_frame frame
frame = @session.find(:frame, 'childFrame')
@session.switch_to_frame frame
@session.click_link 'Close Window'
@session.click_link 'Close Window Now'
@session.switch_to_frame :parent # Go back to parentFrame
expect(@session).to have_selector(:css, 'body#parentBody')
expect(@session).not_to have_selector(:css, '#childFrame')
@session.switch_to_frame :parent # Go back to top
end
it 'works if the frame is closed with a slight delay', requires: %i[frames js] do
frame = @session.find(:frame, 'parentFrame')
@session.switch_to_frame frame
frame = @session.find(:frame, 'childFrame')
@session.switch_to_frame frame
@session.click_link 'Close Window Soon'
sleep 1
@session.switch_to_frame :parent # Go back to parentFrame
expect(@session).to have_selector(:css, 'body#parentBody')
expect(@session).not_to have_selector(:css, '#childFrame')

View File

@ -92,7 +92,18 @@ Capybara::SpecHelper.spec '#within_frame', requires: [:frames] do
it 'works if the frame is closed', requires: %i[frames js] do
@session.within_frame 'parentFrame' do
@session.within_frame 'childFrame' do
@session.click_link 'Close Window'
@session.click_link 'Close Window Now'
end
expect(@session).to have_selector(:css, 'body#parentBody')
expect(@session).not_to have_selector(:css, '#childFrame')
end
end
it 'works if the frame is closed with a slight delay', requires: %i[frames js] do
@session.within_frame 'parentFrame' do
@session.within_frame 'childFrame' do
@session.click_link 'Close Window Soon'
sleep 1
end
expect(@session).to have_selector(:css, 'body#parentBody')
expect(@session).not_to have_selector(:css, '#childFrame')

View File

@ -10,7 +10,8 @@
</script>
</head>
<body id="childBody">
<a href="javascript:void(0)" onClick="closeWin()">Close Window</a>
<a href="javascript:void(0)" onClick="closeWin()">Close Window Now</a>
<a href="javascript:void(0)" onClick="setTimeout(function(){closeWin()}, 10)">Close Window Soon</a>
<iframe src="/frame_one" id="grandchildFrame1"></iframe>
<iframe src="/frame_two" id="grandchildFrame2"></iframe>
</body>

View File

@ -57,10 +57,9 @@ Capybara::SpecHelper.run_specs TestSessions::Safari, SAFARI_DRIVER.to_s, capybar
'Capybara::Session selenium_safari node #click should allow to retry longer',
'Capybara::Session selenium_safari node #click should retry clicking'
pending "safaridriver doesn't return a specific enough error to deal with this"
when /Capybara::Session selenium_safari #within_frame should find multiple nested frames/,
/Capybara::Session selenium_safari #within_frame works if the frame is closed/,
when /Capybara::Session selenium_safari #within_frame works if the frame is closed/,
/Capybara::Session selenium_safari #switch_to_frame works if the frame is closed/
skip 'switch_to_frame(:parent) appears to go to the root in Safari rather than parent'
skip 'Safari has a race condition when clicking an element that causes the frame to close. It will sometimes raise a NoSuchFrameError'
when /Capybara::Session selenium_safari #reset_session! removes ALL cookies/
skip 'Safari webdriver can only remove cookies for the current domain'
when /Capybara::Session selenium_safari #refresh it reposts/