How to check size effectively?

How to check size effectively?

Selenide Advent Calendar
Day 4
04.12.19

Hello!

Today is December 4th, it’s the Selenide Advent calendar, and in today’s post I will show how to check a collection size effectively.

How to effectively check a collection size?

Selenide has convenient methods for checking collections. For example, this is how you can check that a book list contains exactly 3 books:

@Test {
 $$("#books .book").shouldHave(size(3));
}

If this page implemented so that it contains much more books, and only some of them are visible, then you can filter the collection:

@Test {
 $$("#books .book").filter(visible).shouldHave(size(3));
}

The problem

If the page contains a lot of books (say, a few dozens or more), this filtration can be slow (say, few seconds and more).
It’s because method filter(visible) needs to call WebElement.isDisplayed() separately for each element in the collection in loop. Every call means a separate call to webdriver, which is a separate http request etc. This all takes times.

Probably tests run 3 days in your project, and few seconds don’t really play any role. Then you can skip this post. :)

But if you care about effectiveness of your tests, go on.

The first try

How to speed up this check? The first idea is to filter elements right in the selector:

@Test {
 $$("#books .book:visible").shouldHave(size(3));
}

But this selector doesn’t work.

The problem is that there is no CSS selector :visible. It doesn’t exist. Only JQuery can understand it.

The second try

Who saves us? Of course, JavaScript!

You can create a helper method which finds a number of elements (with a help of JavaScript and JQuery):

private int sizeOf(String cssSelector) {
  Number count = executeJavaScript("return $(arguments[0]).length", cssSelector);
  return count.intValue();
}

(this code only works if the page contains JQuery library. If not, you can write a similar code using some other JavaScript library.)

Now your check will be fast because it calls WebDriver method only once. And browser executes any JavaScript very quickly.

@Test {
  assertEquals(1, sizeOf("#books .book:visible"));
}

What’s now?

Learn the power of JavaScript.
It allows many other tricks which can make your tests more fast and stable.



Andrei Solntsev

selenide.org

04.12.19