Selenide. Use or not Use? Benefits vs Drawbacks

Selenide is nice tool for writing selenium tests. I chose Selenide when I was developing the Framework, cool syntax, auto manage browser driver, auto init/destroy webdriver, additional wait methods, addtional locator strategies.

However, when the tests were increasing and I need to use a custom WebDriver and run tests in parallel, then we had problems with Selenide.

First, Let’s talk about what are cool things of Selenide that people should use it.

Selenide provides a concise API for using Selenium WebDriver in UI tests:

  • Smart waiting
  • Transparent WebDriver
  • Convenience methods
  • Ajax support
  • Automated screenshots

Transparent WebDriver

You don’t need to operate with WebDriver directly. Selenide will start and shut down the browser automatically whenever it’s needed. It also helps you manage and update the driver version according to browser version.

Convenience methods

Selenide provides concise API for that makes your tests shorter and more readable. Selenide has convenient methods for operating controls like textfield, radiobutton, selectbox, searching elements by texts and so on.

@Test
public void canFillComplexForm() {
  open("/client/registration");
  $(By.name("user.name")).val("johny");
  $(By.name("user.gender")).selectRadio("male");
  $("#user.preferredLayout").selectOption("plain");
  $("#user.securityQuestion").selectOptionByText("What is my first car?");
}

Ajax support

When testing Ajax applications we often need to wait until some element changes its state. Selenide has built-in methods for waiting.

Any of the following methods waits until the described event happens. Default timeout is 4 seconds.

 $("#topic").should(appear);
 $("#topic").shouldBe(visible);

 $("#topic").should(disappear);
 $("h1").shouldHave(text("Hello"));
 $(".message").shouldNotHave(text("Wait for loading..."));
 $(".password").shouldNotHave(cssClass("errorField"));
 
 $(".error").should(disappear);

Automated screenshots

When your test fail, Selenide will automatically take screenshot. You do not need to do anything for it.

Easy to Upload/Download file

$("#cv").uploadFile(new File("cv1.doc"));
$("#cv").uploadFile(
new File("cv1.doc"),
new File("cv2.doc"),
new File("cv3.doc")
);

$(".btn#cv").download();

Custom Matchers

$("h1").shouldHave(css("font-size", "16px"));

Find Elements by exact/partial Text

$(byText("Hello, VietNam")).shouldBe(visible);

$(withText("Hello")).shouldHave(text("Hello, VietNam"));

Search for parents/children

$("td").parent()
$("td").closest("tr")
$(".btn").closest(".modal")
$("div").find(B.name("q"))

Support sizzle Selectors

Sizzle supports virtually all CSS 3 Selectors. It supports:

  • CSS 3 Selector support
  • Full Unicode support
  • Escaped selector support #id\:value
  • Contains text :contains(text)
  • Complex :not :not(a#id)
  • Multiple :not :not(div,p)
  • Not attribute value [name!=value]
  • Has selector :has(div)
  • Position selectors 
    • :first:last:even:odd:gt:lt:eq
  • Easy Form selectors 
    • :input:text:checkbox:file,:password,
    • :submit:image:reset:button
  • Header selector :header
$$(":input").shouldHave(size(3));
$$(":input:not(.masked)").shouldHave(size(2));
$$(":header").shouldHave(size(3));
$$(":parent").shouldHave(size(13)); //h1, h1, h2
$$(":not(:parent)").shouldHave(size(13)); // all non-leaf elements
$$("input:first").shouldHave(attribute("name", "username")); //all leaf elements
$$("input:nth(1)").shouldHave(attribute("name", "username"));
$$("input:last").shouldHave(attribute("name", "username"));

Easy to click Element by JS, Fast set Value with JS

mvn -Dselenide.fastSetValue=true

mvn -Dselenide.clickByJS=true

More and More useful Functions

$("div").scrollTo();
$("div").scrollIntoView(true);
$("div").hover();
$("div").dragAndDrop();
$("div").doubleClick();
$("div").contextClick();
$("div").innerText();
$("div").innerHtml();
$("div").exists();
$("select").isImage();
$("select").getSelectedText();
$("select").getSelectedValue();
zoom(2.5);

OK. Now, what is the problem of Selenide.

  1. Selenide controls the WebDriver by default. If you want a custom setting like complex capabilities, browser options, timeout setting, you need to declare a new WebDriver and tell Selenide use that custom WebDriver. But behind the scene, you will not really know what is happening. Honestly, I don’t like wrapper. I want to control everything related to Selenium API, I want to know how it works.
  2. Implicitly Wait and Explicitly Wait: Selenide combine the timeout of these two wait types. You may know that they are not working well with each other. I always disable the implicitly wait and only use explicitly Wait for the reliability. When I run tests in parallel, I encountered some timeout exceptions that it only wait for 4 seconds (default timeout in Selende), even though I set explicitly wait of 15 seconds for that Element to be displayed.
  3. Wrapper of Selenium! I think Selenide is cool if you are writing tests using linear scripting. It means only one layer. In my case, I am using BDD and POM, so I have a BasePage, In that file, I wrap Selenide APIs as I don’t want all the tests will stick with Selenide API everywhere. What if the Selenide API changes ? Wrapper of another Wrapper. It may not a good idea.

Reference Link: https://selenide.org/documentation/selenide-vs-selenium.html

Leave a comment