Selenide vs Selenium

vinogradoff edited this page Dec 27, 2015 · 19 revisions

This page brings an overview of how Selenide API is simpler and more powerful than Selenium WebDriver API.

Keynote

Remember, this doesn't mean that Selenium WebDriver is "bad":

  • Selenium WebDriver just has lower-level API which is suitable for wider range of tasks.
  • Selenide API is higher-level, but it was designed specifically for UI- and Acceptance testing.
Though Selenium WebDriver is a great library for operating web browser, it's API is too low-level. Developer needs to write some boilerplate code to create/shutdown webdriver, to search radio buttons, to wait for javascript interactions etc. With Selenide You don't need to operate with Selenium WebDriver directly, don't need to wait for ajax requests etc.

So, let's compare how to do primitive actions with both libraries. Probably the most tasty feature is the Ajax support.

1. Create a browser

Selenium WebDriver:

DesiredCapabilities desiredCapabilities = DesiredCapabilities.htmlUnit();
desiredCapabilities.setCapability(HtmlUnitDriver.INVALIDSELECTIONERROR, true);
desiredCapabilities.setCapability(HtmlUnitDriver.INVALIDXPATHERROR, false);
desiredCapabilities.setJavascriptEnabled(true);
WebDriver driver = new HtmlUnitDriver(desiredCapabilities);

Selenide:

open("/my-application/login");
// And run tests with option -Dbrowser=htmlunit (or "chrome" or "ie", default value is "firefox")

2. Shutdown a browser

Selenium WebDriver:

if (driver != null) {
    driver.close();
}

Selenide:

// Do not care! Selenide closes the browser automatically.

With Selenide You don't need to operate with Selenium WebDriver directly. WebDriver will be automatically created/deleted during test start/finished.

3. Find element by id

Selenium WebDriver:

WebElement customer = driver.findElement(By.id("customerContainer"));

Selenide:

WebElement customer = $("#customerContainer"); 

or a longer conservative option:

WebElement customer = $(By.id("customerContainer"));

4. Assert that element has a correct text

Selenium WebDriver:

assertEquals("Customer profile", driver.findElement(By.id("customerContainer")).getText());

Selenide:

$("#customerContainer").shouldHave(text("Customer profile"));

5. Ajax support (waiting for some event to happen)

Selenium WebDriver (OMG!):

FluentWait<By> fluentWait = new FluentWait<By>(By.tagName("TEXTAREA"));
fluentWait.pollingEvery(100, TimeUnit.MILLISECONDS);
fluentWait.withTimeout(1000, TimeUnit.MILLISECONDS);
fluentWait.until(new Predicate<By>() {
    public boolean apply(By by) {
        try {
            return browser.findElement(by).isDisplayed();
        } catch (NoSuchElementException ex) {
            return false;
        }
    }
});
assertEquals("John", browser.findElement(By.tagName("TEXTAREA")).getAttribute("value"));

Selenide:

$("TEXTAREA").shouldHave(value("John"));

This command automatically waits until element gets visible AND gets expected value.
Default timeout is 4 seconds and it's configurable.

6. Assert that element has a correct CSS class

Selenium WebDriver:

assertTrue(driver.findElement(By.id("customerContainer")).getAttribute("class").indexOf("errorField") > -1);

Selenide:

$("#customerContainer").shouldHave(cssClass("errorField"));

7. Find element by text

Selenium WebDriver:

No way (except XPath)

Selenide:

WebElement customer = $(byText("Customer profile")); 

8. Assert that element text matches a regular expression

Selenium WebDriver:

WebElement element = driver.findElement(By.id("customerContainer"));
assertTrue(Pattern.compile(".*profile.*", DOTALL).matcher(element.getText()).matches());

Selenide:

$("#customerContainer").should(matchText("profile"));

9. Assert that element does not exist

Selenium WebDriver:

try {
    WebElement element = driver.findElement(By.id("customerContainer"));
    fail("Element should not exist: " + element);
}
catch (WebDriverException itsOk) {}

Selenide:

$("#customerContainer").shouldNot(exist);

10. Looking for element inside parent element

Selenium WebDriver:

WebElement parent = driver.findElement(By.id("customerContainer"));
WebElement element = parent.findElement(By.className("user_name"));

Selenide:

$("#customerContainer").find(".user_name");

11. Looking for Nth element

Selenium WebDriver:

WebElement element = driver.findElements(By.tagName("li")).get(5);

Selenide:

$("li", 5);

12. Click "Ok" in alert dialog

Selenium WebDriver:

    try {
      Alert alert = checkAlertMessage(expectedConfirmationText);
      alert.accept();
    } catch (UnsupportedOperationException alertIsNotSupportedInHtmlUnit) {
      return;
    }
    Thread.sleep(200); // sometimes it will fail

Selenide:

    confirm("Are you sure to delete your profile?");

or

    dismiss("Are you sure to delete your profile?");

13. Debugging info for elements

Selenium WebDriver:

    WebElement element = driver.findElement(By.id("customerContainer"));
    System.out.println("tag: " + element.getTag());
    System.out.println("text: " + element.getText());
    System.out.println("id: " + element.getAttribute("id"));
    System.out.println("name: " + element.getAttribute("name"));
    System.out.println("class: " + element.getAttribute("class"));
    System.out.println("value: " + element.getAttribute("value"));
    System.out.println("visible: " + element.isDisplayed());
    // etc. 

Selenide:

    System.out.println($("#customerContainer"));
    // output looks like this: "<option value=livemail.ru checked=true selected:true>@livemail.ru</option>"

14. Take a screenshot

Selenium WebDriver:

    if (driver instanceof TakesScreenshot) {
      File scrFile = ((TakesScreenshot) webdriver).getScreenshotAs(OutputType.FILE);
      File targetFile = new File("c:\temp\" + fileName + ".png");
      FileUtils.copyFile(scrFile, targetFile);
    }

Selenide:

    takeScreenShot("my-test-case");

For JUnit users it's even more simpler:

    public class MyTest {
      @Rule // automatically takes screenshot of every failed test
      public ScreenShooter makeScreenshotOnFailure = ScreenShooter.failedTests();
    }

15. Select a radio button

Selenium WebDriver:

    for (WebElement radio : driver.findElements(By.name("sex"))) {
      if ("woman".equals(radio.getAttribute("value"))) {
        radio.click();
      }
    }
    throw new NoSuchElementException("'sex' radio field has no value 'woman'");

Selenide:

    selectRadio(By.name("sex"), "woman");

16. Reload current page

Selenium WebDriver:

    webdriver.navigate().to(webdriver.getCurrentUrl());

Selenide:

    refresh();

17. Get the current page URL, title or source

Selenium WebDriver:

    webdriver.getCurrentUrl();
    webdriver.getTitle();
    webdriver.getPageSource();

Selenide:

    url();
    title();
    source();

Don't believe?

Then try it yourself! Let's start writing concise UI Tests!