Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wait for multiple elements to be visible in selenium webdriver JavaScript bindings

The selenium webdriver bindings for JavaScript allow to wait for an element to be visible by combing two wait commands like in the following example:

const timeout = 1000;
const locator = webdriver.By.id('test');
driver.wait(webdriver.until.elementLocated(locator, timeout).then(function() {
   that.findElement(locator).then(function(element) {
      driver.wait(webdriver.until.elementIsVisible(element), timeout).then(function() {
         // element is visible!
      });
   });
});

Is there an easier way to do this and how would this be done, when we need to wait for an array of elements to be visible all together?

like image 720
doberkofler Avatar asked Feb 26 '16 01:02

doberkofler


People also ask

How do you add wait until element is visible in Selenium?

Selenium: Waiting Until the Element Is Visiblevar wait = new WebDriverWait(driver, TimeSpan. FromSeconds(20)); As you can see, we give the WebDriverWait object two parameters: the driver itself and a TimeSpan object that represents the timeout for trying to locate the element.

How wait until elements are visible?

We can wait until an element is present in Selenium webdriver. This can be done with the help of synchronization concept. We have an explicit wait condition where we can pause or wait for an element before proceeding to the next step. The explicit wait waits for a specific amount of time before throwing an exception.

Which is the best wait in Selenium?

Explicit Wait in Selenium It gives better options than implicit wait as it waits for dynamically loaded Ajax elements. In the below example, we are creating reference wait for “WebDriverWait” class and instantiating using “WebDriver” reference, and we are giving a maximum time frame of 20 seconds.

Which is the correct syntax to wait for an element to be clickable?

var wait = new WebDriverWait(driver, TimeSpan. FromMinutes(1)); var clickableElement = wait.


1 Answers

One of the great advantages of Promises is that you you can keep your async code linear rather than nested (callback hell from continuation passing style).

Promises give you return statements and error throwing, which you lose with continuation passing style.

In your case, you need to return the promise from your promise returning functions so you can chain your promises.

Example: Promise.all takes an array of promises and resolves once all promises resolve, if any are rejected, the array is rejected.

this.waitForElementsToBecomeVisible = function() {
    return Promise.all([
        driver.wait(webdriver.until.elementIsVisible(usernameTextField), 500),
        driver.wait(webdriver.until.elementIsVisible(firstNameTextField), 500),
        driver.wait(webdriver.until.elementIsVisible(lastNameTextField), 500),
        driver.wait(webdriver.until.elementIsVisible(createEmployeeButton), 500)
    ]);
}

Then you can chain your promise.

driver.get('https://website.com/login').then(function () {
    loginPage = new LoginPage(driver);
    return loginPage.login('company.admin', 'password')
}).then(function () {
    employeePage = new EmployeePage(driver);
    return employeePage.clickAddEmployee()
}).then(function () {
    addEmployeeForm = new AddEmployeeForm(driver);
   /**
    *
    * Wait for elements to become visible
    */
    return addEmployeeForm.waitForElementsToBecomeVisible();
}).then(function() {
    return addEmployeeForm.completeForm(employee);
}).then(function() {
    return addEmployeeForm.clickCreateEmployee();
}).then(function() {
    return employeePage.searchEmployee(employee);
});

You can see how the above example isn't nested and is alot easier to maintain. You return a promise and keep chaining instead of nesting. I hope this helps you and doesn't confuse you at all.

like image 121
Grim Avatar answered Nov 08 '22 19:11

Grim