9

I'm new to selenium. I am facing an issue. The number of web elements in a page increases on a button click(triggered by ajax call). So while getting the size of the element after button click gives the same value.(But it was updated in site manually).

I have tried waiting for ajax, and also implicit wait. On implicit wait it throws element not found exception.

How can I wait until the count of the web element gets changed.

3 Answers 3

13

Thanks for your responses. But this is the script I'm using to resolve this issue

public void waitUntilCountChanges() {
        WebDriverWait wait = new WebDriverWait(getDriver(), 5);
        wait.until(new ExpectedCondition<Boolean>() {
            public Boolean apply(WebDriver driver) {
                int elementCount = driver.findElement(By.xpath("xxxx")).size();
                if (elementCount > 1)
                    return true;
                else
                    return false;
            }
        });
    }

Or in Python

class elements_length_changes(object):
  """An expectation for checking that an elements has changes.

  locator - used to find the element
  returns the WebElement once the length has changed
  """
  def __init__(self, locator, length):
    self.locator = locator
    self.length = length

  def __call__(self, driver):
    element = driver.find_elements(*self.locator)
    element_count = len(element)
    if element_count > self.length:
      return element
    else:
      return False

locator = (By.XPATH, "//a[@aria-label='Home']")
length = len(self.wd.find_elements_by_xpath("//a[@aria-label='Home']")
condition = elements_length_changes(locator, length)
WebDriverWait(driver, 5).until(condition)
0
2

To add to gomesr's answer, you might find yourself needing to wait for other elements during your tests. One way to easily have reusable code for this is to use a closure (also known as an anonymous function or a lambda function) to create a spinner function that you can call whenever you're waiting for an element to load.

The spinner function would look like

public function spin ($lambda, $wait = 60) {
    for ($i = 0; $i < $wait; $i++) {
        try {
            if ($lambda($this)) {
                return true;
            }
        } catch (Exception $e) {
            // do nothing
        }

        sleep(1);
    }

    $backtrace = debug_backtrace();

    throw new Exception(
        "Timeout thrown by " . $backtrace[1]['class'] . "::" . $backtrace[1]['function'] . "()\n" .
        $backtrace[1]['file'] . ", line " . $backtrace[1]['line']
    );
}

And to call the function

$this->spin(function($context) {
    return ($context->getSession()->getPage()->findById('example')->isVisible());
 });

When you call the spinner function you pass an anonymous function with the logic that you want to assert on, in this example it's waiting for an element with an id of 'example' to be visible. The spinner also includes a timeout that will throw an exception if the element is not found within the specified time (default 60 seconds).

The above sample code is from http://docs.behat.org/cookbook/using_spin_functions.html

You can also find more information on spin functions and another code example at http://sauceio.com/index.php/2011/04/how-to-lose-races-and-win-at-selenium/

1
  • thank you for your response. But it seems I'm facing facing a combined issue in this case. let me post it as a different question. so that It might be helpful for users.
    – Ajmal
    Commented Oct 23, 2013 at 11:59
0

You will have to do a manual loop waiting on the count being equal to X. Have a timeout so that it doesn't wait indefinitely. So something like:

start_time=now  
count=number of elements  
while count < X:  
  count=number of elements  
  if now - start_time > timeout  
    exit loop  

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.