Starting with ChromeDriver 127, if your application displays a beforeunload
confirmation dialog, ChromeDriver will immediately close it. In consequence, any automated tests which try to interact with unload prompts will fail.
This is because ChromeDriver now follows the
W3C WebDriver spec
Show archive.org snapshot
which states that any unload prompts should be closed automatically.
However, this applies only to "HTTP" test sessions, i.e. what you're using by default. The spec also defines that bi-directional test sessions (using the "
BiDi
Show archive.org snapshot
" WebDriver) should not automatically accept such dialogs. This means that we want to use the BiDi driver when testing beforeunload
prompts.
Enabling the BiDi WebDriver
Using Capybara, simply set the :web_socket_url
option to true
to enable BiDi mode.
Example:
options = Selenium::WebDriver::Chrome::Options.new(
args: ['--headless'],
unhandled_prompt_behavior: 'ignore',
# ...
)
if unload_confirmation
options.add_option(:web_socket_url, true)
options.add_option(:page_load_strategy, 'none') # required for selenium-webdriver 4.27+
end
Capybara::Selenium::Driver.new(app, browser: :chrome, options: options)
In combination with unhandled_prompt_behavior: 'ignore'
(which we recommend setting) any unload alerts will now stay open until handled.
Note that you also need to set the :page_load_strategy
to "none"
for modern selenium-webdriver ≥ 4.27 since those follow the spec more closely than previous versions and respect the document's
readiness state
Show archive.org snapshot
for navigation events.
If you do not specify a :page_load_strategy
, selenium-webdriver defaults to "complete"
which means it will wait for any beforeunload
to be handled before e.g. a page.refresh
statement returns. That that this also applies to wrapped calls like accept_confirm { page.refresh }
.
Recommendation
We do not recommend BiDi mode as a default because it can have a negative impact on other tests.
For example, if your application shows unload confirmations for forms with unsaved changes, all tests would have to ensure they explicitly save or discard any changes before a test finishes. Otherwise, when the driver closes the page, an unload dialog appears which cannot be handled.
Also, the BiDi driver does not yet implement all features (see
https://wpt.fyi/results/webdriver/tests/bidi
Show archive.org snapshot
).
Instead, specify a BiDi driver and use that driver when testing unload behavior. Example:
Capybara.register_driver(:with_unload_confirmation) do |app|
# ...
end
describe 'unsaved changes confirmation dialog', :js, driver: :with_unload_confirmation do
# ...
end