Released Selenide 5.15.0

Released Selenide 5.15.0

Click and download
26.09.20

Hi all!

We released Selenide 5.15.0.

What’s new?

We added setting Configuration.pageLoadTimeout
(default value is 30 seconds)

Sometimes your browser hands trying to load some heavy page, or a huge image or something else.
You loose your time, your build lasts for a long; sessions get expired by timeout etc.

It would be reasonable to fail test fast in this case. But the default page loading timeout in Selenium is unreasonable big: the whole 5 minutes.

That’s why we added setting Configuration.pageLoadTimeout, so that you could easily change this timeout.

NB! The default is 30 seconds. It might be too small for your application. Be aware.

See issue 1268 and PR 1269.

We added generic click method
with ClickOptions parameter

In a way, this is a new word in Selenide API.

Initially, Selenide has method $.click() which just called standard Selenium method WebElement.click(). Which clicks to the center of web element (I guess).

Over time, variations began to appear:

  • we added setting Configuration.clickViaJs to click using JS code instead of WebElement.click(). In theory, it should make your tests more stable, and maybe even faster.
  • we added click with offset $.click(offsetX, offsetY) to click some other point but the center of element.

But if you ever had need to click “both ways” (standard and via JS), you had to switch the global setting Configuration.clickViaJs every time. It might be inconvenient.

That’s why we added method click which accepts a “way to click” as an explicit parameter.

Now you can click in different ways without changing the global setting:

  $("#page").click(usingJavaScript());
  $("#page").click(usingJavaScript().offset(123, 222));
  $("#page").click(usingJavaScript().offsetY(222));
  $("#page").click(usingDefaultMethod());

NB! We recommend to set Configuration.clickViaJs to a value which is reasonable in most cases, and pass ClickOptions parameter only in exceptional cases.

See issue 1173.
Thanks to Dmytro Stekanov for PR 1226.

We added generic method download method
with DownloadOptions parameter

A similar story is about method $.download(). Initially it could only download files with GET request.
Later Selenide added possibility to download files via PROXY server. And recently we added a third way - FOLDER.
Until now, you could only select the downloading method global, via global setting Configuration.fileDownload.

Now you can explicitly set downloading mode to every call of $.download method:

  File f = $("input").download(DownloadOptions.using(PROXY);
  File f = $("input").download(DownloadOptions.using(PROXY).withTimeout(9999));
  File f = $("input").download(DownloadOptions.using(PROXY).withFilter(withExtension("xls")).withTimeout(9999));
  File f = $("input").download(DownloadOptions.using(FOLDER);
  File f = $("input").download(DownloadOptions.using(FOLDER).withTimeout(9999));
  File f = $("input").download(DownloadOptions.using(FOLDER).withFilter(withExtension("pdf")).withTimeout(9999));

NB! We recommend to set Configuration.fileDownload to a value which is reasonable in most cases, and pass DownloadsOptions parameter only in exceptional cases.

See issue 1259 and PR 1260.

We added methods to work with LocalStorage

import static com.codeborne.selenide.Selenide.localStorage;

// Delete all items from local storage:
localStorage().clear();

// Add an item to local storage:
localStorage().setItem("username", "john");

// Check item value:
assertThat(localStorage().getItem("username")).isEqualTo("john");

// Check items count:
assertThat(localStorage().size()).isEqualTo(1);

// Remove an item from local storage:
localStorage().removeItem("username");
assertThat(localStorage().getItem("username")).isNull();

Thanks to Dmytro Stekanov for PR 1274.

We added checks for element own text (without descendants)

The classical selenide check $.shouldHave(text("Hello, world")) includes text of element itself and all its children (descendants).
But sometimes you want to check only the element itself, without descendants.

Now you can use ownText check for this:

  $.shouldHave(ownText("Hello"));           // We expect element text to contain "Hello" world
  $.shouldHave(exactOwnText("Hello"));      // We expect element have text "Hello"

See issue 1261 and PR 1262.

We improved performance of big filtered collections

Selenide has convenient methods for working with collections. You can search and filter elements, you can checks texts or properties of multiple elements with just one line.

But if you overuse this, you might end up with too slow tests. Like this:

ElementsCollection list = $$("li").filter(visible);   // Page has 100 <li> elements
for (int i = 0; i < 10; i++) {
  list.get(i).shouldBe(visible);
}

Assume that there is 100 <li> elements on the page. Then this test can work too slowly, because:

  • on each step, Selenide needs to reload the element (its state might have changed)
  • To reload Nth element of a collection, Selenide needs to reload the whole collection (Selenium does not have method like WebDriver.findElement(index)).
  • To reload a filtered collection, Selenide needs to apply the filter to all its elements (in this case, call WebElement.isDisplayed() for all 100 elements).


For comparison, this code works much faster:

ElementsCollection unfiltered = $$("li");   // Unfiltered collection 
for (int i = 0; i < 10; i++) {
  unfiltered.get(i).shouldBe(visible);
}

In this release, we improved working we collections. Now Selenide filter for collections is a bit smarter: to get list.get(N), it applies visible filter only to first <N> elements, not to all 100 elements.

See issue 1266 and PR 1270.


P.S. Let me remind you another way to speed up working with collections - method snapshot:

ElementsCollection list = $$("li").filter(visible).snapshot(); // snapshot() creates a "dump" of the collection. Selenide will not reload it  
for (int i = 0; i < 10; i++) {
  list.get(i).shouldBe(visible);
}

Method $$.snapshot() creates a “dump” of the collection. Selenide will not reload it every time.
It makes your test much faster, but there is a risk to get StaleElementReferenceException, if the collection still changes during the iteration.

We added check “href”

Sometimes you want to check that element <a> has a correct href attribute.
Selenide has a method for attribute check: $("a").shouldHave(attribute("href", "/foo/bar/details.html").

But there is a problem with links. Such a check may unexpectedly fail because Selenium returns an absolute, not a relative URL.

To address this issue, we added a special check for “href” attribute:

  `$("a").shouldHave(href("/foo/bar/details.html"))`

See issue 1272 and PR 1273.

We added chrome option “–no-sandbox”

We found that this option should make Chrome tests more stable. Let’s see if it helps.

See commit 3293956d

now Selenide throws an explicit error

… if it failed to create downloads folder.

See issue 1265 and commit 94ece98f](https://github.com/selenide/selenide/commit/94ece98f).

Upgraded to WebDriverManager 4.2.2

See WDM Changelog.


News

Exactly at the moment when I was releasing Selenide 5.15.0, Hima Bindu Peteti presented Selenide on meetup:


Andrei Solntsev

selenide.org

26.09.20