So here's the setup, we have tests where we fetch test data from excel sheet and iterate over all the rows within a particular test. So, for example, there are tests that create some user profiles, once they do; there's a success message that appears on the next page, our test uses the "findElement.." method to capture that element and get's the text to verify that 1) it appears and 2) that the message is correct. Now here's the problem, since the test may iterate over and over a lot (because of excel data rows), every so often we notice that the test throws NoSuchElementException
while looking for that success message. I was recently told by someone that instantiating that page object class at each iteration would solve this issue. So my main question really is that would instantiating the page object class solve this, or is there something else I'm missing? Following is a sample of the code (not exact code of course)
SuccessPage successPage = new SuccessPage(driver);
InputPage inputPage = new InputPage(driver);
String successMessage = "";
excelSheetData = someCustomMethodThatFetchesDataFromExcel();
for (Map<String, String> rows : excelsheetData){
inputPage.inputElement1.sendKeys(rows.get("columnName1"));
inputPage.inputElement2.sendKeys(rows.get("columnName2"));
inputPage.buttonElement.click();
wait.until(ExpectedConditions(visibilityOf(successPage.successEle)));
successMessage = successPage.successEle.getText();
Assert.assertEquals(expectedSuccessMessage, successMessage);
}
Page object file look something like this
public class SuccessPage {
WebDriver driver;
public SuccessPage(WebDriver driver){
this.driver = driver;
}
@FindBy("someLogicalName")
public WebElement someElement;
So roughly about 8 out of 10 times the above code works correctly, but those two other times it throws that NoSuchElementException at successMessage = successEle.getText();
What I've been told I should do instead is something like the following
SuccessPage successPage;
for(....
...
//create a wrapper clickSubmitBtn() method that returns the page object.
successPage = inputPage.clickSubmitBtn(driver); //this will instantiate the page object.
successMessage = successpage.successEle.getText();
... }
So,
- will this really solve the problem?
- is that a good programming practice, should instantiation be done once before the loop?
this.driver = driver
you should call the pagefactory, and I do mine this way:PageFactory.initElements(new AjaxElementLocatorFactory(driver, 15), this);
which gives an implicit wait for elements of 15 seconds.