Click here to Skip to main content
15,886,689 members
Articles / Programming Languages / C# 4.0
Tip/Trick

Writing automation test with Selenium WebDriver Extension jQuery - RaYell Effectively

Rate me:
Please Sign up or sign in to vote.
5.00/5 (3 votes)
9 Mar 2015CPOL2 min read 17.4K   176   6  
This tip describes how to use Selenium WebDriver extension for jQuery of RaYell and customize waiting element loading

Introduction

When you use Selenium WebDriver, Page Object pattern and waiting element loading complete are important when executing test case. Beside one, extension selector with jQuery, query selector helps you to easily interact with web page. This tip introduces how to use this one effectively.

Background

This tip helps you to write your automation test case smoothly with Page object design pattern and customize waiting for loading element to complete.

Using the Code

This code is based-on Selenium WebDiver extension of RaYell: https://github.com/RaYell/selenium-webdriver-extensions. Before using this source, you should download the extension by RaYell from github. To understand this code, you should read this link and research about Page object design pattern in Selenium at sample link: https://code.google.com/p/selenium/wiki/PageObjects or http://martinfowler.com/bliki/PageObject.html. In this source code, beside RaYell lib, I created 2 project, 1 for test, 1 for page object like the image below.

This sample test is used to reference, it follows from our project. You can imagine, we have one webpage, before we run every page, we must pass login page. Then, we do some command like create new item, check item create successfully.

In this source, I create InitializeTest class for initializing driver configuration. After that, I write TeamTest class inherited from InitializeTest like image below:

I will explain some points in the source code...

Init WebDriver, the first thing for selenium web driver. (Source: InitializeTest.cs)

C#
[TestInitialize]
public void Init()
{
    Driver.Initialize();
    LoginPage.GoTo();
    LoginPage.LoginAs("abc123").WithPassword("abc123").Login();
}

Sample case writing test case goes to Team page. We design one file for test and one file for page object. Here page object is Team.cs.

The first, TeamTest.cs will be inherited from InitializeTest.cs to pass login case. We write 4 methods to test this case including: GoTo, GoToAddNewTeamPage, CreateTeam, IsExistTeam.

C#
[TestMethod]
public void Can_Add_New_Team()
{
   Team.GoTo();

   Team.GoToAddNewTeamPage();

   AddNewTeam.CreateTeam(Constants.NewTeamName, Constants.NewTeamNote).Save();

   Assert.IsTrue(Team.IsExistTeam(Constants.NewTeamName), "Fail To Add New Team!");
}

4 methods will be implemented in Team.cs page object.

C#
public static void GoTo()
{
	Driver.Instance.Navigate().GoToUrl("https://abcxyz/#/admin/teams");
}

public static void GoToAddNewTeamPage()
{
	var rows = Driver.Instance.FindElements(By.JQuerySelector("td"));
	Driver.Instance.FindElement(By.ClassName("glyphicon-plus")).Click();
}

public static bool IsExistTeam(string newTeamName)
{
	GoTo();
	Driver.Instance.FindElement(By.JQuerySelector
	("input[placeholder='Search for Team Name...']")).SendKeys(newTeamName);
	Driver.Instance.FindElement(By.JQuerySelector(".fa.fa-search")).Click();
	var rows = Driver.Instance.FindElements(By.JQuerySelector("td"));
	return rows.Any(row => row.FindElement(By.TagName("a")).Text == newTeamName);
}

As this source I mention, when you use AngularJS, Durandal...element will exist after compile and link function time. Therefore, if you find element immediately, element is not found and through exception. I had covered this case by adding customize in extension source code of library in file WebDriverExtensions.cs namespace Selenium.WebDriver.Extensions.JQuery.

C#
public static void WaitForPageToLoad(this IWebDriver driver, string script)
{
  var timeout = new TimeSpan(0, 0, 30);
  var wait = new WebDriverWait(driver, timeout);

  var javascript = driver as IJavaScriptExecutor;
  if (javascript == null)
	  throw new ArgumentException("driver", "Driver must support javascript execution");

  wait.Until((d) =>
  {
	  try
	  {
		  var result = javascript.ExecuteScript(script);
		  var isColection = result is IEnumerable<object> || result is IEnumerable;
		  if (isColection)
		  {
			  var count = (result as IEnumerable).Cast<object>().Count();
			  if (count > 0)
				  return true;
		  }
		  else
		  {
			  if (result != null)
				  return true;
		  }
		  return false;
	  }
	  catch (InvalidOperationException e)
	  {
		  return e.Message.ToLower().Contains("unable to get browser");
	  }
	  catch (WebDriverException e)
	  {
		  return e.Message.ToLower().Contains("unable to connect");
	  }
	  catch (Exception)
	  {
		  return false;
	  }
  });
}

This code covers 2 cases:

  • result is list element
  • result is only 1 element

We are waiting until element exits after timeout. After timeout occurs, this return element exception is not found.

I will not explain more details about the API, you can reference in document to understand selector using jQuery extension.

I am so sorry I do not have the REAL source code for Page object design pattern.

Points of Interest

The Web Driver Extension library I reference from https://github.com/RaYell/selenium-webdriver-extensions is very interest. With the new version, you can use jQuery for your selector very easy and smoothly.

I want to say thank you to RaYell + those contributors of page object design pattern, coding sample for waiting loading element for more completion.

Enjoy your coding.

History

This is the first version of project. I will update changes soon.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect OSM Solution Vietnam Ltd. Co.
Vietnam Vietnam
We are working in Web Application with SPA, MVC domain. Beside we are master in Management Information Systems, how to use IS to improve decision making and knowledge sharing in open learning organization.

Comments and Discussions

 
-- There are no messages in this forum --