New week, new topic! This week we’re sharing our tips for using Selenium – a tool used to automate web browsers and which we use in our end-to-end tests at trivago. You know the drill, we’ll be adding a new tip every day, so keep an eye out. If you’re a frequent user with some tips of your own to share, let us know in the comments below!
Tip #1: Scroll to the top or bottom of the page
Sometimes it can be helpful to navigate to the top or bottom on a website under test, especially if this triggers other elements such as floating headers.
To accomplish this, you can use Selenium’s JavascriptExecutor
combined with JavaScript’s scrollTo
method. This method takes an x and a y position and scrolls to those coordinates.
When scrolling to the top of the page, you just pass 0,0
as coordinates:
// Top of the page
((JavascriptExecutor) driver).executeScript(
"
window.scrollTo(0, 0);");
When scrolling to the bottom, the y coordinate is determined by the current height of the website’s body content:
// Bottom of the page
((JavascriptExecutor) driver).executeScript(
"
window.scrollTo(0, document.body.scrollHeight);");
Tip #2: Log the current session ID
Selenium generates a unique session ID for every browser it interacts with. Internally, this id is used to only send commands to this specific browser - this is especially important when executing tests in parallel. For debugging purposes, it is helpful to know this ID.
Since Selenium’s generic WebDriver class does not have a method to get the session ID directly, it can be cast to RemoteWebDriver to retrieve it.
Since the return value is of type SessionId, you additionally need to call its toString method to get the session ID string.
((RemoteWebDriver) driver).getSessionId()
.toString()
;
Tip #3: Use a different page load strategy
For some Selenium tests, it might not be necessary to completely load a website including all images and stylesheets, especially if a test only needs to check the contents of specific elements.
Since the default page load strategy (called normal) always waits for a full load of the page (meaning that the document ready state has the value complete), using the alternative eager strategy can speed up your test (internally it waits for the DOMContentLoaded event):
options.setPageLoadStrategy(PageLoadStrategy.EAGER);
WebDriver driver = new ChromeDriver(options);
driver.get("https://www.trivago.de");
There even is a third one called none that only waits until the website is downloaded but not parsed - this should be used with caution, though.
Tip #4: Use robust fluent waits
Waits are one of the most important parts of Selenium. Explicit waits should be avoided at all costs (e.g. “Wait for 2 seconds”) as they most likely introduce flakiness.
The “normal” WebDriverWait is much better since it allows waiting until a specific condition is met. It lacks customization options though: every 500 milliseconds it checks if the condition it should wait for is met and it’s not easy to deal with certain exceptions that can occur during this period.
FluentWait is more flexible. It allows you to customize your web driver wait timeout and polling frequency as well as ignore certain exceptions.
Wait<WebDriver> fluentWait = new FluentWait<WebDriver>(driver)
.withTimeout(Duration.ofSeconds(20))
.pollingEvery(Duration.ofSeconds(1))
.ignoring(NoSuchElementException.class);
Tip #5: Search web elements near others
Selenium 4, which is currently in Alpha 7, introduced a concept that was initially called “Friendly Locators” and is now known as “Relative Locators”. Those allow you to locate elements in relation to another known element.
You can search for elements
left of (leftOf(..))
right of (rightOf(..))
above (above(..))
below (below(..)) or
near (near(..))
another element.
All these methods can also be chained in order to perform more detailed searches such as “to the left and below”.
Here is an example that locates a tag to the left of a specific image (specified by the id `trivago-logo`):
driver.findElement(withTagName("a").toLeftOf(By.id("trivago-logo"));
Please note that all relative locator methods work in conjunction with Selenium's standard By locators or specific WebElements which makes them really flexible!
And it’s a wrap! 🌮
All credit to Benjamin Bischoff, Test Automation Engineer at trivago, for compiling our Selenium tips for the week!
More tips coming soon in this space.