Thomas Sundberg

October 18, 2011

Testing a web application with Selenium 2

Selenium a great tool for testing web applications. The current version, Selenium 2, is a merge between Selenium and WebDriver. I will walk you through an example where we test a web site using Selenium in a few different ways. This is the same example as I demonstrated at Scandev on tour in Stockholm 18 October 2011.

Selenium IDE

Selenium IDE is a record and play tool available as a plugin to Firefox. We will start with it and record a simple search scenario.

Start Selenium IDE and follow these steps:

  • Start recording
  • Browse to http://www.yr.no
  • Choose the language English
  • Enter Stockholm in the search field
  • Click search
  • Follow the top link at the result page
  • Notice the weather forecast for Stockholm
  • Assert that the text ‘Weather forecast for’ is available on the page
  • Stop recording in Selenium IDE

Try to replay the scenario and notice that it navigates the same way as you just did. The largest strength with a tool like Selenium is, however, it’s possibilities to be developed and maintained in a programming language. Let’s export the current test case to Java and use it as a starting point for something that may be robuster and easier to maintain in the long run.

Export the test case as JUnit 4 (WebDriver) and save the file as SearchExportedFromIDETest.java in the directory src/test/java

The file location indicates that this will be a Maven project. A Maven pom is needed and one that is sufficient at this stage may look like:

pom.xml

<?xml version="1.0" encoding="UTF-8"?> <project> <modelVersion>4.0.0</modelVersion> <groupId>se.sigma.selenium</groupId> <artifactId>minimal</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>2.29.1</version> <scope>test</scope> </dependency> </dependencies> </project>

Back to the exported file. It looks like this:

src/test/java/SearchExportedFromIDETest.java

package com.example.tests; 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 SearchExportedFromIDETest { private WebDriver driver; private String baseUrl=""; private StringBuffer verificationErrors = new StringBuffer(); @Before public void setUp() throws Exception { driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS); } @Test public void testSearchExportedFromIDE() throws Exception { driver.get("/"); driver.findElement(By.id("sted")).clear(); driver.findElement(By.id("sted")).sendKeys("Stockholm"); driver.findElement(By.id("queryknapp")).click(); driver.findElement(By.xpath("//div[@id='directories']/table/tbody/tr/td[2]/a")).click(); driver.findElement(By.cssSelector("li")).click(); assertEquals("Weather forecast forStockholm (Sweden)", driver.findElement(By.cssSelector("h1")).getText()); } @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; } } }

It needs some cleaning up. Note that it is not good enough to be executed, it is among other things not placed in the correct package and it doesn’t have an address to the system under test set, the web application that should be tested. But it is a starting point.

Selenium WebDriver

We are now done with the IDE part. Selenium IDE is a great tool to record a scenario, but it should only be used as a starting point.

Some cleaning of the exported file will make it look something like this:

src/test/java/se/sigma/selenium/ide/SearchExportedFromIDETest.java

package se.sigma.selenium.ide; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.firefox.FirefoxDriver; import java.util.concurrent.TimeUnit; import static junit.framework.Assert.assertTrue; public class SearchExportedFromIDETest { private WebDriver driver; @Before public void setUp() throws Exception { driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS); } @After public void tearDown() throws Exception { driver.quit(); } @Test public void testSearchExportedFromIDE() throws Exception { String baseUrl = "http://www.yr.no"; driver.get(baseUrl + "/"); WebElement searchField = driver.findElement(By.id("sted")); searchField.clear(); searchField.sendKeys("Stockholm"); searchField.submit(); String topLinkXPathExpression = "//div[@id='directories']/table/tbody/tr/td[2]/a"; WebElement topSearchResult = driver.findElement(By.xpath(topLinkXPathExpression)); topSearchResult.click(); driver.findElement(By.cssSelector("li")).click(); String expected = "Stockholm"; WebElement actualHeadLine = driver.findElement(By.cssSelector("h1")); String actual = actualHeadLine.getText(); assertTrue(actual.contains(expected)); } }

It has been transformed into something that is executable and that may be easier to read. We could leave it like this, but then we wouldn’t be better than the average developer. Since we are better, we will try to make this example even more readable.

Something more readable might look like this:

src/test/java/se/sigma/selenium/po/SearchTest.java

package se.sigma.selenium.po; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; import static junit.framework.Assert.assertTrue; public class SearchTest { private WebDriver driver; @Before public void setUp() { driver = new FirefoxDriver(); } @After public void tearDown() { driver.close(); } @Test public void verifyThatStockholmCanBeFound() { HomePage home = new HomePage(driver); SearchResultPage searchResult = home.searchFor("Stockholm"); LocationPage stockholm = searchResult.clickOnTopSearchResultLink(); String expected = "Stockholm"; String actual = stockholm.getHeadLine(); assertTrue(actual.contains(expected)); } }

This implementation need some support classes and they will be an implementation of the Page Object design pattern.

Page Object Pattern

The idea behind the Page Object Pattern is that there should be one class that represents everything one page can do. If this object is used whenever any interaction with that page occurs, there will be just one place in test code that need to be maintained whenever a page changes. It is an attempt to make test less fragile.

The classes needed are:

HomePage

src/main/java/se/sigma/selenium/po/HomePage.java

package se.sigma.selenium.po; import org.apache.commons.io.FileUtils; import org.openqa.selenium.*; import java.io.File; import java.io.IOException; public class HomePage { private WebDriver driver; public HomePage(WebDriver driver) { this.driver = driver; String baseUrl = "http://www.yr.no"; driver.get(baseUrl + "/"); } public SearchResultPage searchFor(String location) { try { WebElement searchField = driver.findElement(By.id("sted")); searchField.clear(); searchField.sendKeys(location); searchField.submit(); } catch (RuntimeException e) { takeScreenShot(e, "searchError"); } return new SearchResultPage(driver); } private void takeScreenShot(RuntimeException e, String fileName) { File screenShot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); try { FileUtils.copyFile(screenShot, new File(fileName + ".png")); } catch (IOException ioe) { throw new RuntimeException(ioe.getMessage(), ioe); } throw e; } }

SearchResultPage

src/main/java/se/sigma/selenium/po/SearchResultPage.java

package se.sigma.selenium.po; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; public class SearchResultPage { private WebDriver driver; public SearchResultPage(WebDriver driver) { this.driver = driver; if (!driver.getTitle().contains("yr.no")) { throw new IllegalStateException("This is not yr.no: " + driver.getCurrentUrl()); } } public LocationPage clickOnTopSearchResultLink() { String topLinkXPathExpression = "//div[@id='directories']/table/tbody/tr/td[2]/a"; WebElement topResultLink = driver.findElement(By.xpath(topLinkXPathExpression)); topResultLink.click(); return new LocationPage(driver); } }

LocationPage

src/main/java/se/sigma/selenium/po/LocationPage.java

package se.sigma.selenium.po; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; public class LocationPage { private WebDriver driver; public LocationPage(WebDriver driver) { this.driver = driver; if (!driver.getTitle().contains("yr.no")) { throw new IllegalStateException("This is not yr.no: " + driver.getCurrentUrl()); } } public String getHeadLine() { WebElement resultPageHeadLine = driver.findElement(By.cssSelector("h1")); return resultPageHeadLine.getText(); } }

Take a screen shot on failure

Selenium 2 has the capability to save an image of the current browser. This may come very handy if a test fails. An example of an implementation is included in the HomePage implementation above. The specific implementation is this snippet:

private void takeScreenShot(RuntimeException e, String fileName) { File screenShot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); try { FileUtils.copyFile(screenShot, new File(fileName + ".png")); } catch (IOException ioe) { throw new RuntimeException(ioe.getMessage(), ioe); } throw e; }

This implementation is a small example on how it can be done. How you invoke it in your test project is up to you. I would consider to capture the browser every time an unexpected exception is thrown. How I would do it would depend on how I drive the browser.

Increased readability

The Page Object design pattern represents a good step in the direction of maintainability. But it is still hard to read for people who doesn’t care much about code. A way to increase the readability could be to use another tool to define the test. One such tool could be Cucumber.

Cucumber is a tool for Behaviour Driven Development, BDD. Or if you want Executable Specification or Specifications by Examples.

It works like this:

  • You specify a feature
  • The feature contains a set of scenarios
  • Each scenario consists of steps
  • The steps are then executed

In this example, a feature could look like this:

src/test/resources/se/sigma/selenium/cu/Search.feature

Feature: It should be possible to search for places at the Norwegian Meteorological Institute, http://www.yr.no Scenario: Locate Stockholm Given I want to know the weather forecast for coming days When I search for Stockholm Then I should be able to get a weather forecast for Stockholm

The format is

  • Given – set up the pre-requisites
  • When – execute the system under test
  • Then – validate the system under test

This format is easy to read and easy to discuss with people who understands the business and the reasons why we even develop the particular software.

To execute the specification above, we need to connect the feature with some code. It is done using a specific step definition class and a specific JUnit test class.

A JUnit test that connects the feature with some steps may look like this:

src/test/java/se/sigma/selenium/cu/SearchTest.java

package se.sigma.selenium.cu; import cucumber.api.junit.Cucumber; import org.junit.runner.RunWith; @RunWith(Cucumber.class) public class SearchTest { }

The steps that actually can execute the specification may look like this:

src/test/java/se/sigma/selenium/cu/SearchStepDefinitions.java

package se.sigma.selenium.cu; import cucumber.api.java.After; import cucumber.api.java.Before; import cucumber.api.java.en.Given; import cucumber.api.java.en.Then; import cucumber.api.java.en.When; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; import se.sigma.selenium.po.HomePage; import se.sigma.selenium.po.LocationPage; import se.sigma.selenium.po.SearchResultPage; import static junit.framework.Assert.assertTrue; public class SearchStepDefinitions { private WebDriver driver; private HomePage home; private SearchResultPage searchResult; @Before public void prepare() { driver = new FirefoxDriver(); } @After public void cleanUp() { driver.close(); } @Given("^I want to know the weather forecast for coming days$") public void prepareHomePage() { home = new HomePage(driver); } @When("^I search for (.*)$") public void search(String location) { searchResult = home.searchFor(location); } @Then("^I should be able to get a weather forecast for (.*)$") public void assertTheSearchResult(String locationName) { LocationPage location = searchResult.clickOnTopSearchResultLink(); String actualHeadLine = location.getHeadLine(); assertTrue(actualHeadLine.contains(locationName)); } }

The step definitions above may be harder to read compared to the JUnit code that executed the Page Object Pattern above. But the part that should be read by non developers are the features and they are definitely more readable then the JUnit code.

File structure and Maven

The file structure used in this example is:

example
|-- pom.xml
`-- src
    |-- main
    |   `-- java
    |       `-- se
    |           `-- sigma
    |               `-- selenium
    |                   `-- po
    |                       |-- HomePage.java
    |                       |-- LocationPage.java
    |                       `-- SearchResultPage.java
    `-- test
        |-- java
        |   `-- se
        |       `-- sigma
        |           `-- selenium
        |               |-- cu
        |               |   |-- SearchStepDefinitions.java
        |               |   `-- SearchTest.java
        |               |-- ide
        |               |   `-- SearchExportedFromIDETest.java
        |               `-- po
        |                   `-- SearchTest.java
        `-- resources
            `-- se
                `-- sigma
                    `-- selenium
                        `-- cu
                            `-- Search.feature

The final piece that is needed to execute this example is a Maven pom. It defines all dependencies needed and may look like this:

pom.xml

<?xml version="1.0" encoding="UTF-8"?> <project> <modelVersion>4.0.0</modelVersion> <groupId>se.sigma.selenium</groupId> <artifactId>example</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>2.29.1</version> </dependency> <dependency> <groupId>info.cukes</groupId> <artifactId>cucumber-java</artifactId> <version>1.1.2</version> <scope>test</scope> </dependency> <dependency> <groupId>info.cukes</groupId> <artifactId>cucumber-junit</artifactId> <version>1.1.2</version> <scope>test</scope> </dependency> </dependencies> </project>

Conclusion

Selenium 2 is a tool that can be used to verify web sites. It is a merge between Selenium 1 and WebDriver. Code generated out of the box from Selenium IDE is not really nice. It is better to evolve it and implement the Page Object design pattern.

Reading tests is difficult if you don’t like reading code. Defining the specification using Cucumber may be a better way. Cucumber can then be used to execute the tests.

Acknowledgements

This post has been reviewed by some people whom I wish to thank for their help

  • Malin Ekholm
  • Johan Karlsson

Thank you very much for your feedback!

Resources

About these ads

74 Comments »

  1. Just Perfect. Thank you.

    Comment by Lucas Zago — October 26, 2011 @ 18:01

  2. When I try to run multiple scenarios happens a bizarre behavior.

    Comment by noone — October 26, 2011 @ 19:41

    • Do you have an example of this behavior?

      Comment by Thomas Sundberg — October 26, 2011 @ 20:11

      • It runs a “Given” in a scenario and the same time it runs a When in another scenario.

        Comment by noone — October 26, 2011 @ 20:35

  3. Are the regular expressions for your Gven and When the same?
    A better place for this type of questions are the Cucumber mailing list, read more about it here: http://groups.google.com/group/cukes

    Comment by Thomas Sundberg — October 27, 2011 @ 05:14

  4. For some reason @Before isn’t firing for me?

    Comment by Kevin Douglas Gann — October 28, 2011 @ 20:37

    • There are two different @Before used in this example.
      org.junit.Before
      and
      cucumber.annotation.Before

      Which one doesn’t fire? The JUnit @Before will not fire before a Cucumber @Given

      Take a closer look at your imports and verify that you are importing the correct before.

      HTH
      Thomas

      Comment by Thomas Sundberg — October 29, 2011 @ 04:24

      • You’re correct. I wrote into my existing code not noting those particular imports. /me failed. :)

        Comment by Kevin Douglas Gann — October 29, 2011 @ 15:21

  5. Why Selenium isn’t scoped test?

    Comment by Christian Goudreau — February 15, 2012 @ 23:18

    • It could have the scope test. I missed it when I wrote the example.

      Comment by Thomas Sundberg — February 16, 2012 @ 06:19

  6. hello Thomas,
    j see that You have experience of working with selenium webdriver,
    how j can design tests for big web aplication made in smartGwt framework?
    j’ll be glad for some adcives :)
    forgive me my bed english…:(
    thanks for reply

    Comment by wojtas — March 1, 2012 @ 11:18

    • Hi!

      Please read the mail I sent you.

      Thomas

      Comment by Thomas Sundberg — March 1, 2012 @ 22:36

      • hi,

        thanks for advices :)

        j’m waiting for your post.

        wojtas

        Comment by wojtas — March 2, 2012 @ 14:59

      • Hello Thomas,

        I am also about to start to write Selenium webdrive for a SmartGWT app, do you mind sharing any information you have on this?

        Regards,
        Theo

        Comment by Theo — July 8, 2013 @ 17:55

      • Hi!

        I don’t have any specific information regarding SmartGWT. What is different from any other web application?

        /Thomas

        Comment by Thomas Sundberg — July 8, 2013 @ 18:06

  7. Hello Thomas,

    I am new to cucumber, I followed all the steps you mentioned above, but I could not run the feature, I had to learn maven.
    here are what I did.

    I created all the classes you mentioned.
    I created a POM file with the following artifacts (junit
    selenium-java
    cucumber-core
    cucumber-picocontaine
    cucumber-junit
    picocontainer)
    eclicpse added the version automatically

    After that I right clicked on POM ->run As->maven assebly:assembly.

    please could you help me execute the feature. ( what i missed to do?)

    Thank you.

    Comment by zak — March 1, 2012 @ 22:53

    • Hi!

      I have a hard time to know what you did wrong wince you don’t tell me what error you got. What happened when you executed the project from a prompt? I would start to eliminate Eclipse out of the equation.

      One possible problem could be that you have missed the location of one or more files.

      Thomas

      Comment by Thomas Sundberg — March 2, 2012 @ 06:12

      • Hello Thomas,

        everything is working fine.

        is there a way in maven to create good reports like ant generate ? if so could you please tell me how to do it or send me a link.

        Thank you.

        Comment by zak — March 15, 2012 @ 18:43

  8. hello,

    your article: “What is good test?” is great :)
    I write my tests in accordance with what you wrote,
    tests are clear and they do their job very well :)

    thank you very much Thomas, my work now is easier :)

    Now my problem is integrate selenium with junit and hudson,
    my boss want to do this but j dont know hudson,

    you can help me?

    j set up hudson on tomcat aplication server (localhost),
    j get plug-in hudson-seleniumhq to run simple test record in selenium IDE,
    but j dont know how to run selenium2webdriver tests,
    they are in svn repository

    maybe you know somethig how to do this or you can send me links where is something about this problem?

    thanks
    wojtas

    Comment by wojtas — March 12, 2012 @ 17:08

  9. hello Thomas,

    Sorry for the delay reply,

    I have repeated the steps you mentioned in your article, and everything worked as expected.

    but i still have one quesion, is it possible to associate the results from target/sunfire-report with ant to get a good report?

    Thanks again for this article and for your help.

    Comment by zak — March 15, 2012 @ 16:23

    • Hi!

      You could try to use the html formatter for Cucumber. I haven’t really used it so I can’t say much about it yet. Take a look at https://github.com/cucumber and look for examples using the html report.

      Good luck!
      Thomas

      Comment by Thomas Sundberg — March 15, 2012 @ 18:48

  10. hello,

    it is possible to test smartgwt aplication using selenium htmlunitdriver?

    Thanks

    Comment by wojtas — March 16, 2012 @ 14:46

  11. Very good post thank you, is the full code for this example available anywhere?

    Cheers,
    Raf

    Comment by Raf — March 19, 2012 @ 13:00

    • Hi!

      The full code is not available anywhere. But all that is needed is available here. I see a pedagogic point having people to either copy the code or re-write it themselves, so this is what I would suggest if you need a starting point.

      The way to learn is first to copy something and later do it yourself. Or as the saying goes among musicians, fake it until you make it :)

      HTH
      Thomas

      Comment by Thomas Sundberg — March 19, 2012 @ 13:08

  12. Hi Thomas,

    Not sure if the thread is still active or not. I am very new to cucumber and am trying to implement it to my existing selenium tests. Your post was very helpful. Thanks a lot.
    I just had an elementary question.

    How will my feature file Search.feature be linked to the Junit testcase SearchTest.java? I dont see any references asking testcase to look for Search.feature.

    Also in my framework I use ANT and TestNG. Is there anything i should be doing extra for it?

    Thanks in Advance.
    Sarthak

    Comment by sarthak83 — April 17, 2012 @ 14:12

    • Hi!

      The connection to your feature files is done in he file src/test/java/se/sigma/selenium/cu/SearchTest.java with the annotation @RunWith(Cucumber.class)
      It will execute Cucumber and look for feature files in the class path. All feature files found in it’s own package or any sub packages will be used. My example feature, Search.feature, is located in the package se.sigma.selenium.cu and will therefore be picked up. It is actually located in the directory src/test/resources/se/sigma/selenium/cu/ which will be interpreted as the package se.sigma.selenium.cu when you use Maven.

      I don’t think using TestNG will affect anything special. You will have to use the JUnit runner to kick off Cucumber from JUnit. But if you want you could explore the command line tool and kick it off using that.

      If you use Ant, then take a look at this example to get it up and running:

      https://github.com/cucumber/cucumber-jvm/blob/master/examples/java-helloworld/build.xml

      I hope this answers your questions.
      Thomas

      Comment by Thomas Sundberg — April 18, 2012 @ 05:38

  13. If I want to use cucumber what are the steps involved and what other tools are required, I use Webdriver with Java and eclipse as apreferred IDE, I am not familiar with BDD as well and what are the real benefits of using BDD in a real tiem project

    Comment by keki — May 18, 2012 @ 05:02

    • Hi!

      You ask many questions. Let me try to divide them in different parts.

      * Tools needed
      I would recommend using Maven as you build tool. It will assist you to get all the dependencies you need, cucumber-java and cucumber-junit and so on.
      If you are more familiar with Ant, use Ant insted. Check out the https://github.com/cucumber/cucumber-jvm/tree/master/examples/java-helloworld example for more information.

      * Steps involved
      Define what behavior you want in a scenario, define it using the Given, When, Then format.
      Given – Setup the system under test
      When – Execute something in your system that changes its state
      Then – Verify the state change
      Start with next step.
      See the workflow at http://cukes.info/

      * What is the benefit in a real time project
      Communication, documentation, regression tests

      Communication: The Given, When, Then format is easy to discuss and easy to understand. A stake holder could write or or at least understand and discuss it
      Documentation: You may get a html report that contains all scenarios that will tell exactly what you have verified and what acutally passed the verification step.
      Regression tests: You execute all your scenarios continuously and will very soon know if someone broke the system or not

      I hope this answers your questions.
      Thomas

      Comment by Thomas Sundberg — May 19, 2012 @ 05:58

      • Hi Thomas
        Thanks for a very quick reply, it will surely help and I will be on it now. I dont know how this sounds, but in a development environment is it ok if we straight away write our selenium automation test instead of using pageobjects with cucumber?

        Comment by keki — May 21, 2012 @ 03:39

      • Hi!

        I would say that it depends. It is not a matter of doing it only one way or another way. If you feel that writing code that uses Selenium without structuring you code to use the page object pattern, then do that. If you feel that the page object patterns makes life a little easier, then use the page object pattern. Finally, if you think that using Cucumber would make your life easier, then use Cucumber.

        The most important think is not which tools you are using or which pattern you are using. The most important thing is that the system works when your customer uses it. How you got it working is less important.

        I think that Cucumber helps me to focus on getting the right thing verified so I like to use it for that reason. It will also give me the possibility to a nice report that a customer could read and see what actually has been verified. These are enough reasons for me to use tools like Cucumber.

        So, what style you are using when you write your code or which tools you use is not the most important thing. Test different ways and use the tools that works for you.

        HTH
        Thomas

        Comment by Thomas Sundberg — May 21, 2012 @ 05:15

  14. Thanks once again

    Comment by keki — May 22, 2012 @ 06:38

  15. Hi Thomas,
    I ma trying to implement Jbehave with webdriver I keep on getting an error no class found, could you please let me know what am I doing wrong below is the code

    public class LoginStepsGlue extends JUnitStories {

    private WebDriverProvider driverProvider = new PropertyWebDriverProvider();
    //private WebDriverSteps lifecycleSteps = new PerStoriesWebDriverSteps(driverProvider);
    private SeleniumContext context = new SeleniumContext();
    //private ContextView contextView = new LocalFrameContextView().sized(500, 100);
    public Configuration configuration;

    @Override
    public Configuration configuration() {
    return new SeleniumConfiguration().useSeleniumContext(context).useWebDriverProvider(driverProvider);

    }

    @Override
    public List candidateSteps() {
    return new InstanceStepsFactory(configuration(), new LoginSteps())
    .createCandidateSteps();

    }

    @Override
    protected List storyPaths() {
    return Arrays.asList(“D:/Selenium/WorkFiles/EclipseCode/BDD/src/stories”);
    }

    }

    Comment by keki — July 5, 2012 @ 04:50

    • Hi!

      I really can’t say whats wrong with your code. Chances are that there isn’t anything wrong and that you are missing a dependency. Are you sure that all dependencies needed are available in your project?

      /Thomas

      Comment by Thomas Sundberg — July 5, 2012 @ 05:53

  16. Thanks, its working now the story path was not set correct, could you provide your thoughts on this PLEASE. Is it ok if we decide to implement BDD at a later stage in a Dev project or we simply cannot, and also I used jbehave-simple-archetype to set up my practice project I got src/main/java and src/main/resources as my directory structure, whereas you get src/main/java and src/test/java. does that make any difference to our working and is it advisable to use a particular archetype for test project involving Jbehave and Selenium.
    thanks keki

    Comment by keki — July 6, 2012 @ 04:49

    • Hi!

      I interpret your questions as this:

      Q: Do we need to start using BDD from the beginning in a project or is it possible to start using BDD when we have worked with the project for some time?
      A: I think you can benefit from using BDD from the beginning but it is possible to add it later.

      Q: Which Maven structure should be used?
      A: It depends. The one you describe above, with everything in main/*, will result in packaging the test resources into the production jar. The separation I have used, some stuff in main/* and some stuff in test/*, will only ship the stuff in main/* and not include the test resources. You want to read up some more om the behavior on Maven before you decide what you want for this project.

      Q: Should a specific archetype be used when setting up a Maven project that has dependencies to Selenium and JBehave?
      A: If you find a good archetype, then use it. Personally I seldom use archetypes. I set up my Maven projects manually and add whatever dependencies I need to it.

      HTH
      Thomas

      Comment by Thomas Sundberg — July 6, 2012 @ 05:59

      • Hi Thomas,
        I can understand that this concepts work fine when the system is partially or fully developed and the UI is at its best but during the initial iterations when the UI is not yet up or developed, we can still establish acceptance criteria and write a .story file but how or from what docs are we suppose to write the Page Objects, Step files using Webdirver that gets wired to the Config and the .story file.

        Comment by keki — September 20, 2012 @ 02:02

      • Hi!

        It looks to me that you are making the assumption that an acceptance test must be executed through the user interface and that you have to implement it using a specific pattern. This is not correct. If you want to implement an acceptance criteria for the flow through your system, you can do that using the Page Object Pattern without any html pages. You can still write methods that exercise the flow, but without interacting with the GUI.

        I am not sure what documentation you should use to base your implementation for verifying the systems behavior, but what about asking the same persons that does the implementation? They have something that their implementation is based on.

        Notice that the Page Object Pattern can be used for any flow in a system. It doesn’t require a set of pages to navigate between.

        HTH
        Thomas

        Comment by Thomas Sundberg — September 20, 2012 @ 06:42

      • You are right about the assumption, just trying to learn things and get my head around it. I thought Page objects can only be used to wire your test steps if we are using BDD (Jbehave or cucumber). I am afraid I do not know how you can do that using the Page Object Pattern without any html pages / UI. Could you point me to some resource or link on the net

        Comment by keki — September 21, 2012 @ 08:54

  17. Thanks Thomas

    Comment by keki — July 9, 2012 @ 10:45

  18. Hi Thomas,
    I have started using the Cucumber testing.. I want to integrate the SOAP UI with Cucumber. How can i achieve it?

    Comment by Rameez Raja — August 3, 2012 @ 10:31

    • I an using Java language to write the Step Definition file.. Could u please tel how can i configure the SOAP UI with Cucumber?

      Comment by Rameez Raja — August 3, 2012 @ 10:33

      • Hi!

        You will not use Cucumber to control the SopUI GUI. You will rather use SopaUI to create a project file and then use Cucumber to vary parameters in the SoapUI project when you execute your project.

        HTH
        Thomas

        Comment by Thomas Sundberg — August 14, 2012 @ 10:23

    • Hi!

      You can control SoapUI from Cucumber, or any other Java implementation, as I describe above in the JUnit testcase.

      Create a SoapUITestCaseRunner, set some properties on it and execute the SoapUI project file. You want to use SoapUI to create the project file. Executing from Cucumber is the same thing, retrieve properties from the feature and apply them on a SopaUI project.

      HTH
      Thomas

      Comment by Thomas Sundberg — August 14, 2012 @ 10:21

  19. Very good … the better that I found ….
    Thanks ….

    Comment by Dávisson Húdson — November 22, 2012 @ 15:08

  20. Hi Thomas,
    This article is really a very useful guide.I am new to selenium as well as to selenium webdriver and am following exactly as you had mentioned step by step right from the selenium IDE installation to writing a simple script.
    My main problem is am unable to save my .java file created from selenium IDE to src/test/java.How do I create this structure.I believe from maven is it?Could you give me exact step for creation as am confused in this hierarchy.
    Also,what was the src/test/java/se/sigma/selenium/ide/ you mentioned if I create using
    mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

    where does the part se/sigma/selenium/ide fit ?

    I got the above command from Maven website.
    I have gone through all websites but nowhere apart from yours, is it given a simple step for conversion of a script generated from IDE to exporting the same to eclipse and how to save it.What should be the hierarchy?
    I would be thankful if you could help me as am stuck in this.
    -Jagori

    Comment by Jagori — February 14, 2013 @ 11:10

    • Hi!

      I am glad you liked it.

      The structure src/test/java is indeed a Maven structure. I usually create these directories manually from the root of the directory where you keep your files. So, create the src directory manually. Create the test directory manually on the src directory and so on.

      The structure src/test/java/se/sigma/selenium/ide/ is a mix of two things. To start with, it is the test structure that Maven will use to locate test classes written in Java. This is the first part of it, the directories src/test/java. The second part is the package structure I choose to use. Packages in Java are directories so the part se/sigma/selenium/ide is the directories needed to be able to put the test class in a package called se.sigma.selenium.ide. Using a package is not mandatory, you can save the Java file you generate from Selenium Ide in the directory src/test/java and Maven will be able to find it.

      I very seldom uses the mvn archetype:generate mechanism to create my Maven projects. They tend to do a lot more than I want so I avoid them.

      Did this answer your questions or do you have more questions? Please don’t hesitate to ask them if you want.

      HTH
      Thomas

      Comment by Thomas Sundberg — February 16, 2013 @ 11:14

  21. Loved the discussion — the specifics of refactoring a “raw” selenium test in order to make it more palatable was pure gold and reflects an area which is all too often neglected in other blogs and tech-notes.

    On another level, it would be helpful to discuss the mechanics of incorporating the “cleansed” code back into eclipse and rendering it executable as a jUnit test (presumably jUnit4, although I’m not proud — I’ll take what I can get). This discussion glosses over the mechanics of this process, and as we all know it is a lot more complicated than just clicking “File->New->Java Project” and dropping the aforementioned code into a src folder. Precisely because this process is fraught with difficulties and the Se website lacks a corresponding “best-practices” template for doing it properly, I was sort of hoping you or a guru of similar caliber could step up to the plate and take a swing at it. People all over the planet would worship at temples erected in your name subsequently!

    – Dave Lovering
    loveringd@gmail.com

    Comment by David Lovering — February 14, 2013 @ 18:56

    • Hi!

      I am glad you liked it.

      If I understand you correctly, you are missing a discussion that would start with a generated Java class and transform it to a test class. The test class should be as clean and as maintainable as possible. Clean code is a large subject and something that is close to my heart.

      I kind of think that I actually have created and shown a test that is possible to use in Eclipse as a JUnit test. Cleaning the code so it gets maintainable is obviously something I could add. It would, however, probably be a separate post.

      It seems as if you apologize for using JUnit4. I would not apologize for using a good tools and in my opinion, JUnit is a good tool.

      Thomas

      Comment by Thomas Sundberg — February 16, 2013 @ 11:25

  22. Oh thanks so much Thomas..Am sorry for the delay in replying back and in checking.
    Sorry I just missed out on your responses earlier.Thanks for clearing my doubts.
    I will proceed further, now that this part is cleared.
    I am eager to learn selenium2 and really need guidance from someone in this.
    I sure would get back to you if I am stuck anywhere.I hope I don’t overload you with too many questions…:)
    Thanks..
    –Jagori

    Comment by Jagori — February 22, 2013 @ 10:02

  23. Hi Thomas,
    I had few more doubts:

    1.How do I create multiple versions of my test file corresponding to a single project and how do I make that reflect in my pom file.Do I need to create multiple pom files.What would be the hierarchy in that case ?
    2.Also,how do I import my test to Eclipse
    I tried using the mvn eclipse:eclipse and the steps as mentioned in some site as below:
    # File -> Import… # General -> Existing Projects into Workspace # Click next # Next to “Select root Directory:” click “Browse” button # locate the project folder containing your pom.xml and click ok. # Your project should appear in the “Projects” box already # click finish

    Am not clear with the role of mvn eclipse:eclipse
    Although my tests did get imported
    Is there anything else I need to do get started.Also,if I right click on project name in eclipse it shows one option under BuildPath->Use as source folder ,what’s that for?

    3.What is the role of dependencies in the pom file.Whatever I am mentioning within this tag ,this would get handled by maven during compilation?I don’t actually need to install it?Correct me if I am wrong.

    Pardon me if am asking too many general questions.
    Looking forward to a reply from your end.

    Thanks,
    Jagori

    Comment by Jagori — February 23, 2013 @ 09:29

    • Hi!

      1. I actually don’t understand your question. What is it that you want to duplicate and why?

      2. I don’t know to much about Eclipse. I do know that it isn’t worth my time to use Eclipse. I use Intellij Idea, the community version, and mutli module projects just works like a charm out of the box. You may want to test it, http://www.jetbrains.com/idea/
      This Stackoverflow question may help you somewhat with Eclipse: http://stackoverflow.com/questions/4294498/multi-module-maven-project-in-eclipse

      The role of mvn eclipse:eclipse is to create the project files needed to create an Eclipse project from Maven so all you should have to do is open this new project. I don’t know if it works well or not.

      3. The role of the dependencies in the pom is to define things that the project needs. This is one of the best parts with Maven. You define that you need a library, say JUnit. You specify the version of JUnit and Maven will download it and it will be available to your project. You never need to install anything. It gets downloaded and will be available in the class path. If you use Idea, it will be added to the class path and just be available. Idea will also download the dependencies and add them to your local Maven repository.

      I hope this helped you.
      Thomas

      Comment by Thomas Sundberg — February 23, 2013 @ 11:07

  24. Hi Thomas,
    Thanks for your replies.It’s of great help to me.Do you suggest using Intellij Idea?I would then definitely have a look at this.
    Related to my query #1 ,what I meant was ,suppose I create version 1 of my test file and now at certain point of time,my project also undergoes some new changes and I want to do some kind of configuration control so that now I wish to create version 2 of my test file with some newly added cases or suppose my previous cases have now undergone changes.

    In that case what should I mention under version tag in pom.xml?Every time I make changes to my test file,would version be constant in pom.xml?
    I hope am able to phrase my query clearly ..
    Thanks,
    Jagori

    Comment by Jagori — February 23, 2013 @ 14:53

    • Hi!

      Your questions tells me that you want to version control the files. You want to use a tool like Git, Mercurial, Subversion or similar to be able to track any changes that has been done on each file. The version in the pom file can be used to create a new release of your project that other an depend on.

      The workflow is something similar to this:
      * You start with a version, say 1.0.0-SNAPSHOT
      * Work on it for a while, saving all changes in the version control system. I.e. Git, Mercurial etc.
      * When you want to release it, you change the version number in your pom to say 1.0.0
      * Perform the release, i.e. making your work available to others through Maven central or an internal repository manager like Nexus
      * Increase the version number to 1.0.1-SNAPSHOT
      * Repeat the cycle with more good things

      A version number that contains the word SNAPSHOT is considered to be work in progress and people understand that it is subject for change. A released version, say 1.0.0, will never be changed. If you want to to use the same version indefinitely, you may do so.

      Did this answer your question or did I confuse you?
      Thomas

      Comment by Thomas Sundberg — February 24, 2013 @ 09:48

  25. Hi Thomas,
    My sincerest thanks to you for your help and replies.
    I got your point.You mean whenever I work I should start with 1.0.0-snapshot then finally when have reached the stage of release should change to 1.0.0 and then when again I resume my new changes I should change it to 1.0.1-snapshot say and likewise..
    Can I use tortoise svn for version control because that’s the one am bit familiar with or would I have to make use of Git/mercurial?

    Also,one more thing which I wished to know was ,every time suppose I introduce a new dependency in my pom.xml file,how would the same get imported to my project in Eclipse /IntellijIdea? Is it automatic?

    Meanwhile,am going through intellijidea too..have installed it and am trying to import my project there.I am facing some error though but am hoping would be able to resolve myself or else would seek your help on this.:)

    I needed some guidance on few things from you regarding automation.I have a good experience of testing but majority of my experience has been on the manual side.I do sound a bit backward…
    I have heard most people saying that they like automating things whenever they find a chance and don’t rely much on manual testing.Yesterday I had been to an event conducted by ANZTB on automation practices here in Sydney and it was wonderful and very encouraging ,sharing experiences with so many people and by the presenter himself.

    I too have realized there are many tasks which if automated can give better results than when done manually.Since Selenium is one tool which is being widely used these days,so have decided to focus on this.
    But ,a person like me who has just 1 yr dev experience on LAMP(Linux,PHP,MySQL) and with just basic experience in java,how far would I be able to proceed?
    How much development experience would you suggest is actually needed while automating things.I am very keen on learning whatever skills are needed.Would I have to be a hard core java developer or are there certain things which I should master before I begin with automating.

    If you could guide me on how to proceed and what should be my approach?
    Looking forward to your reply.
    Regards,
    Jagori

    Comment by Jagori — February 27, 2013 @ 07:56

    • Hi!

      I would suggest that you use Subversion if you are familiar with it. You will save every small step in subversion. When you are ready for a release, create at tag from trunk in subversion. Then continue working with the next things in trunk.
      You can use the Maven release plugin for performing the actual release.

      Including new dependencies when you use Idea is automated. Idea will ask if you want to do it automatically or not, say yes to this question.

      Regarding automation, I cannot say or speculate in how many years of experience a person needs to do a specific task. It depends a lot on the person, the environment he or she works in etc. A person with limited experience in a supporting environment can achieve miracles. An experienced person in a non-supporting environment can probably not make a difference.

      Spend time with the problem and you will be better and better. Talk to other people, find someone else who also is interested and work together.

      This is just general advices, but i can’t offer anything more specific.

      Cheers
      Thomas

      Comment by Thomas Sundberg — March 12, 2013 @ 12:14

      • Hi Thomas!
        Thanks..understood.Yes you are right would have to keep working at it.:)
        Thanks for the suggestions.

        Comment by Jagori — March 12, 2013 @ 12:28

  26. Hi Thomas, Great post!
    I have got this strange behavior problem..could you please provide your thoughts on this?
    Got solution of getting custom reports using Jbehave as I need to make changes in FTL files but this then cultivates in another problem as
    “I made changes in ftl file so that I can get a customized report by removing columns which i wanted in order to get customized report. Everything worked when I run through eclipse IDE but when I tried to run through command lines(with maven commands), the new report format is not picking up by for report generation. Any idea about why jbehave is behaving such a way? I am using Git, and FTL file changes are only made on local branch and not on the master one. The maven command I am using to run the test case as mvn clean test -Dtest.application= x value ”

    More similar description could be :
    In my project I have customized report generation by making changes in FTL files of resources folder..my folder structure is looks like src/main/java and src/main/resources…now when I am running through IDE(eclipse) when the reports are generated in target folder, there are generated as per the changes made in FTL file but when i try to run through maven command line, the reports are not getting generated with changes i made in ftl file …so somehow call is not being reached to src/main/resources folder where changed FTL file places..any idea why? what could be actual problem and its solution?

    Why maven is behaving in such strange manner? I have manually copy pasted resources folder under src/main and then through eclipse add it into classpath..

    Comment by Kaustubh — April 28, 2013 @ 14:20

    • Hi!

      Unfortunately I have a short answer to your long question. I actually don’t know.

      My theory is however that it is a class path issue. Have you made a mistake when you spelled the directory resources? Did the report get generated before you did the changes to the FTL files? (I don’t know what a FTL file, I had to google it and understand that it has something to do with FreeMarker).

      The way I would approach this type of problem is by reverting to a working state. I would then re-implement my changes step by step and very carefully verify after each tiny step that it still works.

      I am sorry that I’m not able to give you more precis advice.
      Thomas

      Comment by Thomas Sundberg — April 28, 2013 @ 20:09

      • Thanks for the reply Thomas..No probs in not providing advice.
        Have you made a mistake when you spelled the directory resources?[Kaustubh]: No, I did not make mistake while naming the report directory resources..
        Did the report get generated before you did the changes to the FTL files?[Kaustubh]:Yes, these were generated in Target folder and as per code present in FTL files.
        My theory is however that it is a class path issue.Kaustubh]: Hmm, that could be the case, When I manually added resources folder to my directory structure(src/main), under eclipse, I right click on resources folder and gone to add to build tab , added over to class path..
        Now, if i want to do the same through maven what is way to add to class path for such resources folder?Is there something I need to make changes in POM.xml? Please advice..I am not expert in Maven hence asking this another question…please suggest.

        Comment by Kaustubh — April 29, 2013 @ 00:28

      • Hi!

        Anything you add to the directory src/main/resources will be a part of the classpath and anything you place in src/test/resources will be added to the test classpath. That’s why I asked if you have spelled resources correct. Do you have a directory for the sources called src next to your pom.xml?

        HTH
        Thomas

        Comment by Thomas Sundberg — April 29, 2013 @ 19:50

  27. Well, I got structure in POM like mentioned below..is something I need to change so that Maven can read resources folder I have placed under src/main as eclipse could read it when I added in the class path by configuring the build path in IDE and when I try to run test from eclipse , the resources folder was getting read , hence custom reports were generated..How we can make maven to read resources folder?Please suggest as I am not an expert in maven build tool.

    src/main/java
    true

    **/*.java

    src/main/java
    true

    src/main/resources
    true

    4.0-beta-3
    3.5.4
    3.1.1
    2.31.0

    .
    src/main/java/com/project Name/Project name_1/configuration

    application envionment name
    application suite name

    StoryDriver

    true

    **/${test.application}StoryDriver.java

    Comment by Kaustubh — April 30, 2013 @ 16:26

    • Hi!

      As far as I can see and understand from your comment above, it should work. Obviously it doesn’t. I need to see your entire project to be able to say more. Drop me a mail and attach your files as a zip file. There is something broken and without seeing all the files I can’t say what.

      /Thomas

      Comment by Thomas Sundberg — May 1, 2013 @ 09:56

  28. Great write-up! Very thorough. I’ve crafted a similar write-up with examples in Ruby. If you’re interested, you can see it at http://elemental-selenium.com/tips/7-use-a-page-object

    Comment by Dave Haeffner (@TourDeDave) — July 9, 2013 @ 22:52

  29. hi ,

    is selenium only record and test tool. Can we not have test case writen and run by selenium. I am a starter so can you help me out with this. For example if i want to check for a login page and if i have n number of test cases how can i run them or execute in selenium.

    Thanks,
    Sandhya

    Comment by sandhya — October 4, 2013 @ 08:49

    • Hi!

      This example starts with a recoding and is then transformed into something executed from a Java program. There is no need to start with the recoding part if it doesn’t bring you any value. In that case, start writing your test directly in code and execute them as any test.

      In a sense, skip the first part of this blog and just follow the later part of it. That would behave as I interpret that you want.

      /Thomas

      Comment by Thomas Sundberg — October 6, 2013 @ 20:35

  30. Hi thanks a lot

    Comment by ritu7180Ritika — August 27, 2014 @ 14:04

  31. Love u man I got exactly what I need.

    Comment by Abhinav Kumar Singh — September 8, 2014 @ 11:55

  32. Great work!! Just wanted to see if you can answer my question. how to verify whether filed is present in specific section of the page instead searching in entire page. As filed with same name might exist in two places.

    Comment by Usmaan — November 19, 2014 @ 20:01

    • Hi!

      I would try to avoid to have the same name on more than one item. Your question would not be valid if that is the case.

      If that isn’t possible, then would I locate the section on the page where the item should be and then locate the named element within that section. Location the desired section could hopefully be done using a good id on a div. If you don’t have any id to help you, search using path or css. The result is then searchable using findElement(By.name(“wanted element”)) and that should get you your desired element.

      HTH
      Thomas

      Comment by Thomas Sundberg — November 20, 2014 @ 07:38


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Silver is the New Black Theme. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 60 other followers

%d bloggers like this: