Released Selenide 7.6.0

Released Selenide 7.6.0

Video recorder
24.11.24

Good evening!
We released Selenide 7.6.0 with something tasty and interesting.
Yo-yo, rush to update!

Videos are a serious thing. If there are videos, then they reflect something.

What’s new:


Added video recorder

Finally!

We all encounter unstable tests. Blinking tests. Flaky tests.

If this topic is new to you, I envy you. You are in for a fascinating dive into
Flaky Tests.

When investigating flaky tests, videos may be very helpful. And now Selenide can save videos from tests out of the box.

Few years ago, we used to use the VideoRecorder library by Sergey Pirogov a lot. But now Sergey is assembling drones for the Ukrainian Armed Forces and is not working on open source for the time being. Such are the times. :(

How to start recording videos?

It’s easy.

  1. Replace dependency selenide:7.6.0 by selenide-video-recorder:7.6.0
  2. Add extension org.selenide.videorecorder.junit5.VideoRecorderExtension to your tests (in case of JUnit5)
  3. Add listener org.selenide.videorecorder.testng.VideoRecorderListener to your tests (in case, God forgive me, TestNG)
  4. Add annotation @Video to your unstable tests (there aren’t many of them, are there?)

Now Selenide starts recording videos for all annotated tests.
BUT
the videos will be saved only when a test fails. A link to the video will be added to the error message - just as link to a screenshot.

Element should have text "Oreshnik"
Actual value: text="Kokoshnik"

Screenshot: file:/.../build/reports/tests/1732761758509.0.png
Page source: file:/.../build/reports/tests/1732761758509.0.html
Video: file:/.../build/reports/tests/1732761754743.0.webm

How it works?

Before every annotated test, Selenide starts 2 threads:

  1. Regularly takes screenshots from web browser and stores in a queue (just in memory for now)
  2. Merges the screenshots to a video (using library org.bytedeco:javacv)

After the test, the video is either deleted or saved to a file, and attached to the error message.


P.S. The abovementioned behaviour and some parameters can be configured in file selenide.properties, see VideoConfiguration.


NB! Keep in mind that video recording consumes resources and slows down your computer. Use sparingly.


See issue 2145. Thanks Sergey Brit for PR 2768,
Also see PR 2890 with annotations and configuration.


Added because for webdriver conditions

Now you can write not just:

webdriver().shouldHave(numberOfWindows(2)));
webdriver().shouldHave(url("https://dictionary.cambridge.org")));

but with an explanation:

webdriver().shouldHave(
  numberOfWindows(2).because("The login page should open in a new window"));

webdriver().shouldHave(
  url("https://dictionary.cambridge.org/").because("WTF is Oreshnik?"));

Thanks to Daniil Moiseev for PR 2853.


Added method $.scrollIntoCenter()

It’s essentially the same as $.scrollIntoView("{block: 'center'}") but shorter.

Because in most cases, when we scroll, that’s exactly what we want.

  $("#logout")
    .scrollIntoCenter()
    .shouldHave(text("A murky button somewhere at the bottom of the screen"))
    .click();

See PR 2842.


Special space characters support

When we search a web element by text, or verify the element’s text, we usually need to ignore spaces.

According to the HTML specification, several consecutive spaces are considered as one space.

Until now, Selenide treated several whitespace characters in this way (<space>, <tab>, &nbsp;, <newline>). But it turned out that there are many more different distorted spaces (so-called “En Space”, “Em Space”, “Three-Per-Em Space” etc.). Now we can ignore them all. :)

For example, for a web page like this:

<div id="hero">
  Ahoo &#32; &nbsp; &ensp; &emsp; &numsp; &NoBreak; &puncsp; 
  &ThinSpace; &VeryThinSpace; &MediumSpace; Daryae
</div>

The following test will work:

  $("#hero").shouldHave(text("Ahoo Daryae"));

  $(byText("Ahoo Daryae")).ancestor().shouldHave(
    text("Say Her Name"));

Thanks to Daniil Moiseev for PR 2858.
See also PR 2884.


Fixed inNewBrowser with custom configuration

This is rarely used, so don’t bother. But I have to mention it.

First of all, we added method inNewBrowser with config parameter for opening a new browser with custom configuration:

inNewBrowser(Config config, Runnable lambda)

Second, we fixed the existing method inNewBrowser(Runnable lambda) which didn’t restore the previous config if the browser was closed inside it.

See issue 2859 and PR 2902.


Fixed appium page factory

Fixed bug in selenide-appium when a test tried to create page object for website, not mobile app. And website was not opened yet.

Thanks to Petro Ovcharenko for PR 2879.


Reduced the number of Selenide logs

We reviewed Selenide logs and converted some “info” logs into “debug”.
In other words, there should be less spam in the logs now.
If you need to debug some complex problem, turn on the “debug” level. ;)

See PR 2892.


Fixed Selenide.screenshot(filename) behaviour

In javadoc of this method, it was mentioned that it creates two files - “.html” and “.png”. But in reality it created only “*.png”. Now the behaviour of this method matches the description in javadoc.

See issue 2896 and PR 2901.


JSR305 -> JSpecify

Many Selenide methods were annotated with @Nullable, @Nonnull, @CheckReturnValue, @ParametersAreNonnullByDefault.
This is useful to help you avoid some typical bugs. Thanks to these annotations, IDE can highlight this code with a warning:

  $("h1");   // Ooops, somebody forgot a check: .shouldBe(visible)

Until now, we took these annotations from library “JSR 305” (the annotations were imported from package javax.annotation).
But this library is not supported anymore.And recently a new library JSpecify was released to replace it. Now Selenide migrated to JSpecify. The annotations are now imported from packages org.jspecify.annotations and com.google.errorprone.annotations.

See PR 2889.


Simplified custom commands

If you created a subclass from Click, SetValue or some other Selenide built-in command, then we accidentally broke your backwards compatibility. Sorry. :)

Now instead of method

public SelenideElement execute(SelenideElement proxy, WebElementSource locator, Object [] args) { ... }

you need to implement/override method

protected void execute(WebElementSource locator, Object @Nullable [] args) { ... }

But it’s shorter and simpler this way, right?

But in general, if your project compiles, then don’t worry, it doesn’t concern you. :)

See issue 2906 and PR 2889.


Updated dependencies

  • bump Selenium from 4.25.0 to 4.26.0 (incl. CDP 129 -> 130)
  • Bumps BrowserUpProxy from 2.2.19 to 3.0.0.
  • Bump LittleProxy from 2.3.0 to 2.3.2
  • Bump Netty from 4.1.113.Final to 4.1.115.Final
  • Bump Guava from 33.3.0-jre to 33.3.1-jre
  • Bump JUnit from 5.11.0 to 5.11.3
  • Bump Jackson from 2.17.2 to 2.18.1
  • Bump HttpClient from 5.4 to 5.4.1


News


Statistics

Monthly Selenide downloads hit the new record: 1.3 millions in October!


Andrei Solntsev

selenide.org

24.11.24