Maven Selenium

Our goal:

  • compile the app
  • run non-selenium unit tests
  • package your app into a .war file
  • start a test container (jetty or tomcat)
  • deploy your app to the test container
  • start a browser
  • point the browser to the app running in the test container
  • test your application through the browser. these tests are junit tests and were authored using selenium IDE (and then possibly tweaked a little).
  • indicate failure or success, log any errors and quit
  • optionally proceed with deployment of app to a real container

1 Step by Step configuration

This is a step by step guide of how to setup your pom.xml to automatically run your selenium tests when you build your application with maven, with full understanding of what is going on.

For a quick start, skip to step 3, then come back to steps 1 and 2 later if needed.

In step 1/3, you will be able to run your selenium unit tests through maven, but you will need to keep 3 terminals open (command prompt on windows), referred to here as Terminals A, B and C.

Maven Selenium Step1

1.1 Launch your app in jetty in Terminal-A

See how to configure jetty, here

mvn jetty:run

1.2 Start the selenium server in Terminal-B

Edit your pom.xml to add selenium plugin, sample configuration here

mvn selenium:start-server

1.3 Run your selenium test in Terminal-C

To learn how write a selinium unit test looks like, see this sample selenium junit test

mvn test
In step 2/3, you will be able to run your selenium unit tests through maven, but you will only 2 terminals – Terminals A and C.

Maven Selenium Step2

1.4 Configure your pom.xml to automatically start selenium-server in Terminal-C before running tests

So far, you manually started the selenium server. You we will configure the pom.xml to automatically start selenium server before running the tests.

<plugin>
 <groupId>org.codehaus.mojo</groupId>
 <artifactId>selenium-maven-plugin</artifactId>
 <executions>

  <execution>
   <id>start</id>
   <phase>pre-integration-test</phase>
   <goals>
    <goal>start-server</goal>
   </goals>
   <configuration>
    <background>true</background>
    <logOutput>true</logOutput>
    <multiWindow>true</multiWindow>
   </configuration>
  </execution>

  <execution>
   <id>stop</id>
   <phase>post-integration-test</phase>
   <goals>
    <goal>stop-server</goal>
   </goals>
  </execution>
 </executions>
</plugin>

1.5 Launch your app in jetty in Terminal A

mvn jetty:run

1.6 Run your selenium test in Terminal C

Edit your surefire-plugin to make tests unit tests run in test phase and selenium tests run in the integration-test phase. See sample pom.xml configuration here

mvn integration-test

The above command should start the selenium server automatically. Please note that you need to run integration-test and NOT test.

In step 3/3, you will be able to run your selenium unit tests through maven and you will only 1 terminal – Terminals C.

Maven Selenium Step3

1.7 Automatically start jetty server in Terminal-C before running tests

<plugin>
 <groupId>org.codehaus.cargo</groupId>
 <artifactId>cargo-maven2-plugin</artifactId>
 <version>0.3-SNAPSHOT</version>
 <configuration>
  <wait>false</wait>
  <container>
   <containerId>jetty6x</containerId>
   <type>embedded</type>
  </container>
 </configuration>

 <executions>
  <execution>
   <id>start-container</id>
   <phase>pre-integration-test</phase>
   <goals>
    <goal>start</goal>
    <goal>deploy</goal>
   </goals>
  </execution>

 <execution>
   <id>stop-container</id>
   <phase>post-integration-test</phase>
   <goals>
    <goal>stop</goal>
   </goals>
  </execution>
 </executions>
</plugin>

1.8 Run your selenium test in Terminal C

mvn integration-test

The above command should start the jetty server automatically.

2 How it works

maven selenium overview

3 FAQ

3.1 Selenium source

<dependency>
 <groupId>org.openqa.selenium.client-drivers</groupId>
 <artifactId>selenium-java-client-driver</artifactId>
 <version>0.9.2</version>
 <scope>test</scope>
</dependency>

3.2 Maven-Selenium Plugin

Add this to your pluginRepositories section

<pluginRepository>
 <id>codehaus snapshot repository</id>
 <url>http://snapshots.repository.codehaus.org/</url>
 <releases>
  <enabled>true</enabled>
 </releases>
</pluginRepository>

Add this to your build/plugins section

<plugin>
 <groupId>org.codehaus.mojo</groupId>
 <artifactId>selenium-maven-plugin</artifactId>
</plugin>

3.3 Maven Selenium java client driver

Add this to your respositories section

<repository>
 <id>openqa</id>
 <name>OpenQA Repository</name>
 <url>http://nexus.openqa.org/content/repositories/releases/</url>
 <snapshots>
  <enabled>false</enabled>
 </snapshots>
 <releases>
  <enabled>true</enabled>
 </releases>
</repository>

Add this to your dependencies section

<dependency>
 <groupId>org.openqa.selenium.client-drivers</groupId>
 <artifactId>selenium-java-client-driver</artifactId>
 <version>0.9.2</version>
 <scope>test</scope>
</dependency>

3.4 Simple selenium java unit test

Create a simple index.jsp with the following text

<html>
 <body>
  <h1>Hello, World</h2>
 </body>
</html>

Here’s an example junit3 test, SeleniumHelloWorldExample.java

import junit.framework.TestCase;

import com.thoughtworks.selenium.DefaultSelenium;
import com.thoughtworks.selenium.SeleniumException;

public class SeleniumHelloWorldExample extends TestCase {
	private DefaultSelenium selenium;

	@Override
	public void setUp() throws Exception {
		super.setUp();
		selenium = createSeleniumClient("http://localhost:8080/");
		selenium.start();
	}

	@Override
	public void tearDown() throws Exception {
		selenium.stop();
		super.tearDown();
	}

	protected DefaultSelenium createSeleniumClient(String url) throws Exception {
		return new DefaultSelenium("localhost", 4444, "*firefox", url);
	}

	public void testHelloWorld() throws Exception {
		try {
			selenium.open("http://localhost:8080/mywebapp/index.jsp");
			assertEquals("Hello, World", selenium.getText("//h1"));
		} catch (SeleniumException ex) {
			fail(ex.getMessage());
			throw ex;
		}
	}
}

3.5 How to run selenium tests in integration test phase

Here’s a surefire configuration, which

  • In maven:test phase: runs unit tests
  • In maven:integration-test phase: runs (selenium) integration tests
<plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-surefire-plugin</artifactId>
 <configuration>
  <excludes>
   <exclude>**/selenium/*Test.java</exclude>
  </excludes>
 </configuration>

 <executions>
  <execution>
  <id>integration-tests</id>
  <phase>integration-test</phase>
  <goals>
   <goal>test</goal>
  </goals>
  <configuration>
   <skip>false</skip>
   <excludes>
    <exclude>none</exclude>
   </excludes>
   <includes>
    <include>**/selenium/*Test.java</include>
   </includes>
   </configuration>
  </execution>
 </executions>
</plugin>

3.5.1 Run integration tests

mvn integration-test

3.5.2 Test single class

To test your class in

src/test/java/com/vineetmanohar/MyTest

Simply type (don’t give package name)

mvn -Dtest=MyTest test

3.5.3 Compile your test sources

mvn test-compile

3.5.4 Skipping unit tests in maven

mvn -Dmaven.test.skip=true package

3.6 Running Maven Selenium on linux

See this page: http://mojo.codehaus.org/selenium-maven-plugin/examples/headless-with-xvfb.html

You may have to download Xvfb from here: http://ftp.xfree86.org/pub/XFree86/4.4.0/binaries/

3.6.1 Error launching selenese, cannot open display

If you followed the instructions on the above page, as I did, you may end get this error.

[INFO] Starting Xvfb...
[INFO] Using display: :20
Launching Xvfb
Waiting for Xvfb...
[INFO] Redirecting output to: target/selenium/xvfb.log
Xvfb started
[INFO] [selenium:selenese {execution: start}]
[INFO] Results will go to: target/results-firefox-suite.html

(firefox-bin:18143): Gtk-WARNING **: cannot open display:
[INFO] ------------------------------------------------------------------------
[ERROR] FATAL ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Timed out waiting for profile to be created!
[INFO] ------------------------------------------------------------------------
[INFO] Trace
java.lang.RuntimeException: Timed out waiting for profile to be created!
        at org.openqa.selenium.server.browserlaunchers.FirefoxCustomProfileLauncher.waitForFullProfileToBeCreated(FirefoxCustomProfileLauncher.java:271)
        at org.openqa.selenium.server.browserlaunchers.FirefoxCustomProfileLauncher.launch(FirefoxCustomProfileLauncher.java:147)
        at org.openqa.selenium.server.browserlaunchers.AbstractBrowserLauncher.launchHTMLSuite(AbstractBrowserLauncher.java:20)
        at org.openqa.selenium.server.htmlrunner.HTMLLauncher.runHTMLSuite(HTMLLauncher.java:88)

While there are several ways to solve this, the simplest way I found was to set the DISPLAY on command line (or the build environment)

export DISPLAY=:20

This should fix the problem. Note that :20 is the default port that selenium uses. You can also specify a different port in the selenium plugin configuration and then specify the same port in the DISPLAY env variable.

3.7 Browser does not exist

If the specified browser does not exist a detailed error will be logged in this file

less /target/selenium/server.log

The error looks like this

14:42:46,991 WARN  [org.mortbay.http.HttpConnection] GET /selenium-server/driver/?cmd=getNewBrowserSession&1=*firefox&2
=http%3A%2F%2Flocalhost%3A8080%2F HTTP/1.1
java.lang.RuntimeException: Firefox couldn't be found in the path!
Please add the directory containing 'firefox-bin' to your PATH environment
variable, or explicitly specify a path to Firefox like this:
*firefox /blah/blah/firefox-bin

Maven will throw this error

com.thoughtworks.selenium.SeleniumException: ERROR: No launcher found for sessionId null
  at com.thoughtworks.selenium.HttpCommandProcessor.doCommand(HttpCommandProcessor.java:73)
  at com.thoughtworks.selenium.HttpCommandProcessor.stop(HttpCommandProcessor.java:145)

Solution: make sure that firefox is installed and firefox-bin exists in the path.

3.8 How can I run html tests (recorded using Selenium IDE) using maven

The following configuration starts the html tests located in the suite src/test/selenium/suite.html in the test phase.

<plugin>
 <groupId>org.codehaus.mojo</groupId>
 <artifactId>selenium-maven-plugin</artifactId>
 <configuration>
  <browser>*firefox</browser>
  <suite>src/test/selenium/suite.html</suite>
  <startURL>http://www.vineetmanohar.com</startURL>
 </configuration>

 <executions>
  <execution>
   <id>test</id>
   <phase>test</phase>
   <goals>
    <goal>selenese</goal>
   </goals>
  </execution>
 </executions>
</plugin>

The following command will run the tests:

mvn test

If you wish to the tests in a different phase, simply change the phase, for example to integration-test

Here’s a sample test suite file:

<html>
 <head><title>Example Test Suite</title></head>
 <body>
  <table>
   <tr><td><b>Example Test Suite</b></td></tr>
   <tr><td><a href="./test1.html">Test1</a></td></tr>
   <tr><td><a href="./test2.html">Test2</a></td></tr>
   <tr><td><a href="./test3.html">Test3</a></td></tr>
  </table>
 </body>
</html>

Related posts:

  1. Maven Cargo JBoss
  2. Maven FAQ and code snippets for beginners
  3. The plugin ‘org.codehaus.mojo:selenium-maven-plugin’ does not exist or no valid version could be found
  4. First look at Selenium Inspector
  5. Tweet your builds with Maven Twitter Plugin

17 comments to Maven Selenium

  • Dan

    thanks for the tips, it helps a lot!

    i tried to follow the section 1.7 to have Jetty server, selenium server and selenium tests running in the same terminal, however i got some issue with that:

    by default, cargo look for war file as ${project.artifactId}-${project.version}.war, in my pom.xml, the project version is set to 1.0-SNAPSHOT, but in the war plugin, the warName was set to ${project.artifactId}, thus the final war file generated is ${project.artifactId}.war. then Jetty complained that it cannot find the war file. is there anyway i can define the war file name in cargo-maven plugin instead of using the default one? right now i cannot see a good way to do that.

    thanks.

  • vineet

    Take a look at Cargo’s config properties.

    http://cargo.codehaus.org/Maven2+Plugin+Reference+Guide
    WAR The path of the WAR being deployed. Default’s to the project’s generated artifact location

  • Dan

    hi, Vineet,

    Thanks for the reply, one more question about the Xvfb. when i do the selenium testing with RC, i can see the browser keep popping up and then closed. is it possible to disable those popping, just make it run quietly?

  • vineet

    You can create another display (:20) other that the display that you are currently using (typically :0). See the xvfb link in the post. Alternatively you can start a VNC server at :20 and set that as the output, that is typically what I do. All browsers will then “popup” on that display and you will not see anything. If you actually want to see the browsers in action, you can start a VNC client and log on to the :20 display.

  • Dan

    hi, Vineet,

    I kept having trouble with cargo plugin, i used the embedded Jetty server(tried all 5.x, 6.x and & 7.x versions), they all had problem with my spring framework. but if i just run gwt:run i can started my gwt app in the host mode(with embedded Jetty server). i really cannot understand why this happened. from your blog i can see all cargo did is just start Jetty server, so i can replace the cargo with mave-jetty-plugin and run jetty:run instead? then start selenium server and selenium tests.? what’s the point of cargo plugin here? much thanks.

  • Dan

    I kept having trouble with cargo plugin, i used the embedded Jetty server(tried all 5.x, 6.x and & 7.x versions), they all had problem with my spring framework. but if i just run gwt:run i can started my gwt app in the host mode(with embedded Jetty server). i really cannot understand why this happened. from your blog i can see all cargo did is just start Jetty server, so i can replace the cargo with mave-jetty-plugin and run jetty:run instead? then start selenium server and selenium tests.? what’s the point of cargo plugin here? much thanks.

  • vineet

    Cargo is generally used to deploy a .war file to a server. It is a fairly generic plugin, more useful when the server is already started or running on a remote server. In your case, it seems more straight forward to run the app directly via gwt:run if that works. The big picture is that you want to launch your app so that you can test it via Selenium.

  • Dan

    run the app via gwt:run would be a good idea, but when i launch it in Jetty, gwt development mode window pop up and stuck there, the following selenium server didn’t start, no to mention the selenium test. here is my pom.xml:

    selenium

    org.codehaus.mojo
    gwt-maven-plugin
    2.1.0-1


    ${basedir}/war
    ${basedir}/war/WEB-INF/web.xml
    index.html

    -Dgwt.style=DETAILED -Xmx512M -Xss1024k -XX:MaxPermSize=128m -Djavax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl -Djavax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl -Dlogback.configurationFile=./src/test/resources/logback-test.xml


    0.0.0.0

    start-jetty-server
    pre-integration-test

    run

    org.codehaus.mojo
    selenium-maven-plugin
    1.1

    start
    pre-integration-test

    start-server

    true
    true

    stop
    post-integration-test

    stop-server

    do you have any idea what might goes wrong? thanks!

  • Dan

    profile selenium

    plugin
    groupId org.codehaus.mojo

    artifactId gwt-maven-plugin
    
version 2.1.0-1

    configuration

    output ${basedir}/war
    
webXml ${basedir}/war/WEB-INF/web.xml
runTarget index.html
    extraJvmArgs
    -Dgwt.style=DETAILED -Xmx512M -Xss1024k -XX:MaxPermSize=128m -Djavax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl -Djavax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl -Dlogback.configurationFile=./src/test/resources/logback-test.xml
    bindAddress 
0.0.0.0

    executions
    execution
    id start-jetty-server

    phase pre-integration-test
    goals
    goal run

    plugin
    groupId org.codehaus.mojo
    
artifactId selenium-maven-plugin

    version 1.1

    executions
    execution
    id start
 phase pre-integration-test
    goals
    goal start-server
    configuration
    background true

    logOutput true

    execution
    id stop
 phase post-integration-test
    goals
    goal stop-server

  • vineet

    Can you run the app via jetty run (see section 1.1 above) and access the app in the browser?

  • Kamal

    I am new to selenium and have just created a new test which I am trying to run on hudson.

    I keep getting timed out waiting for profile to be created error

    runSeleniumTests:

    BUILD SUCCESSFUL
    Total time: 0 seconds
    java -jar /home/locgrdd/.hudson/jobs/SeleniumTest/workspace/selenium-server.jar -htmlSuite *firefox http://www.bbc.co.uk/weather /home/locgrdd/.hudson/jobs/SeleniumTest/workspace/TestSuite1.html /home/locgrdd/.hudson/jobs/SeleniumTest/workspace/results.html
    [workspace] $ java -jar /home/locgrdd/.hudson/jobs/SeleniumTest/workspace/selenium-server.jar -htmlSuite *firefox http://www.bbc.co.uk/weather /home/locgrdd/.hudson/jobs/SeleniumTest/workspace/TestSuite1.html /home/locgrdd/.hudson/jobs/SeleniumTest/workspace/results.html
    14:57:22.295 INFO – Java: Sun Microsystems Inc. 10.0-b19
    14:57:22.297 INFO – OS: Linux 2.6.18-164.10.1.el5 i386
    14:57:22.304 INFO – v2.0 [a2], with Core v2.0 [a2]
    14:57:22.402 INFO – RemoteWebDriver instances should connect to: http://10.117.130.32:4444/wd/hub
    14:57:22.403 INFO – Version Jetty/5.1.x
    14:57:22.404 INFO – Started HttpContext[/selenium-server/driver,/selenium-server/driver]
    14:57:22.404 INFO – Started HttpContext[/selenium-server,/selenium-server]
    14:57:22.404 INFO – Started HttpContext[/,/]
    14:57:22.415 INFO – Started org.openqa.jetty.jetty.servlet.ServletHandler@a6d51e
    14:57:22.416 INFO – Started HttpContext[/wd,/wd]
    14:57:22.418 INFO – Started SocketListener on 0.0.0.0:4444
    14:57:22.418 INFO – Started org.openqa.jetty.jetty.Server@1d63e39
    14:57:22.461 WARN – It looks like your baseUrl (http://www.bbc.co.uk/weather) is pointing to a file, not a directory (it doesn’t end with a /). We’re going to have to strip off the last part of the pathname.
    14:57:22.489 INFO – Preparing Firefox profile…
    Error: no display specified
    HTML suite exception seen:
    java.lang.RuntimeException: Timed out waiting for profile to be created!
    at org.openqa.selenium.server.browserlaunchers.FirefoxChromeLauncher.waitForFullProfileToBeCreated(FirefoxChromeLauncher.java:348)
    at org.openqa.selenium.server.browserlaunchers.FirefoxChromeLauncher.populateCustomProfileDirectory(FirefoxChromeLauncher.java:124)
    at org.openqa.selenium.server.browserlaunchers.FirefoxChromeLauncher.launch(FirefoxChromeLauncher.java:91)
    at org.openqa.selenium.server.browserlaunchers.FirefoxChromeLauncher.launchHTMLSuite(FirefoxChromeLauncher.java:393)
    at org.openqa.selenium.server.browserlaunchers.FirefoxLauncher.launchHTMLSuite(FirefoxLauncher.java:94)
    at org.openqa.selenium.server.htmlrunner.HTMLLauncher.runHTMLSuite(HTMLLauncher.java:121)
    at org.openqa.selenium.server.htmlrunner.HTMLLauncher.runHTMLSuite(HTMLLauncher.java:166)
    at org.openqa.selenium.server.SeleniumServer.runHtmlSuite(SeleniumServer.java:545)
    at org.openqa.selenium.server.SeleniumServer.boot(SeleniumServer.java:239)
    at org.openqa.selenium.server.SeleniumServer.main(SeleniumServer.java:198)
    14:57:42.615 INFO – Shutting down…

  • John Anderson

    Vineet,

    Great article for Maven Selenium setup. I just follwed your steps but I never can successfully test my selenium test cases, although I can see both jetty server startup and selenium startup on the console. When I commented out the section (pom.xml) of start selenium-server and manually started selenium server, then I ran mvn integration-test and it worked fine. If I commented out the executions section of starting jetty server and manually started jetty server by executing mvn cargo:start, integration-test also worked fine. If I leave both start jetty server and selenium-server in place, and when I tested selenium test cases, I always got HTTP ERROR: 404.

  • anjing

    selenium = new DefaultSelenium(“localhost”, 4444, “C:\\Program Files\\Mozilla Firefox\\firefox.exe”, “http://10.151.124.159:7101/”);
    selenium.start();

    I can’t run my test case if I setUp firebox browser,but iexplore is OK.

    selenium = new DefaultSelenium(“localhost”, 4444, “*iexplore”, “http://10.151.124.159:7101/”);
    selenium.start();

  • Sergio Carabetta

    @Anging,

    I think your problem is the browserType field, it should be like:

    selenium = new DefaultSelenium(“localhost”, 4444, “*firefox”, “http://10.151.124.159:7101/”);

  • Meena

    Hi Vineet, i am using selenium grid, c#, mbunit and Gallio to run my test case parallel but only 1 test case is running successfully other test cases are showing different error message like “Selenium.SeleniumException: ERROR: Got a null result
    at Selenium.HttpCommandProcessor.DoCommand(String command, String[] args) in c:\hudson\workspace\selenium-rc-trunk-win-headless\trunk\clients\dotnet\src\Core\HttpCommandProcessor.cs:line 98
    at Selenium.DefaultSelenium.Click(String locator) in c:\hudson\workspace\selenium-rc-trunk-win-headless\trunk\clients\dotnet\src\Core\DefaultSelenium.cs:line 166
    at GDA.MyClass.TheUntitledTest12() in c:\Users\mnarvariya\Desktop\Junit\GDA\GDA\MyClass.cs:line 63″

    Please Reply ASAP
    Thanks,
    Meena

  • John

    Hello Vineet,

    to completely automate tests, one ideally would like to automate also the packaging of the webapp
    into .war, its deployment on a webserver, and starting the web server so that maven waits until
    it starts and then starts to run the selenium tests. Do you have some idea on how to do this? I can
    only think of some heavy weight solution – Maven calls a custom plugin which starts an external
    process, which packages the .war, deploys it into the deployment directory of a webserver on the
    file system, then calls run.bat or whatever of the webserver to get it started, and then waits
    for some fixed amount of time before it tries to run selenium tests. Can you think of a more elegant
    approach?

  • soumya

    Dear friends

    I am trying to convert html test to java but could not find Java(JUnit)-Selenium RC in my selenium ide

    could you please help me..

    thank you in advance

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Get Adobe Flash playerPlugin by wpburn.com wordpress themes