Selenium WebDriver, Selenium Server and PageObjects by Example

March 6th, 2012 by

A lot has changed since Selenium RC and WebDriver has given us a new syntax to write tests for our web pages. PageObjects add an abstraction to the pages under test and finally we’re able to programatically start Selenium server instances and use them to run the tests.

In the following tutorial, we’re writing some tests using PageObjects, WebDriver, Selenium Server and finally we’re even taking some screenshots of our tested web pages..

 

Adding Selenium to your Project

Using Maven in our project there are two dependencies of interest for us – this first one is for Selenium including WebDriver and PageObjects:

<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>2.20.0</version>
</dependency>

If you’re planning to programattically startup a Selenium server instance then you need the following dependency for Selenium server

<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-server</artifactId>
    <version>2.20.0</version>
</dependency>

Now we’re ready to write some Selenium tests.. if you want to build the following examples, please add one additional dependency for jUnit to your pom.xml

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.10</version>
</dependency>
jUnit Testrunner in Eclipse IDE

jUnit Testrunner in Eclipse IDE

A simple Test using WebDriver

Our first test case is covering this scenario:

  • Open the Dzone.com website
  • Assert that a specific page title is shown
  • Enter a term in the page’s search form
  • Assert that a specific page title exists in the target page
package com.hascode.tutorial;
 
import static org.junit.Assert.assertEquals;
 
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;
 
public class WebpageTest {
	private WebDriver driver;
 
	@Before
	public void setUp() {
		driver = new FirefoxDriver();
	}
 
	@After
	public void tearDown() {
		driver.close();
	}
 
	@Test
	public void testGetTitle() {
		driver.get("http://www.dzone.com/links/index.html");
		assertEquals("dzone.com - fresh links for developers",
				driver.getTitle());
		WebElement searchBox = driver.findElement(By.id("mh_searchQuery"));
		searchBox.sendKeys("message driven beans");
		searchBox.submit();
		assertEquals("Search Results For: message driven beans",
				driver.getTitle());
	}
}

Selenium Server and Taking Screenshots

In this example we’re first starting a new instance of Selenium server that listens localhost, port 4444 (url: /wd/hub).

Afterwards we’re starting a client instance that instructs the server to open the Dzone.com website and takes a screenshot.

Finally we’re adding some assertions that the screenshot isn’t empty..

package com.hascode.tutorial;
 
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
 
import java.io.File;
import java.io.IOException;
import java.net.URL;
 
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.server.RemoteControlConfiguration;
import org.openqa.selenium.server.SeleniumServer;
 
import com.google.common.io.Files;
 
public class RemoteDriverTest {
	private static SeleniumServer server;
 
	@BeforeClass
	public static void setUpTest() throws Exception {
		RemoteControlConfiguration conf = new RemoteControlConfiguration();
		conf.setPort(4444);
		conf.setDebugURL("/wd/hub");
		server = new SeleniumServer(conf);
		server.start();
	}
 
	@AfterClass
	public static void tearDownTest() {
		server.stop();
	}
 
	@Test
	public void testTakeScreenshot() throws IOException {
		WebDriver driver = new RemoteWebDriver(new URL(
				"http://localhost:4444/wd/hub"), DesiredCapabilities.firefox());
 
		driver.get("http://www.dzone.com/");
 
		WebDriver augmentedDriver = new Augmenter().augment(driver);
		File screenshot = ((TakesScreenshot) augmentedDriver)
				.getScreenshotAs(OutputType.FILE);
		assertNotNull(screenshot);
		assertTrue(screenshot.exists());
		assertTrue(Files.toByteArray(screenshot).length > 0);
		driver.close();
	}
}

My screenshot looks like this:

Selenium Screenshot

Selenium Screenshot

Using Page Objects

PageObjects are used as an abstraction to a concrete web page and may be constructed using a PageFactory .. nowadays we’re also able to configure a page object using annotations..

In the following test we’re using Dzone.com’s search again and validate afterwards that a term is present in the search result page..

In the first step, we’re defining two page objects for the Dzone home page and the search results page .. the home page references the search box by its id and allows to search the site for a given term

package com.hascode.tutorial;
 
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;
 
public class DzoneHomePage {
	@FindBy(how = How.ID, using = "mh_searchQuery")
	private WebElement searchBox;
 
	public void searchFor(final String term) {
		searchBox.sendKeys(term);
		searchBox.submit();
	}
 
}

The page object for the search results page maps the div-element that contains the search hits by its id and allows a coarse search for a given term in those results

package com.hascode.tutorial;
 
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;
 
public class DzoneSearchResultsPage {
	@FindBy(how = How.ID, using = "content-inner")
	private WebElement searchResultWrapper;
 
	boolean containsSearchResult(final String term) {
		// for tutorial purpose only ;)
		return searchResultWrapper.getText().contains(term);
	}
}

This is the final test using page objects..

package com.hascode.tutorial;
 
import static org.junit.Assert.assertTrue;
 
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.PageFactory;
 
public class UsingPageObjectsTest {
	private WebDriver driver;
 
	@Before
	public void setUp() {
		driver = new FirefoxDriver();
	}
 
	@After
	public void tearDown() {
		driver.close();
	}
 
	@Test
	public void testSearchDzone() {
		driver.get("http://www.dzone.com/links/index.html");
		DzoneHomePage homePage = PageFactory.initElements(driver,
				DzoneHomePage.class);
		homePage.searchFor("message driven beans");
		DzoneSearchResultsPage resultsPage = PageFactory.initElements(driver,
				DzoneSearchResultsPage.class);
		assertTrue(resultsPage
				.containsSearchResult("Message Driven Beans in Java EE 6"));
	}
}

Running the test might look like the following screencast ;)

Tutorial Sources

I have put the source from this tutorial on my Bitbucket repository – download it there or check it out using Mercurial:

hg clone https://bitbucket.org/hascode/selenium-webdriver-tutorial

Resources

Tags: , , , , , , , , ,

One Response to “Selenium WebDriver, Selenium Server and PageObjects by Example”

  1. Hardik Says:

    Very nice article and explanation.

Leave a Reply

Please leave these two fields as-is:

Protected by Invisible Defender. Showed 403 to 81,008 bad guys.

Search
Categories