Capturing screenshots of failed tests in Selenium Webdriver + JUnit4

Beside the exception / failure information, it is almost always helpful for the developers to provide them with additional screenshot of the failed tests.
From JUnit 4.7 the @Rule annotation is introduced which can be used to extend the capabilities of JUnit. With it we can invoke a custom piece of code when a test fails or succeeds.
In this example we will capture a screenshot of a failed test.
Before showing how it is done, we should have a test class at hand. For the following example just download the selenium driver from the page http://seleniumhq.org/download/ and add the jar files to classpath.

package test;

import static org.junit.Assert.assertTrue;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverBackedSelenium;
import org.openqa.selenium.firefox.FirefoxDriver;

import com.thoughtworks.selenium.Selenium;

//This is an example for the usage of ScreenshotTestRule
public class TestWithScreenshotExample {
    //
    static WebDriver driver;
    static Selenium selenium;
    // an annotation is used for defining a new rule for Junit
    @Rule
    public ScreenshotTestRule screenshotTestRule = new ScreenshotTestRule();

    @BeforeClass
    public static void beforeClass() {
        driver = new FirefoxDriver();
        selenium = new WebDriverBackedSelenium(driver, "http://www.google.com");
    }

    @AfterClass
    public static void afterClass() {
       driver.quit();
    }

    @Test
    public void testThatSucceeds() {
        selenium.open("/");
        // some text code here
        assertTrue(selenium.isTextPresent("This test will pass"));
    }

    @Test
    public void testThatFails() {
        selenium.open("/");
        //some text code here
        assertTrue(selenium.isTextPresent("This test will fail"));
    }

    // the static driver object will be needed for capturing screenshots
	public static WebDriver getDriver() {
		return driver;
	}

The trick above is to define a new JUnit rule with @Rule annotation.
The class which is used to define the new rule needs to implement the MethodRule interface and to override the apply() function.

package test;

import java.io.File;

import org.apache.commons.io.FileUtils;
import org.junit.rules.MethodRule;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.Statement;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;

class ScreenshotTestRule implements MethodRule {
    public Statement apply(final Statement statement, final FrameworkMethod frameworkMethod, final Object o) {
        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                try {
                    statement.evaluate();
                } catch (Throwable t) {
                    // exception will be thrown only when a test fails.
                    captureScreenshot(frameworkMethod.getName());
                    // rethrow to allow the failure to be reported by JUnit
                    throw t;
                  }
            }

            public void captureScreenshot(String fileName) {
                try {
//
               File screenshot =  ((TakesScreenshot)TestWithScreenshotExample.getDriver()).getScreenshotAs(OutputType.FILE);
// the screenshots can be moved to a folder for sorting               FileUtils.copyFile(screenshot, new File("./screenshot-"+fileName+".png"));
                } catch (Exception e) {
                    // No need to crash the tests if the screenshot fails
                }
            }
        };
    }
}

By overwriting the apply() function we can intervene before Junit sends out the test results, and we can insert the screenshot capturing code.
For further information on using the @Rule annotation check out: http://www.junit.org/node/580
Happy screenshot capturing!

Selenium – How to check if an element has focus

Problem:

We have a contact form with Name, Email and Comment fields, and if invalid data is entered to the fields, the validation system will highlight that field and it will be focused, so the user can change it quickly. In our tests we want to check if the proper field gets the focus.

<div class="contact-form">
    <label> Name </label>
    <input id="contact-name" type="text" />
    <label> Email </label>
    <input id="contact-email" type="text" />
    <label> Comment </label>
    <input id="contact-comment" type="text" />
</div>

(this is just an example code, and not a functional one)

Solution:

Selenium suggest to use css selectors, so we will start with that. To see if the element has the focus we will use css pseudo-class “:focus” and check if an element is present like this:

Assert.IsTrue(selenium.IsElementPresent("css=#contact-name:focus"));

This looks quite nice and easy, but you may encounter some problems with it. The element #contact-name can be found, but #contact-name:focus can not. In this case we have to think outside of the box, and come up with another solution. We can use the Javascript DOM locator to get the element that is selected (has focus), and compare it to the element we expect to have focus:

Assert.AreEqual(selenium.GetElementIndex("dom=document.activeElement"),
selenium.GetElementIndex("css=#contact-name"));

Solution for – Could not start Selenium Session : Connection timed out

If you get the “Could not start Selenium Session : Connection timed out” while running a test scenario it is usually due to the ports not matching for the Server and the client and results in “Selenium server not able to make a connection with the local client machine”.

a sample error message:

 java.lang.RuntimeException: Could not start Selenium session: Connection timed out: connect
at com.thoughtworks.selenium.DefaultSelenium.start(DefaultSelenium.java:89)
at com.ibm.lconn.files.test.ui.BaseFilesSeleniumTestCase.setUp(BaseFilesSeleni umTestCase.java:54)
at junit.framework.TestCase.runBare(TestCase.java:128)
at com.thoughtworks.selenium.SeleneseTestCase.runBare(SeleneseTestCase.java:21 2)
at junit.framework.TestResult$1.protect(TestResult.java:106) 

The solution for it is to make sure to run the on the same ports. The default port where the selenium server starts up is 4444.

How To Make Android Screenshots for testing

When testing Android mobile applications the one of the first things that come up is how to record and document the error that happened.
As in desktop testing there are apps that allow you to record the screen. The only thing that you need to do is to make sure the phone
is rooted before using the screenshot applications. (there are several descriptions out there just Google for them for the specific android
version and phone model).

here is a list of screenshot applications:

Screenshot V1.4 from http://www.geeksofts.com/ (I Suggest this one)

  • You can use the camera button to take screenshots
  • You can also choose to shake the phone to take pictures when you want

Screenshot It Trial from http://www.koushikdutta.com/ (only 5 screenshots in the trial mode)

  • Hold down the camera button
  • Assign a hot key to the application
  • Use a delayed timer



Binding data with Spring Forms

Spring has its own tag library, which makes JSPs easier to develop, maintain and read. One of these libraries is the form tag library, and in this post we’ll demonstrate how to use it.

For this we will use a sample project that will let us modify the user’s account details. In order to display the stored values for the account in the form, we have previously tied an object named foo to the session that holds all the information about our user’s account.

The form used for displaying and sending the account data is displayed here:

<form action="/account" method="post">
	<fieldset>
	<legend>Edit account information:</legend>
	<table>
		<tr>
			<td><label for="name" >Name:</label></td>
			<td><input type="text" id="name" name="name" value=${foo.name} /></td>
		</tr>
		<tr>
			<td><label for="email">E-mail:</label></td>
			<td><input type="text" id="email" name="email" value=${foo.email} /></td>
		</tr>
		<tr>
			<td><label for="website">Website:</label></td>
			<td><input type="text" id="website" name="website" value=${foo.website} /></td>
		</tr>
		<tr><td>&nbsp;</td><td><input type="submit" value="Save" /></td></tr>
	</table>
	</fieldset>
</form>

Now lets do the implementation of the form tag library on this code:

Servlet Mapping for Google App Engine and Spring

This post is all about Spring MVC 3 and Google App Engine and their interaction.

The starting point for this project was the Google App Engine’s documentation, the Google Eclipse plugin, and some tutorials found on various sites.

After reading all about the App Engine and Spring, the first thing to do was to create a project in our favorite editor, Eclipse. This generated some necessary files, and gave us a good starting point. As we want to use Spring to perform all its magic, we’ve created a web.xml like this:

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

Solution for Selenium IDE – Your browser doesnt support Xml Http Request

If you get the “Your browser doesnt support Xml Http Request” error while running tests
in Selenium IDE even if its shows that all tests passed below is the cure for it:

This issue only happens on versions of Selenium IDE prior to 1.0.6

So there are two workarounds to this problem:

1) Get the newest version and use that (currently 1.0.7) :

http://seleniumhq.org/download/

2) Or if for whatever reason you are stuck with the version you have here is a workaround:

http://code.google.com/p/selenium/issues/detail?id=388

 

Selenium test in Java with Eclipse and JUnit

Its quite easy to run Selenium tests using Eclipse and JUnit. Basically all you need is to get Selenium RC:

http://seleniumhq.org/download/

and get Eclipse (Eclipse Classic will do if you don’t need the rest, the Helios 3.6 already includes JUnit)

http://www.eclipse.org/downloads/

to make things easier also get Selenium IDE (Firefox plugin for recoding tests and exporting to the desired language)

http://seleniumhq.org/download/

Install Selenium IDE the rest just unpack to a desired dir and you are ready to roll. If you already have Eclipse its most likely

that you have JUnit as well but just in case you need it it can be found here:

http://www.junit.org/

Record some test case in Selenium IDE by opening up FireFox and going to Tools->Selenium IDE

For example open up blog.wedoqa.com and assert some text (or do whatever test you desire)

While Selenium IDE is running you can easily assert things by right clicking (except on web pages that

have their own right click handling) and looking at the bottom commands on the popup all those come from

Selenium IDE.

After you have the desired test go to Options->Format and pick Java(JUnit) format and you’ll get the test formated for Java and JUnit

and will look something like this:

package com.example.tests;

import com.thoughtworks.selenium.*;
import java.util.regex.Pattern;

public class Untitled extends SeleneseTestCase {
	public void setUp() throws Exception {
		setUp(&amp;quot;http://blog.wedoqa.com/&amp;quot;, &amp;quot;*chrome&amp;quot;);
	}
	public void testUntitled() throws Exception {
		selenium.open(&amp;quot;/&amp;quot;);
		assertTrue(selenium.isTextPresent(&amp;quot;Because quality matters!&amp;quot;));
	}
}

Now start up Eclipse and create a new Java project and add in the selenium-java-client-driver.jar from selenium-remote-control-1.0.3selenium-java-client-driver-1.0.1

(note versions might be different but you get the idea of its location), you can choose to migrate the jar will make it easier if you give the project to someone etc. At this point

you can add the JUnit jar as well or let Eclipse auto add it when you create a JUnit Test Case.

Now add a JUnit Test Case to the project (in package explorer right click the desired location and pick new-> JUnit Test Case:

Copy in the code that the Selenium IDE generated. You’ll notice some errors fix them (the name of the class should be the same as the file that was just create

also fix the package or just remove it)

Now its time to run the test. Start up the Selenium server from console using java -jar selenium-server.jar or create a neat bat file that will do this for you every time

something like:

cd E:Seleniumselenium-remote-control-1.0.3selenium-server-1.0.3
E:
java -jar selenium-server.jar

After the Server is started it should look something like this:
Now run your test from Eclipse and watch the thing come to life :)

Happy testing! :)

Solution for Selenium already running on port problem

When running selenium server often it happens that it can’t start with the following error:

“Selenium is already running on port 4444. Or some other service is.”

This happens because Selenium uses the 4444 port as its default and if you already started selenium or some other application is using that port Selenium will be prevented from using the same port.

There are several ways around this problem:

  • Find the application that is blocking/using the 4444 port and turn it off or change its port. Using the command “netstat -ano” (under Linux use “netstat –tcp –listening –programs”) from command prompt identify the applications PID and then look it up in task manager. If you don’t see the PID in task manager make sure to turn the column on in View->Select Columns:
    Once you have identified the application either kill it or change its port. Now its safe to run “java -jar selenium-server.jar” and Selenium will start up correctly.
  • Change the port Selenium is using. Run “java -jar selenium-server.jar -port XXXX” where XXXX is the desired unused port for example “java -jar selenium-server.jar -port 4448″.
    This fix is also useful if you want several instances of the selenium server running on the same machine.

 

Solution for Selenium IDE Export to C# problem

[ad#WeDoQa blog TOP]
When using the Selenium IDE to generate C# tests users get the following error “Suite export not implemented for the cs-rc formatter”:

This happens because there is an error in the code that can’t convert from the default HTML Format to C#. The workaround is to go to Options -> Format and then select C# – Selenium RC. Once converted you don’t need to export anything you can just save it or copy paste it to your C# test.

With this workaround you can also export existing saved selenium test cases from HTML or any of the others to C#. Just open up the saved test case and then switch to C# in Options -> Format
[ad#WeDoQA Bottom]