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

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;

Related

org.springframework.dao.EmptyResultDataAccessException -->Help me fix this

public String deleteCounterParty(List<CounterParty>counterParties)
{
String message = "";
for(CounterParty counterParty:counterParties) {
if (counterParty.getId() != null && counterPartyRepository.getById(counterParty.getId()) != null) {
counterPartyRepository.deleteById(counterParty.getId());
message="deleted successfully";
}
else {
message="id not found";
}
}
return message;
}
I'm using this method to delete rows by giving list of ids if the given id is found it is deleted,if not it throws this EmptyResultDataAccessException help me fix this
Data access exception thrown when a result was expected to have at least one row (or element) but zero rows (or elements) were actually returned.
Use a try-catch block to catch the exception if thrown and alter your logic accordingly so that when the code follows a happy path, at least one row is returned.
try { //code to delete rows } catch(final
EmptyResultDataAccessException e) { //exception message }

How to break out of a while loop with a nested forEach loop?

I have written a code which has a forEach loop and a while loop, and i am trying to make repeated requests until condition is satisfied using while loop. However, I am unable to break out of the while loop, as it gives the error "Break outside switch or loop". Also how can i go to the next user iteration in the forEach loop.
My code:
while(count>0){
usersClient.getUserUUIDList().forEach(user -> {
try{
LOG.info("USER STATUS for user {}",user.getId().toString());
Optional<ExternalUserStatus> userStatus= adminClientFactory.newUssClient().getStatusForUser(orgId, Constants.IMP_ENTITLEMENT,user.getId().toString());
System.out.println(userStatus.toString());
if(userStatus.isPresent()&&(userStatus.get().getState()=="activated")){
//break;
//continue;
}
}
catch(Exception ex){
LOG.info("Exception caught while getting userStatus");
}
});
count--;
Thread.sleep(1000 * 60 *1);
}
Instead of break or continue (which won't work as they're in the lambda block), set count to zero:
count = 0;
If you need the value of count after you exit the loop, use a boolean as an exit condition:
boolean done = false;
while(count>0){
for (UUID user : usersClient.getUserUUIDList()){
try{
LOG.info("USER STATUS for user {}",user.getId().toString());
Optional<ExternalUserStatus> userStatus=adminClientFactory.newUssClient().getStatusForUser(orgId,Constants.IMP_ENTITLEMENT,user.getId().toString());
System.out.println(userStatus.toString());
done = (userStatus.isPresent() && (userStatus.get().getState()=="activated"))
}
catch(Exception ex){
LOG.info("Exception caught while getting userStatus");
}
});
count--;
if (done) break;
Thread.sleep(1000*60*1);
}
From Bill Horvath's answer,
done = (userStatus.isPresent() && (userStatus.get().getState()=="activated"))
done always takes the result of last user from usersClient.getUserUUIDList()
So better we can use one more break if activated.
Add at the end of for loop
if(done)
break;
Finally:
boolean done = false;
while(count>0){
for (UUID user : usersClient.getUserUUIDList()){
try{
LOG.info("USER STATUS for user {}",user.getId().toString());
Optional<ExternalUserStatus> userStatus=adminClientFactory.newUssClient().getStatusForUser(orgId,Constants.IMP_ENTITLEMENT,user.getId().toString());
System.out.println(userStatus.toString());
done = (userStatus.isPresent() && (userStatus.get().getState()=="activated"))
if(done) break;//Add this
}
catch(Exception ex){
LOG.info("Exception caught while getting userStatus");
}
});
count--;
if (done) break;
Thread.sleep(1000*60*1);
}

WebDriverException while waiting for visibility

Since last week I got stuck in a problem that can't resolve it.
I have an ear project containing an EJB project and a WAR project that worked fine before.
When I execute my project first i get the login page, authenticate and get my home page.
But when I want to write in an input, i tell him to wait until the element is visible but it throws a WebDriverEception :
Can't send keys to the element com.sun.proxy.$Proxy23 Expected condition failed: waiting for visibility of [[ChromeDriver: chrome on XP (508d2b6115709e937cfa289fdb0a438b)] -> xpath: //div[#class='form-control browse__browse-name-display___2s17-']/following-sibling::input[#type='file']] (tried for 20 second(s) with 500 milliseconds interval)
The problem here is that I have an old project with the same files and when I execute it through main class, it works fine but when i want to run it with Junit, i get this exception.
This is my Code :
public void sendKeyOnElement(WebElement element, String string) {
try {
if (new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOf(element)) != null) {
System.out.println("d5allll");
if (element.getText().equals(""))
element.sendKeys(string);
else {
System.out.println("d5al louta");
element.clear();
element.sendKeys(string);
}
} else {
System.out.println("Can't send keys element not visible ");
}
} catch (ElementNotVisibleException v) {
System.out.println("Element Not Visible");
} catch (WebDriverException e) {
System.out.println("Can't send keys to the element " + element.getClass().getName() + " " + e.getMessage());
}
}
After modifying my code it appears to be a Timeout Exception but the problem is that the element exists and returns its tagName and shows that the element is enabled
public boolean waitVisibilityOfElement(WebElement element) {
try {
System.out.println("Waiting visibility of element : " + element.getTagName());
if (element.isEnabled())
System.out.println("Element " + element.getTagName() + " is enabled");
else
System.out.println("Element " + element.getTagName() + " is not enabled");
fluentWait.until(ExpectedConditions.visibilityOf(element));
return true;
} catch (TimeoutException e) {
System.out.println("Time out for visibility");
return false;
} catch (ElementNotVisibleException v) {
System.out.println("Element Not Visible");
return false;
} catch (NoSuchElementException u) {
System.out.println("Element does not exist");
return false;
}
}
public void sendKeyOnElement(WebElement element, String string) {
try {
if (waitVisibilityOfElement(element)) {
System.out.println("d5allll");
if (element.getText().equals(""))
element.sendKeys(string);
else {
System.out.println("d5al louta");
element.clear();
element.sendKeys(string);
}
} else {
System.out.println("Can't send keys element not visible ");
}
} catch (ElementNotVisibleException v) {
System.out.println("Element Not Visible");
} catch (WebDriverException e) {
System.out.println("Can't send keys to the element " + element.getClass().getName() + " " + e.getMessage());
}
I can't show my Html because it is confidential but i can only show the div and input elements :
<div class="form-control browse__browse-name-display___2s17-"> </div>
<input type="file" style="display:none">
I found the solution.
I don't know if it is normal with selenium, but by default the input which its type is file can't be displayed although it is displayed in Web Browser, The method isEnabled() returns true and isDisplayed() returns false so the wait until will wait, and at the end will throws a Timeout Exception and The most funny thing is even for selenium it is not displayed you can send keys in the input which is not logic.

Java Selenium: How to validate xpath?

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));

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