1

I'm writing an automated test case for a web page. Here's my scenario. I have to click and type on various web elements in an html form. But, sometimes while typing on a text field, an ajax loading image appears , fogging all elements i want to interact with. So, I'm using web-driver wait before clicking on the actual elements like below,

WebdriverWait innerwait=new WebDriverWait(driver,30);
innerwait.until(ExpectedConditions.elementToBeClickable(By.xpath(fieldID)));
driver.findelement(By.xpath(fieldID)).click();

But the wait function returns the element even if it is fogged by another image and is not clickable. But the click() throws an exception as

Element is not clickable at point (586.5, 278).
Other element would receive the click: <div>Loading image</div>

Do I have to check every time if the loading image appeared before interacting with any elements?.(I can't predict when the loading image will appear and fog all elements.) Is there any efficient way to handle this? Currently I'm using the following function to wait till the loading image disappears,

public void wait_for_ajax_loading() throws Exception
{
    try{
    Thread.sleep(2000);
    if(selenium.isElementPresent("id=loadingPanel"))
    while(selenium.isElementPresent("id=loadingPanel")&&selenium.isVisible("id=loadingPanel"))//wait till the loading screen disappears
    {
         Thread.sleep(2000);
         System.out.println("Loading....");

    }}

    catch(Exception e){
        Logger.logPrint("Exception in wait_for_ajax_loading() "+e);
        Logger.failedReport(report, e);
        driver.quit();
        System.exit(0);
    }

}

But I don't know exactly when to call the above function, calling it at a wrong time will fail. Is there any efficient way to check if an element is actually clickable? or the loading image is present?

Thanks..

2
  • Do you run this test for different browsers? If so, do you get the same exception for all of them? If you run it for Chrome, the exception might have nothing to do with your code, but the Chrome driver's bug for 'click()' method. Commented Jun 24, 2013 at 9:26
  • @Sergio I do, and it isn't a browser driver bug, based on the comments from this question stackoverflow.com/questions/9878478/… and from what I've learned the webdriver wait returns the element even if it is not clickable i.e if there are multiple layers obscuting it. So is there any wait methods that waits till the element is really clickable? Commented Jun 24, 2013 at 11:33

1 Answer 1

2

Given the circumstances that you describe, you are forced to verify one of two conditions:

  1. Is the element that you want to click clickable?
  2. Is the reason that blocks the clicks still present?

Normally, if the WebDriver is able to find the element and it is visible, then it is clickable too. Knowing the posible reasons that might block it, I would rather choose to verify those reasons. Besides, it would be more expressive in the test code: you clearly see what you are waiting for, what you are checking before clicking the element, instead of checking the "clickability" with no visible reason for it. I think it gives one (who reads the test) a better understanding of what is (or could be) actually going on.

Try using this method to check that the loading image is not present:

// suppose this is your WebDriver instance
WebDriver yourDriver = new RemoteWebDriver(your_hub_url, your_desired_capabilities);

......
// elementId would be 'loadingPanel'
boolean isElementNotDisplayed(final String elementId, final int timeoutInSeconds) {
    try {
        ExpectedCondition condition = new ExpectedCondition<Boolean>() {
            @Override
            public Boolean apply(final WebDriver webDriver) {
                WebElement element = webDriver.findElement(By.id(elementId));
                return !element.isDisplayed();
            }
        };
        Wait w = new WebDriverWait(yourDriver, timeoutInSeconds);
        w.until(condition);
    } catch (Exception ex) {
        // if it gets here it is because the element is still displayed after timeoutInSeconds
        // insert code most suitable for you
    }
        return true;
}

Perhaps you will have to adjust it a bit to your code (e.g. finding the element once when the page loads and only checking if it is displayed).

If you are not sure when exactly the loading image comes up (though I suppose you do), you should call this method before every click on elements that would become "unclickable" due to the loading image. If the loading image is present, the method will return true as soon as it disappears; if it doesn't disappear within 'timeoutInSeconds' amount of time, the method will do what you choose (e.g. throw an exception with specific message).

You could wrap it together like:

void clickSkippingLoadingPanel(final WebElement elementToClick) {
    if (isElementNotDisplayed('loadingPanel', 10)) {
        elementToClick.click();
    }
}

Hope it helps.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.