Write Concise Web Tests With Selenide for Java Projects

Last Updated:  May 28, 2021 | Published: November 6, 2020

Good old web tests – extremely valuable but annoying once they get flaky. If you are familiar with Selenium, you might find your self-writing helper functions to e.g. wait on elements to be present in the DOM or AJAX calls to finish. As Selenium is more or less a low-level API to manage the browser, this usually leads to boilerplate code for your projects. The Selenide project eliminates the shortcoming of the low-level API nature of Selenium. With Selenide you can write concise, stable, and short web tests for your Java projects.

Java Project Setup for Selenide

For a Maven-based project, we have to include the following dependency:

That's all we need. The Selenide dependency already includes Selenium's selenium-java dependency, so we don't have to include any Selenium-related dependency on our own. All specific browser APIs are part of this library and we can start writing automated web tests for Chrome, Edge, Firefox, Opera, Safari, etc.

Apart from this, Selenide also ships with the WebDriverManager. This is a useful utility library to automate the management of browser drivers. As we always need the driver binary of our target browser (e.g. chromedriver) installed while executing the web tests, manually downloading them and managing their versions is cumbersome.

The WebDriverManager project takes over this task for us. Prior to executing a web test, the WebDriverManager ensures to download the required driver binary or use an already existing one. Hence we don't have to fiddle around with setting any parameters like -Dwebdriver.chrome.driver.

At the end of this blog post, we'll also see how we can utilize the WebDriver module of Testcontainers so that the driver is running in isolation as part of a Docker container.

Accessing Browser Elements with Selenide

The first step of every web test is to open the browser for a specific URL. With Selenide, that's a one-liner:

For demonstration purposes, let's assume we'll use a Spring Boot application that exposes one Thymleaf view and a REST API endpoint. The view displays a table of books whenever someone clicks a button to fetch them via AJAX.

Once the browser window opens our application, we can access HTML elements. Selenide provides two functions to access any SelenideEelement (a wrapper around Selenium's WebElement): $ and $$ (good old jQuery memories).

Using $, we'll get the first element that matches your search, whereas with $$ we get a list of all the elements that match.

Selenide provides different mechanisms (similar to Selenium) to locate elements by …

  • id
  • tagName (e.g. h1)
  • xpath
  • className
  • cssSelector
  • etc.

In our example, we first want to make sure the book table does not exist inside the DOM. Next, we want to click the button to fetch data via the book REST API.  After that, we can verify that our book table is rendered.

With Selenide, that's a three-liner:

As soon as we have access to the SelenideElement, we can perform actions (e.g. click or fill inputs) or express expectations using a readable and fluent API.

In addition to this, we can make sure that our page only contains one h1 element:

Make Screenshots During the Web Test Execution

Most of the time the execution of our web test is automated on a CI server (e.g. Jenkins or Gitlab CI). This makes it hard to actually see the automated test and understand the reason whenever the test fails.

Fortunately, Selenide creates a screenshot and captures the HTML for every failing test out-of-the-box. What's left to adjust is the location where Selenide stores these files. By default it's build/reports. As a Maven fanboy, I want the location to be inside the target folder.

For those of you that use JUnit Jupiter, you can override this by registering the ScreenShooterExtension:

We can also configure this using the Configuration class of Selenide:

In addition to the screenshots on failure, we can also manually take screenshots throughout our test execution:

Use Testcontainers to Provide The WebDriver

If you are familiar with Tescontainers, you might wonder if we can utilize its WebDriver module for the web tests that we write with Selenide.

Good news: Yes we can use Testcontainers to write web tests with Selenide for our Java projects!

For this to work, we need some additional dependencies:

Even though Selenide ships with the WebDriverManager, we don't have to create the WebDriver with it. We can instruct Selenide to use a WebDriverthat we created with Testcontainers:

The full example for our existing Java web test with Selenide but now using Testcontainers to provide the WebDriver looks like the following:

Keep in mind that the driver is now running in an isolated Docker container and we can't use localhost to refer to our application. Depending on which Docker version and operating system you execute the test, you might need to refer to your host via container.getTestHostIpAddress() or host.docker.internal. For more information on how to refer to your Docker Host take a look at this blog post or the answers to this question on Stack Overflow.

For more hands-on examples, consider joining the Testing Spring Boot Applications Masterclass. We'll use Selenide to write web tests for the real-world Book Reviewr application (React, Spring Boot, AWS, PostgreSQL) and verify its happy-path user journeys.

The source code for the demo application and this introduction to Selenide is available on GitHub.

Have fun writing web tests with Selenide for your Java projects,

Philip

 

{"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}

Join Our Mailing List To Get 3x Free Cheat Sheets

Free Java Cheat Sheets
>