I have a selenium java function below where i am reading file from excel
Requirement- if my code fails for particular row due to some error message on page, then my should go to next row but iteration do not stop
for (int i = 0; i <rowcount-2; i++) {
wait.ignoring(StaleElementReferenceException.class).until(ExpectedConditions.visibilityOfElementLocated(By
.id("_FOpt1:_FOr1:0:_FOSritemNode_procurement_supplier_qualification:0:_FOTsditasksId::icon")));
WebElement task = driver
.findElement(By
.id("_FOpt1:_FOr1:0:_FOSritemNode_procurement_supplier_qualification:0:_FOTsditasksId::icon"));
WebElement menu;
boolean menuVisible = false;
while (!menuVisible) {
task.click();
wait.ignoring(StaleElementReferenceException.class).until(ExpectedConditions.visibilityOfElementLocated(By
.id("_FOpt1:_FOr1:0:_FOSritemNode_procurement_supplier_qualification:0:_FOTRaT:0:RAtl1")));
menu = driver
.findElement(By
.id("_FOpt1:_FOr1:0:_FOSritemNode_procurement_supplier_qualification:0:_FOTRaT:0:RAtl1"));
if (menu.isDisplayed()) {
menuVisible = true;
}
}
wait.ignoring(StaleElementReferenceException.class).until(ExpectedConditions.visibilityOfElementLocated(By
.id("_FOpt1:_FOr1:0:_FOSritemNode_procurement_supplier_qualification:0:_FOTRaT:0:RAtl1")));
driver.findElement(
By.id("_FOpt1:_FOr1:0:_FOSritemNode_procurement_supplier_qualification:0:_FOTRaT:0:RAtl1"))
.click();
}
if it fails inside the loop, it should not stop execution and move to next iteration value
if it fails for i=1, then it should move to i=2
use try catch block to control the exception case.
for example:
for (...){
try {
//read excel
//if failed then continue
} catch (FailedToReadException e) {
continue;
}
}
Related
Am having an issue where I need to perform a click using Selenium Java on the link "PrestaShop" shown below. It's in an IFrame and my code is also below the picture.
Link to be clicked
When inspect the link using FireBug, it shows like below
Inspect using FireBug
And below is my code
try {
List<WebElement> frames = getAllFrames();
for (int i = 0; i < frames.size(); i++) {
WebElement frame = frames.get(i);
driver.switchTo().frame(frame);
if (driver.findElement(By.xpath(".//*[#classname='_1drp _5lv6']/a")).getSize() != null) {
driver.findElement(By.className(".//*[#classname='_1drp _5lv6']/a")).click();
} else {
driver.switchTo().defaultContent();
}
}
} catch (NoSuchElementException ex) {
System.out.println(ex.getMessage());
}
The code is getting all frames on the page and verify if the link "PrestaShop" is presence on the frame. If yes then it needs to fire a click on the link. Now, instead it returns error message - Unable to locate element: .//*[#classname='_1drp _5lv6']/a
Can please help to advise how can I fire the click successfully on the link?
While checking the presence of element, try using findElements instead of findElement. Below code might give you some idea.
List<WebElement> frames = getAllFrames();
for (int i = 0; i < frames.size(); i++) {
WebElement frame = frames.get(i);
driver.switchTo().frame(frame);
//use driver.findElements
if (driver.findElements(By.xpath(".//*[#classname='_1drp _5lv6']/a")).getSize() != null) {
driver.findElement(By.xpath("//*[contains(text(),'PrestaShop')]")).click();
} else {
driver.switchTo().defaultContent();
}
}
} catch (NoSuchElementException ex) {
System.out.println(ex.getMessage());
}
Hope this helps you. Thanks.
You can use following updated code:
List<WebElement> frames = getAllFrames();
for (int i = 0; i < frames.size(); i++) {
WebElement frame = frames.get(i);
driver.switchTo().frame(frame);
if (driver.findElement(By.xpath("//*[contains(text(),'PrestaShop')]")).getSize() != null) {
driver.findElement(By.xpath("//*[contains(text(),'PrestaShop')]")).click();
} else {
driver.switchTo().defaultContent();
}
}
} catch (NoSuchElementException ex) {
System.out.println(ex.getMessage());
}
Hope it will work for you.
thanks for your comment. I realized its because of the FB link was loaded too slow and hence the code fails. It's able to click now with below code if I added a Thread.sleep(30000) there.
if (driver.findElements(By.xpath(".//*[#class='lfloat']/div/a")).size() > 0) {
System.out.println("Found elements.");
driver.findElement(By.xpath("//*[contains(text(),'PrestaShop')]")).click();
} else {
System.out.println("Element not found.");
driver.switchTo().defaultContent();
}
However, if I want a FluentWait, then below code will just stop if the condition was not met
if (wait.ignoring(StaleElementReferenceException.class).ignoring(TimeoutException.class)
.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(".//*[#class='lfloat']/div/a")))
.isDisplayed()) {
System.out.println("Found elements.");
driver.findElement(By.xpath("//*[contains(text(),'PrestaShop')]")).click();
} else {
System.out.println("Element not found.");
driver.switchTo().defaultContent();
}
It just return message Expected condition failed: waiting for visibility of element located by By.xpath: .//*[#class='lfloat']/div/a (tried for 30 second(s) with 500 MILLISECONDS interval) and then not continue the loop. Can I know what's the way to make the code to continue even if the condition was not met?
I saw one os the posts before regarding stale element exception and used the retry code for handling it. But inspite of keeping the count at 20 , stale element exception still persists. I can see that the element2 is loaded in the webpage being tested .But its still id'd as stale element. The code works in case of element1 sometimes. but never for element2
code:
for (i = 1; i < 7; i++)
{
sServiceID = ExcelUtils.getCellData(i,Constant.Col_ServiceID);
System.out.println("sServiceID:"+sServiceID);
ServiceID_Filter().clear();//function returns element
ServiceID_Filter().sendKeys(sServiceID);
BaseClass.driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);
Thread.sleep(3000);
ApplyFilters_element().click();
Thread.sleep(3000);
boolean result = false;
int attempts = 0;
while(attempts < 20) {
System.out.println("inside stale check loop");
BaseClass.driver.manage().timeouts().implicitlyWait(20,TimeUnit.SECONDS);
try {
if(element1.isDisplayed()||element2.isDisplayed()) //either one of the elements will be loaded
{
System.out.println("not stale "+Table_widget.ExportButton().isDisplayed());
result = true;
break;
}
} catch(StaleElementReferenceException e) {
System.out.println("stale at attempt "+attempts);
}
attempts++;
}
if(result==true)
{
if(element1.isDisplayed())
{
element3.click();
System.out.println(" button clicked");
Thread.sleep(1000);
}
else
if(element2.isDisplayed())
{ element3.click();
System.out.println("No records found");
Thread.sleep(1000);
}
}
}
In my humble opinion the problem is here:
BaseClass.driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);
Thread.sleep(3000);
ApplyFilters_element().click();
Thread.sleep(3000);
First of all you are using implicit wait plus thread sleep which is a recipe for disaster. This is what is causing your stale elements exceptions, try something like this below:
public boolean waitForElement(String elementXpath, int timeOut) {
try{
WebDriverWait wait = new WebDriverWait(driver, timeOut);
boolean elementPresent=wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(elementXpath)).isDisplayed());
System.out.printf("%nElement is present [T/F]..? ")+elementPresent;
}
catch(TimeoutException e1){e1.printStackTrace();elementPresent=false;}
return elementPresent;
}
Best of luck!
I have a If Else block within a while block. If element is present, click it to remove it and put it back to parent list. Else if element is not in the list then select from parent list and put it back.
The first time it works. It sees that the element is present, clicks it to removes it. On the second pass it fails when checking for the element
I tried with FindElement.IsDisplayed and !=null.
I get this exception :
org.openqa.selenium.NoSuchElementException: Unable to find element with css selector == select[id="idSelSelectedLanes"]>option[value="9012"] (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 30.16 seconds
What am I missing?
This is my first post here so apologize for any formatting issues.
thanks
count ++;
if(count % 2 == 0){
if(BROWSER.equals("IE")) {
// check if 9012 is present
if(driver.findElement(By.cssSelector("select[id=\"idSelSelectedLanes\"]>option[value=\"9012\"]"))!=null){
try {
// since its present, click to remove
driver.findElement(By.cssSelector("select[id=\"idSelSelectedLanes\"]>option[value=\"9012\"]")).click();;
Thread.sleep(1000);
} catch(NoSuchElementException e) {
System.out.println("Couldn't remove 9012");
}
} else {
try {
//Not present, so select from Available Lanes
driver.findElement(By.cssSelector("select[id=\"idSelAvailableLanes\"]>option[value=\"9012\"]")).isDisplayed();
} catch (NoSuchElementException e) {
System.out.println("Couldn't add 9012");
}
}
}
}
You need to put driver.findElement(...) in a try-catch block
count ++;
WebElement e;
if(count % 2 == 0) {
if(BROWSER.equals("IE")) {
// check if 9012 is present
try {
e = driver.findElement(By.cssSelector("select[id=\"idSelSelectedLanes\"]>option[value=\"9012\"]"));
Thread.sleep(1000);
e.click()
} catch (NoSuchElementException e) {
System.out.println("Couldn't remove 9012");
// the else part goes here
}
}
}
Another approach is to use findElements instead of findElement to avoid the try-catch, and use .get(0) to get the element you want.
Another solution, you should check elementExist first using findElements, if it exists -> perform other actions
count ++;
WebElement e;
String e9012Css = "select[id=\"idSelSelectedLanes\"]>option[value=\"9012\"]";
if(count % 2 == 0) {
if(BROWSER.equals("IE")) {
// check if 9012 is present
e9012Existed = driver.findElements(By.cssSelector(e9012Css)).size() > 0;
if(e9012Existed) {
driver.findElement(By.cssSelector(e9012Css)).Click();
}
}
else {
System.out.println("Couldn't remove 9012");
}
}
try to use isElementPresent
if(isElementPresent(By.cssSelector("select[id=\"idSelSelectedLanes\"]>option[value=\"9012\"]"))){
// since its present, click to remove
} else {
//Not present, so select from Available Lanes
}
I create test cases in Eclipse IDE using JAVA with some Selenium scripts.
My Problem is that sometimes, Continuous Run of Test Cases produce error/failed test in the selenium.waitForPageToLoad("30000") method. I made a solution that the method will loop until a specific condition is met so I came to this code. BUT THIS DOESN'T WORK.
This what happens: Run Junit Test > #Test1,2,3..n > page does not load # Test n > execute next line code > failed test in #Test n > because Page does not load so the next scripts cannot be done (missing required elements in the page because it doesn't load).
This what SUPPOSED to happen:Run Junit Test > #Test1,2,3..n > page does not load # Test n > wait for page to load until Specific condition is met (ex. Element X is already present in the page)> execute next line code > passed test in #Test n
I need a Solution that wait the Page to load until the element required for the next lines of scripts is present.
THIS CODE DOESN'T WORK. I badly need your help. Thanks
//Wait for Page to Load until Expected Element is not Present
public void waitForPageToLoadElement(final String isElementPresent){
boolean elementBoolean;
do{
selenium.waitForPageToLoad("30000");
elementBoolean = selenium.isElementPresent(isElementPresent);
if (elementBoolean==false){
try{Thread.sleep(3000);}
catch (Exception e) {
//catch
}}
}
while(elementBoolean==false);
}
//Wait for Page to Load until Expected Text is not Present
public void waitForPageToLoadText(String isTextPresent){
boolean elementBoolean;
do{
selenium.waitForPageToLoad("30000");
elementBoolean = selenium.isTextPresent(isTextPresent);
if (elementBoolean==false){
try{Thread.sleep(3000);}
catch (Exception e) {
//catch
}}
}
while(elementBoolean==false);
}
//Opens url until Expected Element is not Present
public void openUrl(String url){
boolean userNameBoolean, passwordBoolean;
do {
selenium.open(url);
userNameBoolean = selenium.isElementPresent("id=loginForm:username");
passwordBoolean = selenium.isElementPresent("id=loginForm:password");
if (userNameBoolean==false && passwordBoolean==false){
try{Thread.sleep(3000);}
catch (Exception e) {
//catch
}}
}while (userNameBoolean==false && passwordBoolean==false);
}
This type of logic might be helpful for you
public static void waitforElement(Selenium selenium,String element)
{
try
{
int second;
for (second = 0; ; second++)
{
if (selenium.isElementPresent(element))
{
break;
}
if (second >= 20)
{
break;
}
Thread.sleep(1000);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
Before doing any operation with any element just call this method for that element so that it will wait for that element until timeout reached (i.e., 20sec) if that element is not found.
Example
waitforElement(selenium,"id=loginForm:username");
selenium.type("id=loginForm:username","username");
waitforElement(selenium,"id=loginForm:password");
selenium.type("id=loginForm:password","password");
selenium.click("submit");
I've been testing an application involving multiple ajax calls, so I required wait condition so that elements are present/visible once the ajax call is made. I used both methods implicitwait and explicitwait but none of them seem to be working for me as one or the other exceptions are generated as follows:
1.Unable to locate element
2.Element is disabled and so may not be used for actions
Implicit wait used as follows:
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
WebElement we = driver.findElement(By.name("q"));
PROBLEM:
When I test this code, after browser opens, it throws exception in 2 seconds.
Result:Exception generated
Explicit Wait
WebDriverWait wait = new WebDriverWait(driver, /*seconds=*/3);
WebElement element = wait.until(presenceOfElementLocated(By.name("q"));
PROBLEM:
When I test this code, after browser opens, it throws exception in 2 seconds
Result:Exception generated.
Also used visibilityOfElementLocated but it does not work for me.
Has anybody faced this issue or anybody has a solution for this??
I can't say that I have faced that issue before but I also wrote my own custom DOM polling class. Here's what I do.
private int Timer = 180;
private bool CheckForElement(WebDriver driver,string byType,string selector)
{
bool elementFound = false;
for (int i = Timer - 1; i > 0; i--)
{
if (!itemFound)
{
Thread.Sleep(1000); //sets the loop to check every second this can be done at a much faster or slower rate depending on your preferences
if (byType.ToLower() == "id")
{
try{
WebDriver element = driver.FindElement(By.Id(selector);
if(element.Displayed)
{
elementFound = true;
}
}
catch {
//Do Nothing Here as we don't need to handle the exception
}
}
else if (byType.ToLower() == "tagname")
{
try{
WebDriver element = driver.FindElement(By.TagName(selector);
if(element.Displayed)
{
elementFound = true;
}
}
catch {
//Do Nothing Here as we don't need to handle the exception
}
}
else if (byType.ToLower() == "cssselector")
{
try{
WebDriver element = driver.FindElement(By.cssSelector(selector);
if(element.Displayed)
{
elementFound = true;
}
}
catch {
//Do Nothing Here as we don't need to handle the exception
}
}
else if (byType.ToLower() == "classname")
{
try{
WebDriver element = driver.FindElement(By.ClassName(selector);
if(element.Displayed)
{
elementFound = true;
}
}
catch {
//Do Nothing Here as we don't need to handle the exception
}
}
}
else
{
i = 0; //stops the loop when the element is found
}
}
return elementFound ;
}