Display errors in JUnit failure trace - java

I use Selenium Web Driver in Eclipse with JUnit. I need create simple checking if some text exists on the page - if it is, than I need generate error. I want this error to be displayed in JUnit failure trace. This is my code:
public class Check {
#Rule
public ErrorCollector errCollector = new ErrorCollector();
#FindBy(tagName="body")
#CacheLookup
private WebElement titl;
#FindBy(partialLinkText="Exception")
#CacheLookup
private WebElement excep;
public void check_false(String t, String r) {
try {
String bodyText = titl.getText();
Assert.assertFalse("Exception found", bodyText.contains(t)); }
catch (AssertionError e) {
System.err.println(r + ": " + e.getMessage());
System.out.println(excep.getText());
errCollector.addError(e);
}
}
If I get error, it is displayed in Eclipse consol, but test if shown as without error in JUnit and no exception message is displayed. How can I make checking properly?

I use
AssertJUnit.assertFalse("Exception found", bodyText.contains(t));
It's from http://testng.org/doc/index.html
see http://testng.org/javadoc/org/testng/AssertJUnit.html
Within eclipse when my test fails, in the junit window I get the stackstrace. Have never tried collecting the errors. It would throw an
AssertionFailedError
if the test fails but if you catch it, I don't know if the stacktrace will be in the JUnit window.

This might not be quite what you're after, in which case ignore it, but you can simply fail it and supply an optional message as to why.
public void checkText(String actual, String expected){
try{
if(!expected.equals(actuals){
fail("Expected : [ " expected + " ] , actual [" + actual + "]"
}catch(SomeOtherException soe){
fail(soe.getMessage());
}
}

Related

Customized selenium Output

Am working on selenium Automation
I want to know the name of which elements is not found when test cases got failed instead of getting object not found with property By.id("Login")
am expecting output like Object not found LoginButton(Customized name which i will give in code) when test cases fails due to defect
public static void logonCustomerPortal() throws Exception{
Thread.sleep(5000);
driver.findElement(By.xpath("//a[#id='nav_login']/span")).click();
Thread.sleep(2000);
}
I am new to Automation. Can anyone please help me ?
try to use try catch like this :
public void urmethod(){
try {
//do your code
}catch (Exception e){
e.printStackTrace();
}
}
this will print details of your error, in other words, what kind of error, in which line it fails...etc

Attempting to execute Selenium IDE exported code and getting this runtime error: Exception in thread "main" java.lang.NoSuchMethodError: main

My end goal is to confirm that I have Java, Selenium WebDriver, and JUnit functioning such that I can run an automated test case utilizing these technologies.
What I have done so far:
installed Selenium IDE (v 2.8.0) for Firefox (v 34.0.5)
recorded a simple test case using Selenium IDE and added the test case to a test suite
in Selenium IDE exported the test case using the option: File->Export Test Case As...->Java / JUnit 4 / WebDriver
downloaded and installed JUnit 4 from: https://github.com/junit-team/junit/wiki/Download-and-Install (Plain-old jar method)
downloaded and installed Selenium client and WebDriver Java language binding (v 2.44.0) from: http://www.seleniumhq.org/download/
performed some slight modifications to the code generated in step 3 such as removing the package statement at the beginning
compiled the code with the following command (windows command prompt):
C:\docs\tech\code\myCode\java\testing\selenium\utest\practice>C:\java\jdk\bin\javac.exe -cp C:\docs\installs\programming\automation\test\xUnit\java\jUnit\junit\v4_12\junit-4.12.jar;C:\docs\installs\programming\automation\test\xUnit\java\jUnit\hamcrest\hamcrest-core-1.3.jar;C:\docs\installs\programming\automation\web\selenuim\webdriver\java\selenium-2.44.0\selenium-java-2.44.0.jar C:\docs\tech\code\myCode\java\testing\selenium\utest\practice\TestGooglePlayApp.java
this compiles with no warnings/errors
attempt to execute the code with the following command:
C:\docs\tech\code\myCode\java\testing\selenium\utest\practice>java -cp .;C:\docs\installs\programming\automation\test\xUnit\java\jUnit\junit\v4_12\junit-4.12.jar;C:\docs\installs\programming\automation\test\xUnit\java\jUnit\hamcrest\hamcrest-core-1.3.jar;C:\docs\installs\programming\automation\web\selenuim\webdriver\java\selenium-2.44.0\selenium-java-2.44.0.jar TestGooglePlayApp
Actual Result:
The output of this attempt is:
Exception in thread "main" java.lang.NoSuchMethodError: main
No other error/warning is given and no indication is given that the code begins to execute
Expected Result:
This is my first time interacting with these technologies so I'm learning as I go! However, based on the research I have done my expectation is that a local Selenium WebDriver instance will be initialized as a Firefox Driver. This Firefox Driver will be sent instructions by the Java code in order to carry out the steps in the test case. JUnit will then indicate somehow on the command line the Pass/Fail status of the test case.
The big assumption I have here is that the Selenium Server/Selenium RC is not required in this case since all I intend to do is execute a local Selenium WebDriver script. Furthermore, my hope is that this can be launched directly from the command-line independent of Eclipse, Maven, etc. I would like to be able to send the final Java class to a colleague and the only dependency for expected execution would be a working SDK of Java on the end machine.
What's Next?
I'm looking for advice on what I can do to get this code up and running under the restraints I have outlined. It may be that the code needs to be modified. It may be that my expectations need to be tempered down and it's just not possible to do everything I want directly from the command-line. It may be that I did not compile the code correctly or some library is missing. It may be that... okay you get the point!
Other Relevant Details:
OS = Windows 7 - 64 bit
Here is the contents of TestGoogleApp.java:
import java.util.regex.Pattern;
import java.util.concurrent.TimeUnit;
import org.junit.*;
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;
import org.openqa.selenium.*;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.Select;
public class TestGooglePlayApp {
private WebDriver driver;
private String baseUrl;
private boolean acceptNextAlert = true;
private StringBuffer verificationErrors = new StringBuffer();
#Before
public void setUp() throws Exception {
driver = new FirefoxDriver();
baseUrl = "https://www.google.com/";
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}
#Test
public void test000() throws Exception {
driver.get("http://www.google.com/");
// COMMENT: Assert the 'Apps' icon is present and then click on it
assertTrue(isElementPresent(By.cssSelector("a.gb_C.gb_Sa")));
driver.findElement(By.cssSelector("a.gb_C.gb_Sa")).click();
// COMMENT: Assert the 'Play' app is present and then click on the 'Play' app and wait for the expected contents to load
assertTrue(isElementPresent(By.cssSelector("#gb78 > span.gb_s")));
driver.findElement(By.cssSelector("#gb78 > span.gb_s")).click();
// COMMENT: Assert that the input element associated with search queries is present and then type 'Testing' in the input element associated with search queries
assertTrue(isElementPresent(By.id("gbqfq")));
driver.findElement(By.id("gbqfq")).clear();
driver.findElement(By.id("gbqfq")).sendKeys("Testing");
// COMMENT: Click on the 'Search' element to perform a query for the input query term previously entered and wait for the expected contents to load
driver.findElement(By.id("gbqfb")).click();
// COMMENT: Assert that the desired result is contained in the search results returned and then click on the desired search result and wait for the expected contents to load
for (int second = 0;; second++) {
if (second >= 60) fail("timeout");
try { if (isElementPresent(By.linkText("Software Testing Concepts"))) break; } catch (Exception e) {}
Thread.sleep(1000);
}
driver.findElement(By.linkText("Software Testing Concepts")).click();
for (int second = 0;; second++) {
if (second >= 60) fail("timeout");
try { if ("Software Testing Concepts - Android Apps on Google Play".equals(driver.getTitle())) break; } catch (Exception e) {}
Thread.sleep(1000);
}
// COMMENT: Assert that the page contains the expected content as follows: 1) title of app 2) user rating 3) number of users who have rated the app 4) format of text value of user rating (4.0) 5) format of text value for number of user who have rated the app (128)
for (int second = 0;; second++) {
if (second >= 60) fail("timeout");
try { if (isElementPresent(By.cssSelector("div.score"))) break; } catch (Exception e) {}
Thread.sleep(1000);
}
for (int second = 0;; second++) {
if (second >= 60) fail("timeout");
try { if (isElementPresent(By.cssSelector("span.reviews-num"))) break; } catch (Exception e) {}
Thread.sleep(1000);
}
try {
assertTrue(Pattern.compile("[0-9]\\.[0-9]").matcher(driver.findElement(By.cssSelector("div.score")).getText()).find());
} catch (Error e) {
verificationErrors.append(e.toString());
}
try {
assertTrue(Pattern.compile("[0-9]+").matcher(driver.findElement(By.cssSelector("span.reviews-num")).getText()).find());
} catch (Error e) {
verificationErrors.append(e.toString());
}
// COMMENT: store value for user rating and store value for number of users who have rated the app
String _currentUserRating = driver.findElement(By.cssSelector("div.score")).getText();
System.out.println(_currentUserRating);
String _numOfUserRatings = driver.findElement(By.cssSelector("span.reviews-num")).getText();
System.out.println(_numOfUserRatings + "HELLO");
}
#After
public void tearDown() throws Exception {
driver.quit();
String verificationErrorString = verificationErrors.toString();
if (!"".equals(verificationErrorString)) {
fail(verificationErrorString);
}
}
private boolean isElementPresent(By by) {
try {
driver.findElement(by);
return true;
} catch (NoSuchElementException e) {
return false;
}
}
private boolean isAlertPresent() {
try {
driver.switchTo().alert();
return true;
} catch (NoAlertPresentException e) {
return false;
}
}
private String closeAlertAndGetItsText() {
try {
Alert alert = driver.switchTo().alert();
String alertText = alert.getText();
if (acceptNextAlert) {
alert.accept();
} else {
alert.dismiss();
}
return alertText;
} finally {
acceptNextAlert = true;
}
}
}

TestNG reporter not logging for exceptions

Hey guys I am trying to customize the output of my selenium framework using testNG. Right now I have an 'action' class which is wrapping all the selenium methods and I am wraping those up in try catches. Here's an example. (I am manually throwing the exception for testing purposes.)
public void closeBrowser(){
try{
driver.quit();
throw new WebDriverException();
}
catch(Exception e){
ExceptionHandler exception = new ExceptionHandler(e, null);
}
}
My exception handler class looks like this:
public ExceptionHandler(Exception exceptionName, String element){
this.exceptionName = exceptionName;
this.element = element;
report();
}
public void report(){
String delims = "[.]";
String[] tokens = exceptionName.getClass().toString().split(delims);
System.out.println(tokens[tokens.length-1]);
switch(tokens[tokens.length-1]){
case "WebDriverException":
System.out.println("Made it to case 1");
Reporter.log("Test Message here <------ \n", true);
break;
default:
Reporter.log("Unknown Exception");
}
}
When I run I get this output on the console:
WebDriverException
Made it to case 1
Test Message here <------
But I never get anything in the HTML files that TestNG generates. Any ideas??

How to write to log file when test fail, with Log4j

I want to achieve writing to log file with Log4j.
I have found one easy solution - surround test body with try - catch:
#Test(groups = "GMAIL_PAGE")
public void testAllMailLink() {
try {
List<WebElement> allMessages = page.takeAllMessage();
page.clickInboxLink();
List<WebElement> inboxMessages = page.takeInboxMessage();
page.clickDraftLink();
List<WebElement> draftMessages = page.takeDraftMessage();
Assert.assertTrue(allMessages.containsAll(inboxMessages),
"All messages doesn't contains all inbox messages");
Assert.assertTrue(allMessages.containsAll(draftMessages),
"All messages doesn't contains all draft messages");
log.info("test is passed");
} catch (Exception e) {
log.error(e);
}
}
But it has some drawbacks - this test is always passed, even if it fails.
It is ok if I work on my machine and able to see console. But what to do when this test is pushed to Continuous Integration server?
Does exist any other way to write info into log file, when test fail?
Add Assert.fail() below your log.error(e):
catch (Exception e) {
log.error(e);
Assert.fail();
}
By the way, you're calling Logger#error(Object), which uses e.toString(). In this case, it is better to use a descriptive message and then pass the exception to get the respective stacktrace:
catch (Exception e) {
log.error("Some descriptive message should go here.", e);
Assert.fail("Some descriptive message should go here as well.");
}

Attaching screenshots to TestNG Failed methods results

I am looking for a way to attach a screenshot to Results section of TestNG Report for the failed methods.
So far I was able to attache my screenshots to Reporter Output by implementing this:
Reporter.log("<br> <img src=.\\screenshots\\" + fileName + " /> <br>");
but still struggling with adding them to Test Results section of failed methods.
I was able to implement Listener and intercept onTestFailure actions which was originally suggested here:
How can I include a failure screenshot to the testNG report
Here is an example of that:
#Override
public void onTestFailure(ITestResult result) {
Reporter.setCurrentTestResult(result);
Reporter.log("<br> <img src=.\\screenshots\\Untitled.png /> <br>");
Reporter.setCurrentTestResult(null);
}
But Reporter.log function still pushes my information in the Reporter output log but not in the Results->Failed methods->Failed method log.
Update (03/14/14): I've attached screenshot to clarify my question. The problem is not in capturing screenshot and attaching it to Report. That part works fine. The problem is that screenshot is attached to Test Output part of the report but I want to see it in Results -> Failed Methods.
I have also implemented the same extending Testng TestListenerAdapter. By capturing the screenshot then attach it to the Testng Report with the image of size height=100 and width=100 with onTestFailure. Please see below if this helps solve your problem
File scrFile = ((TakesScreenshot) WebdriverManager.globalDriverInstance).getScreenshotAs(OutputType.FILE);
//Needs Commons IO library
try {
FileUtils.copyFile(scrFile, new File(file.getAbsolutePath()+ "/selenium-reports/html/" + result.getName() + ".jpg"));
Reporter.log("<a href='"+ file.getAbsolutePath()+"/selenium-reports/html/" + result.getName() + ".jpg'> <img src='"+ file.getAbsolutePath()+"/selenium-reports/html/"+ result.getName() + ".jpg' height='100' width='100'/> </a>");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Reporter.setCurrentTestResult(null);
In addition to above don't forget to add following lines to your testng suite xml
<listeners>
<listener class-name="com.tests.DotTestListener" />
</listeners>
OR
passing as listner parameter if you are executing it from command line
java -classpath testng.jar;%CLASSPATH% org.testng.TestNG -listener com.tests.DotTestListener test\testng.xml
Reference : http://testng.org/doc/documentation-main.html#logging-listeners
I've had same problem but it solved. By implementing SuitePanel you will be able to add screenshot as you want
https://github.com/cbeust/testng/blob/master/src/main/java/org/testng/reporters/jq/SuitePanel.java
I almost don't change the original code except
...
// Description?
String description = tr.getMethod().getDescription();
if (! Strings.isNullOrEmpty(description)) {
xsb.push("em");
xsb.addString("(" + description + ")");
xsb.pop("em");
}
// Add screen shot here
xsb.push(“img”,”src”,imagePath);
xsb.pop(“img”);
xsb.pop(D);
xsb.pop(D);
If you want to show the screen shot on the failed method then you will have to capture the exception and modify its message content and add img html to that and then it will appear. Let me know if you need example
I had same issue but its fixed now. I made a method to catcher screenshot in base class. this method return full path of screenshot.
public String getScreenshot (String screenshotName, WebDriver driver) throws IOException{
DateFormat dateformate = new SimpleDateFormat("dd-mm-yy-hh-mm-ss");
Date date = new Date();
String currentdate = dateformate.format(date);
String imageName =screenshotName+currentdate;
TakesScreenshot ts=(TakesScreenshot)driver;
File source=ts.getScreenshotAs(OutputType.FILE);
String location =System.getProperty("user.dir")+"\\testOutput\\screenshot\\"+imageName+".png";
File screenshotLocation =new File (location);
FileUtils.copyFile(source, screenshotLocation);
return location;
}
Add use this path to add screenshot in testng report as well as report log by updating testng TestNgListener-
public void onTestFailure(ITestResult arg0) {
Object currentClass = arg0.getInstance();
WebDriver driver = ((BrowserSetup) currentClass).getDriver();
String name = arg0.getName();
System.out.println(name);
try {
String screenshotPath =getScreenshot(name, driver);
System.out.println("Screenshot taken");
String path = "<img src=\"file://" + screenshotPath + "\" alt=\"\"/>";
System.out.println(screenshotPath+" and path - "+path);
Reporter.log("Capcher screenshot path is "+path);
} catch (Exception e) {
System.out.println("Exception while takescreenshot "+e.getMessage());
}
printTestResults(arg0);
}
I suggest you to use ReportNG instead of the primitive TestNG reports.
If the problem only with getting screenshots, you can try to get it like this:
private static byte[] GetCropImg(IWebDriver targetChrome, IWebElement targetElement)
{
var screenshot = ((ITakesScreenshot)targetChrome).GetScreenshot();
var location = targetElement.Location;
using (MemoryStream stream = new MemoryStream(screenshot.AsByteArray))
{
var rect = new Rectangle(location.X, location.Y, targetElement.Size.Width, targetElement.Size.Height);
using (Bitmap bmpImage = new Bitmap(stream))
{
using (Bitmap cropedImag = bmpImage.Clone(rect, bmpImage.PixelFormat))
{
using (MemoryStream ms = new MemoryStream())
{
cropedImag.Save(ms, ImageFormat.Jpeg);
byte[] byteImage = ms.ToArray();
return byteImage;
}
}
}
}
}
and then you can save file or save sting64
var imgString64 = Convert.ToBase64String(byteImage); //Get Base64
PS: on JAVA it should be almost the same)
you can get failed test cases screen shots with name of failed test class by using #After method.
Use below code segment

Categories