This is the multi-page printable view of this section. Click here to print.
Blog Posts - 2023
- Building Selenium
- Java 8 support in Selenium
- Selenium 4.10.0 Released!
- InvalidSelectorException has changed
- Selenium 4.9.0 Released!
- Let's meet at SeleniumConf, Once Again!
- Headless is Going Away!
- Selenium 4.8.0 Released!
Building Selenium
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
“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!
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 seveal sections of deprecated code.
- Most of them were arguments that can be set in the
Options
classes (browser values) orService
classes (browser driver values). - They have been deprecated since the first Selenium 4 release
- Most of them were arguments that can be set in the
Contributors
Special shout-out to everyone who helped the Selenium Team get this release out!
Selenium
Boris Petrov
Nikolay Borisenko
Maid
Rishav Trivedi
Alex
Michael Mintz
Vladislav Velichko
Moritz Kiefer
Valery Yatsynovich
Oboleninov Anton
Scott Stevens
Sandeep Suryaprasad
Alpatron
Tarek Oraby
robin gupta
Pallavi
Kat Rollo
Brandon Squizzato
Luis Correia
Stephan Erlank
Jordan Zimmitti
Brian Schreder
Selenium Docs & Website
Tarek Oraby
robin gupta
Pallavi
Kat Rollo
Brandon Squizzato
Docker Selenium
Luis Correia
Stephan Erlank
Jordan Zimmitti
Brian Schreder
Thanks as well to all the Selenium Team Members who contributed to this release:
Boni García
Alex Rodionov
Tamsil Sajid Amani
Diego Molina
Titus Fortner
Simon Stewart
Krishnan Mahadevan
Sri Harsha
Puja Jagani
David Burns
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!
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
- Chrome DevTools support is now: v110, v111, and v112 (Firefox still uses v85 for all versions)
- Maven BOM for the Java bindings.
- Remote file downloads are now possible through Selenium Grid.
- First steps taken to phase out CDP in Firefox and replace it with the BiDi implementation.
InvalidSelectorException
now extendsWebDriverException
instead ofNoSuchElementException
.- Selenium Manager uses information set in the browser options to get the correct browser driver.
- A sub-path can be set in Selenium Grid to have a custom Grid url.
- Complete removal of Json Wire Protocol support in Java and Grid.
Contributors
Special shout-out to everyone who helped the Selenium Team get this release out!
Ashley Trinh
Nikolay Borisenko
Ardi
Dana Sherson
Alex
Zach Attas
Ariel Juodziukynas
Henrik Skupin
Abdullah Aslam
ting
fuyou
Johnny.H
Mohab Mohie
Michael Mintz
Michael Render
Tobias Smolka
Étienne Barrié
James Hilliard
Mark Mayo
Thanks as well to all the Selenium Team Members who contributed to this release:
Alex Rodionov
Boni García
Titus Fortner
Diego Molina
Tamsil Sajid Amani
Sri Harsha
Simon Stewart
Krishnan Mahadevan
David Burns
Simon K
Puja Jagani
Stay tuned for updates by following SeleniumHQ!
Happy testing!
Let's meet at SeleniumConf, Once Again!
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!
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!
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
Kian Eliasi
James Hilliard
Potapov Dmitriy
Johnson Sun
George Adams
Jon Dufresne
Valery Yatsynovich
Thanks as well to all the Selenium Team Members who contributed to this release:
David Burns
Alex Rodionov
Titus Fortner
Diego Molina
Puja Jagani
Krishnan Mahadevan
Sri Harsha
Boni García
Simon K
Simon Stewart
Tamsil Sajid Amani