Skip to main content

Interactive selenium testing

The problem


Location of elements

When I started using selenium, I noticed that it is not easy to do it right. First you start with IDE, but you notice, that the IDE does not really record a lot. In a next step I added firebug, and started analyzing how the elements where to be located: either by tag, id, class etc.

Junit testcase

With this information I could then create my junit testcase:
 @Test
 public void testMapView() throws Exception {

  //assert that we cannot see submenu of MapCreator
  elem = driver.findElement(By.className(SeleniumConstants.MAP_SUB_MENU));
  String style = elem.getAttribute("style");
  assertTrue("Element must have style display off.",style.matches("display: none.*"));
  logger.debug("Located element " + SeleniumConstants.MAP_SUB_MENU);

  //find menu and click on mapview
  elem = driver.findElement(By.id(SeleniumConstants.MAP_CONTROL));
  actions.moveToElement(elem).click().perform();
  //assert submenu is shown now
  elem = driver.findElement(By.className(SeleniumConstants.MAP_SUB_MENU));
  style = elem.getAttribute("style");
  assertTrue("Element must have style display on.",style.matches("display: block.*"));
Now this all works very nice, only, not after the first time. It took many iterations to get here.

selenium iterations

Usual failures are, that element cannot be found:
org.openqa.selenium.NoSuchElementException: Unable to locate element: {"method":"id","selector":"
or, that you cannot click on an element, as it is not the top element or not visible:
Element is not currently visible and so may not be interacted with Build info: 
This kind of failures eat a lot of time. The forced me to analyze, use firebug, make some changes, and to restart my junit testcase. Every failure caused me to restart my testcase ...

The first solution: eclipse debugger

I started running my testcases from eclipse, in debugging mode. I put my debug point at the location where it started to get interesting. Now I could see the exact state of my application. Also, with the debugger expression viewer, I could create expressions, that actually executed something:
(new Action(driver).moveToElement(elem).click().moveByOffSet(100,100).click().perform()
Althoug the expression viewer is actually to discover calucated values, you can also use it to pass on new commands. It is running in the context of your JVM, so can directly pass commands to your selenium driver.

Disadvantage of debugger expressions

This helped a lot, I could do better analysis, and try out before adding it to my test code. However, on any exception or failure, my debugger threw an exception, and I was out. I still had to restart my jvm. The problem is also with junit: when you get an exception, your test is over. No way to retry.

The new solution: groovy console

The new solution is a lot more elegant:
  • No junit test, but just a simple main program
  • Initialisation of selenium driver takes place in program, then control is handed over to a groovyconsole
  • Groovy allows for runtime compilation
  • Test scripts can be saved and replayed.
This was the real winner, and I still love it. Suddenly test automation with selenium starts to make fun again.

A simple example

When I start up my selenium-groovy, I get a swing groovy console that allows me to type selenium commands:
These are just a few lines of selenium. But the nice thing is: if they are wrong, you get a failure in your console, and you can just retry. Likewise, you can select only a few lines of your script, and only run those again.

Coming topics

In future blogs, I will continue on this topic:
  • code explained to setup the groovy console
  • how to setup your maven project to get this working
  • making your own utilities
  • a few more examples
  • running your recorded scripts in junit tests.

Stay tuned!

Comments

Chinni said…
Hardly waiting for Groovy console
man9ar00 said…
Great post. Just wanted to mention this same technique is available with other Java interpreter options as well: Beanshell, Jython, JRuby. And it's natively available for Python and Ruby bindings.

I've blogged about this as well, though I used Beanshell:

http://autumnator.wordpress.com/2012/02/02/developing-and-debugging-in-java-via-an-interpreter/

http://autumnator.wordpress.com/2011/11/06/using-selenium-with-interactive-interpreter-shells/
Unknown said…
This information which you provided is very much useful for us.It was very interesting and useful for qa online training.We also providing qa online training institute in worldwide.

Popular posts from this blog

Create a groovy console and bind to selenium

Required groovy files In the previous posting we defined the pom file that we need for our build environment. Now we will setup some groovy files to get selenium and groovy running interactively. ConsoleWaiter.groovy The idea of Groovy Console I found on some other sides. Honour goes for instance too: http://josefbetancourt.wordpress.com/tag/eclipse-2/ I copied some code of this, and put it under src/test/groovy/com/jankester/selenium/test/utils: package com.jankester.selenium.test.utils /** * File: ConsoleWaiter.groovy */ import groovy.lang.Binding; import groovy.ui.Console; /** * Provides a wrapper for the console. * * Based on source by John Green * Adapted from: http://www.oehive.org/files/ConsoleWaiter.groovy * Released under the Eclipse Public License * http://www.eclipse.org/legal/epl-v10.html * * I added methods to allow use from Java. * * The run() method launches the console and causes this thread * to sleep until the console's window is closed.

SSL handshake failed: Secure connection truncated

Got this problem on Ubuntu 9.10 and 10.10. svn co --username=xx https:/yy zz “SSL handshake failed: Secure connection truncated” According to this link bug-ubuntu The solution is: sudo apt-get install libneon27 cd /usr/lib/ sudo rm libneon-gnutls.so.27 sudo ln -s /usr/lib/libneon.so.27 libneon-gnutls.so.27

Junit4 running parallel junit classes

To run junit testcases parallel, you can create your own class to run junit with: Add this tag to your class declaration. @RunWith(Parallelized.class) Implementation of this class looks like: package mypackage; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import org.junit.runners.Parameterized; import org.junit.runners.model.RunnerScheduler; public class Parallelized extends Parameterized {         private static class ThreadPoolScheduler implements RunnerScheduler     {         private ExecutorService executor;                 public ThreadPoolScheduler()         {             String threads = System.getProperty("junit.parallel.threads", "16");             int numThreads = Integer.parseInt(threads);             executor = Executors.newFixedThreadPool(numThreads);         }                 public void finished()         {             executor.shutdown();             try