Selenide Test Automation: Using Selenoid in the Docker Container - IntexSoft
August 30, 2023 • by Dora & Margarita

Selenide Test Automation: Using Selenoid in the Docker Container

Tech Staff
image

This article covers a basic Selenium project, including integrating TestNG and implementing a Page Object pattern. It also explores the features and benefits of Selenide, demonstrating its usage for elements, assertions, and waits. You will know how to incorporate the Selenoid framework to execute tests within or outside Docker containers.rnrnReading time: 36 min.

u0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eQA teams face an ongoing challenge to meet the increasing demands of software testing in today’s ever-evolving technological landscape. The need for efficient and reliable test automation solutions has become paramount. Enter Selenide Test Automation, a groundbreaking framework transforming QA professionals’ approach to testing.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eAt its core, Selenide Test Automation represents a significant shift in the software testing world. It offers an intuitive and streamlined approach to automate web application testing, enabling QA teams to achieve exceptional efficiency, accuracy, and speed in their testing processes. By harnessing the power of Selenide, QA professionals can elevate their testing efforts, ensuring the delivery of high-quality software products in record time.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eSelenide Test Automation is a cutting-edge framework built on top of Selenium, a widely adopted automation tool for web browsers. It takes the Selenium experience to the next level by providing a simplified API, making it accessible for professional and personal usage. This means QA professionals no longer need to struggle with complex and lengthy code. Instead, they can write clean, concise, and highly readable test scripts that are easier to maintain and understand.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eEquipped with a comprehensive set of features, Selenide Test Automation enhances the testing endeavors of QA professionals. Built-in assertions and smart waits eliminate the challenges of manual waiting and troubleshooting flaky tests. Selenide effortlessly handles dynamic elements, AJAX calls, and JavaScript-heavy applications, ensuring stable and robust test execution.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eFurthermore, Selenide Test Automation seamlessly integrates with popular testing frameworks like TestNG and JUnit, enabling effective test management and reporting. The framework supports parallel test execution, empowering QA teams to leverage distributed environments or cloud-based platforms for faster and more efficient testing.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eTo maximize the potential of Selenide, we explore the integration of Selenoid in Docker containers. This powerful combination grants QA teams unmatched flexibility, scalability, and portability in their test environments. Testers can easily manage and orchestrate their testing infrastructure by leveraging Docker containers, ensuring reliable test execution within controlled and isolated environments.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eIn this article, we delve deep into the world of Selenide Test Automation, showcasing its transformative capabilities and the significant benefits it offers QA teams. We provide a comprehensive understanding of Selenide’s core concepts, simplified API, and unique features that position it as a game-changer in test automation. Additionally, we demonstrate the seamless integration of Selenoid in Docker containers, enabling the downloading binary and unlocking a new level of efficiency and scalability for your testing infrastructure.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eJoin us on this journey as we unveil the power and potential of Selenide Test Automation. Explore the remarkable benefits of this revolutionary framework and witness a significant improvement in test efficiency, accuracy, and overall software quality. With its intuitive and streamlined approach, Selenide Test Automation empowers QA teams to achieve outstanding results, confidently delivering high-quality software products. Embrace this robust implementation and revolutionize your QA efforts like never before.u003c/spanu003ernrnu0026nbsp;rnrnu0026nbsp;

u003cspan style=u0022color: #ffffff;u0022u003e.u003c/spanu003ernrnu003cspan style=u0022color: #ffffff;u0022u003e.u003c/spanu003ernu003ch3u003eu003cspan style=u0022color: #000000;u0022u003eSelenium + TestNG. Selenium Mavenu003c/spanu003eu003c/h3u003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eWe are considering a project build on the u003c/spanu003eu003ca href=u0022https://maven.apache.org/u0022 rel=u0022nofollowu0022u003eMavenu003c/au003e u003cspan style=u0022color: #000000;u0022u003ebuilder, so we can find the project structure description in the u003cemu003epom.xmlu003c/emu003e file. To order use u003cbu003eSelenium+TestNGu003c/bu003e, we should add appropriate dependencies to u003cemu003epom.xmlu003c/emu003e file. You can observe them between the u003ciu003edependenciesu003c/iu003e tags below:u003c/spanu003ernrnu0026nbsp;rnu003cpre class=u0022blog-codeu0022u003eu003cspan style=u0022color: #000000;u0022u003e u0026lt;?xml version=u00221.0u0022 encoding=u0022UTF-8u0022?u0026gt;rn u0026lt;project xmlns=u0022http://maven.apache.org/POM/4.0.0u0022rn xmlns:xsi=u0022http://www.w3.org/2001/XMLSchema-instanceu0022rn xsi:schemaLocation=u0022http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdu0022u0026gt;rn u0026lt;modelVersionu0026gt;4.0.0u0026lt;/modelVersionu0026gt;rnrn u0026lt;groupIdu0026gt;testu0026lt;/groupIdu0026gt;rn u0026lt;artifactIdu0026gt;testu0026lt;/artifactIdu0026gt;rn u0026lt;versionu0026gt;1.0-SNAPSHOTu0026lt;/versionu0026gt;rn u0026lt;dependenciesu0026gt;rn u0026lt;dependencyu0026gt;rn u0026lt;groupIdu0026gt;org.seleniumhq.seleniumu0026lt;/groupIdu0026gt;rn u0026lt;artifactIdu0026gt;selenium-javau0026lt;/artifactIdu0026gt;rn u0026lt;versionu0026gt;3.141.59u0026lt;/versionu0026gt;rn u0026lt;/dependencyu0026gt;rn u0026lt;dependencyu0026gt;rn u0026lt;groupIdu0026gt;org.testngu0026lt;/groupIdu0026gt;rn u0026lt;artifactIdu0026gt;testngu0026lt;/artifactIdu0026gt;rn u0026lt;versionu0026gt;6.14.3u0026lt;/versionu0026gt;rn u0026lt;scopeu0026gt;testu0026lt;/scopeu0026gt;rn u0026lt;/dependencyu0026gt;rn u0026lt;/dependenciesu0026gt;rn u0026lt;/projectu0026gt;u003c/spanu003eu003c/preu003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eHere is the example of the Page Object:u003c/spanu003ernrnu0026nbsp;rnu003cpre class=u0022blog-codeu0022u003eu003cspan style=u0022color: #000000;u0022u003eimport…rnrnpublic class SignUpPage {rn private WebDriver driver;rnrn public SignUpPage(WebDriver driver) { this.driver = driver; }rnrn private By emailField = cssSelector(u0022#register-emailu0022);rn private By confirmEmailField = cssSelector(u0022#register-confirm-emailu0022);rn private By passwordField = cssSelector(u0022#register-passwordu0022);rn private By displayNameField = cssSelector(u0022#register-displaynameu0022);rn private By monthDropDown = cssSelector(u0022#register-dob-monthu0022);rn private By dayField = cssSelector(u0022#register-dob-dayu0022);rn private By yearField = cssSelector(u0022#register-dob-yearu0022);rn private By shareCheckbox = cssSelector(u0022#register-thirdpartyu0022);rn private By registerButton = cssSelector(u0022#register-button-email-submitu0022);rnrn public SignUpPage typeEmail(String email) {rnrntdriver.findElement(emailField).sendKeys(email);rn return this;rn }rn rn public SignUpPage typeConfirmEmailField(String email) {…}rnrn public SignUpPage typePassword(String password) {…}rnrn public SignUpPage typeName(String name) {…}rnrn public SignUpPage setMonth(String month) {…}rn rn public SignUpPage typeDay(String day) {…}rnrn public SignUpPage typeYear(String year) {…}rnu003c/spanu003eu003c/preu003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eAs we can see, there is a description of variables with locators for the elements of the registration page at the top of the java file. There are methods directly for interacting with elements of our page below the variable section.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eLet’s open the tests themselves:u003c/spanu003ernrnu0026nbsp;rnu003cpre class=u0022blog-codeu0022u003eu003cspan style=u0022color: #000000;u0022u003eprivate WebDriver driver;rnrnprivate SignUpPage page;rnrn@BeforeMethodrnpublic void setUp() {rnSystem.setProperty(u0022webdriver.gecko.driveru0022, rnu0022C:\Users\Nikita\IdeaProjects\autotests_examples\drivers\geckodriver.exeu0022);rndriver = new FirefoxDriver();rndriver.manage().timeouts().impicitlyWait(10, TimeUnit.SECONDS);rndriver.get(u0022https://www.spotify.com/us/signup/u0022);rn}rnu003c/spanu003eu003c/preu003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eAs we can see, in the u003cbu003e@BeforeMethodu003c/bu003e annotation we describe what will have before each method.u003c/spanu003ernrnu0026nbsp;rnu003cpre class=u0022blog-codeu0022u003eu003cspan style=u0022color: #000000;u0022u003e@Testrnpublic void typeInvalidYear() {rn page = new SignUpPage(driver);rn page.setMonth(u0022Decemberu0022);rn .typeDay(u002220u0022)rn .typeYear(u002285u0022)rn .setShare(true);rn Assert.assertTrue(page.isErrorVisible(u0022Please enter a valid year.u0022));rnu003c/spanu003eu003c/preu003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eThe u003cbu003e@Testu003c/bu003e annotation provides code for test methods.u003c/spanu003ernrnu0026nbsp;rnu003cpre class=u0022blog-codeu0022u003eu003cspan style=u0022color: #000000;u0022u003e @AfterMethodrn public void tearDown() {rn driver.quit();rn }rnu003c/spanu003eu003c/preu003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eThe u003cbu003e@AfterMethodu003c/bu003e annotation contains the code that should be executed after each method.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eWhen running tests using Selenium, the following will happen:u003c/spanu003ernrnu0026nbsp;rnu003culu003ern tu003cliu003eu003cspan style=u0022color: #000000;u0022u003eOpening a separate browser window.u003c/spanu003eu003c/liu003ernu003c/ulu003ernu0026nbsp;rnu003culu003ern tu003cliu003eu003cspan style=u0022color: #000000;u0022u003eFollowing the url.u003c/spanu003eu003c/liu003ernu003c/ulu003ernu0026nbsp;rnu003culu003ern tu003cliu003eu003cspan style=u0022color: #000000;u0022u003eTest code execution.u003c/spanu003eu003c/liu003ernu003c/ulu003ernu0026nbsp;rnu003culu003ern tu003cliu003eu003cspan style=u0022color: #000000;u0022u003eClosing browser session after each test case.u003c/spanu003eu003c/liu003ernu003c/ulu003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eWhen running the next test the same things will happen. It should be mentioned that running tests on Selenium is rather a resource-consuming process.u003c/spanu003ernrnu0026nbsp;rnu003ch3u003eu003cspan style=u0022color: #000000;u0022u003eSelenide: what, where, and howu003c/spanu003eu003c/h3u003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eSo what is Selenide itself? What are its main features and advantages?u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eIn short, u003ca style=u0022color: #000000;u0022 href=u0022https://selenide.org/index.htmlu0022u003eSelenideu003c/au003e is a wrapper around Selenium WebDriver that makes it quick and easy to use when writing tests. At its core, Selenide is a tool for automating user actions in a browser, focused on the convenience and ease of implementing business logic in autotests in the user’s language, without being distracted by the technical details of working with the “browser driver”. For example, we do not need to focus on working with the waiting for elements in the process of automating testing of dynamic web applications, as well as on the implementation of high-level actions on elements.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eKey and main advantages of Selenide:u003c/spanu003ernrnu0026nbsp;rnu003culu003ern tu003cliu003eu003cspan style=u0022color: #000000;u0022u003eConcise jQuery-style syntax.u003c/spanu003eu003c/liu003ernu003c/ulu003ernu0026nbsp;rnu003culu003ern tu003cliu003eu003cspan style=u0022color: #000000;u0022u003eAutomatic handling of most problems with Ajax, waitings and timeouts.u003c/spanu003eu003c/liu003ernu003c/ulu003ernu0026nbsp;rnu003culu003ern tu003cliu003eu003cspan style=u0022color: #000000;u0022u003eAutomatic handling of browser lifecycle.u003c/spanu003eu003c/liu003ernu003c/ulu003ernu0026nbsp;rnu003culu003ern tu003cliu003eu003cspan style=u0022color: #000000;u0022u003eAutomatic creation of screenshots.u003c/spanu003eu003c/liu003ernu003c/ulu003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eThe purpose of Selenide is to u003cbu003efocus on the business logicu003c/bu003e of tests and not “waste” mental energy on technical details.u003c/spanu003ernrnu0026nbsp;rnu003ch3u003eu003cspan style=u0022color: #000000;u0022u003eGetting started with the Selenide aditional configurationu003c/spanu003eu003c/h3u003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eTo get started with the Selenide we need to add the Selenide dependency to the u003cemu003epom.xml u003c/emu003efile. Since we no longer need the Selenium dependency, we simply remove it.u003c/spanu003ernu003cpre class=u0022blog-codeu0022u003eu003cspan style=u0022color: #000000;u0022u003eu0026lt;dependencyu0026gt;rn u0026lt;groupIdu0026gt;com.codeborneu0026lt;/groupIdu0026gt;rn u0026lt;artifactIdu0026gt;selenideu0026lt;/artifactIdu0026gt;rn u0026lt;versionu0026gt;5.2.8u0026lt;/versionu0026gt;rnu0026lt;/dependencyu0026gt;rnu003c/spanu003eu003c/preu003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eIn order to start using Selenide in our project, we also need to make some imports. Here are the examples of import required classes:u003c/spanu003ernrnu0026nbsp;rnu003culu003ern tu003cliu003eu003cspan style=u0022color: #000000;u0022u003eu003cemu003eimport static com.codeborne.selenide.Selenide.*;u003c/emu003eu003c/spanu003eu003c/liu003ernu003c/ulu003ernu0026nbsp;rnu003culu003ern tu003cliu003eu003cspan style=u0022color: #000000;u0022u003eu003cemu003eimport static com.codeborne.selenide.Selectors.*;u003c/emu003eu003c/spanu003eu003c/liu003ernu003c/ulu003ernu0026nbsp;rnu003culu003ern tu003cliu003eu003cspan style=u0022color: #000000;u0022u003eu003cemu003eimport static com.codeborne.selenide.Condition.*;u003c/emu003eu003c/spanu003eu003c/liu003ernu003c/ulu003ernu0026nbsp;rnu003culu003ern tu003cliu003eu003cspan style=u0022color: #000000;u0022u003eu003cemu003eimport static com.codeborne.selenide.CollectionCondition.*;u003c/emu003eu003c/spanu003eu003c/liu003ernu003c/ulu003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eFor more information on how to connect Selenide using the rest of the project builders, see the u003ca style=u0022color: #000000;u0022 href=u0022https://selenide.org/quick-start.htmlu0022 rel=u0022nofollowu0022u003eQuick startu003c/au003e section of Selenide documentation.u003c/spanu003ernrnu0026nbsp;rnu003ch3u003eu003cspan style=u0022color: #000000;u0022u003eWorking with elements, assertions, and waitsu003c/spanu003eu003c/h3u003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eLet’s move on to the Selenide elements and consider the assertions and waits available in Selenide.u003c/spanu003ernrnu0026nbsp;rnu003cpre class=u0022blog-codeu0022u003eu003cspan style=u0022color: #000000;u0022u003eimport…rnrnpublic class SignUpTest {rnrnprivate SignUpPage page;rnrn @BeforeClassrn public static void setUp() {rnrnt baseurl = u0022https://www.spotify.comu0022;rn rn browser = u0022chromeu0022;rn rn }rnu003c/spanu003eu003c/preu003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eWe replace the u003cbu003eBeforeMethodu003c/bu003e annotation with the u003cbu003eBeforeClassu003c/bu003e annotation in the test file since we no longer need it. Selenide eliminates the need to write u003cemu003eBefore u003c/emu003eand u003cemu003eAfteru003c/emu003e methods as Selenide takes care of the u003cemu003eAfterMethodu003c/emu003e function. We only have the u003cbu003eBeforeClassu003c/bu003e annotation left to register a pair of properties.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eWe registered the u003cemu003eproperty baseurlu003c/emu003e, which is in the u003cemu003econfiguration classu003c/emu003e and in the BeforeClass annotation and it will be the base url. Therefore, the u003cemu003edriver.getu003c/emu003e that we used in our Selenium tests is no longer needed. We set the browser on which we will run our tests in the u003cemu003eproperty browseru003c/emu003e.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eWe can completely abandon the Selenium driver in our test project, Selenide will take care of all the work, encapsulating it in its classes. We will only have to focus on the logic of the tests themselves.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eLet’s proceed to using Selenide on our page:u003c/spanu003ernu003cpre class=u0022blog-codeu0022u003eu003cspan style=u0022color: #000000;u0022u003e rn public SignUpPage open() {rn rn Selenide.open (relativeOrAbsoluteUrl: u0022/us/signup/u0022);rn return this;rn }rn rn public SignUpPage typeEmail(String email) {rn rn $(emailField).sendKeys(email);rn return this;rn rn }rnu003c/spanu003eu003c/preu003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eWhen invoking the open method, Selenide itself starts a browser session and opens a web page. Selenide also makes sure the browser is closed at the end. Within Selenide.u003ciu003eopenu003c/iu003e we can write either the whole u003cemu003ehttpu003c/emu003e url path, or we can write a u003cemu003erelative urlu003c/emu003e. Since we indicated an absolute path as a u003ciu003ebaseurlu003c/iu003e, within the Selenide.u003cemu003eopenu003c/emu003e method it’s enough to indicate just “/”.u003c/spanu003ernrnu0026nbsp;rnu003cpre class=u0022blog-codeu0022u003eu003cspan style=u0022color: #000000;u0022u003epublic SignUpPage typeEmail(String email) {rn rn $(emailField.sendKeys(email);rn return this;rn}rnrnrnpublic SignUpPage typeConfirmEmailField(String email) {rn rn $(confirmEmailField).setValue(email);rn return this;rn}rnu003c/spanu003eu003c/preu003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eIn order to find an element using Selenide, we should indicate $ instead of u003cemu003edriver.findElementu003c/emu003e command used in Selenium. I.e using a one-character method we can find directly the element itself. The search method is accepted as a string, similar to the jQuery JavaScript library by default. This streamlined syntax enhances the readability and efficiency of writing Selenium tests with Selenide. Additionally, if no elements are found, Selenide returns a default value, eliminating the need for explicit null checks in the test code.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eIn order to find a list of elements using Selenide, we should indicate $$ characters. Instead of List u0026lt;WebElementu0026gt;, we write the u003cemu003eElementsCollectionu003c/emu003e command that is already extended with additional methods.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eTo work with elements we can use both standard Selenium methods u003cemu003e(sendKeys())u003c/emu003e and u003cemu003esetValue()u003c/emu003e method or its short version u003cemu003evаl()u003c/emu003e.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eAs we can see, Selenide methods are more understandable. Method u003cemu003eclick()u003c/emu003e remains the same, though Selenide has several click() methods: u003cemu003econtextClick()u003c/emu003e (right mouse button imitation) u003cemu003edoubleClick()u003c/emu003e ( imitation of double click on element ) and so on. Having a certain element found, we can continue the search using other locators.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eThe difference between Selenide u003cemu003efind()u003c/emu003e method and Selenium u003cemu003edriver.findElement(By)u003c/emu003e is that Selenide u003cemu003efind()u003c/emu003e can immediately receive CSS selectors and operate with the Selenide elements, not the Web elements. Basically, Selenide-elements are a more “smart” alternative to Selenium web elements.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eSelenide already contains those methods, which would have to be done through an u003cemu003eactionu003c/emu003e class or some other way. Selenide allows writing brief and “nice” methods that are understandable for everybody. Selenide is also rather flexible, and due to that we can use standard Selenium features.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #333333;u0022u003eu003cspan style=u0022color: #000000;u0022u003eYou can find more information about Selenide methods in theu003c/spanu003e u003c/spanu003eu003ca href=u0022https://selenide.org/documentation.htmlu0022u003eofficial documentationu003c/au003eu003cspan style=u0022color: #000000;u0022u003e.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eLet’s look into wider and more understandable verification examples provided by Selenide:u003c/spanu003ernrnu0026nbsp;rnu003cpre class=u0022blog-codeu0022u003eu003cspan style=u0022color: #000000;u0022u003e page.getError(u0022Please enter a valid year.u0022).shouldBe(Condition.visible);rnrn page.getError(u0022When were you born?u0022).shouldNotBe(Condition.visible);rnrn page.getErrors().shouldHave(CollectionCondition.size(6));rnrn page.getErrorByNumber(3).shouldHave(Condition.text(u0022Please enter your birth month.u0022));rnu003c/spanu003eu003c/preu003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eSelenide verification scheme allows us to take any element, find it and use the following assertions for it: u003cemu003eshould, shouldBe, shouldHave, shouldNot, shouldNotBe and shouldNotHaveu003c/emu003e. Depending on the logic and our needs, we use certain u003cbu003e“should-methods”u003c/bu003e. When we want to check if the element exists, we use u003ciu003eshould(exist)u003c/iu003e. When we want to check if the element is visible, we use u003cemu003eshouldBe(visible)u003c/emu003e method and so on. In fact, we use only three assertions: should, shouldBe, shouldHave, or opposite to them u003cemu003eshouldNot, shouldNotBe, shouldNotHaveu003c/emu003e.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eVerifications of elements and element collections on Selenide are carried out with the help of methods (assertions) described above. They play role of explicit waits in Selenide: they wait for a condition for a certain element to be satisfied.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eFormulations in Selenide are quite logical and understandable. We can write our methods either using the development environment hints or using our logical assumptions. And of course, we can always take a look at the code for implementing the necessary methods described in the documentation, or we can look through the implementing of the method itself.u003c/spanu003ernrnu0026nbsp;rnu003ch3u003eu003cspan style=u0022color: #000000;u0022u003eAutomatic screenshots in testsu003c/spanu003eu003c/h3u003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eFor u003cbu003eJUnitu003c/bu003e:u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eIn order to take a screenshot automatically after each failed test, we can make an import and indicate the Rule.u003c/spanu003ernrnu0026nbsp;rnu003cpre class=u0022blog-codeu0022u003eu003cspan style=u0022color: #000000;u0022u003eimport com.codeborne.selenide.junit.ScreenShooter;rnrn@Rulernpublic ScreenShooter makeScreenshotOnFailure = ScreenShooter.failedTests();rnu003c/spanu003eu003c/preu003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eBut in fact, it’s a rudiment, since Selenide has been taking screenshots automatically when tests fail for quite a while. It’s very convenient for error analysis. Selenide saves all the screenshots to a u003cemu003ebuild/reports/testsu003c/emu003e folder by default.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eIn order to take a screenshot automatically of each test (even succeeded), we use the following command:u003c/spanu003ernrnu0026nbsp;rnu003cpre class=u0022blog-codeu0022u003eu003cspan style=u0022color: #000000;u0022u003e@Rule rnpublic ScreenShooter makeScreenshotOnFailure = ScreenShooter.failedTests().succeededTests();rnu003c/spanu003eu003c/preu003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eFor u003cbu003eTestNGu003c/bu003e we also make an import:u003c/spanu003ernrnu0026nbsp;rnu003cpre class=u0022blog-codeu0022u003eu003cspan style=u0022color: #000000;u0022u003eimport com.codeborne.selenide.testng.ScreenShooter;rnrn@Listeners({ ScreenShooter.class})rnu003c/spanu003eu003c/preu003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eIn order to take screenshots automatically after succeeded test, we invoke the following command before running tests:u003c/spanu003ernrnu0026nbsp;rnu003cpre class=u0022blog-codeu0022u003eu003cspan style=u0022color: #000000;u0022u003eScreenShooter.captureSuccessfulTests = true;rnu003c/spanu003eu003c/preu003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eWe can also make a screenshot with a single line of code at any moment:u003c/spanu003ernrnu0026nbsp;rnu003cpre class=u0022blog-codeu0022u003eu003cspan style=u0022color: #000000;u0022u003eimport static com.codeborne.selenide.Selenide.screenshot;rnrnscreenshot(u0022my_file_nameu0022);rnu003c/spanu003eu003c/preu003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eThus, Selenide will create two filesu003cemu003e: my_file_name.pngu003c/emu003e and u003cemu003emy_file_name.htmlu003c/emu003eu003c/spanu003ernrnu0026nbsp;rnrnu0026nbsp;rnu003ch3u003eu003cspan style=u0022color: #000000;u0022u003eDocker: features and advantages of usageu003c/spanu003eu003c/h3u003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eLet’s proceed to Docker itself and its advantages:u003c/spanu003ernrnu0026nbsp;rnu003culu003ern tu003cliu003eu003cspan style=u0022color: #000000;u0022u003eu003cstrongu003eRapid deploymentu003c/strongu003e: enables rapid deployment of applications and tools without the need for extensive setup. By running them in containers, you can quickly launch and manage the required components.u003c/spanu003eu003c/liu003ernu003c/ulu003ernu0026nbsp;rnu003culu003ern tu003cliu003eu003cspan style=u0022color: #000000;u0022u003eu003cstrongu003eConvenient encapsulationu003c/strongu003e: provides convenient encapsulation of applications, allowing you to package all the necessary dependencies, libraries, and configurations within a container. This encapsulation ensures consistent and reproducible environments for your applications, including the Selenoid container.u003c/spanu003eu003c/liu003ernu003c/ulu003ernu0026nbsp;rnu003culu003ern tu003cliu003eu003cspan style=u0022color: #000000;u0022u003eu003cstrongu003eClean monitoringu003c/strongu003e: facilitates clean and streamlined monitoring of your applications. By running each application in its own container, you can easily monitor resource usage, logs, and performance metrics, ensuring efficient management and troubleshooting of issues.u003c/spanu003eu003c/liu003ernu003c/ulu003ernu0026nbsp;rnu003culu003ern tu003cliu003eu003cspan style=u0022color: #000000;u0022u003eu003cstrongu003eEasy scalingu003c/strongu003e: simplifies the process of scaling your applications. With containerization, you can easily replicate and distribute containers across multiple hosts or clusters, enabling seamless scaling to meet increased demand or workload.u003c/spanu003eu003c/liu003ernu003c/ulu003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eWhen discussing Docker, it’s essential to clarify a few key concepts:u003c/spanu003ernrnu003cspan style=u0022color: #000000;u0022u003eu003cstrongu003eContaineru003c/strongu003e is a running instance that encapsulates the necessary software, including the browser image, allowing for efficient and isolated execution of applications. Containers can be created, deleted, and recreated quickly within a short period of time.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eu003cstrongu003eContainer imageu003c/strongu003e serves as the essential foundation for each container, encompassing all the requisite dependencies and configurations. This includes the incorporation of new images for browsers, ensuring the availability of the necessary components to execute the application within the container. By leveraging these container images, you can seamlessly set up and run your applications within isolated environments, guaranteeing consistency and reliability across different containers. The inclusion of new browser images further enhances the versatility and adaptability of the container, enabling you to tailor your testing environment to specific requirements and scenarios.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eu003cstrongu003eDocker Hubu003c/strongu003e, the primary public Docker repository provided by Docker Inc., is a centralized source for a vast collection of container images. Within this repository, you’ll find a diverse range of u0022officialu0022 browser images developed by the Docker team or in collaboration with developers. These images are specifically designed to include essential components such as live browser screen, video recording capabilities, and other necessary functionalities. With these images, you can perform comprehensive testing and analysis, capturing recorded video files of the testing sessions for later review and evaluation. Docker Hub thus acts as a valuable resource for obtaining reliable and feature-rich container images that enhance your testing and analysis workflows.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eBy granting appropriate execution permission to your containers, you ensure that they can run and execute the desired applications effectively. This permission allows the containers to access and utilize the necessary resources, interact with the operating system, and perform the required actions for successful application execution.u003c/spanu003ernrnu0026nbsp;rnu003ch3u003eu003cspan style=u0022color: #000000;u0022u003eDocker installingu003c/spanu003eu003c/h3u003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eTo install Docker for Windows, we open the direct link u003c/spanu003eu003ca href=u0022https://hub.docker.com/u0022u003ehttps://hub.docker.comu003c/au003e u003cspan style=u0022color: #000000;u0022u003eand download the Docker Desktop app for Windows or MacOS. Ensure that you have Docker installed on your system to proceed with the installation. u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eTo install Docker for Ubuntu Linux, we need the u003cemu003esudo apt install docker.iou003c/emu003e command.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eThen we need to run Docker and configure it to start automatically when the system boots by executing the following commands:u003c/spanu003ernrnu0026nbsp;rnu003culu003ern tu003cliu003eu003cspan style=u0022color: #000000;u0022u003esudo systemctl start docker;u003c/spanu003eu003c/liu003ernu003c/ulu003ernu0026nbsp;rnu003culu003ern tu003cliu003eu003cspan style=u0022color: #000000;u0022u003esudo systemctl enable docker.u003c/spanu003eu003c/liu003ernu003c/ulu003ernu0026nbsp;rnu003ch3u003eu003cspan style=u0022color: #000000;u0022u003eSelenoid: features and advantagesu003c/spanu003eu003c/h3u003ernu0026nbsp;rnrnu003ca href=u0022https://aerokube.com/selenoid/latest/u0022u003eSelenoidu003c/au003e u003cspan style=u0022color: #000000;u0022u003eis a powerful server that excels in launching isolated browsers within Docker containers, eliminating the need for a centralized Selenium hub. This capability empowers you to effortlessly manage and control the browser instances required for your test automation, ensuring seamless execution and eliminating any dependencies on a centralized hub. With Selenoid, you gain control and flexibility to launch browsers within Docker containers, simplifying your testing infrastructure.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eAdvantages of Selenoid usage:u003c/spanu003ernrnu0026nbsp;rnu003culu003ern tu003cliu003eu003cspan style=u0022color: #000000;u0022u003eSelenoid provides a single environment for the parallel launch of automated tests. It allows you to run tests concurrently on multiple browsers, maximizing efficiency and reducing test execution time. By leveraging Selenoid’s capabilities, you can achieve parallel testing and effectively scale your automation efforts.u003c/spanu003eu003c/liu003ernu003c/ulu003ernu0026nbsp;rnu003culu003ern tu003cliu003eu003cspan style=u0022color: #000000;u0022u003eCM Selenoid allows running each browser in a separate container, which enables full isolation of the browser environment.u003c/spanu003eu003c/liu003ernu003c/ulu003ernu0026nbsp;rnu003culu003ern tu003cliu003eu003cspan style=u0022color: #000000;u0022u003eCM Selenoid environment does not affect qualitative and continuous testing.u003c/spanu003eu003c/liu003ernu003c/ulu003ernu0026nbsp;rnu003culu003ern tu003cliu003eu003cspan style=u0022color: #000000;u0022u003eResources consumption and utilization: Selenoid enables to maintain a high load without additional waste of resources; in addition, all inactive containers are removed at the end of each session. Thus, the level of free memory is always appropriate.u003c/spanu003eu003c/liu003ernu003c/ulu003ernu0026nbsp;rnu003culu003ern tu003cliu003eu003cspan style=u0022color: #000000;u0022u003eCM Selenoid requires little time and effort. And in fact it is done with the help of one command.u003c/spanu003eu003c/liu003ernu003c/ulu003ernu0026nbsp;rnu003culu003ern tu003cliu003eu003cspan style=u0022color: #000000;u0022u003eSimultaneous support of multiple browser versions: this option is only available if you use Selenoid; several containers with the appropriate browsers are to be built.u003c/spanu003eu003c/liu003ernu003c/ulu003ernu0026nbsp;rnu003culu003ern tu003cliu003eu003cspan style=u0022color: #000000;u0022u003eTo address the challenges that may arise when running multiple browsers on the same machine within Selenium Grid, CM Selenoid offers a solution. In Selenium Grid, due to the OS-specific nature, the focus can only be on one window, leading to potential competition among windows. However, by utilizing Selenoid, each test can be run in a separate container. This eliminates the problem of windows competing for focus, ensuring smoother and more reliable test execution. With Selenoid, you can overcome these challenges and achieve better isolation and stability when running tests across multiple browsers.u003c/spanu003eu003c/liu003ernu003c/ulu003ernu0026nbsp;rnu003culu003ern tu003cliu003eu003cspan style=u0022color: #000000;u0022u003eAll available logs are accessed easily in CM Selenoid. There is also the possibility of integration with the ELK stack for faster collection and analysis of current log files.u003c/spanu003eu003c/liu003ernu003c/ulu003ernu0026nbsp;rnu003ch3u003eu003cspan style=u0022color: #000000;u0022u003eAerocube Selenoid installationu003c/spanu003eu003c/h3u003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eBefore installing Selenoid, there are a few prerequisites:u003c/spanu003ernrnu0026nbsp;rnu003culu003ern tu003cliu003eu003cspan style=u0022color: #000000;u0022u003eMake sure you have recent Docker version installed (further we look into the usage of Selenoid together with Docker).u003c/spanu003eu003c/liu003ernu003c/ulu003ernu0026nbsp;rnu003culu003ern tu003cliu003eu003cspan style=u0022color: #000000;u0022u003eThe simplest method to install Selenoid is by downloading the u003ca href=u0022https://aerokube.com/cm/latest/u0022 target=u0022_blanku0022 rel=u0022noopeneru0022u003eConfiguration Manageru003c/au003e, which facilitates the automatic installation of Aerokube products. Selenoid, being one of these products, can be effortlessly installed using this manager. By utilizing the Configuration Manager, you can streamline the process of setting up and starting Selenoid, ensuring a smooth and hassle-free deployment. Additionally, you can use the u0022docker pullu0022 command to download and retrieve the necessary Selenoid Docker image for your installation. This allows you to efficiently retrieve the necessary components to run Selenoid, including the configuration files and video screen size settings.u003c/spanu003eu003c/liu003ernu003c/ulu003ernu0026nbsp;rnu003culu003ern tu003cliu003eu003cspan style=u0022color: #000000;u0022u003eRename the downloaded file to cm.exe (for easy interaction).u003c/spanu003eu003c/liu003ernu003c/ulu003ernu0026nbsp;rnu003culu003ern tu003cliu003eu003cspan style=u0022color: #000000;u0022u003eRun the following commands to start Selenoid UI: u003c/spanu003eu003c/liu003ernu003c/ulu003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eu003cemu003e./cm.exe selenoid start u002du002dvncu003c/emu003eu003c/spanu003ernrnu003cspan style=u0022color: #000000;u0022u003eu003cemu003e./cm.exe selenoid-ui startu003c/emu003eu003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eThe u003cemu003e./cm.exe selenoid start u002du002dvncu003c/emu003e command will download the latest Selenoid version, browser container images, web driver binaries, generate configuration file and finally start Selenoid.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #333333;u0022u003eThe u003cemu003e./cm.exe selenoid-ui startu003c/emu003e command installs and starts u003cbu003eSelenoid UIu003c/bu003e. It is a user interface to track what’s happening during the test execution.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eSelenoid runs on standard Selenium 4444 port by default. We can redefine the port using the u002du002dport key.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eAerocube Selenoid was developed to work in big clusters, that’s why it has no user interface. And that’s why the attempt to open tests Endpoint http://localhost:4444/wd/hub will return a 404 error.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eHowever, with the VNC feature enabled, you can utilize remote desktop functionality to access and interact with the graphical interface of browsers that run Selenoid containers.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eThis allows for convenient visualization and debugging of tests. u003c/spanu003ernrnu0026nbsp;rnu003ch3u003eu003cspan style=u0022color: #000000;u0022u003eStat Selenoid UIu003c/spanu003eu003c/h3u003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eSelenoid UI is available at the link: http://localhost:8080/u003c/spanu003ernrnu0026nbsp;rnrnu003cimg class=u0022alignnone wp-image-8843 size-largeu0022 src=u0022https://intexsoft.com/app/uploads/2019/11/selenoid-stats-and-sessions-1024×456.pngu0022 alt=u0022u0022 width=u00221024u0022 height=u0022456u0022 /u003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eHere we can see the current quota usage, pending browsers and the queue itself. Selenoid UI gets updates via SSE, so there is no need to renew the browser to see what is going on. It will reconnect automatically after any temporary failure.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eIf we talk about simultaneous testing on different devices, e.g: we have a cross-platform web app with a real-life chat function, we can simultaneously test the interaction between them, that is obviously comfortable.u003c/spanu003ernrnu0026nbsp;rnu003ch3u003eu003cspan style=u0022color: #000000;u0022u003eSelenoid UI capabilitiesu003c/spanu003eu003c/h3u003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eSelenoid UI has the following capabilities:u003c/spanu003ernrnu0026nbsp;rnrnu003cimg class=u0022alignnone wp-image-8844 size-largeu0022 src=u0022https://intexsoft.com/app/uploads/2019/11/selenoid-ui-capabilities-1024×477.pngu0022 alt=u0022u0022 width=u00221024u0022 height=u0022477u0022 /u003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eYou can choose a browser from available browsers and UI will provide a setup example with the right capabilities. We can see from the screenshot that examples are available for several languages.u003c/spanu003ernrnu0026nbsp;rnrnu003cimg class=u0022alignnone wp-image-8845 size-fullu0022 src=u0022https://intexsoft.com/app/uploads/2019/11/selenoid-UI-capabilities-2.pngu0022 alt=u0022u0022 width=u0022962u0022 height=u0022490u0022 /u003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eWith the selection of the browser, it could be launched manually right in the interface. While executing tests, we can connect to vnc port in a real-time regime, get access to the browser and even intervene in the process of autotests execution.u003c/spanu003ernrnu0026nbsp;rnu003ch3u003eu003cspan style=u0022color: #000000;u0022u003eLogs and VNCu003c/spanu003eu003c/h3u003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eIf you use u003cemu003eenableVNC=trueu003c/emu003e capability, you can see a list of the available statistics. With VNC, you have the ability to see and interact with the browser directly, while the log will reflect all the actions performed within the browser. This feature provides a visual representation of the test execution process, allowing for real-time monitoring and interaction with the browser. By utilizing the VNC feature, you can gain valuable insights into the behavior and functionality of the browser. u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eVNC session:u003c/spanu003ernrnu0026nbsp;rnrnu003cimg class=u0022alignnone wp-image-8846 size-fullu0022 src=u0022https://intexsoft.com/app/uploads/2019/11/vnc-session.pngu0022 alt=u0022u0022 width=u0022970u0022 height=u0022494u0022 /u003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eVNC fullscreen mode:u003c/spanu003ernrnu0026nbsp;rnrnu003cimg class=u0022alignnone wp-image-8847 size-fullu0022 src=u0022https://intexsoft.com/app/uploads/2019/11/vnc-full-screen.pngu0022 alt=u0022u0022 width=u0022974u0022 height=u0022496u0022 /u003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eEven without utilizing the VNC (Virtual Network Computing) flag, Selenoid provides the ability to access the logs of the Docker container for each Selenium session. This standalone binary feature allows you to view comprehensive logs, offering valuable insights into the execution and behavior of the containerized environment during test execution. By enabling centralized log storage, you can efficiently analyze and monitor the logs, gaining valuable information and facilitating troubleshooting and debugging processes. With access to detailed logs and the ability to view the live browser screen, you can effectively investigate issues, improve test reliability, and enhance overall test quality. This comprehensive logging capability in Selenoid empowers you to identify and address any issues that may arise during test execution, ensuring smoother and more reliable testing processes.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eIn addition, it is worth noting that Selenoid is regularly updated to ensure compatibility with the recent version of Selenium. This ensures that you can leverage the latest features and enhancements available in the recent version of Selenoid, further optimizing your test automation efforts.u003c/spanu003ernrnu0026nbsp;rnrnu003cimg class=u0022alignnone wp-image-8848 size-fullu0022 src=u0022https://intexsoft.com/app/uploads/2019/11/logs.pngu0022 alt=u0022u0022 width=u0022928u0022 height=u0022533u0022 /u003ernrnu0026nbsp;rnu003ch2u003eu003cspan style=u0022color: #000000;u0022u003eVideo recorder imageu003c/spanu003eu003c/h2u003ernu003cspan style=u0022color: #000000;u0022u003eIn addition to its powerful features, Aerokube Selenoid offers the capability to record videos of your test sessions. You can easily access these recorded videos by opening http://localhost:4444/video/ or by navigating to the u0022Videosu0022 tab in the Selenoid user interface. This allows you to review and analyze the recorded test videos, gaining valuable insights into the behavior and interactions of your tests with the browser.u003c/spanu003ernrnu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eThe video recorder image provided by Selenoid captures the entire test session, including the video screen size, providing a comprehensive visual representation of the test execution process. This feature is particularly useful for debugging purposes, allowing you to identify any issues or unexpected behavior during test execution. u003c/spanu003ernrnu0026nbsp;rnu003ch3u003eu003cspan style=u0022color: #000000;u0022u003eAdding Selenoid to run tests within Docker containeru003c/spanu003eu003c/h3u003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eIn order to add Selenoid into the u003cbu003e@BeforeClassu003c/bu003e annotation we need to do the following configuration:u003c/spanu003ernrnu0026nbsp;rnu003cpre class=u0022blog-codeu0022u003eu003cspan style=u0022color: #000000;u0022u003eConfiguration.remote = u0022http://localhost:4444/wd/hubu0022;rnConfiguration.browser = u0022chromeu0022;rnConfiguration.browserSize = u00221920x1080u0022;rnDesiredCapabilities capabilities = new DesiredCapabilities();rncapabilities.setCapability(capabilityName: u0022enableVNCu0022, value: true);rncapabilities.setCapability(capabilityName: u0022enableVideou0022, value: true);rnConfiguration.browserCapabilities = capabilities;rnu003c/spanu003eu003c/preu003ernu0026nbsp;rnrnu003cspan style=u0022color: #000000;u0022u003eSince now we have the u003ciu003eConfiguration.browser = u0022chromeu0022u003c/iu003e property, we delete u003ciu003eProperty baseurlu003c/iu003e which defined the browser for running our tests:u003c/spanu003ernrnu0026nbsp;rnu003cpre class=u0022blog-codeu0022u003eu003cspan style=u0022color: #000000;u0022u003e@BeforeClass rnpublic static void setUp() {rn Configuration.remote = u0022http://10.0.75.1:4444/wd/hubu0022; rn Configuration.browser = u0022chromeu0022; rn Configuration.browserSize = u00221920x1080u0022; rn DesiredCapabilities capabilities = new DesiredCapabilities(); rn capabilities.setCapability(capabilityName: u0022enableVNCu0022, value: true); rn capabilities.setCapability(capabilityName: u0022enableVideou0022, value: true); rn Configuration.browserCapabilities = capabilities;rnrnu003c/spanu003eu003c/preu003e

Written by

image

Dora

Marketing Manager
image

Margarita

Industry Expert

FAVORITES OF THE MONTH

Don't miss our updates