Selenium Recipes in Csharp Sample
Selenium Recipes in Csharp Sample
This is a Leanpub book. Leanpub empowers authors and publishers with the Lean
Publishing process. Lean Publishing is the act of publishing an in-progress ebook using
lightweight tools and many iterations to get reader feedback, pivot until you have the right
book and build traction once you do.
2014 - 2015 Zhimin Zhan
Contents
1. Preface . . . . . . . . . . . . . .
1.1 Who should read this book
1.2 How to read this book . . .
1.3 Recipe test scripts . . . . .
1.4 Send me feedback . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1
2
2
2
2
2. Introduction . . . . . . . . . . . . . . . . .
2.1 Selenium . . . . . . . . . . . . . . . .
2.2 Selenium language bindings . . . . . .
2.3 Cross browser testing . . . . . . . . .
2.4 Visual Studio Unit Testing Framework
2.5 Alternative framework NUnit . . . . .
2.6 Run recipe scripts . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3
3
3
11
14
16
16
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
21
21
21
22
22
22
23
24
24
25
25
25
4. Hyperlink . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.1 Click a link by text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
27
27
CONTENTS
4.2
4.3
4.4
4.5
4.6
4.7
4.8
4.9
Click a link by ID . . . . . . . . . . . .
Click a link by partial text . . . . . . .
Click a link by XPath . . . . . . . . .
Click Nth link with exact same label .
Click Nth link by CSS Selector . . . . .
Verify a link present or not? . . . . . .
Getting link data attributes . . . . . .
Test links open a new browser window
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
27
28
28
29
29
30
30
30
1. Preface
After observing many failed test automation attempts by using expensive commercial test
automation tools, I am delighted to see that the value of open-source testing frameworks has
finally been recognized. I still remember the day (a rainy day at a Gold Coast hotel in 2011)
when I found out that the Selenium WebDriver was the most wanted testing skill in terms
of the number of job ads on the Australias top job-seeking site.
Now Selenium WebDriver is big in the testing world. We all know software giants such as
Facebook and LinkedIn use it, immensely-comprehensive automated UI testing enables them
pushing out releases several times a day. However, from my observation, many software
projects, while using Selenium WebDriver, are not getting much value from test automation,
and certainly nowhere near its potential. A clear sign of this is that the regression testing is
not conducted on a daily basis (if test automation is done well, it will happen naturally).
Among the factors contributing to test automation failures, a key one is that automation
testers lack sufficient knowledge in the test framework. It is quite common to see some testers
or developers get excited when they first create a few simple test cases and see them run in a
browser. However, it doesnt take long for them to encounter some obstacles: such as being
unable to automate certain operations. If one step cannot be automated, the whole test case
does not work, which is the nature of test automation. Searching solutions online is not
always successful, and posting questions on forums and waiting can be frustrating (usually,
very few people seek professional help from test automation coaches). Not surprisingly, many
projects eventually gave up test automation or just used it for testing a handful of scenarios.
The motivation of this book is to help motivated testers work better with Selenium. The book
contains over 100 recipes for web application tests with Selenium. If you have read one of
my other books: Practical Web Test Automation, you probably know my style: practical. I
will let the test scripts do most of the talking. These recipe test scripts are live, as I have
created the target test site and included offline test web pages. With both, you can:
1.
2.
3.
4.
http://www.wired.com/business/2013/04/linkedin-software-revolution/
https://leanpub.com/practical-web-test-automation
Preface
2. Introduction
Selenium is a free and open source library for automated testing web applications. I assume
that you have had some knowledge of Selenium, based on the fact that you picked up this
book (or opened it in your eBook reader).
2.1 Selenium
Selenium was originally created in 2004 by Jason Huggins, who was later joined by his other
ThoughtWorks colleagues. Selenium supports all major browsers and tests can be written in
many programming languages and run on Windows, Linux and Macintosh platforms.
Selenium 2 is merged with another test framework WebDriver (thats why you see seleniumwebdriver) led by Simon Stewart at Google (update: Simon now works at FaceBook),
Selenium 2.0 was released in July 2011.
Introduction
import
import
import
import
org.openqa.selenium.By;
org.openqa.selenium.WebDriver;
org.openqa.selenium.WebElement;
org.openqa.selenium.firefox.FirefoxDriver;
C#:
Introduction
using
using
using
using
System;
OpenQA.Selenium;
OpenQA.Selenium.Firefox;
OpenQA.Selenium.Support.UI;
class GoogleSearch
{
static void Main()
{
IWebDriver driver = new FirefoxDriver();
driver.Navigate().GoToUrl("http://www.google.com");
IWebElement query = driver.FindElement(By.Name("q"));
query.SendKeys("Hello Selenium WebDriver!");
query.Submit();
Console.WriteLine(driver.Title);
}
}
Python:
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("http://www.google.com")
elem = driver.find_element_by_name("q")
elem.send_keys("Hello WebDriver!")
elem.submit()
print(driver.title)
Ruby:
Introduction
require "selenium-webdriver"
driver = Selenium::WebDriver.for :firefox
driver.navigate.to "http://www.google.com"
element = driver.find_element(:name, 'q')
element.send_keys "Hello Selenium WebDriver!"
element.submit
puts driver.title
Introduction
Introduction
Here is what looks like in Visual Studios Solution Explorer after Selenium WebDriver
was installed.
Also install Selenium.Support, which includes helper .NET classes for the Selenium
WebDriver API.
PM> Install-Package Selenium.Support
Introduction
Introduction
10
The several red underlines indicate compiling errors. In this case, the Selenium classes
were not loaded. To fix, right mouse click these red underlines and select Resolve.
You shall see a Firefox browser is opening and do a google search in it, as we our
instruction (in the GoogleSearchTest.cs).
Click Test Explorer tab to see test execution result.
Introduction
11
Firefox
Selenium supports Firefox out of the box, i.e., as long as you have Firefox (not too outdated
version) installed, you are ready to go. The test script below will open a web site in a new
Firefox window.
using OpenQA.Selenium.Firefox;
// ...
IWebDriver driver = new FirefoxDriver();
Chrome
To run Selenium tests in Google Chrome, besides the Chrome browser itself, ChromeDriver
needs to be installed.
Installing ChromeDriver is easy: go to http://chromedriver.storage.googleapis.com/index.html
http://en.wikipedia.org/wiki/Usage_share_of_web_browsers
http://chromedriver.storage.googleapis.com
http://chromedriver.storage.googleapis.com/index.html
Introduction
12
download the one for your target platform, unzip it and put chromedriver executable in your
PATH. To verify the installation, open a command window, execute command chromedriver,
You shall see:
The test script below opens a site in a new Chrome browser window and closes it one second
later.
using OpenQA.Selenium.Chrome;
//...
IWebDriver driver = new ChromeDriver();
Internet Explorer
Selenium requires IEDriverServer to drive IE browser. Its installation process is very similar
to chromedriver. IEDriverServer is available at http://www.seleniumhq.org/download/.
Choose the right one based on your windows version (32 or 64 bit).
When a tests starts to execute in IE, before navigating the target test site, you will see this
first:
http://www.seleniumhq.org/download/
Introduction
13
If you get this on IE9: Unexpected error launching Internet Explorer. Protected Mode must
be set to the same value (enabled or disabled) for all zones. Go to Internet Options, select
each zone (as illustrated below) and make sure they are all set to the same mode (protected
or not).
Further configuration is required for IE10 and IE11, see IE and IEDriverServer Runtime
Configuration for details.
using OpenQA.Selenium.IE;
//...
IWebDriver driver = new InternetExplorerDriver();
https://code.google.com/p/selenium/wiki/InternetExplorerDriver#Required_Configuration
Introduction
14
System;
Microsoft.VisualStudio.TestTools.UnitTesting;
OpenQA.Selenium;
OpenQA.Selenium.Firefox;
OpenQA.Selenium.IE;
OpenQA.Selenium.Chrome;
System.Collections.ObjectModel;
[TestClass]
public class GoogleSearchDifferentBrowsersTest {
[TestMethod]
public void TestInIE() {
IWebDriver driver = new InternetExplorerDriver();
driver.Navigate().GoToUrl("http://testwisely.com/demo");
System.Threading.Thread.Sleep(1000);
driver.Quit();
}
[TestMethod]
public void TestInFirefox() {
IWebDriver driver = new FirefoxDriver();
driver.Navigate().GoToUrl("http://testwisely.com/demo");
System.Threading.Thread.Sleep(1000);
driver.Quit();
}
[TestMethod]
public void TestInChrome() {
IWebDriver driver = new ChromeDriver();
driver.Navigate().GoToUrl("http://testwisely.com/demo");
Introduction
15
System.Threading.Thread.Sleep(1000);
driver.Quit();
}
}
@TestMethod annotates a test case below, in a format of testCamelCase() or TestCapitalCase. You will find more about VS Unit Test Framework from its home page. However, I
honestly dont think it is necessary. The part used for test scripts is not much and quite
intuitive. After studying and trying out some examples, you will be quite comfortable with
it.
Introduction
16
Please note that ClassCleanup does not guarantee all tests from one test class have been
executed before a new test class is initialized. What does this mean to your execution? If
you run one test case or all test cases in one test class, [ClassCleanup] is invoked as you
expected. However, when you run several test classes in one go, the time of invocation
of [ClassCleanup] is nondeterministic (which lead many browser windows open). In my
opinion, it sucks. Read this MSDN blog post for explanation: ClassCleanup May Run Later
Than You Think.
Introduction
17
A pop up window lists all artefacts (test cases, classes) in the project for your selection. The
finding starts as soon as you type.
Introduction
18
[TestMethod]
public void TestCase2() {
// one test case
}
Right mouse click and select Run Tests to run this case.
The below is a screenshot of execution panel when one test case failed,
The below is a screenshot of the execution panel when all test cases in a test script file passed,
Introduction
19
The below is a screenshot of the test results panel after running over 100 tests across dozens
of test files.
Introduction
20
To run a C# class, you need to be compile it first (Within IDE, IDEs do it for you
automatically).
1. Open a Visual Studio command prompt.
Click Start -> All Programs -> Visual Studio 2013 -> Visual Studio Tools, and
choose Developer Command Prompt for VS2013.
By default, the Visual Studio command prompt opens to the following folder:
<drive letter>:\Program Files (x86)\Microsoft Visual Studio 12.0>
Example Output
Example
ID
Name
Link Text
Partial Link Text
XPath
Tag Name
Class Name
CSS
FindElement(By.Id("user"))
FindElement(By.Name("username"))
FindElement(By.LinkText("Login"))
FindElement(By.PartialLinkText("Next"))
FindElement(By.Xpath("//div[@id="login"]/input"))
FindElement(By.TagName("body"))
FindElement(By.ClassName("table"))
FindElement(By.CssSelector, "#login > input[type="text"]"))
You may use any one of them to narrow down the element you are looking for.
22
to texts, test scripts that use IDs are less prone to application changes (e.g. developers may
decide to change the label, but are less likely to change the ID).
driver.FindElement(By.Id("submit_btn")).Click();
// Button
driver.FindElement(By.Id("cancel_link")).Click(); // Link
driver.FindElement(By.Id("username")).SendKeys("agileway"); // Textfield
driver.FindElement(By.Id("alert_div")).getText(); // HTML Div element
23
Some testers feel intimidated by the complexity of XPath. However, in practice, there is only
limited scope of XPath to master for testers.
The copied XPath for the second Click here link in the example:
//*[@id="container"]/div[3]/div[2]/a
24
The above test statement returns the text view of a web page, this is a very useful one as
Selenium WebDriver does not have built-in method return the text of a web page.
// Cancel link
// the below will return error "Compound class names not permitted"
// driver.FindElement((By.ClassName("btn btn-deault btn-primary")).Click();
The ClassName locator is convenient for testing JavaScript/CSS libraries (such as TinyMCE)
which typically use a set of defined class names.
25
// inline editing
driver.FindElement(By.Id("client_notes")).Click();
System.Threading.Thread.Sleep(500);
driver.FindElement(By.ClassName("editable-textarea")).SendKeys("inline notes\
");
System.Threading.Thread.Sleep(500);
driver.FindElement(By.ClassName("editable-submit")).Click();
However, the use of CSS selector is generally more prone to structure changes of a web page.
26
Sometimes FindElement fails due to multiple matching elements on a page, which you were
not aware of. FindElements will come in handy to find them out.
4. Hyperlink
Hyperlinks (or links) are fundamental elements of web pages. As a matter of fact, it is
hyperlinks that makes the World Wide Web possible. A sample link is provided below, along
with the HTML source.
HTML Source
<a href="index.html" id="recommend_selenium_link" class="nav" data-id="123" \
style="font-size: 14px;">Recommend Selenium</a>
Furthermore, if you are testing a web site with multiple languages, using IDs is probably the
only feasible option. You do not want to write test scripts like below:
Hyperlink
28
if (isItalian()) {
driver.FindElement(By.LinkText("Accedi")).Click();
} else if (isChinese()) { // a helper function determines the locale
driver.FindElement(By.LinkText, "").Click();
} else {
driver.FindElement(By.LinkText("Sign in")).Click();
}
Your might say the example before (find by LinkText) is simpler and more intuitive, thats
correct. but lets examine another example:
Hyperlink
29
<div>
First div
<a href="link-url.html">Click here</a>
</div>
<div>
Second div
<a href="link-partial.html">Click here</a>
</div>
If test case requires you to click the second Click here link, the simple FindElement(By.LinkText("Click
here")) wont work (as it clicks the first one). Here is a way to accomplish using XPath:
driver.FindElement(By.XPath("//div[contains(text(), \"Second\")]/a[text()=\"\
Click here\"]")).Click();
criteria in appearing order. Selenium (in fact C#) uses 0-based indexing, i.e., the first one is 0.
Hyperlink
30
Also you can get the value of custom attributes of this element and its inline CSS style.
Assert.AreEqual("font-size: 14px;", driver.FindElement(By.Id("recommend_sele\
nium_link")).GetAttribute("style"));
// Please note using attribute_value("style") won't work
Assert.AreEqual("123", driver.FindElement(By.Id("recommend_selenium_link")).\
GetAttribute("data-id"));
Hyperlink
31
While we could use switchTo() method (see chapter 10) to find the new browser window, it
will be easier to perform all testing within one browser window. Here is how:
String currentUrl = driver.Url;
String newWindowUrl = driver.FindElement(By.LinkText("Open new window")).Get\
Attribute("href");
driver.Navigate().GoToUrl(newWindowUrl);
driver.FindElement(By.Name("name")).SendKeys("sometext");
driver.Navigate().GoToUrl(currentUrl); // back
In this test script, we use a local variable currentUrl to store the current URL.