Using Assert containing wildcards (Selenium Webdriver) - java

I'm trying to use webdriver to check that something DOESN'T exist on the webpage (after it has been deleted by the user).
I'm using a try-catch method to handle the NoSuchElementException, but within the 'catch' I want to be able to assert that the NoSuchElementException contains the text "NoSuchElementException", and use wildcards for the rest of the exception (since other details within the exception change every time)
Here's what the bit of code looks like, as you can see I've tried to use a * as a wild card to indicate that nothing after the exception matters to me, I just want it to check that the exception is the correct one and pass the test based on that:
catch (NoSuchElementException e1)
{
Assert.assertEquals(e1, "org.openqa.selenium.NoSuchElementException: *");
}

You are catching NoSuchElementException and inside the catch block you are checking if it is a NoSuchElementException which does not add any value. You are testing if JDK works correctly.
To check if the element does not exist on page, you could use a method like this :
public boolean isElementPresent(By locatorKey) {
try {
driver.findElement(locatorKey);
return true;
} catch (org.openqa.selenium.NoSuchElementException e) {
return false;
}
}
You should then assert on the above method,
if element should not be present
Assert.assertFalse(isElementPresent(By.id("login")));
if element should be present
Assert.assertTrue(isElementPresent(By.id("login")));

I assume you are using TestNG assertions. If so, I would use contains to search for a partial match.
assertTrue(e1.getClass().toString.contains("org.openqa.selenium.NoSuchElementException:"));

Related

SonarQube rule "Methods returns should not be invariant" with catch block

I'm using latest SonarQube server 9.4 and it constantly reports "Refactor this method to not always return the same value." - java:S3516 in piece of code like this:
try
{
FileUtils.moveFile(dcomExportFile, destination);
}
catch(IOException e)
{
Logger.error(this, "Could not move file {} to {}, future job runs might fail as well",
dcomExportFile.getAbsolutePath(), destination.getAbsolutePath());
return false;
}
return true;
Which is very strange because method FileUtils.moveFile can throw IOException and in this case method returns false.
Any idea?
Thx!
I would move the return false statement to outside and after the catch (where return true is now). And move the return true to immediately follow the Fileutils call in the try block, like this:
try
{
FileUtils.moveFile(dcomExportFile, destination);
return true;
}
catch(IOException e)
{
Logger.error(this, "Could not move file {} to {}, future job runs might fail as well",
dcomExportFile.getAbsolutePath(), destination.getAbsolutePath());
}
return false;
It's confusing and arguably bad style to return from within a catch block anyway.
I'm not sure that in this case not letting the exception be thrown is a great idea because this seems like the sort of error I would want to bubble up, where having a return value lets it get lost too easily. Maybe it's not so bad if logging the error is the only thing the code does to handle this.
I think it may not be good idea to just catch & log exception & return false. You might need to throw exception back to caller of your method.
Good example which comes in my mind is list.add(..) where if operation is success it returns true but in case of any failure it throws exceptions to caller instead of returning false.
I found solution - scanning with correct sonar.java.libraries path resolves this issue.

Is there a point to handle exceptions in selenium besides for logging purposes?

I am finding it hard to understand the point of exception handling in selenium.
For example, if I try to click on an element, and the element could not be found then NoSuchElementException occurs.
I can catch the exception, throw new RunTimeException, or do nothing. The result will be the same ( the program will fail and stop ).
Why would I bother to handle such an exception?
Am I missing something here?
thanks
public void clickOnElement(MobileElement element, Integer waitInSeconds){
waitInSeconds = (waitInSeconds != null ? waitInSeconds : this.secondsToWait);
try {
waitFor(ExpectedConditions.elementToBeClickable(element),waitInSeconds);
element.click();
} catch (Exception e) {
System.out.println("Could not click on element");
e.printStackTrace();
}
}
Exception handling for Selenium is a great way to proof your tests against unexpected conditions. For example, you can try to find the element again if it is no longer attached to the page, for example after a javascript is executed that changes something in the element.
try{
driver.findElement(By.id("MyId")).click();
} catch (StaleElementReferenceException e){
driver.findElement(By.id("MyId")).click();
}
Or, for example, you can ignore if an element does not appear, for example, a GDPR overlay at the top of the page after logging in.
try {
wait.until(ExpectedConditions.presenceOfElementLocated(By.id("gdpr_overlay")));
} catch (TimeoutException ignored){
}
This will ignore the exception thrown by the wait if the overlay does not appear and continue to run your test.
Exceptions are very useful features, far more useful than just for logging, you should look it up.
You can do whatever you want in the catch block, you can try to click a different element if the first one failed, redirect to another page... The possibilities are endless really.
Advice: Avoid generic exceptions, you should catch specific exceptions and react accordingly, and in the last catch block you can do generic Exception e and throw an error.
Firstly ExceptionHandling is not a concept of Selenium but it is related to JAVA. Now coming to the usage of handling exceptions it has a lot of depth to the concept which you will understand while constructing frameworks but as of now it is important to understand by handling exceptions you can continue to execute your code without JVM terminating the rest when it comes across an exception.
try{
}
catch{
}
finally
{
}
Finally is also very helpful when you always want to execute a block of code irrespective of whether ur scenario is going to pass or fail for example like driver.close().
Hope that helped ... Happy coding :)

Java - TestNG : Is It Wrong to use testng Assert.fail() in a catch block

I came across a code written by someone with Assert.fail("some text") in a catch block. This is my code:
try {
//WebDriver code here which interacts with WebElements
//When an exception occurs in this try block, it will be caught in
//the catch and further catch block has Assert.fail()
} catch (Exception e) {
Assert.fail("failed to click 'Webelement' ");
}
I somehow felt this is not right way to do it. Am i wrong?
Note: Not exactly a duplicate of Is Assert.Fail() considered bad practice , As i am not expecting any Exception. If any exception occurs i need to fail the test case
Though it's syntactically not incorrect. But you should preferably rephrase your tests to use expectedException instead and be specific about the exception is thrown as well. For e.g. :
If your method fromTest() when called with "test" as an argument could throw an NumberFormatException, then your test definition for such behaviour should be :
#Test(expectedExceptions = NumberFormatException.class)
public void testMethod() {
System.out.println("About to throw an exception!");
fromTest("test");
}
Note: If you believe that the exception may so happen within your test execution itself instead of any other method being called from it. I would suggest to not catch it. Let it fail and then you shall fix it.

Verify if a link is present or not

I'm trying to verify if a link is present or not -- but -- if it's not present, I want my script to continue executing (close the browser, etc).
The purpose of my script is to determine if a 'Delete Address' link is present or not. If it is, I click on the link and delete the address. This works fine. If the link is not present however, I just want to continue execution without triggering an exception. My code below triggers an exception if the link is not there.
Thanks for any help...
try {
String txt = driver.findElement(By.linkText("Delete Address")).getText().trim();
Assert.assertTrue(txt.equals("Delete Address"));
Alert javascriptprompt = driver.switchTo().alert();
javascriptprompt.accept();
} catch (NoSuchElementException e) {
}
I can see several options here
Do not use asserts in the test at all. In this case the test is marked as successful (if you caught exceptions)
If you want the lines after the findElement() call be executed you can
move all lines expect for findElement() out of the try {} clause
use the try {} catch {} finally {} construction and put to the finally {} clause all the code you want to be executed, no matter what happens in the try {}
If you want to avoid catching exception, you can create a listener class by implementing the interface ITestListener and in onTestFailure() obtain the exception using getThrowable()
String stackTraceString = Throwables.getStackTraceAsString(getCurrentTestResult().getThrowable());
Then, if the exception is NoSuchElementException then set test result to success
result.setStatus(ITestResult.SUCCESS);
setCurrentTestResult(result);
Another solution would be to use .findElements. It will return an empty collection, as opposed to throwing an exception, if there are no elements found with the given selector.

Exception handling in this scenario

Trying my hands on Java for the first time, please be kind. I have following code in a Web Controller where a service is called based on enclosed Switch-Case statement.
Issue I am facing is, if the service call throws an Exception, this exception gets shown on the JSP page. Basically the code never reaches the lines:
if(!statusFlag)
{
model.addAttribute("statusFlag", statusFlag);
return "myJspPage"
}
How do I make sure the executing goes to above lines, even though an exception is thrown in the WebService call at:
statusFlag = myWebService.getMeStatus();
Should I enclose the whole Switch Statement inside try-catch block?
Snippet:
#Controller
public String mySpringController() throws Exception
{
//rest of the controller code
switch ( condition )
{
case MAY :
statusFlag = myWebService.getMeStatus();
if(!statusFlag)
{
model.addAttribute("statusFlag", statusFlag);
return "myJspPage"
}
break;
case JUNE :
statusFlag = myWebService.getMeStatus();
if(!statusFlag)
{
model.addAttribute("statusFlag", statusFlag);
return "myJspPage"
}
break;
case JULY :
statusFlag = myWebService.getMeStatus();
if(!statusFlag)
{
model.addAttribute("statusFlag", statusFlag);
return "myJspPage"
}
break;
default:
//Do something by default.
}
return "myJspPage";
}
If that line is throwing an Exception it means that it is never returning, so statusFlag is still with its original value and the execution of that method has stopped. You need to surround it in a try - catch if you want to catch the Exception and do something about it.
I see you are using Spring. In Spring Controllers you can also have your own special methods which get invoked when an Exception occurs. Using the #ExceptionHandler annotation.
I don't see the purpose of your switch statement since each case does the same thing.
But basically you can put your webservice call in a try-catch block
try{
webservice.call();
}
catch (Exception e){
// handle the exception
}
finally{
//anything in here will be executed regardless if an exception is caught or not
}
You're writing Java in the style of C++, where you're returning error codes and then checking them to determine whether anything went wrong. There are a number of issues with this snippet, but the reason for the exception display is that you never catch the exception that's being thrown. Where you should put your try-catch block depends on what the exception means; if it's something that isn't specific to a particular month, then yes, enclose the entire switch statement to share the error handling.
As an aside, did you copy and paste your actual code, or did you try to retype an example? Those case blocks all look identical.

Categories