Multi-browser test with Selenium

In this post, I will describe how to implement a project to automatize manual tests for different browsers using Selenium and JUnit. I will show how to design a Selenium project and how to execute a unit test in several browsers at once without duplicate code.

The page to be tested has an input text and a button that displays the text typed in the input text. Below you can see a screenshot of the page.

Selenium test page

The important elements of the html code of the page are:


<input id="test-input" type="text" />
<button id="test-button">Show text</button>
Typed text: <span id="test-text"></span>

Creation of Page Class

First, I create the page class that represents the web page. It follows the Page Object model pattern containing the html elements as Selenium web elements and the actions that can be executed in the page as methods.


public class IndexPage {
	
	private static final String PATH = "/selenium-test";

	@FindBy(xpath="//*[@id='test-input']")
	private WebElement inputText;
	
	@FindBy(xpath="//*[@id='test-button']")
	private WebElement button;
	
	@FindBy(xpath="//*[@id='test-text']")
	private WebElement text;
	
	public IndexPage(WebDriver driver, String url) {
		driver.get(url + PATH);
		PageFactory.initElements(driver, this);
	}
	
	public void fillInputText(String text) {
		inputText.sendKeys(text);
	}
	
	public void clickButton() {
		button.click();
	}
	
	public String getText() {
		return text.getText();
	}
}

The important parts of the class are:

private static final String PATH = "/selenium-test";

Define the relative path of the page in the web application.

@FindBy(xpath="//*[@id='test-input']")
private WebElement inputText;

Declares the web element that represents the input text where the text can be typed. The annotation @FindBy indicates to Selenium how to find the element. In this case, the element can be found using a xpath expression. It’s also possible to find the element by id, css, etc. The other 2 elements of the page are declared in the same way.

public IndexPage(WebDriver driver, String url) {
   driver.get(url + PATH);
   PageFactory.initElements(driver, this);
}

The constructor receives the driver of the browser and the url of the web application. It will access to the web page defined by the url of the web application and the relative path of the page. Then it will initialize the web elements of the page, looking for all the properties annotated as web elements with the annotation @FindBy.

public void fillInputText(String text) {
   inputText.sendKeys(text); // introduce a text in the input text
}

public void clickButton() {
   button.click(); // click the button
}
	
public String getText() {
   return text.getText(); // get the text contained in the web element
}

These 3 methods define the user actions that can be executed in the page.

Creation of Unit Test

Finally, I will create a JUnit test class to test the page with several browsers and without duplication of code. It will use the JUnit parameterized test feature that allows to run the same test several times using different values.

@RunWith(value = Parameterized.class)
public class IndexPageTest {

	private WebDriver driver;

	private String driverName;

	private static final String URL = "http://walfen.com";

	public IndexPageTest(WebDriver driver, String driverName) {
		this.driver = driver;
		this.driverName = driverName;
	}

	@Parameterized.Parameters(name = "{1}")
	public static List<Object[]> listWebDrivers() {
		List<Object[]> webDrivers = new ArrayList<Object[]>();
		webDrivers.add(new Object[] { new HtmlUnitDriver(true), "HtmlUnit" });
		webDrivers.add(new Object[] { new FirefoxDriver(), "Firefox" });
		System.setProperty("webdriver.chrome.driver", "src/main/resources/chromedriver.exe");
		webDrivers.add(new Object[] { new ChromeDriver(), "Chrome" });

		return webDrivers;
	}

	@Before
	public void setUp() throws Exception {
		driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
	}

	@Test
	public void test() throws InterruptedException {
		String sourceText = "Hello World!";

		IndexPage indexPage = new IndexPage(driver, URL);
		indexPage.fillInputText(sourceText);
		indexPage.clickButton();
		String resultText = indexPage.getText();

		assertEquals(sourceText, resultText);
	}

	@After
	public void tearDown() throws Exception {
		driver.close();
	}

}

The steps to create a multi-browser test class are:

  • Annotate the test class with @RunWith(Parameterized.class)
  • Create a public static method annotated with @Parameters that returns a Collection with the drivers of the browsers to be tested
  • Create a constructor that takes as parameters a row of the test data returned by the method annotated with @Parameters

Finally we can create the test method:

@Test
public void test() throws InterruptedException {
   String sourceText = "Hello World!";
 
   IndexPage indexPage = new IndexPage(driver, URL);
   indexPage.fillInputText(sourceText);
   indexPage.clickButton();
   String resultText = indexPage.getText();
 
   assertEquals(sourceText, resultText);
}

This test creates and accesses to the index page, fill the input text with a source text, clicks the button, gets the displayed text and asserts if source text is equals to the displayed text.

Full Code

You can get the full code of the project on GitHub: https://github.com/walfen/selenium

Hire Walfen services

If you are interested in Selenium to automate your manual tests or repetitive tasks, you can contact Walfen on info@walfen.com.