0

I working in selenium and now for checking visibility of element i use following wait until:

@FindBy (css=".delete-basket-modal-btn") WebElement deleteItemFromBasketCancelButton;
public void clickDeleteItemFromBasketCancelButton() throws InterruptedException {   
    wait.until(ExpectedConditions.elementToBeClickable(deleteItemFromBasketCancelButton));
    deleteItemFromBasketCancelButton.click();
}

that's not good idea, this function is not checking for presence of element, so sometimes i get 'stale element reference element is not attached to the page document'

Now i trying to create universal function which will be inherited by all of mine page object class. In this function i need checking (5 sec) for presence, enability, clickability and visibilty of WebElement passed in argument.

For this moment i have new function below, but i dont know that is good approach for my problem

public void verifyElement(WebElement element) throws InterruptedException {
    boolean isPresent = false;


    for (int i = 0; i < 5; i++) {
        try {
            if (element != null) {
                isPresent = true;               // metoda do czekania na element  
                break;
            }
        } catch (Exception e) {
            // System.out.println(e.getLocalizedMessage());
            Thread.sleep(1000);
        }

    }
    Assert.assertTrue(isPresent, "\"" + element + "\" is not present.");


    boolean isEnabled = false;
    for (int i = 0; i < 5; i++) {
        try {
            if (element.isEnabled()==true) {
                isEnabled = true;
                break;
            }
        }catch (Exception e) {
        Thread.sleep(1000);
    }
}
    Assert.assertTrue(isEnabled, "\"" + element + "\" is not enabled.");

}

Do you have any suggestion or similar problem for this issue?

2 Answers2

0

StaleElementReferenceException doesn't (necessarily) mean the element is not present, it means the DOM had changed/refreshed since the element was located, so the element reference which the driver holds is no longer valid. This is a disadvantage of using PageFactory model.

The solution is to locate the element just before the click operation, however this will break the consistency of the page object. Instead of using FindBy send By to the method and locate the element there

public void clickDeleteItemFromBasketCancelButton(By by) throws InterruptedException {
    WebElement deleteItemFromBasketCancelButton = wait.until(ExpectedConditions.elementToBeClickable(by));
    deleteItemFromBasketCancelButton.click();
}
Guy
  • 46,488
  • 10
  • 44
  • 88
0

The first written code is enough. To overcome stale element exception write code in try/catch block and use ExpectedConditions.stalenessOf(deleteItemFromBasketCancelButton) for presence, enability, clickability and visibilty (for any type of operation).

Try below one, hope it's help for you.

try{
wait.until(ExpectedConditions.elementToBeClickable(deleteItemFromBasketCancelButton));
    deleteItemFromBasketCancelButton.click();
}
catch(Exception e){
wait.until(ExpectedConditions.refreshed(ExpectedConditions.stalenessOf(deleteItemFromBasketCancelButton)))
deleteItemFromBasketCancelButton.click();
}
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352