Released Selenide 6.18.0

Released Selenide 6.18.0

Actual texts
06.09.23

Good night!

Good news.
We released Selenide 6.18.0.


Show actual texts in collections

In Selenide 6.16.0, we speed up collections checks.

$$(".troubles").shouldHave(texts(
  "Health", "Emptiness", 
  "Financial Crisis", "Career Pressure"));

One of the optimizations was: if collection size doesn’t match the number of expected texts, Selenide doesn’t even start loading texts of elements, but immediately throws an error:

List size mismatch: expected: = 4, actual: 3

But people started complaining that they want to see the actual text even in this case.
This seems to be a case where convenience is more important than speed. And your tests don’t fail too often, right? ;)

That’s why we will show both sizes and texts from this release:

List size mismatch (expected: 4, actual: 3)
Actual (3): [Health, Emptiness, Financial Crisis]
Expected (4): [Health, Emptiness, Financial Crisis, Career Pressure]

See issue 2434 and PR 2456.


Updated Selenium from 4.11.0 to 4.12.1

Changelog is here. Among others, it fixes that deadlock in devtools, because of which we had to make the previous release.

See PR 2452.


Restore BasicAuth via DevTools

In Selenide 6.16.0, we implemented BasicAuth authentication via HasAuthentication mechanism (in Chromium-based browsers).

Later we had to roll it back due to the aforementioned deadlock in webdriver.
Now Selenium has been updated, the deadlock has been fixed, and we have returned the authorization back.

See issue 2336, PR 2358 and PR 2452.


Added method $$.getOptions()

Selenide has method $$.getSelectedOptions() which returns selected options of a <select> element.
Now we added a similar method $$.getOptions(), which returns all options.

$("select#hero").getOptions()
  .shouldHave(texts("Frodo", "Samwise", "Peregrin", "Meriadoc"));

$("select#hero").selectOption("Samwise");

$("select#hero").getSelectedOptions()
  .shouldHave(texts("Samwise"));

See issue 2445 and PR 2446.


Method getFocusedElement() made lazy

Now method Selenide.getFocusedElement() returns SelenideElement instead of WebElement.

It effectively means lazy initialization, re-tries, “should*” checks etc.:

getFocusedElement()
  .shouldHave(tagName("input"), id("otpCode"));

See PR 2454.


Added support for SelenideAppiumElement fields in page objects

If you write tests for mobile apps using our plugin selenide-appium, now you can declare fields in your page objects with type SelenideAppiumElement instead of SelenideElement.

It gives you some additional mobile-specific methods like hideKeyboard(), swipe() etc.

class LoginPage {
  @AndroidFindBy(accessibility = "Username input field")
  SelenideAppiumElement login;

  @AndroidFindBy(accessibility = "Password input field")
  SelenideElement password;
  
  public void login() {
    password.swipeTo();
  }
}

See issue 2437 and PR 2438.


Precise scrolling in mobile apps

Continuing the theme of mobile phones. In plugin selenide-appium, there is method scroll:

import static com.codeborne.selenide.appium.AppiumScrollOptions.with;

$.scroll(with(UP, 20)); // swipe up, no more than 20 times

Now you can specify the starting and ending position for the swipe (percentage of screen height):

import static com.codeborne.selenide.appium.AppiumScrollOptions.up;

$.scroll(up(10, 80)); // swipe from 10% point to 80% point

Thanks to qwez for PR 2449.


Don’t inherit page objects from ElementsContainer

Some users complained about this warning from Selenide:

WARN com.codeborne.selenide.impl.SelenidePageFactory - Cannot initialize field private com.codeborne.selenide.SelenideElement com.codeborne.selenide.ElementsContainer.self

We realized it happens when you inherit a page object from ElementsContainer:

class LoginPage extends ElementsContainer {
}

Which is not really needed. In fact, you cannot do it anymore. :)

Initially, ElementsContainer was intended to declare components inside page objects:

class LoginPage {
  @FindBy(id="weather")
  WeatherWidget weatherWidget;
}

class WeatherWidget extends ElementsContainer {
  @FindBy(id="temperature")
  SelenideElement temperature;
}

Just remove extends ElementsContainer from your page objects, and everything just works.

P.S. The point is, that these objects have different lifecycle:

  1. Page objects can be created using method page: like, LoginPage page = Selenide.page();. And method page does NOT require your class to extend ElementsContainer.
  2. And some fields of your page object can extend ElementsContainer. It makes Selenide search @FindBy elements inside of these classes.

See issue 2439 and PR 2455.


Updated dependencies

  • bump LittleProxy from 2.0.19 to 2.0.20 (fixes a memory leak in Selenide proxy)
  • update vulnerable jackson dependency - see PR 2442


Statistics

The number of monthly downloads of Selenide has exceeded 670 thousands!


It’s getting serious…


Andrei Solntsev

selenide.org

06.09.23