Updated: How to allow testing beforeunload confirmation dialogs with modern ChromeDrivers

Posted . Visible to the public. Auto-destruct in 59 days

Updated for selenium-webdriver 4.27 which requires options.add_option(:page_load_strategy, 'none').

Changes

  • 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](https://w3c.github.io/webdriver/#user-prompts) 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](https://w3c.github.io/webdriver-bidi/)" 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:
  • ```ruby
  • 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](https://makandracards.com/makandra/617366-configure-selenium-webdriver-automatically-close-alerts)) 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](https://www.w3.org/TR/webdriver-bidi/#type-browsingContext-ReadinessState) 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>).
  • Instead, specify a BiDi driver and use that driver when testing unload behavior. Example:
  • ```ruby
  • Capybara.register_driver(:with_unload_confirmation) do |app|
  • # ...
  • end
  • ```
  • ```ruby
  • describe 'unsaved changes confirmation dialog', :js, driver: :with_unload_confirmation do
  • # ...
  • end
  • ```
Arne Hartherz
License
Source code in this card is licensed under the MIT License.
Posted by Arne Hartherz to makandra dev (2024-12-16 11:33)