My first attempts at addressing this issue looked something like this:
@driver.execute_script("window.onbeforeunload = undefined;") @driver.find_element(:css => "a.unload_prompt").click ## Wait for next page ... hope that a race condition doesn't occur
This worked most of the time. But one out of ten or fifteen times, the race condition would occur where the autoSave js call would occur just after I cleared the window.onbeforeunload and just before the element actually got clicked. This re-set the unload prompt, and caused the extremely frustrating
Selenium::WebDriver::Error::UnhandledAlertError: Modal dialog present
error to appear, failing my control room tests from that point on. 😦
If you are one of the many users struggling with this, never fear. There is hope!
pry> @driver.find_element(:css => ".homepage a").click => "ok"
If we click a link that shows this window.onbeforeunload prompt:
pry> @driver.find_element(:css => "a.unload_prompt").click => "Are you sure you would like to leave this page?"
Aha! Webdriver is nice enough to detect that this unload is going to throw a nasty prompt and sends it back through the JSON Wire to be returned to the Ruby call to click. So how does this solve our issues? We can just get and accept the alert to continue on in the page!
pry> @driver.switch_to.alert.text => "Are you sure you would like to leave this page?" pry> @driver.switch_to.alert.accept => ""
Thus, we can update our code to conditionally take care of the alert if the click returns anything other than an ok response:
click_resp = @driver.find_element(:css => "a.unload_prompt").click @driver.switch_to.alert.accept unless click_resp.eql?("ok") ## Continue on to the next page, etc...
And that is how you solve this nasty problem!