Java Selenium: How to validate xpath? - java

I am trying to find an element using xpath.
I tried this method:
if(a_chromeWebdriver.findElement(By.xpath(XPATH1)) != null){
homeTable = a_chromeWebdriver.findElement(By.xpath(XPATH1));
}
else{
homeTable = a_chromeWebdriver.findElement(By.xpath(XPATH2));
}
I assumed that if the first xpath won't be found, it will try he second one. But it throws an exception of element not found.
I also tried to check size = 0 instead of null, but got the same result.

You can use this method to check whether your xpath is present or not :
create a method : isElementPresent
public boolean isElementPresent(By by) {
try {
driver.findElements(by);
return true;
} catch (org.openqa.selenium.NoSuchElementException e) {
return false;
}
}
Call it using xpath like this :
isElementPresent(By.xpath(XPATH1));
So your code would become :
if(isElementPresent(By.xpath(XPATH1))){
homeTable = a_chromeWebdriver.findElement(By.xpath(XPATH1));
}
else{
homeTable = a_chromeWebdriver.findElement(By.xpath(XPATH2));
}

You could use findElements instead of findElement and then check the size:
List<WebElement> elements = a_chromeWebdriver.findElements(By.xpath(XPATH1));
if(elements.size() > 0){
homeTable = elements.get(0);
} else{
homeTable = a_chromeWebdriver.findElement(By.xpath(XPATH2));
}
But a better way would be to combine the 2 XPath in a single one with |:
homeTable = a_chromeWebdriver.findElement(By.xpath(XPATH1 + "|" + XPATH2));

You could create a method,
public WebElement getElement(By by) {
try {
return a_chromeWebdriver.findElement(by);
} catch (org.openqa.selenium.NoSuchElementException e) {
return null;
}
}
You could use it as follows,
WebElement element = getElement(By.xpath(XPATH1));
if (element == null)
element = getElement(By.xpath(XPATH2));

First add implicit wait to your code that will handle synchronization issues
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
Add OR Operator rather than adding condition as other answers points out. homeTable = a_chromeWebdriver.findElement(By.xpath(XPATH1 | XPATH2));

Related

How to find an item by index in iOS Appium Selenium?

I have this piece of code that used to help me to find an element by the index, with Android I have no problem, but my problem is with iOS because since "IosUIAutomation" was deprecated I can't find how to replace it.
This is my code:
private void SelectByIndex(LocatorTypesEnum locatorType, String locator, String index, String condition,
int timeoutForWaitCondition) {
try {
element = getElement(locator, locatorType, condition, timeoutForWaitCondition);
System.out.println("Element: "+element);
MobileElement listItem = null;
if (os_name.equalsIgnoreCase("Android")){
listItem = element.findElement(
MobileBy.AndroidUIAutomator("new UiSelector().index(" + Integer.parseInt(index) + ")"));
} else if (os_name.equalsIgnoreCase("ios")) {
/*listItem = element.findElement(
MobileBy.IosUIAutomation("new UiSelector().index(" + Integer.parseInt(index) + ")"));*/
//This is the part I need to replace
}
assertNotNull(listItem.getLocation());
ar = this.setActionResultValues(ar, _takeScreenshotToStep, "", true, false, null);
listItem.click();
} catch (Exception e) {
...
}
}
I am new to this topic, please if anyone can help me, I will be very grateful.
I tried to use "iOSNsPredicateString" but it didn't work either because it doesn't find the element for the given index.
else if (os_name.equalsIgnoreCase("ios")) {
listItem = element.findElement (MobileBy.iOSNsPredicateString ("new UiSelector().index(" + Integer.parseInt(index) + ")"));
}

NoSuchElementException with isDisplayed() method within try catch block in Selenium

i want to check negative condition.
above boolean element is not displayed ,but i have to print true and false but it shows no such element exception
please help.
try{
boolean k= driver.findElement(By.xpath("xpath_of_element")).isDisplayed();
if(!k==true)
{
System.out.println("true12");
}
}catch (NoSuchElementException e) {
System.out.println(e);
}
There are two distinct stages of an element as follows:
Element present within the HTML DOM
Element visible i.e. displayed within the DOM Tree
As you are seeing NoSuchElementException which essentially indicates that the element is not present within the Viewport and in all possible conditions isDisplayed() method will return false. So to validate both the conditions you can use the following solution:
try{
if(driver.findElement(By.xpath("xpath_of_the_desired_element")).isDisplayed())
System.out.println("Element is present and displayed");
else
System.out.println("Element is present but not displayed");
}catch (NoSuchElementException e) {
System.out.println("Element is not present, hence not displayed as well");
}
You should use the below code which will validate if at least one or more than one elements are present or not for the given xpath, before checking for the display status of the element.
List<WebElement> targetElement = driver.findElements(By.xpath("xpath_your_expected_element"));
try {
if(targetElement>=1) {
if(targetElement.isDisplayed()) {
System.out.println("Element is present");
}
else {
System.out.println("Element is found, but hidden on the page");
}
else {
System.out.println("Element not found on the page");
}
}catch (NoSuchElementException e) {
System.out.println("Exception in finding the element:" + e.getMessage());
}
if (driver.findElements(xpath_of_element).size() != 0) return true;
return false;

How to make control on Foreach loop while executing it with Selenium driver?

I try to retrieve text via foreach loop,as according to page wise. Flow is : It prints text of single row and as soon as it completes, it goes to second page and start again to retrieve text. Problem is, it retrieves data of first page multiple times like sometimes 2 or 3 or 4 times, How to control it for single time execution ?
if (driver.findElement(By.xpath("//button[#ng-click='currentPage=currentPage+1']")).isEnabled()) {
int ilength = driver.findElements(By.xpath("//input[#ng-attr-id='{{item.attr}}']")).size();
Outer: for (int i1 = ilength; i1 > 0;) {
List<WebElement> findData = driver.findElements(By.xpath("//input[#ng-attr-id='{{item.attr}}']"));
for (WebElement webElement : findData) {
String printGroupName = webElement.getAttribute("value").toString();
System.out.println(printGroupName);
ilength--;
}
if (driver.findElement(By.xpath("//button[#ng-click='currentPage=currentPage+1']")).isEnabled()) {
action.moveToElement(driver.findElement(By.xpath("//button[#ng-click='currentPage=currentPage+1']"))).click().perform();
page.pagecallingUtility();
ilength = driver.findElements(By.xpath("//input[#ng-attr-id='{{item.attr}}']")).size();
} else {
break Outer;
}
}
} else {
List<WebElement> findAllGroupName = driver.findElements(By.xpath("//input[#ng-attr-id='{{item.attr}}']"));
for (WebElement webElement : findAllGroupName) {
String printGroupName = webElement.getAttribute("value").toString();
System.out.println(printGroupName);
}
}
Console Data, on which it retrieve information
Your loop can be simplified as below.
boolean newPageOpened = true;
while (newPageOpened) {
List<WebElement> findData = driver.findElements(By.xpath("//input[#ng-attr-id='{{item.attr}}']"));
for (WebElement webElement : findData) {
if (webElement.isDisplayed()) {
String printGroupName = webElement.getAttribute("value").toString();
System.out.println(printGroupName);
}
}
WebElement nextButton = driver.findElement(By.xpath("//button[#ng-click='currentPage=currentPage+1']"));
if (nextButton.isEnabled()) {
action.moveToElement(nextButton).click().perform();
page.pagecallingUtility();
} else {
newPageOpened = false;
}
}
As for the contents of the fist page printing again and again, I suspect when you open the second page the contents of the first page are simply hidden in the page. So when you use driver.findElements(By.xpath("//input[#ng-attr-id='{{item.attr}}']")) the hidden first page elements are also found. The simple solution is to check if the element is displayed before printing it.

Change method findByOneCss that he received more than one meaning and all

This is the method itself
private static WebElement findByOneCss (WebElement we, String selector) {
try {
return we.findElement (By.cssSelector (selector));
} catch (NoSuchElementException e) {
return null;
}
}
I understand that you need to change to findElement findElements but do not get to take account of all the views.
I have a loop that bypasses the values ​​here he
for (WebElement wle: wlElements) {
WebElement commenWe = findByOneCss (wle, ".activity-new-val");
wl.setReason1 (commenWe! = null? commenWe.getText (): "");
wlList.add (wl);
}
What does it need to change, I tried to like this
List <WebElement> commenWe = findAllByOneCss (wle, ".activity-old-val");
wl.setReason (commenWe! = null? ((WebElement) commenWe) .getText (): "");
wlList.add (wl);
But it beats mistake java.util.ArrayList can not be cast to org.openqa.selenium.WebElement
Depending on what type wlList is you could use: wlList.addAll(commenWe);
Or you iterate over commenWe like this:
List<WebElement> commenWe = findAllByOneCss(wle, ".activity-old-val");
for (WebElement we : commenWe) {
//whatever [wl] is...
wl.setReason(we!=null ? ((WebElement) we).getText(): "");
wlList.add(wl);
}

Selenium WebDriver with Java - how to add "else" condition

I have code:
public void setList(By localizator, String v_value {
Select some_list = new Select(driver.findElement(localizator));
for(WebElement position_list : some_list.getOptions()) {
if(position_list.getText().equalsIgnoreCase(v_value)) {
some_list.selectByVisibleText(position_list.getText());
break;
}
}
}
How can I add condition: if selenium doesn't find position_list.getText().equalsIgnoreCase(v_value) then system throw new RuntimeExpression?
Use iterator instead of foreach, it provides a hasNext() method with which you can check if you are currently dealing with the last element of your list.
Iterator<WebElement> iterator = some_list.getOptions().iterator();
and then instead of your foreach:
while(iterator.hasNext()) {
WebElement current = iterator.next();
if(current.getText().equalsIgnoreCase(v_value)) {
current.selectByVisibleText(position_list.getText());
break;
}
if(!iterator.hasNext()){
throw new RuntimeException();
}
}
Just a suggestion from what I see in your code.
When you use some_list.selectByVisibleText(position_list.getText()); the selectByVisibleText(..) method is already setup to iterate over all available options and select the one that matches the text parameter you pass in. Putting the call inside a loop checking for the option to be available is not ideal if you are looking to throw an exception.
Also, let's say you have the following code -
public void setList(By localizator, String v_value {
Select some_list = new Select(driver.findElement(localizator));
some_list.selectByVisibleText(position_list.getText());
....
}
In this case selectByVisibleText would throw a NoSuchElementException("Cannot locate element with text: " + text); in case the option is not available for selection. You should be able to catch that and throw a runtime exception.
I guess a simple answer to your question is a try catch
public void setList(By localizator, String v_value {
Select some_list = new Select(driver.findElement(localizator));
for(WebElement position_list : some_list.getOptions()) {
try{
if(position_list.getText().equalsIgnoreCase(v_value)) {
some_list.selectByVisibleText(position_list.getText());
break;
}
}
catch(RuntimeExpression ex)
{
...
}
}
}

Categories