Mike ASP
Mike ASP

Reputation: 2333

Click functionality is not working good all the time on CRM application

Sources: Selenium WebDriver, Chrome 73V, ChromeDriver, Java , testNG, CRM application , Eclipse

I am working on web application which is kind of CRM, loaded with tons of UI elements. One test case works today and fail tomorrow. FYI, I used fluent wait for my test cases.

I checked all the xpaths and they are good. On top of this I executed with Debug mode and tests are passing on debug mode. They are randomly flaky and un-stable , I am not sure what to do to make them stable? I don't want to use thread.sleep , off course.

Below code (just for the idea) I used to click few elements of the page , sometime Action class works sometime doesn't and sometime Click function works sometime doesn't, not sure how to handle such weird scenario?

driver.findElement(By.name("submit")).sendKeys(Keys.ENTER);

OR

driver.findElement(By.name("submit")).sendKeys(Keys.RETURN);

OR

driver.findElement(By.name("submit")).click();

OR

WebElement webElement = driver.findElement(By.id("Your ID Here"));
Actions builder = new Actions(driver);
builder.moveToElement(webElement).click(webElement);
builder.perform();

OR

WebElement webElement = driver.findElement(By.id("Your ID here"));
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", webElement);

Thanks for your comments, Please see below, this is my fluent wait:

  public static boolean waitForElementToBeVisibleOrClickable (WebDriver driver, WebElement element) {

    boolean webElement = false;

    try {
        driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
        wait = new WebDriverWait(driver, 30)
                .ignoring(NoSuchElementException.class, 
        StaleElementReferenceException.class)
                .pollingEvery(200);
        wait.until(ExpectedConditions.visibilityOf(element));
        **OR** 
        wait.until(ExpectedConditions.elementToBeClickable(element));
        Log.info("Element is visible");
        webElement = true;
    } catch (Exception e) {
        Log.error("Element is not visible");
        webElement = false;
    } finally {
        driver.manage().timeouts().implicitlyWait(45, TimeUnit.SECONDS);
    }
    return webElement;
}

Upvotes: 1

Views: 234

Answers (2)

undetected Selenium
undetected Selenium

Reputation: 193138

You need to take care of the couple of things:

You can find a relevant discussion in How to click a hyperlink without any link text

  • If the element is within a <form> tag, as an alternative you can use the submit() method.

You can find a detailed discussion in Selenium: submit() works fine, but click() does not

  • As per the documentation, Do not mix implicit and explicit waits! Doing so can cause unpredictable wait times. For example, setting an implicit wait of 10 seconds and an explicit wait of 15 seconds could cause a timeout to occur after 20 seconds.

You can find a detailed discussion in How to properly configure Implicit / Explicit Waits and pageLoadTimeout through Selenium?


Solution

Instead of using fluent wait you can induce WebDriverWait in conjunction with ExpectedConditions and an optimized code block will be:

public static boolean waitForElementToBeVisibleOrClickable (WebDriver driver, WebElement element) {

    try {
            driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
            new WebDriverWait(driver, 30).until(ExpectedConditions.elementToBeClickable(element));
            System.out.println("Element is clickable now");
    } catch (TimeoutException e) {
            System.out.println("Element isn't clickable");
    } finally {
            driver.manage().timeouts().implicitlyWait(45, TimeUnit.SECONDS);
    }
    return element;
}

Upvotes: 0

Guy
Guy

Reputation: 50899

You defined method to wait, but you don't actually use it. You are locating the element using driver and immediately click it. You should also modify the wait to use it while locating the element, not afterwards

public WebElement waitForElement(By by) {
    return wait.until(ExpectedConditions.visibilityOfElementLocated(by));
}

waitForElement(By.name("submit")).click();

Upvotes: 1

Related Questions