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
- ```
Posted by Arne Hartherz to makandra dev (2024-12-16 11:33)