Removal of AbstractEventListener + EventFiringWebDriver + WebDriverEventListener

This blog will go over some examples on how to transition code that uses the aforementioned classes.

Upgrading to WebDriverListener and EventFiringDecorator

Decorating the webdriver

new EventFiringWebDriver(driver); // Old approach
new EventFiringDecorator().decorate(driver); // New approach

Implementing method wrappers

One may find the need to have their own custom implementations be used for underlying decorated method calls. An example may be wanting to use your own findElement implementation to store metadata from web elements. One can go down a deep rabbit hole of decorators ( extending WebDriverDecorator and such ), so to keep things simple we will extend EventFiringDecorator since we want a single decorator to handle all our listener events.

public class WebDriverWrapper implements WebDriver {
    private final WebDriver driver;
    WebDriverWrapper(WebDriver driver) {
        this.driver = driver;
    }
    // custom implementation goes here
    @Override
    public WebElement findElement(final By by) {
        // custom implementation goes here
        return driver.findElement(by);
    }
}

public class testDecorator extends EventFiringDecorator<WebDriver> {

    @Override
    public Object call(Decorated<?> target, Method method, Object[] args) throws Throwable {
        String methodName = method.getName();
        if ("findElement".equals(methodName)) {
            WebDriverWrapper newDriver = new WebDriverWrapper((WebDriver) target.getOriginal());
            return newDriver.findElement((By) args[0]);
        }
        return super.call(target, method, args);
    }
}

Some notes about the above example, we are only overriding the ‘general’ call method and checking the method name against every call made. Without going too deep decorators one can also override calls made by class instances to offer a more targeted approach. Just to expose some more functionality, let’s modify our example. We can modify WebElement context since we might care about child elements and elements found by WebDriver ( WebDriver and WebElement both extend the SearchContext ).

public class WebElementWrapper implements WebElement {
    private final WebElement element;
    WebElementWrapper(WebElement element) {
        this.element = element;
    }
    @Override
    public WebElement findElement(final By by) {
        // custom implementation goes here
        return element.findElement(by);
    }
}

public class WebElementDecorator extends EventFiringDecorator<WebDriver> {
    @Override
    public Decorated<WebElement> createDecorated(WebElement original) {
        return new DefaultDecorated<>(original, this) {
            @Override
            public Object call(Method method, Object[] args) throws Throwable {
                String methodName = method.getName();
                if ("findElement".equals(methodName)) {
                    // custom implementation goes here
                    WebElementWrapper element = new WebElementWrapper(getOriginal());
                    return element.findElement((By) args[0]);
                }
                return super.call(method, args);
            }
        };
    }
}

In the sample above, we are still doing a very similar approach of overriding the call method but now we are also targeting WebElement instances.

Registering Listeners

new EventFiringWebDriver(driver).register(listener1).register(listener2); // Old approach
new EventFiringDecorator(listener1, listener2); // New approach

Listening to Events

A quality of life change that is featured in WebDriverListener class is the use of ‘default’. In Java, the default keyword, when used in the context of an interface method, indicates that the method has a default implementation. If a class implementing the interface chooses not to override the method, it will inherit the default implementation. This change allows for splitting up listeners without needing to implement the unnecessary methods you don’t need or care about.

Listening to specific events using before/after methods call

// Old approach
public class AlertListener implements WebDriverEventListener {
    @Override
    public void beforeAlertAccept(final WebDriver driver) {
        // custom implementation goes here
    }
// implement every method in interface
}

// New approach
public class AlertListener implements WebDriverListener {
    @Override
    public void beforeAccept(Alert alert) {
        // custom implementation goes here
    }
// does not need to implement every method in interface
}

Listening to Generic Events

A change that was brought on is the ability to listen to generic events. One use case is logging information in a parallelized test suite. Rather than create a listener and override every method to add a simple log statement, there is now a simpler alternative of overriding one method call. Below I override beforeAnyCall, but afterAnyCall exists as well which also has the results of the call to the decorated method.

public class Listener implements WebDriverEventListener {
    private static final Logger LOGGER = Logger.getLogger(Listener.class.getName());

    @Override
    public void beforeAnyCall(Object target, Method method, Object[] args) {
        logger.debug("Thread: " + Thread.currentThread().getName() +
                " | Method Name: " + method.getName() +
                " | Method Args: " + Arrays.toString(args));
    }
}

There also was an addition listening to more specific generic events. Going back to the logging example, beforeAnyCall is a good method for debugging information or tracking the actions of a thread but might generate too much noise. In the same use case we might only care about WebDriver or WebElement calls. One can override instances of WebDriver and derived objects( WebElement, Alert, etc.) for before/after events.

public class Listener implements WebDriverEventListener {
    private static final Logger LOGGER = Logger.getLogger(Listener.class.getName());

    @Override
    public void beforeAnyWebDriverCall(WebDriver driver, Method method, Object[] args) {
        logger.debug("Thread: " + Thread.currentThread().getName() +
                " | Method Name: " + method.getName() +
                " | Method Args: " + Arrays.toString(args));
    }

    @Override
    public void beforeAnyWebElementCall(WebElement element, Method method, Object[] args) {
        logger.debug("Thread: " + Thread.currentThread().getName() +
                " | Method Name: " + method.getName() +
                " | Method Args: " + Arrays.toString(args));
    }
}

So that’s some general examples on how to transition your code! Happy testing!

Selenium 4.16 Released!

Today we’re happy to announce that Selenium 4.16 has been released!

We’re very happy to announce the release of Selenium 4.16.0 for Javascript, Ruby, Python, and Selenium 4.16.1 for .NET, Java and the Grid. Links to everything can be found on our downloads page.

Highlights

  • Chrome DevTools support is now: v118, v119, and v120 (Firefox still uses v85 for all versions)
  • Users may now opt in to Selenium Manager by specifying a browserVersion that is different from what is found on the System
  • All bindings now log Selenium information

Noteworthy changes per language

  • Java
    • Improve Grid usage of Selenium Manager by always allowing browser version of “stable”
    • Implement CDP script pinning for Chrome-based browsers
    • Allow reusing devtools instance with JDK 11 client
    • Moved org.openqa.selenium.remote.http.jdk to selenium-http
    • See all changes


  • .NET
    • Allow overriding default Actions duration
    • Remove System.Drawing.Common as package dependency
    • See all changes

  • Python
    • Remove deprecated Safari parameters for reuse_service and quiet
    • Fix bug to allow Remote WebDriver to use custom Chrome-based commands
    • See all changes

  • Ruby
    • Added initial typing support with rbs files
    • Fix bug preventing Selenium Manager from working with Unix and Cygwin
    • See all changes

  • Rust
    • Use online mapping to discover proper geckodriver version
    • Fix webview2 support when browser path is set
    • See all changes

Contributors

Special shout-out to everyone who helped the Selenium Team get this release out!

Selenium

Augustin Gottlieb

Augustin Gottlieb

Anthony Sottile

Anthony Sottile

Dominik Stadler

Dominik Stadler

Johnny.H

Johnny.H

Manuel Blanco

Manuel Blanco

Matthew Kempkers

Matthew Kempkers

Nikhil Agarwal

Nikhil Agarwal

Daniel P. Purkhús

Daniel P. Purkhús

Viet Nguyen Duc

Viet Nguyen Duc

Henrik Skupin

Henrik Skupin

Selenium Docs & Website

Sparsh Kesari

Sparsh Kesari

Ed Manlove

Ed Manlove

Ronald Abegg

Ronald Abegg

Tamas Utasi

Tamas Utasi

Docker Selenium

Thabelo Ramabulana

Thabelo Ramabulana

Amar Deep Singh

Amar Deep Singh

Matt Colman

Matt Colman

Viet Nguyen Duc

Viet Nguyen Duc

Selenium Team Members

Thanks as well to all the team members who contributed to this release:

ian zhang

ian zhang

Boni García

Boni García

Diego Molina

Diego Molina

Sri Harsha

Sri Harsha

Luis Correia

Luis Correia

Nikolay Borisenko

Nikolay Borisenko

Alex Rodionov

Alex Rodionov

Puja Jagani

Puja Jagani

Simon Stewart

Simon Stewart

Titus Fortner

Titus Fortner

Stay tuned for updates by following SeleniumHQ!

Happy testing!

Novelties in Selenium Manager 0.4.15

Selenium Manager 0.4.15 is shipped with Selenium 4.15.0. This blog post summarizes the novelties introduced in this new release.

Support for Firefox ESR

Selenium Manager 0.4.15 includes support for Firefox Extended Support Release (ESR). This way, Firefox ESR can be automatically managed with Selenium using the label esr in the browser version. Bindings languages set this browser version (like other accepted labels for browser versions, such as stable, beta, dev, canary, and nightly) using a browser option called browserVersion.

Support for Edge WebView2

Selenium Manager 0.4.15 allows automated driver management for Microsoft Edge WebView2. WebView2 is a component that enables embedding web technologies (HTML, CSS, and JavaScript) in native apps, using Microsoft Edge as the rendering engine to display web content. At the time of this writing, WebView2 is available in Windows.

This way, Selenium Manager allows detecting WebView2 in Windows machines and resolving the proper msedgedriver binary for it. Internally, Selenium Manager uses the browser name webview2 to handle WebView2, detecting its version based on registry queries. In the bindings, WebView2 is enabled through a browser option called useWebView.

Support for mirror repositories

Selenium Manager 0.4.15 includes a couple of new arguments in Selenium Manager for specifying custom URLs for drivers and browsers (instead of the default ones, such as chromedriver, Chrome for Testing, etc.). These arguments are:

  • --driver-mirror-url: Mirror URL for driver repositories.
  • --browser-mirror-url: Mirror URL for browser repositories.

As usual, these values can be configured using the config file or environment variable (e.g., SE_DRIVER_MIRROR_URL or SE_BROWSER_MIRROR_URL). Moreover, there are browser and driver-specific configuration keys, i.e. chrome-mirror-url, firefox-mirror-url, edge-mirror-url, etc. (in the configuration file), and SE_CHROME_MIRROR_URL, SE_FIREFOX_MIRROR_URL, SE_EDGE_MIRROR_URL, etc. (as environment variables).

Here is an example of this feature calling Selenium Manager from the shell:

./selenium-manager --debug --browser chrome --browser-version 100 --avoid-browser-download --driver-mirror-url=https://registry.npmmirror.com/-/binary/chromedriver/
DEBUG   chromedriver not found in PATH
DEBUG   chrome detected at C:\Program Files\Google\Chrome\Application\chrome.exe
DEBUG   Running command: wmic datafile where name='C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe' get Version /value
DEBUG   Output: "\r\r\n\r\r\nVersion=117.0.5938.150\r\r\n\r\r\n\r\r\n\r"
DEBUG   Detected browser: chrome 117.0.5938.150
DEBUG   Discovered chrome version (117) different to specified browser version (100)
DEBUG   Required driver: chromedriver 100.0.4896.60
DEBUG   Downloading chromedriver 100.0.4896.60 from https://registry.npmmirror.com/-/binary/chromedriver/100.0.4896.60/chromedriver_win32.zip
INFO    Driver path: C:\Users\boni\.cache\selenium\chromedriver\win64\100.0.4896.60\chromedriver.exe
INFO    Browser path: C:\Program Files\Google\Chrome\Application\chrome.exe

Debug release

To troubleshoot Selenium Manager in complex error cases, it is interesting to capture the backtrace. But to do that, the Selenium Manager binaries must be created with the debug symbols. Since the resulting binaries with debug symbols are much larger than the default release artifacts, we generate them on demand using a custom workflow in GitHub Actions. This way, we have included a checkbox in the workflow for triggering the Selenium Manager build. When this checkbox is enabled when building Selenium Manager, the debug symbols will be added to the resulting binaries (for Windows, Linux, and macOS). All in all, these binaries will be used on demand to troubleshoot complicated problems.

Selenium Manager workflow screenshot

Selenium Manager in cache (only for Java bindings)

As of version 4.15.0 of the Selenium Java bindings, the Selenium Manager binary is extracted and copied to the cache folder. For instance, the Selenium Manager binary shipped with Selenium 4.15.0 is stored in the folder ~/.cache/selenium/manager/0.4.15). This feature will allow direct manipulation of Selenium Manager as a CLI tool, for instance, for troubleshooting. This feature is only available for Java bindings since Java is the only language that does not have direct access to the Selenium Manager binaries (since they are released compressed into the JAR files of the selenium-java artifacts).

Next steps

Look at Selenium Manager documentation for a detailed description of its features. Also, you can trace the status of the development activities in the Selenium Manager project dashboard.

Selenium 4.15 Released!

Today we’re happy to announce that Selenium 4.15 has been released!

We’re very happy to announce the release of Selenium 4.15.0 for Java, Javascript, Ruby, .NET and the Grid; 4.15.2 for Python. Links to everything can be found on our downloads page.

Highlights

  • Chrome DevTools support is now: v117, v118, and v119 (Firefox still uses v85 for all versions)
  • Implemented Remote File Downloads
  • Selenium Manager supports webview2, Firefox ESR and Driver and Browser Mirrors

Noteworthy changes per language

  • Java
    • Numerous BiDi implementations
    • Remove CDP version dependencies in the server
    • Selenium Manager now gets copied to cache directory instead of being used from temp directory
    • See all changes

  • JavaScript
    • Replaced calls to console.log with managed loggers
    • Added several BiDi methods
    • See all changes

  • .NET
    • Improved nuget packages metadata
    • Allows starting service object directly
    • See all changes



  • Rust
    • Included debug and split-debuginfo in dev profile
    • Changed windows target to stable-i686-pc-windows-gnu
    • See all changes

Contributors

Special shout-out to everyone who helped the Selenium Team get this release out!

Selenium

Selenium Docs & Website

Afranio Alves

Afranio Alves

Anselmo Pfeifer

Anselmo Pfeifer

Luis Correia

Luis Correia

Sang Nguyen

Sang Nguyen

Vicente Sombo

Vicente Sombo

sripriyapkulkarni

sripriyapkulkarni

Zachary Zollman

Zachary Zollman

Vinicius Caetano

Vinicius Caetano

Docker Selenium

Luis Correia

Luis Correia

Mårten Svantesson

Mårten Svantesson

Matt Colman

Matt Colman

Philippe GRANET

Philippe GRANET

sebastian haas

sebastian haas

Viet Nguyen Duc

Viet Nguyen Duc

Thanks as well to all the Selenium Team Members who contributed to this release:

Boni García

Boni García

Diego Molina

Diego Molina

Sri Harsha

Sri Harsha

Nikolay Borisenko

Nikolay Borisenko

Puja Jagani

Puja Jagani

Simon Stewart

Simon Stewart

Titus Fortner

Titus Fortner

Stay tuned for updates by following SeleniumHQ!

Happy testing!

Selenium Open Space Conference Oct 28th

Free and online open space conference for Selenium community on Oct 28th, Selenium’s 19th birthday

In less than two weeks, Selenium project is holding space for free and online community meetup, the inaugural Selenium Open Space Conference. Open space conferences are ones where everyone is a speaker, and we co-create our agenda for conversations, questions or answers, workshops, sharing and learning.

We start our 24 hour event at time of 19 years from the tracked Selenium release announcement. We split the day into four segments to facilitate the global community. We set up an event site, and a mechanism to enroll: by pull request or issue to the site in github.

With enrollment, you can already tell if you have a topic in mind you would like to host, and see some (not all!) of the sessions people have in mind for the day.

To run the event, we set up Welo and Miro. Our space has 11 track rooms that each fit up to 150 people regardless of appearance, and we build our agenda on Miro during marketplace of ideas, one for each four time segments. Welo Miro

Welcome from the organizers, would be lovely to see you join us all.

Status of Selenium Manager in October 2023

This blog post summarizes the novelties introduced in the latest two versions of Selenium Manager (i.e., 0.4.13 and 0.4.14).

Selenium Manager continues its development plan. As usual, in the latest releases, i.e., 0.4.13 and 0.4.14 (shipped with Selenium 4.13 and 4.14, respectively), we have fixed the problems reported so far. In these releases, the issues were related to the extraction of the Firefox binary from the self-extracting archive (SFX) in Windows and the advanced configuration through the configuration file (se-config.toml) and environment variables (e.g., SE_BROWSER). Moreover, these recent releases include new features, as explained below.

Search for the best driver possible in the cache

By default, Selenium Manager needs to request online endpoints (such as Chrome for Testing JSON API or Firefox product-details JSON API to discover, download, and maintain the proper drivers and browsers that Selenium requires. The downloaded artifacts are stored in the cache (by default, ~/.cache/selenium) and reused from there.

To make the driver resolution procedure more robust, as of version 0.4.13, Selenium Manager includes a new feature for locating the drivers in the cache when some error happens. This way, when a network request (or other function) fails in Selenium Manager, it tries to locate the driver in the cache. This characteristic aims to provide a best-effort solution for creating a Selenium session properly, which is the final objective of Selenium Manager. Also, this feature will help to provide a better experience for locating drivers for Selenium Grid.

Locating Selenium Manager binary with an environment variable

The next feature related to Selenium Manager 0.4.13 has been implemented in the Selenium bindings (i.e., Java, JavaScript, Python, .Net, and Ruby). As of Selenium 4.13.0, the Selenium bindings allow locating the Selenium Manager binary using an environment variable called SE_MANAGER_PATH. This way, if this variable is set, the bindings will use its value as the Selenium Manager path in the local filesystem. This feature will allow users to provide a custom compilation of Selenium Manager, for instance, if the default binaries (compiled for Windows, Linux, and macOS) are incompatible with a given system (e.g., ARM64 in Linux).

Automated Edge management

Selenium Manager 0.4.14 includes automated Edge management. This browser is the last we have in mind for this feature, after Chrome and Firefox.

This feature has been implemented in the same way that Chrome and Firefox for macOS and Linux. In other words, Selenium Manager allows to automatically manage (i.e., discover, downloads, and cache) the latest Edge versions (i.e., stable, beta, dev, canary) and old versions (e.g., 115, 116, etc.). The downloaded binaries, as usual, are stored in the Selenium cache. The following output commands showcase this feature in macOS (first snipped) and Linux (second snippet):

./selenium-manager --browser edge --debug --force-browser-download

DEBUG	msedgedriver not found in PATH
DEBUG	Checking edge releases on https://edgeupdates.microsoft.com/api/products
DEBUG	Required browser: edge 117.0.2045.40
DEBUG	Downloading edge 117.0.2045.40 from https://msedge.sf.dl.delivery.mp.microsoft.com/filestreamingservice/files/6e65d9ef-0bb9-4636-8d9e-2b1b9d16149d/MicrosoftEdge-117.0.2045.40.pkg
DEBUG	edge 117.0.2045.40 has been downloaded at /Users/boni/.cache/selenium/edge/mac64/117.0.2045.40/Microsoft Edge.app/Contents/MacOS/Microsoft Edge
DEBUG	Reading msedgedriver version from https://msedgedriver.azureedge.net/LATEST_RELEASE_117_MACOS
DEBUG	Required driver: msedgedriver 117.0.2045.40
DEBUG	Downloading msedgedriver 117.0.2045.40 from https://msedgedriver.azureedge.net/117.0.2045.40/edgedriver_mac64.zip
INFO	Driver path: /Users/boni/.cache/selenium/msedgedriver/mac64/117.0.2045.40/msedgedriver
INFO	Browser path: /Users/boni/.cache/selenium/edge/mac64/117.0.2045.40/Microsoft Edge.app/Contents/MacOS/Microsoft Edge
./selenium-manager --browser edge --debug --browser-version beta

DEBUG	msedgedriver not found in PATH
DEBUG	edge not found in PATH
DEBUG	edge beta not found in the system
DEBUG	Checking edge releases on https://edgeupdates.microsoft.com/api/products
DEBUG	Required browser: edge 118.0.2088.11
DEBUG	Downloading edge 118.0.2088.11 from https://packages.microsoft.com/repos/edge/pool/main/m/microsoft-edge-beta/microsoft-edge-beta_118.0.2088.11-1_amd64.deb
DEBUG	edge 118.0.2088.11 has been downloaded at /home/user/.cache/selenium/edge/linux64/118.0.2088.11/msedge
DEBUG	Reading msedgedriver version from https://msedgedriver.azureedge.net/LATEST_RELEASE_118_LINUX
DEBUG	Required driver: msedgedriver 118.0.2088.11
DEBUG	Downloading msedgedriver 118.0.2088.11 from https://msedgedriver.azureedge.net/118.0.2088.11/edgedriver_linux64.zip
INFO	Driver path: /home/user/.cache/selenium/msedgedriver/linux64/118.0.2088.11/msedgedriver
INFO	Browser path: /home/user/.cache/selenium/edge/linux64/118.0.2088.11/msedge

Nevertheless, this feature cannot be implemented similarly for Windows. The reason is that the Edge installer for Windows is distributed as a Microsoft Installer (MSI) file, designed to be executed with administrator rights. We tried to extract the Edge binaries from that MSI file. Still, it seems not possible (see Stack Overflow post that summarized the problem). All in all, the only solution we found is to install Edge in Windows using the MSI installer, and so, administrator grants are required.

This way, when Edge is attempted to be installed with Selenium Manager in Windows with a non-administrator session, a warning message will be displayed as follows:

./selenium-manager --debug --browser edge --browser-version beta

DEBUG   msedgedriver not found in PATH
DEBUG   edge not found in PATH
DEBUG   edge beta not found in the system
WARN    There was an error managing edge (edge can only be installed in Windows with administrator permissions); using driver found in the cache
INFO    Driver path: C:\Users\boni\.cache\selenium\msedgedriver\win64\118.0.2088.17\msedgedriver.exe

But when Selenium Manager is executed with administrator grants in Windows, it will be able to automatically discover, download, and install Edge (stable, beta, dev, canary, and older versions):

./selenium-manager --debug --browser edge --browser-version beta

DEBUG   msedgedriver not found in PATH
DEBUG   edge not found in PATH
DEBUG   edge beta not found in the system
DEBUG   Checking edge releases on https://edgeupdates.microsoft.com/api/products
DEBUG   Required browser: edge 118.0.2088.17
DEBUG   Downloading edge 118.0.2088.17 from https://msedge.sf.dl.delivery.mp.microsoft.com/filestreamingservice/files/7adec542-f34c-4dea-8e2a-f8c6fab4d2f3/MicrosoftEdgeBetaEnterpriseX64.msi
DEBUG   Installing MicrosoftEdgeBetaEnterpriseX64.msi
DEBUG   edge 118.0.2088.17 is available at C:\Program Files (x86)\Microsoft\Edge Beta\Application\msedge.exe
DEBUG   Required driver: msedgedriver 118.0.2088.17
DEBUG   msedgedriver 118.0.2088.17 already in the cache
INFO    Driver path: C:\Users\boni\.cache\selenium\msedgedriver\win64\118.0.2088.17\msedgedriver.exe
INFO    Browser path: C:\Program Files (x86)\Microsoft\Edge Beta\Application\msedge.exe

Chromium support

Chromium is released as portable binaries, distributed as zip files for Windows, Linux, and macOS (see Chromium download page). Nevertheless, there is a case in which Chromium is actually installed in the system. This happens in Linux systems when installing Chromium through package managers like atp or snap, for instance, as follows:

sudo snap install chromium

Therefore, as of 0.4.14, Selenium Manager looks for the Chromium binaries in the PATH when Chrome is not discovered. The following snippet showcases how this feature works in a Linux machine in which Chrome is not available, but Chromium has been installed through snap:

./selenium-manager --browser chrome --debug
DEBUG   chromedriver not found in PATH
DEBUG   Found chromium in PATH: /snap/bin/chromium
DEBUG   Running command: /snap/bin/chromium --version
DEBUG   Output: "Chromium 117.0.5938.149 snap"
DEBUG   Detected browser: chrome 117.0.5938.149
DEBUG   Required driver: chromedriver 117.0.5938.149
DEBUG   chromedriver 117.0.5938.149 already in the cache
INFO   Driver path: /home/user/.cache/selenium/chromedriver/linux64/117.0.5938.149/chromedriver
INFO   Browser path: /snap/bin/chromium

Next steps

We are close to implementing all the features initially planned for Selenium Manager. You can trace the status of the development activities in the Selenium Manager project dashboard.

Selenium 4.13 Released!

Today we’re happy to announce that Selenium 4.13 has been released!

We’re very happy to announce the release of Selenium 4.13.0 for Java, Python, Javascript and the Grid; and 4.13.1 for .NET and Ruby. Links to everything can be found on our downloads page.

Highlights

  • Chrome DevTools support is now: v115, v116, and v117 (Firefox still uses v85 for all versions)
  • Reminder: this is the last version of Selenium with Java 8 support. Please upgrade to at least Java 11.
  • The location of Selenium Manager can be set manually in all bindings with SE_MANAGER_PATH environment variable.

Relevant improvements per language

  • Java
    • Deprecated setScriptTimeout(), use scriptTimeout()
    • Fixed several bugs related to logging driver output
    • Removed a number of previously deprecated methods
    • See all changes


  • .NET
    • Users can now start a service before creating the driver object instance
    • Removed Microsoft.IdentityModel.Tokens as dependency
    • Fixed several bugs and made improvements to DevTools implementations
    • See all changes

  • Python
    • Removed deprecated headless methods
    • Fixed bug preventing using performance logging in Chrome and Edge
    • See all changes

  • Ruby
    • Fixed bug preventing using performance logging in Chrome and Edge
    • Users can now start a service before creating the driver object instance
    • Removed deprecated driver extensions for location and network connection
    • See all changes

  • Rust
    • Various bug fixes for improved Selenium Manager functionality
    • See all changes

Contributors

Special shout-out to everyone who helped the Selenium Team get this release out!

Selenium

Krishna Suravarapu

Krishna Suravarapu

Sean Gomez

Sean Gomez

Manuel Blanco

Manuel Blanco

Michael Mintz

Michael Mintz

Nikolay Borisenko

Nikolay Borisenko

Sandeep Suryaprasad

Sandeep Suryaprasad

Scott Babcock

Scott Babcock

Selenium Docs & Website

Sparsh Kesari

Sparsh Kesari

#QualityWithMillan

#QualityWithMillan

Nikolay Borisenko

Nikolay Borisenko

Sachin Kumar

Sachin Kumar

Docker Selenium

Amar Deep Singh

Amar Deep Singh

Luis Correia

Luis Correia

William Lacerda

William Lacerda

Thanks as well to all the Selenium Team Members who contributed to this release:

David Burns

David Burns

Boni García

Boni García

Diego Molina

Diego Molina

Sri Harsha

Sri Harsha

Puja Jagani

Puja Jagani

Simon Stewart

Simon Stewart

Titus Fortner

Titus Fortner

Stay tuned for updates by following SeleniumHQ!

Happy testing!

Selenium 4.14 Released!

Today we’re happy to announce that Selenium 4.14 has been released!

We’re very happy to announce the release of Selenium 4.14.0 for Java, Python, Javascript, Ruby, .NET and the Grid. Links to everything can be found on our downloads page.

Highlights

  • Chrome DevTools support is now: v116, v117, and v118 (Firefox still uses v85 for all versions)
  • If you are using Java, this release requires Java 11! (see post on Java 8 support)
  • Selenium supports automatic downloading and management of the Microsoft Edge browser

Relevant improvements per language

  • Java
    • Removed support for Async HTTP Client, the default is now the default Java library
    • Allow setting SSL context in client config for HttpClient
    • Several logging message improvements
    • See all changes


  • .NET
    • Saving screenshots with different image formats is deprecated
    • Removed IdentityModel dependency
    • See all changes

  • Python


  • Rust
    • Automated Edge management
    • Recognizes and handles webview2
    • Locates existing Chromium browsers when specifying Chrome
    • See all changes

Contributors

Special shout-out to everyone who helped the Selenium Team get this release out!

Selenium

Alexey Pelykh

Alexey Pelykh

Manuel Blanco

Manuel Blanco

Scott Babcock

Scott Babcock

Selenium Docs & Website

ian zhang

ian zhang

Docker Selenium

Amar Deep Singh

Amar Deep Singh

Ismael Onilearan

Ismael Onilearan

Cody Lent

Cody Lent

William Lacerda

William Lacerda

Thanks as well to all the Selenium Team Members who contributed to this release:

Boni García

Boni García

Sri Harsha

Sri Harsha

Nikolay Borisenko

Nikolay Borisenko

Puja Jagani

Puja Jagani

Simon Stewart

Simon Stewart

Simon K

Simon K

Titus Fortner

Titus Fortner

Stay tuned for updates by following SeleniumHQ!

Happy testing!

Selenium 4.12.0 Released!

Today we’re happy to announce that Selenium 4.12.0 has been released!

We’re very happy to announce the release of Selenium 4.12.0 for Java, .NET, Ruby, Python, and Javascript as well as the Grid. Links to everything can be found on our downloads page.

Highlights

  • Chrome DevTools support is now: v114, v115, and v116 (Firefox still uses v85 for all versions)
  • Quite a few fixes for Selenium Manager, and now with Firefox browser management! Read about all the new Selenium Manager features
  • .NET only explicitly targets netstandard2.0
  • Python no longer supports Python 3.7
  • Ruby no longer supports :capabilities arguments for local drivers (must use :options now)

Relevant improvements per language

  • Java
    • Several improvements in working with Selenium Manager
    • Allow deleting remote downloaded files from grid (#12501)
    • Removed deprecated UNEXPECTED_ALERT_BEHAVIOR, BROWSER_LOGFILE, createPointerDown, createPointerUp and JWP /file endpoint
    • Deprecated disableNativeEvents and Remote Response status field
    • See all changes




  • Ruby
    • Fix bug preventing good error messages in Selenium Manager when stdout empty
    • Fix bug with Firefox not loading net/http library by default (#12506)
    • See all changes

Contributors

Special shout-out to everyone who helped the Selenium Team get this release out!

Selenium

Nikolay Borisenko

Nikolay Borisenko

Sandeep Suryaprasad

Sandeep Suryaprasad

Scott Babcock

Scott Babcock

Selenium Docs & Website

Andrii Maliuta

Andrii Maliuta

Andrei Solntsev

Andrei Solntsev

Nikolay Borisenko

Nikolay Borisenko

Tahanima Chowdhury

Tahanima Chowdhury

Veerendra Jana

Veerendra Jana

Docker Selenium

Mario Segura

Mario Segura

Thanks as well to all the Selenium Team Members who contributed to this release:

David Burns

David Burns

Boni García

Boni García

Diego Molina

Diego Molina

Sri Harsha

Sri Harsha

Jonathan Lipps

Jonathan Lipps

Luke Hill

Luke Hill

Alex Rodionov

Alex Rodionov

Puja Jagani

Puja Jagani

Simon Stewart

Simon Stewart

Simon K

Simon K

Titus Fortner

Titus Fortner

Stay tuned for updates by following SeleniumHQ!

Happy testing!

What's new in Selenium Manager 0.4.12, shipped with Selenium 4.12.0

Selenium Manager 0.4.12 is shipped with Selenium 4.12.0. This release aims to stabilize the features provided so far, delivering a new relevant characteristic: automated browser management for Firefox.

A new release of Selenium Manager is out. For this release, we made a relevant decision concerning the Selenium Manager versioning format. From now on, Selenium Manager will follow the same version as Selenium. Nevertheless, since Selenium Manager is still in beta, its major version is 0. Thus, Selenium 4.12.0 is shipped with Selenium Manager 0.4.12.

First, we made a substantial effort to stabilize the already available features on Selenium Manager. This way, the version includes several bug-fixing related to automated driver management or caching. You can find the details of the changes implemented in Selenium Manager 0.4.12 in the (newly created) changelog file.

Besides, for this release, we made a significant update to the documentation page of Selenium Manager. This page contains all the fine-grained information related to automated driver and browser management, configuration, etc. Also, it has several TL;DR summarizing the main ideas for the eager reader.

Automated Firefox management

After shipping automated browser management based on Chrome for Testing on the previous release, Selenium Manager 0.4.12 continues the job by providing automated Firefox management. This way, Selenium Manager 0.4.12 allows us to manage the different Firefox releases (for Windows, Linux, and macOS), making them seamlessly available for Selenium.

The procedure is the same as with Chrome. When Firefox is unavailable in the machine running Selenium, it is automatically discovered, downloaded, and cached by Selenium. If no version is specified, the latest stable Firefox release is managed by Selenium Manager. Besides, the bindings can use a browser option called browserVersion to specify a particular Firefox release (e.g., 114, 115, etc.). Finally, the label stable allows us to manage the current stable Firefox release explicitly, and the labels beta, dev, and nightly as used for unstable Firefox releases.

This feature is possible thanks to the remarkable work of the Firefox team by maintaining current and old releases in their public repository. Moreover, the Firefox version discovery in Selenium Manager is made thanks to the availability of the product-details JSON API, also maintained by the Firefox team.

Improved configuration

Custom setup is sometimes necessary for browser automation. For that reason, Selenium Manager already provides different features for rich configuration. Selenium Manager 0.4.12 extends this feature by delivering a new configuration argument called --cache-path. This argument allows changing the path of the local folder used to store downloaded assets (drivers and browsers) by Selenium Manager (by default, ~/.cache/selenium). As usual, this argument can also be changed by including an entry in the configuration file or using an environment variable (SE_CACHE_PATH). Regarding the former, the name of the configuration file has been renamed to se-config.toml in Selenium Manager 0.4.12. As usual, if you use this configuration file, it must be placed in the root of the cache folder.

Other changes

A minor change in Selenium Manager 0.4.12 is related to the metadata file, now called se-metadata.json. As usual, this file is stored in the root of the cache folder. This file contains versions discovered by Selenium Manager making network requests and the time-to-live (TTL) in which they are valid. Since the TTL for browsers and drivers is now the same concept, Selenium Manager unifies these two configuration elements (previously, browser_ttl and driver_ttl) in a single one called ttl (with a default value of 3600 seconds, i.e., 1 hour). For further details, visit the Selenium Manager page about caching.

Last but not least, the Selenium Manager binary compiled for macOS is universal, in the sense that it can be executed both in x64 and arm64 architectures out of the box. Previously, the binary was compiled for x64, and so, Rosetta should be available in arm64 macOS machines (i.e., M1 or M2). With the new Selenium Manager macOS binary, Rosetta is no longer mandatory.

Next steps

The next release of Selenium Manager will continue delivering automated browser management, this time for Edge, and other features. As usual, you can trace the work in progress in the Selenium Manager project dashboard.

Selenium 4.11.0 Released!

Today we’re happy to announce that Selenium 4.11.0 has been released!

We’re very happy to announce the release of Selenium 4.11.0 for Java, .NET, Ruby, Python, and Javascript as well as the Grid and Internet Explorer Driver. Links to everything can be found on our downloads page.

Highlights

  • Chrome DevTools support is now: v113, v114, and v115 (Firefox still uses v85 for all versions)
  • Support for Chrome for Testing (CfT) through Selenium Manager. Read more at the new Selenium Manager features blog post.
  • Selenium Manager now locates the browser driver binary on PATH or the configured path, checks for potential incompatibilities, and gives better warning and error messages.
  • Nightly builds are being pushed for Ruby and Java. Support for other languages is coming soon.
  • Ignore process id match when finding the window handle - IE Mode on Edge. (#12246) (#12279)

Relevant improvements per language

  • Java
    • Make user defined SlotMatcher used everywhere in Grid code (#12240)
    • Add support for FedCM commands (#12096)


  • .NET
    • Implementation of event wrapped shadow root element (#12073)
    • Allow setting a different pointer, keyboard, or wheel on input device (#11513)
    • Add move to location method to Actions (#11509)
    • Add support for Safari Technology Preview (#12342)
    • Fix error when we send non-base64 data for fetch command (#12431)
    • Fix continueResponse method in CDP (#12445)

  • Python
    • removed redundant attributes capabilities and set_capability in wpewebkit/options.py (#12169)
    • improve driver logging, implement log_output() for flexibility and consistency of driver logging (#12103)
    • let users pass service args to IE driver (#12272)
    • Expose WPEWebKitService and WebKitGTKService in the public API
    • Remove deprecated ActionChains.scroll(...)
    • Add creation flag for windows in selenium_manager (#12435)

  • Ruby
    • Made network interception threads fail silently (#12226)
    • Remove deprecated code (#12417)

Contributors

Special shout-out to everyone who helped the Selenium Team get this release out!

Selenium

Michael Mintz

Michael Mintz

Nikolay Borisenko

Nikolay Borisenko

Sandeep Suryaprasad

Sandeep Suryaprasad

Hanbo Wang

Hanbo Wang

Sebastian Meyer

Sebastian Meyer

Daniel Brown

Daniel Brown

Vedanth Vasu Dev

Vedanth Vasu Dev

Bartek Florczak

Bartek Florczak

João Luca Ripardo

João Luca Ripardo

Debanjan Choudhury

Debanjan Choudhury

Christian Biesinger

Christian Biesinger

SenZmaKi

SenZmaKi

Selenium Docs & Website

Cristian Greco

Cristian Greco

Gayathri Rukmadhavan

Gayathri Rukmadhavan

Mikhail C.

Mikhail C.

nevinaydin

nevinaydin

Erick Ribeiro

Erick Ribeiro

Docker Selenium

Luis Correia

Luis Correia

alb3ric

alb3ric

Bartek Florczak

Bartek Florczak

Mårten Svantesson

Mårten Svantesson

wintersolutions

wintersolutions

Thanks as well to all the Selenium Team Members who contributed to this release:

Tamsil Sajid Amani

Tamsil Sajid Amani

Diego Molina

Diego Molina

Sri Harsha

Sri Harsha

Titus Fortner

Titus Fortner

Simon Stewart

Simon Stewart

Boni García

Boni García

Puja Jagani

Puja Jagani

Simon K

Simon K

Alex Rodionov

Alex Rodionov

Krishnan Mahadevan

Krishnan Mahadevan

David Burns

David Burns

James Mortensen

James Mortensen

Stay tuned for updates by following SeleniumHQ!

Happy testing!

What's new in Selenium Manager with Selenium 4.11.0

Selenium 4.11.0 ships very relevant new features of Selenium Manager: support of Chrome for Testing (CfT) endpoints for chromedriver management and automated Chrome management (based also on CfT).

As of version 4.6.0, all releases of Selenium (Java, JavaScript, Python, Ruby, and .Net) are shipped with Selenium Manager. Selenium Manager is a binary tool (implemented in Rust) that provides automated driver management for Selenium. Selenium Manager is still in beta, although it is becoming a relevant component of Selenium.

So far, the main feature of Selenium Manager is called automated driver management. I use the term management for this feature (and not just download) since this process is broader and implies different steps:

  1. Browser version discovery. Selenium Manager discovers the browser version (e.g., Chrome, Firefox, Edge) installed in the machine that executes Selenium. For this step, shell commands are used (e.g., google-chrome --version).
  2. Driver version discovery. With the discovered browser version, the proper driver version is resolved. For this step, the online metadata maintained by the browser vendors (e.g., chromedriver, geckodriver, or msedgedriver) are used.
  3. Driver download. With the resolved driver version, the driver URL is obtained; with that URL, the driver artifact is downloaded, uncompressed, and stored locally.
  4. Driver cache. Uncompressed driver binaries are stored in a local cache folder (~/.cache/selenium). The next time the same driver is required, if the driver is already in the cache, it will be used from there.

Drivers on the PATH

Driver management through Selenium Manager is opt-in for the Selenium bindings. Thus, users can continue managing their drivers manually (putting the driver in the PATH or using system properties) or rely on a third-party manager to do it automatically. Selenium Manager only operates as a fallback: if no driver is provided, Selenium Manager will come to the rescue. Nevertheless, Selenium Manager also helps users to identify potential problems with the drivers on the PATH.

Let’s consider an example. Imagine you manually manage your chromedriver for your Selenium tests. When you carry out this management, the stable version of Chrome is 113, so you download chromedriver 113 and put it in your PATH. Your Selenium tests execute. Everything is fine. But the problem here is that Chrome is evergreen. This name refers to Chrome’s ability to upgrade automatically and silently to the next stable version when available. This feature is excellent for end-users but potentially dangerous for automated testing. Let’s go back to the example to discover it. Your local Chrome will eventually update to version 115. And that moment, your Selenium tests will be broken due to the incompatibility of the manually managed driver (113) and your Chrome (115). That day, your test dashboard will be red due to the following error message: “session not created: This version of ChromeDriver only supports Chrome version 113”.

This problem is the primary reason for the existence of the so-called driver managers. And as of Selenium 4.11, Selenium Manager helps to understand potential issues related to the drivers in the PATH. When an incompatible driver release is found in the PATH, a warning message like the following is displayed to the user:

WARN    The chromedriver version (113.0.5672.63) detected in PATH at C:\my-drivers\chromedriver.exe might not be compatible with the detected chrome version (115.0.5790.110); currently, chromedriver 115.0.5790.102 is recommended for chrome 115.*, so it is advised to delete the driver in PATH and retry

Entering Chrome for Testing (CfT)

The Chrome team started a very relevant initiative for the testing community in 2023: Chrome for Testing (CfT). CfT is a reduced release of Chrome primarily addressed to the testing use case.

One of the key differences between a regular Chrome release and CfT is that Chrome is evergreen, but CfT is not. This way, CfT allows pined browsers for testing. CfT releases are portable binaries (for Windows, Linux, and macOS) for different versions, including the stable, beta, dev, and canary channels. These releases can be programmatically discovered using the CfT JSON endpoints.

As of version 114, the chromedriver team has stopped publishing the chromedriver releases and metadata using their traditional chromedriver download repository. This way, and as of version 115, chromedriver releases can only be discovered programmatically using the abovementioned CfT JSON endpoints.

This change has been very relevant for the so-called driver managers. Luckily, Selenium already supports this new way of chromedriver discovery. The last version of Selenium Manager uses the CfT endpoints for chromedriver management. Therefore, if you are using Selenium Manager and Chrome, you must be updated to Selenium 4.11.0 to continue managing chromedriver automatically.

Automated browser management

Moreover, as of Selenium 4.11.0, Selenium Manager implements automated browser management based on CfT. In other words, Selenium Manager uses the CfT endpoints to discover, download, and cache the different CfT releases, making them seamlessly available for Selenium.

Let’s suppose we want to driver Chrome with Selenium (see the doc about how to start a session with Selenium). Before the session begins, and when the driver is unavailable, Selenium Manager manages chromedriver for us. This way, all the complexity related to CfT endpoints, driver versions, etc., is transparent, and we can rely on Selenium Manager to discover, download, and cache the proper driver for us.

In addition, and as a significant novelty starting on Selenium 4.11.0, if Chrome is not installed on the local machine when executing the previous line, the current stable CfT release is discovered, downloaded, and cached (in ~/.cache/selenium/chrome). But there is more. In addition to the stable CfT version, Selenium Manager also allows downloading of older versions of CfT (starting in version 113, which is the first version published as CfT).

To set a browser version with Selenium, we use a browser option called browserVersion. Until now, the value of this option had no effect when using the local browser since Selenium could not change what is installed in the system. But things are different with Selenium 4.11.0.

Let’s consider a simple example. Suppose we set browserVersion to 114 using Chrome options. In this case, Selenium Manager will check if Chrome 114 is already installed. If it is, it will be used. If not, Selenium Manager will manage (i.e., discover, download, and cache) CfT 114. And in either case, the chromedriver is also managed. Finally, Selenium will start Chrome to be driven programmatically, as usual.

But there is even more. In addition to fixed browser versions (e.g., 113, 114, 115, etc.), we can use the following labels for browserVersion:

  • stable: Current CfT version.
  • beta: Next version to stable.
  • dev: Version in development at this moment.
  • canary: Nightly build for developers.

When these labels are specified, Selenium Manager first checks if a given Chrome is already installed (beta, dev, etc.), and when it is not detected, CfT is automatically managed.

Under the hood

Selenium Manager is a CLI (command line interface) tool implemented in Rust and compiled for Windows, Linux, and macOS. The Selenium Manager binaries are shipped with each Selenium release. This way, each Selenium binding language invokes Selenium Manager to carry out the automated driver and browser management previously explained.

For most users, Selenium Manager should work silently and transparently. But if you want to play with Selenium Manager or use it for your own use case (e.g., to download drivers or CfT releases), you can get the Selenium Manager binaries from the Selenium main repository.

For instance, to manage Chrome/chromedriver, the Selenium Manager command we need to invoke from the shell is the following (notice that the flag --debug is optional, but it helps us to understand what Selenium Manager is doing):

> selenium-manager --browser chrome --debug
DEBUG   Checking chromedriver in PATH
DEBUG   Running command: chromedriver --version
DEBUG   Output: ""
DEBUG   chromedriver not found in PATH
DEBUG   chrome detected at C:\Program Files\Google\Chrome\Application\chrome.exe
DEBUG   Using shell command to find out chrome version
DEBUG   Running command: wmic datafile where name='C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe' get Version /value
DEBUG   Output: "\r\r\n\r\r\nVersion=115.0.5790.110\r\r\n\r\r\n\r\r\n\r"
DEBUG   Detected browser: chrome 115.0.5790.110
DEBUG   Reading metadata from https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json
DEBUG   Required driver: chromedriver 115.0.5790.102
DEBUG   Driver URL: https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/115.0.5790.102/win64/chromedriver-win64.zip
INFO    Driver path: C:\Users\boni\.cache\selenium\chromedriver\win64\115.0.5790.102\chromedriver.exe
INFO    Browser path: C:\Program Files\Google\Chrome\Application\chrome.exe

In this case, the local Chrome (in Windows) is detected by Selenium Manager. Then, using its version and the CfT endpoints, the proper chromedriver version (115, in this example) is downloaded to the local cache. Finally, Selenium Manager provides two results: i) the driver path (downloaded) and ii) the browser path (local).

Let’s consider another example. Now we want to use Chrome beta. Therefore, we invoke Selenium Manager specifying that version label as follows (notice that the CfT beta is discovered, downloaded, and stored in the local cache):

> selenium-manager --browser chrome --debug --browser-version beta
DEBUG   Checking chromedriver in PATH
DEBUG   Running command: chromedriver --version
DEBUG   Output: ""
DEBUG   chromedriver not found in PATH
DEBUG   Checking chrome in PATH
DEBUG   Running command: where chrome
DEBUG   Output: ""
DEBUG   chrome not found in PATH
DEBUG   chrome has not been discovered in the system
DEBUG   Reading metadata from https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions-with-downloads.json
DEBUG   Required browser: chrome 116.0.5845.49
DEBUG   Downloading chrome 116.0.5845.49 from https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/116.0.5845.49/win64/chrome-win64.zip
DEBUG   chrome 116.0.5845.49 has been downloaded at C:\Users\boni\.cache\selenium\chrome\win64\116.0.5845.49\chrome.exe
DEBUG   Reading metadata from https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json
DEBUG   Required driver: chromedriver 116.0.5845.49
DEBUG   Driver URL: https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/116.0.5845.49/win64/chromedriver-win64.zip
INFO    Driver path: C:\Users\boni\.cache\selenium\chromedriver\win64\116.0.5845.49\chromedriver.exe
INFO    Browser path: C:\Users\boni\.cache\selenium\chrome\win64\116.0.5845.49\chrome.exe

Troubleshooting in the bindings

If you want to get the Selenium Manager debugging information (as shown in the section before) when using the Selenium bindings languages, you can enable the logging capabilities of Selenium. Please visit the Selenium troubleshooting page for details.

Next steps

You can trace the work in progress in the Selenium Manager project dashboard. The following features to be implemented in Selenium Manager will continue the automated browser management mechanism, this time for Firefox and Edge. Stay tuned!

Building Selenium

How does the Selenium team build Selenium itself, and why did we chose the tools we chose?

One of the things that we knew from the very beginning of the Selenium project was that people like to code in more than one language. Some people love a bit of JS, others Ruby, and still others prefer C# or Java.

To complicate matters, there’s plenty of pieces we want to share between the language bindings you’ll be using. Examples include the “atoms” (re-usable pieces of javascript that perform common functions – such as “isDisplayed” or “getAttribute” – that we want to work the same way no matter which language you prefer to write tests in), things like our CDP support, which uses shared files that describe all the available functions we can call, and the new Selenium Manager, which is written in Rust, but we bundle with each of the language bindings.

The process of converting the source code and other artefacts (such as the atoms) together into the artefacts we distribute (such as the Selenium Server, or the language bindings) is called the “build”. There are plenty of build tools out there. If you’re a java developer, you’ve probably come across Maven or Gradle. If you’re a JS hacker, then perhaps something like npm or yarn is something you’ve used. If you’re a C developer (there are still plenty out there!) then you’re likely using make or CMake.

The problem with many build tools is that they’re focused on one language. Npm is great, but it’s a terrible choice for a Java project. Gradle is fine, but not if you’re working in Ruby.

Why is this a problem? Because in the Selenium codebase we want to support multiple different languages, and we want to be able to “stitch” them together into a single cohesive whole. For example, the Selenium jars contain a fairly large amount of JS. The Ruby gems do too.

What we want is a single build tool that can cope with lots of different languages, so we can weave our build into something where we only need that one tool.

Enter Bazel. This was a build tool originally developed by Google, but which is now Open Source and increasingly widely used. Bazel itself is relatively limited in what it can do, but it can be extended easily using “rulesets” that allow it to support everything we need, and more!

Bazel is one of a new generation of build tools, and focuses on exposing how each part of the build process relates to the other parts. You could imagine drawing a chart, with each thing we need to compile (eg. Selenium Manager, or the atoms, or one of the jars we ship) connected by lines to other parts that they depend upon. In Computer Science, that chart is called a “graph”, and because each line has a direction (“this thing depends upon that thing”) we call it a directed graph. Because we can’t depend on something that depends on itself, we can introduce a “cycle”. Bazel is a build tool designed to work with these “directed acyclic graphs”.

One nice thing about these graphs is that there are well-known ways to figure out which parts of the build can be performed in parallel. A modern computer has a CPU with many (4, 8, 16!) cores, plenty of memory, and fast SSDs: it can comfortably perform many tasks at the same time. So Bazel takes advantage of this, running as many parts of the build at the same time as it can. This makes our builds significantly faster than they used to be!

Better yet, Bazel makes us list all the things that each part of the build depends on. Not just the source code, but which versions of which tools we’re using. That makes it a lot easier for a developer new to the project to get started: they just need to clone our repo, make sure they have Bazel installed, and the build process will take care of making sure that they have everything they need (although that first build may be very slow as everything that’s needed will be downloaded from the Net). That’s not just nice for people new to the project, it’s nice for the existing developers. They no longer need to know how to install and set up toolchains that they may not be familiar with – they just run the build.

Using the “build graph”, Bazel is able to tell which pieces of code in the Selenium source code depend on which other parts. This means that although we can tell Bazel to “run all our tests” when we make a change, it’s smart enough to know that it only needs to run those tests which are actually affected by a change. You can see this in action in this video, but needless to say, this can save us a huge amount of time! We can also ask Bazel to re-run flaky tests

But there’s another advantage of describing all the things we need for a build. Since we’ve described everything we need to Bazel, and how all the pieces fit together, there’s no need to just run the build on our own machines. We’re working with EngFlow to make use of their build grid. Rather than just running a small number of things at the same time on our machines, we can run many times that on their build grid. Our builds there are incredibly fast!

So, that’s why we use Bazel on our project: it supports all the languages we want to use in a single tool, allows us to not think about how to set up our development machines, runs builds incredibly quickly, and we can make use of build grids to build things even faster.

Java 8 support in Selenium

On September 30, 2023, Java 11 will be the minimum version supported by Selenium.

“If it ain’t broke, don’t fix it” is a saying you may have heard, but sometimes it’s necessary to move on from our old favorites. That’s why we’re announcing that Selenium will stop supporting Java 8 on September 30, 2023. This applies for both the Java bindings and the Selenium Grid.

Selenium has long supported Java 8, but as technology evolves, so must we. One of the primary reasons for this change is that Java 8 reached the end of active support over a year ago. In addition, our default HTTP Client has not had a major release in several years, and a bug has been found that we can not fix. We have decided to move to the native Java HTTP Client, but it requires using Java 11 or greater. The sooner we make this change, the sooner we can avoid dealing with this issue.

Our new minimum version will be Java 11. September 30, 2023 is also the end of active support for Java 11. However, we want to take a cautious and conservative path forward, and not force our users to make the big jump from Java 8 to Java 17, as we understand the community might need longer to move to that version. We will revisit this topic in the future to announce the plan to support Java 17 as a minimum version.

We understand that this change may require some of our users to make adjustments, but we believe that it’s a necessary step for the continued growth of Selenium. Please take some time to check your infrastructure and ensure you’re running on Java 11 or higher. We understand that some may be hesitant or may find it difficult to make the switch, but we believe it will pay off in the long run.

Please let us know your questions, concerns, and feedback through our community chat.

Happy testing!

Selenium 4.10.0 Released!

Today we’re happy to announce that Selenium 4.10.0 has been released!

We’re very happy to announce the release of Selenium 4.10.0 for Java, .NET, Ruby, Python, and Javascript as well as the Grid and Internet Explorer Driver. Links to everything can be found on our downloads page.

Highlights

  • Chrome DevTools support is now: v112, v113, and v114 (Firefox still uses v85 for all versions)
  • Selenium Manager supports proxy usage by using the proxy information set in the browser options.
  • Adding support for webview2 in Edge for Java, JavaScript, and Ruby
  • Error messages across bindings now include links to the Selenium documentation.
  • Overhaul of the service classes and logging output options.
  • Logger in Ruby updated default behavior to match other languages and added features to improve filtering types of logging.
  • Python - removal of several sections of deprecated code.

Contributors

Special shout-out to everyone who helped the Selenium Team get this release out!

Selenium

Boris Petrov

Boris Petrov

Nikolay Borisenko

Nikolay Borisenko

Rishav Trivedi

Rishav Trivedi

Michael Mintz

Michael Mintz

Vladislav Velichko

Vladislav Velichko

Moritz Kiefer

Moritz Kiefer

Valery Yatsynovich

Valery Yatsynovich

Oboleninov Anton

Oboleninov Anton

Scott Stevens

Scott Stevens

Sandeep Suryaprasad

Sandeep Suryaprasad

Alpatron

Alpatron

Tarek Oraby

Tarek Oraby

robin gupta

robin gupta

Kat Rollo

Kat Rollo

Brandon Squizzato

Brandon Squizzato

Luis Correia

Luis Correia

Stephan Erlank

Stephan Erlank

Jordan Zimmitti

Jordan Zimmitti

Brian Schreder

Brian Schreder

Selenium Docs & Website

Tarek Oraby

Tarek Oraby

robin gupta

robin gupta

Kat Rollo

Kat Rollo

Brandon Squizzato

Brandon Squizzato

Docker Selenium

Luis Correia

Luis Correia

Stephan Erlank

Stephan Erlank

Jordan Zimmitti

Jordan Zimmitti

Brian Schreder

Brian Schreder

Thanks as well to all the Selenium Team Members who contributed to this release:

Boni García

Boni García

Alex Rodionov

Alex Rodionov

Tamsil Sajid Amani

Tamsil Sajid Amani

Diego Molina

Diego Molina

Titus Fortner

Titus Fortner

Simon Stewart

Simon Stewart

Krishnan Mahadevan

Krishnan Mahadevan

Sri Harsha

Sri Harsha

Puja Jagani

Puja Jagani

David Burns

David Burns

James Mortensen

James Mortensen

Stay tuned for updates by following SeleniumHQ!

Happy testing!

InvalidSelectorException has changed

⚠️ InvalidSelectorException now extends from WebDriverException

Before Selenium 4.8.2 in Java and C#, when an invalid locator was used to identify an element, the resulting behavior would be inconsistent in our bindings.

For example, let’s check the following code:

ArrayList<Class<? extends Exception>> expectedExceptions = new ArrayList<>();
        expectedExceptions.add(org.openqa.selenium.NoSuchElementException.class);
        expectedExceptions.add(org.openqa.selenium.StaleElementReferenceException.class);
        expectedExceptions.add(org.openqa.selenium.ElementNotInteractableException.class);
        expectedExceptions.add(org.openqa.selenium.InvalidElementStateException.class);
        
return new FluentWait<>(driver)
      .withTimeout(Duration.ofMillis(ELEMENT_IDENTIFICATION_TIMEOUT))
      .pollingEvery(Duration.ofMillis(ELEMENT_IDENTIFICATION_POLLING_DELAY))
      .ignoreAll(expectedExceptions)
      .until(nestedDriver -> {
         nestedDriver.findElement(By.xpath("invalid-xpath")).click;
      });

The expected result before this change would be that the driver waits until the timeout expires and then throw an InvalidSelectorException.

This doesn’t make much sense because a broken/invalid selector would never fix itself, and hence should throw immediately.

This was discussed and agreed during the TLC meeting on August 17, 2022, and implemented through the pull request 11727 and the following commit.

With the changes mentioned above, an invalid selector will throw an InvalidSelectorException immediately.

Please note that this may have an impact on backwards compatibility if you are not expecting this exception to be thrown while handling invalid locators.

Stay tuned for updates by following SeleniumHQ!

Happy testing!

Selenium 4.9.0 Released!

Today we’re happy to announce that Selenium 4.9.0 has been released!

We’re very happy to announce the release of Selenium 4.9.0 for Java, .NET, Ruby, Python, and Javascript as well as the Grid and Internet Explorer Driver. Links to everything can be found on our downloads page.

Highlights

Contributors

Special shout-out to everyone who helped the Selenium Team get this release out!

Ashley Trinh

Ashley Trinh

Nikolay Borisenko

Nikolay Borisenko

Orion (Ardi) Gonzalez

Orion (Ardi) Gonzalez

Dana Sherson

Dana Sherson

Zach Attas

Zach Attas

Ariel Juodziukynas

Ariel Juodziukynas

Henrik Skupin

Henrik Skupin

Abdullah Aslam

Abdullah Aslam

ting

ting

Johnny.H

Johnny.H

Mohab Mohie

Mohab Mohie

Michael Mintz

Michael Mintz

Michael Render

Michael Render

Tobias Smolka

Tobias Smolka

Étienne Barrié

Étienne Barrié

James Hilliard

James Hilliard

Mark Mayo

Mark Mayo

Thanks as well to all the Selenium Team Members who contributed to this release:

Alex Rodionov

Alex Rodionov

Boni García

Boni García

Titus Fortner

Titus Fortner

Diego Molina

Diego Molina

Tamsil Sajid Amani

Tamsil Sajid Amani

Sri Harsha

Sri Harsha

Simon Stewart

Simon Stewart

Krishnan Mahadevan

Krishnan Mahadevan

David Burns

David Burns

Simon K

Simon K

Puja Jagani

Puja Jagani

Stay tuned for updates by following SeleniumHQ!

Happy testing!

Let's meet at SeleniumConf, Once Again!

SeleniumConf is back in person! Yes! It does feel good to say this.

This year is special, thanks to the decision to host an in-person conference after a long hiatus and several years of virtual-only events. We’ve gone out of our way to reflect this feeling at the conference. We have engrossing keynotes, well-researched talks, hands-on pre-conference workshops, hallway tracks, and whatnot!

Here’s a quick list of what to expect!

What’s cooking in Keynotes?

We have Diego Molina kicking things off with ‘Selenium: State of the Union’ where he will talk about all things Selenium, including the project, the code, and the community. Think of it as a journey through the times with Selenium. A must-attend without any shred of doubt!

Next up is Erika Chestnut’s ‘Bigger Than The Box’ where she will focus on the idea of quality and whether it has been restricted to only a single step in the delivery process. It is indeed a dialogue that needs to happen given that our lives revolve around quality.

On day 2, we have first-time SeleniumConf keynote speaker Mark Winteringham from the Ministry of Testing talking about ‘What Exactly Do You Do in Test Automation?’ Is it just about coding and frameworks or is there more to it? How should a test automation practitioner think about their role? Think of this as learning from the ground up or in some cases, back to the basics!

Talks, talks, and more talks

We’ve cast our net far and wide this time around.

Just as a highlight, across the two days, we will cover a diverse range of topics from crawlers, identifying code smells, blended testing, component testing, quality gates, quality metrics to track, testing with real robots, and managing the test data nightmare, among others. Quite a list, huh? Trust me, this is just a sneak peek. You can check out the entire list here.

Also, we’ve got a session on how testing with Selenium is solving unemployment in Africa.

The cherry on the cake is the Q&A with the Selenium Committer’s Panel where you’ll get to pick the brains of the very people who’ve built Selenium.

In a way, we’ve truly tried our best to touch upon the technology, people, and process aspects of testing. We’d love to have you over to catch these experts in action!

Getting your hands dirty with tailored workshops

Testing is all about exploring. How about exploring and diving into something new?

We’ve got community leaders doing deep dives into Selenium, Appium 2.0, how to become a committer, state model-based testing, and driving observability with Selenium Grid.

We truly believe that nothing beats hearing it from the horse’s mouth.

What’s more?

While there are some amazing keynotes, well-researched talks, and structured workshops, we really think the biggest takeaway for any attendee is the people they’ll get to meet. Selenium has been a great example of how the community can come together to build something that is greater than the sum of its parts. A conference like this brings together folks from across the world, with different levels of experience, and puts them under a single roof.

What can be more beautiful than getting to interact with the very community that has built and grown Selenium?

What are you waiting for? Register now! We can’t wait to welcome you to Chicago!

Headless is Going Away!

Now that we got your attention, headless is not actually going away, just the convenience method to set it in Selenium

Headless is an execution mode for Firefox and Chromium based browsers. It allows users to run automated scripts in headless mode, meaning that the browser window wouldn’t be visible. In most of Selenium’s bindings there is a convenience method to set this execution mode while setting the browser options. However, Selenium 4.8.0 will be deprecated this method and now users need to set it through arguments when setting the browser options.

Why is Selenium doing this?

Chromium based browsers have now two different headless modes (the original one, and one with more capabilities added in 2022). When a user sets headless to true via the convenience method in Selenium, it is using the initial method provided by Chromium based browsers.

By deprecating the convenience method (and removing it in Selenium 4.10.0), users will be in full control to choose which headless mode they want to use.

What are the two headless modes?

The traditional --headless, and since version 96, Chrome has a new headless mode that allows users to get the full browser functionality (even run extensions). Between versions 96 to 108 it was --headless=chrome, after version 109 --headless=new.

Using --headless=new should bring a better experience when using headless with Selenium.

Thanks to Michael Mintz for the detailed explanation!

Check more details about the new headleass mode at the official Chrome blog.

How can I set headless mode from now on?

In short, users can add the headless mode they want to use through arguments in browser options.

Before

ChromeOptions options = new ChromeOptions();
options.setHeadless(true);
WebDriver driver = new ChromeDriver(options);
driver.get("https://selenium.dev");
driver.quit();
let driver = await env
  .builder()
  .setChromeOptions(new chrome.Options().headless())
  .build();
await driver.get('https://selenium.dev');
await driver.quit();
// C# did not have a convenience method
options = Selenium::WebDriver::Chrome::Options.new
options.headless!
driver = Selenium::WebDriver.for :chrome, options: options
driver.get('https://selenium.dev')
driver.quit
options = ChromeOptions()
options.headless = True
driver = webdriver.Chrome(options=options)
driver.get('http://selenium.dev')
driver.quit()

After

ChromeOptions options = new ChromeOptions();
options.addArguments("--headless=new");
WebDriver driver = new ChromeDriver(options);
driver.get("https://selenium.dev");
driver.quit();
let driver = await env
  .builder()
  .setChromeOptions(options.addArguments('--headless=new'))
  .build();
await driver.get('https://selenium.dev');
await driver.quit();
var options = new ChromeOptions();
options.AddArgument("--headless=new");
var driver = new ChromeDriver(options);
driver.Navigate().GoToUrl("https://selenium.dev");
driver.Quit();
options = Selenium::WebDriver::Options.chrome(args: ['--headless=new'])
driver = Selenium::WebDriver.for :chrome, options: options
driver.get('https://selenium.dev')
driver.quit
options = ChromeOptions()
options.add_argument("--headless=new")
driver = webdriver.Chrome(options=options)
driver.get('http://selenium.dev')
driver.quit()

If you have any questions or comments, please reach out through any of all the available options shown at our support page.

Stay tuned for updates by following SeleniumHQ!

Happy testing!

Selenium 4.8.0 Released!

Today we’re happy to announce that Selenium 4.8.0 has been released!

We’re very happy to announce the release of Selenium 4.8.0 for Java, .NET, Ruby, Python, and Javascript as well as the Grid and Internet Explorer Driver. Links to everything can be found on our downloads page.

Highlights

  • Chrome DevTools support is now: v107, v108, and v109 (Firefox still uses v85 for all versions)
  • Large JS executions have the name as a comment to help understand what payload being sent to/from server/driver.
  • Deprecation of headless convenience method. Read more about in the headless blog post.
  • Ruby overhauls Options classes (again)
  • Initial BiDi support in JavaScript, Ruby, and improvements in Java.
  • We’re continuing to remove Legacy Protocol classes in Java and Grid.
  • Accommodate ability to specify sub-paths in Grid.
  • Plus various language specific bug fixes; see the full list of changes in the Changelogs

Contributors

Special shout-out to everyone who helped the Selenium Team get this release out!

Nikolay Borisenko

Nikolay Borisenko

Kian Eliasi

Kian Eliasi

James Hilliard

James Hilliard

Potapov Dmitriy

Potapov Dmitriy

Johnson Sun

Johnson Sun

George Adams

George Adams

Jon Dufresne

Jon Dufresne

Valery Yatsynovich

Valery Yatsynovich

Thanks as well to all the Selenium Team Members who contributed to this release:

David Burns

David Burns

Alex Rodionov

Alex Rodionov

Titus Fortner

Titus Fortner

Diego Molina

Diego Molina

Puja Jagani

Puja Jagani

Krishnan Mahadevan

Krishnan Mahadevan

Sri Harsha

Sri Harsha

Boni García

Boni García

Simon K

Simon K

Simon Stewart

Simon Stewart

Tamsil Sajid Amani

Tamsil Sajid Amani