I am having multiple links on a Webpage. After clicking the link, a popup opens, I Set some values on fields in the popup and click on 'Save'.
On clicking on 'Save', the main web page refreshes to show the updated status of the link. I use a "for" loop to iterate through all the Links one-by-one and update the status. To avoid stale element reference, I have written a utility to check if element is stale still but I am unable to get rid of this exception.
Below is my Utility code:
public static boolean isStale(WebElement e){
try{
e.isDisplayed();
return false;
}catch(StaleElementReferenceException ex){
return true;
}
}
Below is my page Objects code:
public class DocCheckPageObjects {
WebDriver driver = null;
public DocCheckPageObjects(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
@FindBy(tagName="a")
WebElement tagName_a;
public WebElement tagName_a() { return tagName_a; }
@FindBy(xpath="//input[@name='progress']")
WebElement listBoxDocStatus;
public WebElement listBoxDocStatus() { return listBoxDocStatus; }
@FindBy(xpath="//span[@title='Received Hard Copy']")
WebElement listBoxDocStatusOptionReceivedHardCopy;
public WebElement listBoxDocStatusOptionReceivedHardCopy() { return listBoxDocStatusOptionReceivedHardCopy; }
@FindBy(xpath="//button[@name='update']")
WebElement btnSave;
public WebElement btnSave() { return btnSave; }
@FindBy(xpath="//*[contains(text(),'Saved Successfully')]")
WebElement toastMsg;
public WebElement toastMsg() { return toastMsg; }}
Below is my Class code:
DocCheckPageObjects docCheckObj = new DocCheckPageObjects(driver);
WebElement docCheckTable = driver.findElement(By.xpath("//div[@class='slds-gutters slds-wrap slds-m-horizontal_xx-small']/table"));
System.out.println("No of Links: " + docCheckTable.findElements(By.tagName("a")).size());
int linkCount = docCheckTable.findElements(By.tagName("a")).size();
for(int i=0; i<linkCount;i++) {
wait.until(ExpectedConditions.elementToBeClickable(docCheckTable.findElements(By.tagName("a")).get(i)));
docCheckTable.findElements(By.tagName("a")).get(i).click();
docCheckObj.listBoxDocStatus().click();
docCheckObj.listBoxDocStatusOptionReceivedHardCopy().click();
docCheckObj.btnSave().click();
while(util.isStale(docCheckTable.findElements(By.tagName("a")).get(i))) {
docCheckTable = driver.findElement(By.xpath("//div[@class='slds-gutters slds-wrap slds-m-horizontal_xx-small']/table"));
}
}
I think the code inside while loop is executing before the page is refreshed hence I am still getting Stale element exception.
Below is the code which works using thread.sleep:
for(int i=0; i<linkCount;i++) {
Thread.sleep(1000);
docCheckTable = driver.findElement(By.xpath("//div[@class='slds-gutters slds-wrap slds-m-horizontal_xx-small']/table"));
wait.until(ExpectedConditions.elementToBeClickable(docCheckTable.findElements(By.tagName("a")).get(i)));
docCheckTable.findElements(By.tagName("a")).get(i).click();
docCheckObj.listBoxDocStatus().click();
docCheckObj.listBoxDocStatusOptionReceivedHardCopy().click();
docCheckObj.btnSave().click();
}
Q1) Above code resolves the state element reference, but i want to avoid using thread.sleep.
Q2) I had to put my locator like "docCheckTable" in my executable class instead of in Page Object factory class. How do I put all my Locators in Page Object class which returns a list of Webelements and also avoids Stale Element exception.