Skip to content

beforeunload event doesn't trigger with chromedriver v127+ #1104

@GuySartorelli

Description

@GuySartorelli

Bug description

Found this in our CI https://github.com/silverstripe/silverstripe-admin/actions/runs/10138301536/job/28029791648, there's more details in silverstripe/.github#287

There's javascript that blocks page navigation using the onbeforeunload event handler.

This alert works as expected with chromedriver 126 (specifically tested with 126.0.6478.182 (5b5d8292ddf182f8b2096fa665b473b6317906d5-refs/branch-heads/6478@{#1776})), and it works as expected when a user manually performs the actions in a browser. But when using chromedriver 127 (specifically tested with 127.0.6533.72 (9755e24ca85aa18ffa16c743f660a3d914902775-refs/branch-heads/6533@{#1760})) there is no alert, and the following error occurs:

Fatal error: Uncaught Facebook\WebDriver\Exception\TimeoutException: Alert is expected in /var/www/vendor/php-webdriver/webdriver/lib/WebDriverWait.php:71

How could the issue be reproduced

<?php

use Facebook\WebDriver\Chrome\ChromeOptions;
use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\WebDriverBy;
use Facebook\WebDriver\WebDriverExpectedCondition;

require_once __DIR__ . '/vendor/autoload.php';

$desiredCapabilities = DesiredCapabilities::chrome();

// Disable accepting SSL certificates
$desiredCapabilities->setCapability('acceptSslCerts', false);

// Add arguments via ChromeOptions to start headless chrome
$options = new ChromeOptions();
$options->addArguments(['--headless', '--no-sandbox', '--disable-gpu']);
$desiredCapabilities->setCapability(ChromeOptions::CAPABILITY, $options);

$driver = RemoteWebDriver::create('http://127.0.0.1:9515', $desiredCapabilities);

// Go to the page
// Replace "<local-dev-domain>" with whatever the domain is for your local dev environment
$driver->get('http://<local-dev-domain>/test.html');
// Interact with the page (or else the alert won't appear)
$driver->findElement(WebDriverBy::tagName('input'))->sendKeys('test');
// Navigate away to trigger the alert
$driver->navigate()->to('http://<local-dev-domain>/');

// Dismiss the alert
$driver->wait()->until(
    WebDriverExpectedCondition::alertIsPresent(),
    "Alert is expected"
);
$alert = $driver->switchTo()->alert();
$alert->dismiss();

$driver->quit();

The test.html file:

<html>
    <head>
        <script>
            window.onbeforeunload = () => {
                return 'WARNING: Your changes have not been saved.';
            };
        </script>
    </head>
    <body>
        <input type="text">
    </body>
</html>

Expected behavior

Navigating away from the page should trigger the beforeunload event and result in an alert, the same as it does when a human user navigates using a browser.

Php-webdriver version

1.15.1

PHP version

8.1.29

How do you start the browser driver or Selenium server

nohup sh -c "chromedriver" > /dev/null 2>&1 &

Selenium server / Selenium Docker image version

No response

Browser driver (chromedriver/geckodriver...) version

chromedriver 127.0.6533.72 (9755e24ca85aa18ffa16c743f660a3d914902775-refs/branch-heads/6533@{#1760})

Browser name and version

Google Chrome for Testing 127.0.6533.72

Operating system

Ubuntu

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions