Selenium Selector Cheat Sheet

Background

Selenium uses the By class to find elements on a page. There are a number of tools to help you find a selector but once you figure out how they work you should be able to figure it out using just the element’s HTML. Creating a selector that is reliable enough to find your element, no matter its position on the page, is a learned skill. It is highly recommeded that you review the documentation for CSS Selectors and XPath Syntax.

Selenium Selector Cheat Sheet

The following tables focus on FindElement (and not FindElements), so any JavaScript function that returns multiple results is directed to return only the first (at index 0).

Basic Selenium Selectors

Description Selenium Selector JavaScript Selector
By.ByClassName  By.ClassName(“gsfi”)  document.getElementsByClassName(“gsfi”)[0]
By.ByCssSelector By.CssSelector(“#hplogo”) document.querySelector(“#hplogo”)
By.ById By.Id(“hplogo”) document.getElementById(“hplogo”)
By.ByLinkText  By.LinkText(“About”)  $x(“//a[text()=’About’]”)
By.ByName  By.Name(“q”)  document.getElementsByName(“q”)[0]
By.ByTagName  By.TagName(“a”)  document.getElementsByTagName(“input”)[0]
By.ByXPath By.XPath(“//*[@id=’hplogo’]”) $x(“//*[@id=’hplogo’]”)
  • All XPath expressions can be evaluated using jQuery. jQuery commands typically start with $
  • In XPath * is a wildcard. “//*[…” says to find any element type. “//a[…” says to find only <a> element types.

Advanced Selenium Selectors

Description Selenium Selector JavaScript Selector
Parent Element  childElement.FindElement(By.XPath(“..”)) childElement.parentElement
Element Containing Text  By.XPath(“//*[text()[contains(.,’Privacy’)]]”)  $x(“//*[text()[contains(.,’Privacy’)]]”)[0]
 Element Attribute By.CssSelector(“input[value=’3.2′]”)  document.querySelector(“input[value=’3.2′]”)
 Element Attribute By.XPath(“//input[@value=’3.2′]”)  $x(“//input[@value=’3.2′]”)

Selector Tips

Long Selectors

Using Chrome (covered below), I got a selector for Google’s “Google Search” button: #tsf > div.tsf-p > div.jsb > center > input[type="submit"]:nth-child(1). This selector reads, “Get the element with ID=’tsf’, then its child div with class=’tsf-p’, then its child div with class=’jsb’, then its child ‘center’ element > then its child input with type=’button’ and is the first child”. This selector can be trimmed down to any of the following:

  1. “center > input”
    • Returns the first <center> element’s first <input>
    • Brittle warning: If the element is moved, <center> element is removed, or another <input> becomes the first child.
  2. “input[type=submit]”
    • Returns an<input> element where type=”submit”
  3. “//*[@value=’Google Search’]”
    • Returns any element where value=”Google Search”
    • Brittle warning: If another element has the same value and appears first in the document.

Dynamic Attributes

Lets say we have a selector, “#div123 > a” and the “div123″ is dynamically generated and changes every time the page is reloaded. One simple trick is to edit the element and remove the id=”” attribute. This is done by inspecting the element and then double clicking the id attribute. When you get a new selector, it will have gone up the document tree a bit and might now look like “section > div > a” where ‘div” was the dynamically ID’d element.

 

Multiple Child Elements

This can be related to dynamic classes, too. A <ul> might have 5 <li> children. When the <ul> is first presented, all the <li> have the same class. Once one is selected the class of the selected element changes. For this example, let’s say that it goes from “li.defaultState” to “li.selected”. If your selector is “ul > li.defaultState:nth-child(5)” (to select the last <li>) you would receive an error since now only 4 elements have that class. This selector can be modified to the following:

  1. “ul > li:nth-child(5)”
    • Returns the 5th <li> of the first <ul>
    • Brittle warning: If the <ul> child count changes or if another <ul> appears first in the document.
  2. “//li[text()=’Coffee’]”
    • Returns the first <li> found where the textContent=”Coffee”
    • Brittle warning: If another <ll> appears first in the document with the same textContent value.

Getting a Selector Using Chrome’s DevTools

  1. Navigate to https://www.google.com/
  2. Right-click on the logo and then select “Inspect”
  3. The element is highlighted in the “Elements” tab of Chrome’s DevTools
  4. Right-click on the highlighted element and then select “Copy → Copy selector”

Testing a Selector Using Chrome’s DevTools Element Search

  1. Open Chrome’s DevTools [F12] and then select the “Elements” tab
  2. Press [Ctrl]+[F] to open the search
  3. Paste in your selector and if the element is found, then it will be highlighted

Testing a Selector Using JavaScript

  1. Open Chrome’s DevTools [F12] and then select the “Console” tab
  2. In the command line type document.querySelector("#hplogo") and then press [Enter]
  3. Hover over the returned element and the element will be highlighted on the page

Selenium Selectors and JavaScript

As seen in the previous section, you can test CSS Selectors using plain ol’ JavaScript. The document object is the deserialized HTML. We then call a method of that object. This can be querySelector (returns the first element matching the expression) or querySelectorAll (returns all elements matching the expression). These methods match Selenium’s functionality:

document.querySelector("your-selector-here") → driver.FindElement(By.CssSelector("your-selector-here"))

document.querySelectorAll("your-selector-here") → driver.FindElements(By.CssSelector("your-selector-here"))

The State of Selenium 3 WebDrivers

Background on Selenium 3 WebDrivers

… all the major browser vendors ship their own implementations (Apple, Google, Microsoft, and Mozilla).
… there is now a W3C specification for browser automation, based on the Open Source WebDriver. This has yet to reach “recommendation” status, but the people working on it (including members of the Selenium project!) are now focusing on finishing the text and writing the implementations.
– https://seleniumhq.wordpress.com/2016/10/13/selenium-3-0-out-now/

The Issue

While official support from browser vendors and an accompanying W3C spec are a step in the right direction, we are in the midst of a transition phase. The spec is still in “working” status. So any vague specs are either implemented as the browser vendor sees fit or not at all.

Examples

Mozilla and “Actions”

So the deal is that “actions” is terribly underspecified. I have been trying to fix that, but it’s very unclear to me what the semantics are supposed to be (e.g. when you move the mouse, should events be dispatched on all the elements along the pointers’ path). Until that is clear it’s not going to be possible to make this work the same way across multiple implementations.
– https://github.com/SeleniumHQ/selenium/issues/2285#issuecomment-227742441

Track the status of the implementation:

Apple and “Wait”

I haven’t found a bug tracker for this issue but the (above) screenshot shows that “Wait” is not implemented in Safari. This test runs fine on all the other browsers you see in the screenshot.

Workarounds

Until such time as the WebDrivers are fully fleshed out and implemented you’ll have to craft your own code if you want to test in all browsers. I do what I can in JavaScript using the JavascriptExecutor.

The Method:

The Usage:

 Non-Selenium 3 Specific Issue – IE .Click()

The IE WebDriver is still packaged with the Selenium download [Source] and to my knowledge not made by Microsoft (their efforts seem focused on Edge at this time). The .Click() implementation has mixed results [Source]. So I use JavaScript’s .click() instead.

Working with Selenium 3 Grid

Selenium 3 Grid

Selenium-Grid allows you run your tests on different machines against different browsers in parallel. That is, running multiple tests at the same time against different machines running different browsers and operating systems. Essentially, Selenium-Grid support distributed test execution. It allows for running your tests in a distributed test execution environment.
http://www.seleniumhq.org/docs/07_selenium_grid.jsp#what-is-selenium-grid

Getting the Necessary Files

This post will cover a Selenium 3 Grid setup with a Windows hub and an OSX Safari node. I highly recommend having a readme.txt file to each folder so that you can record the version number and URL for each file. If you change the file names you are going to have a bad time.

Windows

For your convenience I have uploaded a .zip of the necessary files for Windows. Download Link: Selenium_Windows.zip

Download the following files and place them in C:\Selenium

Set Your Path File

  1. Right-click “This PC” and select “Properties”
  2. In the left navigation menu, select “Advanced system settings”
  3. Select the “Advanced” tab
  4. Select “Environment Variables…”
  5. Under “System variables” select “Path” and then select “Edit…”
  6. Select “New”
  7. Enter C:\Selenium\
  8. Select “OK”

OSX

Download the following files and place them in ~/Documents/Selenium

Enable Automation Playback in Safari

  1. Ensure that the Develop menu is available.
    • It can be turned on by opening Safari preferences (Safari > Preferences in the menu bar), going to the Advanced tab, and ensuring that the Show Develop menu in menu bar checkbox is checked.
  2. Enable Remote Automation in the Develop menu.
    • This is toggled via Develop > Allow Remote Automation in the menu bar.
  3. Authorize safaridriver to launch the webdriverd service which hosts the local web server.
    • To permit this, run /usr/bin/safaridriver once manually and complete the authentication prompt.

Creating the Necessary Scripts

Windows – Start Grid Hub

Create a new file called start-grid-hub.bat and paste in the following:

cd C:\Selenium
java -jar selenium-server-standalone-3.3.1.jar -role hub

Note: Be sure to replace 3.3.1 with the current version number.

Windows – Start Grid Node

Create a new file called start-grid-node.bat and paste in the following:

cd C:\Selenium
java -Dwebdriver.chrome.driver=C:\Selenium\chromedriver.exe -Dwebdriver.gecko.driver=C:\Selenium\geckodriver.exe -Dwebdriver.edge.driver=C:\Selenium\MicrosoftWebDriver.exe -jar selenium-server-standalone-3.3.1.jar -role node -hub http://localhost:4444/grid/register

Note: Be sure to replace 3.3.1 with the current version number and localhost with your hub’s machine name or IP.

OSX – Start Grid Node

Create a new file called start-grid-node.sh and paste in the following:

#!/bin/bash
cd ~/Documents/Selenium/
java -jar selenium-server-standalone-3.3.1.jar -browser browserName=safari,platform=MAC -role node -hub http://localhost:4444/grid/register

Note: Be sure to replace 3.3.1 with the current version number and localhost with your hub’s machine name or IP.

WebDriver Setup

To create a driver that uses the remote instance of Safari add the following to your code:

DesiredCapabilities capabilities = DesiredCapabilities.Safari();
capabilities.SetCapability(CapabilityType.BrowserName, "safari");
capabilities.SetCapability(CapabilityType.Platform, "MAC");
driver = new RemoteWebDriver(hubUri, capabilities);

Note: The code (above) is C# so you may have to massage it a bit to work in other languages.

Running the Test

  1. On the Windows machine, run start-grid-hub.bat
  2. On the OSX machine:
    1. Open Terminal
    2. Drag-and-drop the start-grid-node.sh file into the Terminal window and then press [Enter]
  3. On the Windows machine, run your test(s)

Fix webdriver.chrome.driver system property Error

Background – webdriver.chrome.driver system property

I was following along Selenium’s quick-start guide but kept getting an error, “The path to the driver executable must be set by the webdriver.chrome.driver system property“. Most of the answers I found were for Java and simply set the value in code. I tried a similar fix in C# to no avail. Finally, I found a solution that works that sets the values as command-line parameters when I launch the Node.

Files

All files were placed in C:\Selenium. An entry was added to my Windows PATH variable by:

  1. Right-click “This PC” and select “Properties”
  2. In the left navigation menu, select “Advanced system settings”
  3. Select the “Advanced” tab
  4. Select “Environment Variables…”
  5. Under “System variables” select “Path” and then select “Edit…”
  6. Select “New”
  7. Enter C:\Selenium\
  8. Select “OK”

Start the Hub

The following script will start the Grid Hub (on the default port of 4444).

cd C:\Selenium
java -jar selenium-server-standalone-3.0.0.jar -role hub

Start the Node

The following script will start a Grid Node (on the default port of 5555). It will also register the locations of the Chrome and Firefox WebDrivers (respectively).

cd C:\Selenium
java -Dwebdriver.chrome.driver=C:\Selenium\chromedriver.exe -Dwebdriver.gecko.driver=C:\Selenium\geckodriver.exe -jar selenium-server-standalone-3.0.0.jar -role node -hub http://localhost:4444/grid/register

Setup Eclipse for Automation Testing

Update

This article is still relevant but a more comprehensive guide exists at http://timothycope.com/c-selenium-automation. This new guide also covers Page Object Design Pattern (POM) and Selenium Server (Grid).

Background

Eclipse is an IDE for many languages and in this case we will use it for Java development. Tests created using Selenium IDE can be exported to Java and ran in Eclipse using the JUnit plugin.

Getting What you Need

Eclipse will be an executable while jUnit and Selenium will be .jar files.

  1. Eclipse (for Java Developers) – http://www.eclipse.org/downloads/packages/eclipse-ide-java-developers/mars1
  2. JUnit – https://github.com/junit-team/junit/wiki/Download-and-Install 
  3. Selenium (Server and Client) – http://www.seleniumhq.org/download/
  4. Selenium IDE – http://www.seleniumhq.org/download/

Setting It All Up

  1. Install Eclipse
    1. For OSX, when the .tar.gz file opens move the extracted app to your Applications folder.
  2. Run Eclipse
    1. For OSX, open your Applications folder and then right-click Eclipse and select Open. Select Open from the prompt.
  3. For now, just use the default workspace. So, simply select Ok when the workspace prompt appears
  4. Close the welcome screen by clicking the X on its tab
    1. You should now see a blank project explorer
  5. From the menu select File -> New -> Java Project
  6. Name the project “Example” and select Finish
  7. Right-click in the Package Explorer pane and select New -> Folder
  8. Select “Example” as the parent folder
  9. Name the new folder “lib” and select Finish
    1. This will act as our “libraries” folder
  10. Copy over the .jar files to the “lib” folder (you can drag and drop)
    1. junit-#.#.jar
    2. selenium-server-standalone-#.#.#.jar
    3. selenium-java-#.#.#.jar
  11. Select Copy files on the prompt
  12. Select all files in the lib folder, right-click and select Build Path -> Add to Build Path
    1. This will copy the files into a folder called “Referenced Libraries” in your Package Explorer

Creating an Example Test Using Selenium IDE

  1. Install Selenium IDE if you haven’t already
    1. Use Firefox to download using the link on the Selenium downloads page
  2. Open Firefox
  3. Click the Selenium icon to the right of the address bar
  4. Enter https://www.google.com as your Base URL
  5. Click the record button (if not already recording)
    1. Navigate to https://www.google.com/
    2. Type Tim
    3. Click Search button
    4. Right-click on the page and select waitForTitle Tim – Google Search from the context menu
    5. Click the record button to stop recording
  6. Click the Play Current Test button
    • Ensure all steps are highlighted in green, meaning the test passed
  7. Click File -> Export Test Case As… and select Java/JUnit4/Webdriver
  8. Save as “test01.java

Adding the Test to the Eclipse Project

  1. Add/Drag-and-drop the .java file into the “src” folder of your project
    1. Select Copy file if prompted
  2. There will be errors reported during the import so let’s fix those:
    1. In the Package Explorer, drill down to the newly added test and double-click it
      1. Example -> src -> default package -> test01.java
    2.  The declared package “com.example.tests” does not match the expected package “” test01.java /Example/src line 1 Java Problem
      1. Remove the line “package com.example.tests;”
    3. The public type Test01 must be defined in its own file test01.java /Example/src line 12 Java Problem
      1. Rename the class “test01”
    4. Save the changes and refresh the package explorer (F5)

Running Your First Test

  1. Right-click the test in the package explorer and select Run As -> JUnit Test
  2. Eclipse will open the JUnit pane and execute the test in Firefox (the default WebDriver).
  3. Upon completion you should see the result(s)

Running More Tests

You can add more test to the default package. When you want to run them all you can select the default package folder and run as a JUnit test.

Running Tests Using a Headless Browser

A headless browser is an “internet browser” without a GUI. For this example, we will use HtmlUnit. It is an HtmlClient wrapper for Java applications. Get it here, http://sourceforge.net/projects/htmlunit/files/htmlunit/.

  1. Download the .jar file
  2. Add the .jar file to your “lib” folder
  3. Add the file to your build path
  4. Using the test created (above):
    1. Using //, comment out the line private WebDriver driver;
    2. Add a line under that, private HtmlUnitDriver driver;
      1. Hover over WebClient and select Import ‘HtmlUnitDriver’ (org.openqa.selenium.htmlunit)
      2. This will add the reference for WebClient from the HtmlUnit jar
    3. Using //, comment out the line driver = new FirefoxDriver();
    4. Add a line under that, driver = new HtmlUnitDriver();
    5. Add a line under that, driver.setJavascriptEnabled(true);
  5. Save your changes
  6. Execute the test
    1. Note: HtmlUnit will show a bunch of warnings, ignore them for now as it is normal behavior
      1. These warnings related to the page being loaded (akin to DevTools Console) and not the test itself
    2. Note: Google changes IDs based on browsers so this example will fail since it was recorded in Firefox and will be ran using HtmlUnit [Source].
      1. You can set the User-Agent by setting, driver = new HtmlUnitDriver(BrowserVersion.FIREFOX_38);
      2. You will also have to hover over BrowserVerison and add the missing reference, Import ‘BrowserVersion’ (com.gargoylesoftware.htmlunit)
      3. Documentation on BrowserVersion

Selenium Locators

Background

For many Selenium commands, a target is required. This target identifies an element in the content of the web application, and consists of the location strategy followed by the location in the format locatorType=location. The locator type can be omitted in many cases. The various locator types are explained below with examples for each.
http://www.seleniumhq.org/docs/02_selenium_ide.jsp#locating-elements

A Note on Locators

Most locators will find the first element that matches the criteria. So, if you have “link=Click Here” as your target and you have multiple “Click Here” links on the page, then Selenium will run with the first one it find in the DOM.

Selenium IDE

While using Selenium IDE it will chose the selector for you. Most often this is fine but in the case of dynamic IDs, you’ll need to know how to make your own. The order in which Selenium IDE picks a selector seems to be:

  1. ID
  2. Link Text (for <a> only)
  3. Name + Type (optional) + Value (optional)
  4. Xpath

There are other locators, but I have yet to see Selenium IDE use them. You can see all of them by clicking on the link in the Background quote (above).

Locating By ID

This is probably the simplest as an ID should be unique. A challenge would be if the ID is dynamic. If so, use another locator method (below).

Example (Source):

<html>
  <body>
    <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
    </form>
  </body>
</html>

To target the <form> your target will be id=loginForm

Locating by Link Text

Generally speaking, links do not have many attributes. As such we can use the <a> tag and it’s TextContent.

Example (Source):

<html>
  <body>
    <p>Are you sure you want to do this?</p>
    <a href="continue.html">Continue</a>
    <a href="cancel.html">Cancel</a>
  </body>
<html>

To target the <a> whose TextContent is “Continue” your target will be link=Continue

Locating By Name + Type + Value

This uses the element attributes to target the element. Name is required but Type and Value are optional.

Example (Source):

<html>
  <body>
    <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
    </form>
  </body>
<html>

To target the <input> whose name is “continue”, type is “button”, and value is “Clear” your target will be name=continue type=button value=Clear. Note that if you don’t specify a value, then Selenium will find the element whose value is “Login” as it is the first element to meet the conditions.

Locating by Xpath

Xpath was intended for XML but works with HTML as well. This uses an elements position in the DOM as a locator. An Xpath of html/div/a[1] would look in the <html> section of the DOM, drill down into the first <div>, and then find the first <a>.

Example (Source):

<html>
  <body>
    <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
    </form>
  </body>
<html>

To target the <form> your target will be xpath=/html/body/form[1]

Locating with CSS Instead of Xpath

Xpath is great when it works. When it doesn’t it’s usually because the element changed position in the DOM. For this reason we should target elements in a way that front-end developers would. That is CSS selectors. To do so your target will be css={insert path here}

Tips on Building Xpath and CSS Locators

In Chrome you can inspect an element, right-click, and select ‘Copy CSS Path’ or ‘Copy Xpath’.

Screen Shot 2015-11-12 at 3.05.57 PM

In Firefox you can do the same thing but you will need the Firebug add-on.

Screen Shot 2015-11-12 at 3.07.57 PM

Selenium Demystified

The Selenium Story

In 2004, Jason Huggins developed an early version of Selenium-RC as an internal tool for ThoughtWorks. Selenium-IDE was originally created by Shinya Kasatani and donated to the Selenium project in 2006. Google got involed in 2009 and is largely responsible for what became WebDriver. Then in 2012 a W3C standard draft was pusblished, solidifying WebDriver’s place as the defacto standard. Today Selenium is widely used in the QA community. Just hop on any employment board and see how many QA Automation positions mention Selenium.

Requirements

You understand basic HTML and JavaScript for the Selenium IDE content.

For the WebDriver content you’ll need a basic understanding of Java or other supported language.

Selenium IDE

The Selenium IDE is a Firefox add-on that allows the user to record, click, and play back actions in the browser. If you have ever used macros in Microsoft’s Office products or AutoIT this will be familiar. These tests are saved in HTML files in a format referred to as Selenese. The test playback is done via JavaScript [source]. So when you have Command = open and Target = http://timothycope.com

Capture1

it is executed almost like you opened up the Developer Tools Console (F12) and in the console tab ran window.location.href = 'http://timothycope.com';

Capture2

Selenium Tests

Test steps are comprised of three things; command, target, and value.

Capture3

  • A command is what tells Selenium what to do. Selenium commands come in three ‘flavors’;
    • Actions are commands that generally manipulate the state of the application. They do things like “click this link” and “select that option”. If an Action fails, or has an error, the execution of the current test is stopped.
      • Many Actions can be called with the “AndWait” suffix, e.g. “clickAndWait”. This suffix tells Selenium that the action will cause the browser to make a call to the server, and that Selenium should wait for a new page to load.
    • Accessors examine the state of the application and store the results in variables, e.g. “storeTitle”. They are also used to automatically generate Assertions.
    • Assertions are like Accessors, but they verify that the state of the application conforms to what is expected. Examples include “make sure the page title is X” and “verify that this checkbox is checked”.
  • The target is a element locator for the html element. There are a number of supported selectors;
    • By ID – This is the most efficient and preferred way to locate an element. Common pitfalls that UI developers make is having non-unique id’s on a page or auto-generating the id, both should be avoided. A class on an html element is more appropriate than an auto-generated id.
    • By Class – “Class” in this case refers to the attribute on the DOM element. Often in practical use there are many DOM elements with the same class name, thus finding multiple elements becomes the more practical option over finding the first element.
    • By Tag Name – The DOM Tag Name of the element.
    • By Name – Find the input element with matching name attribute.
    • By Link Text – Find the link element with matching visible text.
    • By Partial Link Text – Find the link element with partial matching visible text.
    • By CSS -Like the name implies it is a locator strategy by css. Native browser support is used by default, so please refer to w3c css selectors for a list of generally available css selectors. If a browser does not have native support for css queries, then Sizzle is used. IE 6,7 and FF3.0 currently use Sizzle as the css query engine.
      • Beware that not all browsers were created equal, some css that might work in one version may not work in another.
    • By XPATH – At a high level, WebDriver uses a browser’s native XPath capabilities wherever possible. On those browsers that don’t have native XPath support, we have provided our own implementation. This can lead to some unexpected behaviour unless you are aware of the differences in the various xpath engines.
    • Using JavaScript – You can execute arbitrary javascript to find an element and as long as you return a DOM Element, it will be automatically converted to a WebElement object.
  • The value is used for certain commands. Official documentation is currently lacking in respect to a list of all API endpoints and their support with various frameworks. Here is a list of all actions, though.

IDE to WebDriver

You can “write” your tests by using Selenium IDE to record your actions. Then you just need to export to your language of choice. You may find that some of your tests are not exported how you might expect. Some libraries are not fully fleshed out so you’ll get a comment in the exported coded saying that the Command is unsupported. When this happens you’ll need to code something language specific to suit your needs.

After you export the test from IDE to WebDriver, your code will now be interpreted by WebDriver and executed on the browser.

flow-chart

It is more likely that you will build a suite of tests and have them executed by something like JUnit or NUnit. You could even run on multiple machines using something like Selenium Grid2, too. Many CI tools, like Jenkins, can be used to kick off the tests automatically with any new code changes.

Selenium WebDriver

The Selenium WebDriver is an application  that works as a middle man between your automation code and your browser. This application called be called from many languages and frameworks using the WebDriver API. The level of support you get differs based on the programming language, operating system, and browser you use. Know that Selenium is developed  in Java + Windows + Firefox. There is limited support for Linux and OSX. Additional browsers are supported by extensions. Headless browsers, like HtmlUnit, allow a UI-less WebView to be used as a web browser.

Handling Pop-ups with Selenium IDE and Java

Problem – Selenium Popup

You need to test an anchor whose target is _blank.

Example

http://www.htmlcodetutorial.com/linking/_A_TARGET_95y98y108y97y110y107y.html

<a href="newwindow.html" target="_blank">a new window</a>

Solution in IDE

  1. Open Firefox
  2. Click the Selenium icon to the right of the address bar
  3. Enter http://www.htmlcodetutorial.com/ as your Base URL
  4. Click the record button
    1. Navigate to http://www.htmlcodetutorial.com/linking/_A_TARGET_95y98y108y97y110y107y.html
    2. Left-click the a new window link
    3. Right-click on the page and select verifyTitle A Whole New Window – HTML Code Tutorial
    4. Close the new window/tab
    5. Right-click on the original window/tab page and select verifyTitle HTML _blank – HTML Code Tutorial
  5. In Selenium IDE, click the record button to stop recording
  6. Add a pause 1000 step after the click step to give the window/tab time to load
  7. Add a selectWindow A Whole New Window – HTML Code Tutorial step after the pause to connect to the new window/tab
  8. Add a close step after the verifyTitle A Whole New Window – HTML Code Tutorial step
  9. Add a selectWindow HTML _blank – HTML Code Tutorial step after the close step
  10. Select Play Current Test Case to verify the test

Your test should look like this:

Capture

Solution in Java

  1. Export the test from the IDE solution (above)
    • Click File -> Export Test Case As… and select Java/JUnit4/Webdriver
    • Save as test01.java in your project’s src folder
    • Refresh your project in Eclipse (F5)
    • Fix any errors in the code and save
      • Remove package com.example.tests;
  2.  Open Test01.java
    • Scroll down some and you will see some comments, like // ERROR: Caught exception [ERROR: Unsupported command [selectWindow | A Whole New Window – HTML Code Tutorial | ]]
    • Some of Selenium IDE’s functions don’t have WebDriver equivalents just yet
  3. Before the link click event add String parentHandle = driver.getWindowHandle();
    • This will get the parent window handle
  4. After the link click event add for (String winHandle : driver.getWindowHandles()) {driver.switchTo().window(winHandle);}
    • This will switch us to the child window
  5. After the close event add driver.switchTo().window(parentHandle);
    • This will switch us back to the parent window
  6. Right-click somewhere in the code file and select Run As -> JUnit Test
    • Or, click the green run button on the Eclipse toolbar
    • A browser window should open and run the test
    • The test results should display on the left pane of the Eclipse window

Your code for @test should look like:

@Test
public void test01() throws Exception {
	driver.get(baseUrl + "linking/_A_TARGET_95y98y108y97y110y107y.html");
	String parentHandle = driver.getWindowHandle();
	driver.findElement(By.linkText("a new window")).click();
	for (String winHandle : driver.getWindowHandles()) {
		driver.switchTo().window(winHandle);
	}
	try {
	  assertEquals("A Whole New Window - HTML Code Tutorial", driver.getTitle());
	} catch (Error e) {
	  verificationErrors.append(e.toString());
	}
	driver.close();
	driver.switchTo().window(parentHandle);
	try {
	  assertEquals("HTML _blank - HTML Code Tutorial", driver.getTitle());
	} catch (Error e) {
	  verificationErrors.append(e.toString());
	}
}

Setup Selenium, JUnit, and Eclipse

Update

This article is still relevant but a more comprehensive guide exists at http://timothycope.com/c-selenium-automation. This new guide also covers Page Object Design Pattern (POM) and Selenium Server (Grid).

Background

Selenium automates browsers. That’s it! What you do with that power is entirely up to you. Primarily, it is for automating web applications for testing purposes, but is certainly not limited to just that. Boring web-based administration tasks can (and should!) also be automated as well.
http://docs.seleniumhq.org/

JUnit is a simple framework to write repeatable tests. It is an instance of the xUnit architecture for unit testing frameworks.
http://junit.org/

Eclipse is a platform that has been designed from the ground up for building integrated web and application development tooling. By design, the platform does not provide a great deal of end user functionality by itself. The value of the platform is what it encourages: rapid development of integrated features based on a plug-in model.
https://www.eclipse.org/

Setup Eclipse

  1. Go to https://github.com/junit-team/junit/wiki/Download-and-Install and download “junit.jar”
    • (Optional) You can also grab the “hamcrest-core.jar”
      • “junit.jar” contains common functions of hamcrest, which can be expanded by using the core library
  2. Go to http://www.seleniumhq.org/download/ and download “Selenium Server” and “Selenium Client”
    • We will be using the Java client, which comes in an archive. We are only concerned with the .jar not including “srcs” in the file name
  3. Go to https://www.eclipse.org/downloads/ and download the version you need for your operating system
    • I use Eclipse IDE for Java Developers
  4. Extract the archive
    • (Optional) Move the extracted folder to your application folder
  5. Run the executable for Eclipse
  6. Select a workspace
  7. Click File -> New -> Java Project
    • For standard IDE Find/Select Java Project
  8. Name your project and click Finish
    • The default settings are good for this tutorial
  9. Create a new folder called “lib” in your project to hold the external assemblies
    • The name does not matter, but should make sense
  10. Drag-and-Drop the .jar files for Selenium Server, Selenium Client, and JUnit into the new folder
    • When prompted, select Copy Files
  11. Expand the lib folder and select the .jar files
  12. Right-click and select Build Path -> Add to Build Path
    • This will create a new folder called “Referenced Libraries” that contains the binaries for the .jar files

Creating Your First Test

Until you become a Subject Matter Expert you will likely be using the Selenium IDE for Firefox to write your tests. You can download the IDE from http://www.seleniumhq.org/download/

  1. Open Firefox
  2. Click the Selenium icon to the right of the address bar
  3. Enter https://www.google.com/ as your Base URL
  4. Click the record button
    1. Navigate to https://www.google.com/
    2. Type Tim
    3. Click Search button
    4. Right-click on the page and select waitForTitle Tim – Google Search from the context menu
    5. Click the record button to stop recording
  5. Click the Play Current Test button
    • Ensure all steps are highlighted in green, meaning the test passed
  6. Click File -> Export Test Case As… and select Java/JUnit4/Webdriver
  7. Save as test01.java in your project’s src folder
  8. Refresh your project in Eclipse (F5)
  9. Fix any errors in the code and save
    • Remove package com.example.tests;
    • Rename public class Test01 to test01
  10. Right-click somewhere in the code file and select Run As -> JUnit Test
    • Or, click the green run button on the Eclipse toolbar
  11. A browser window should open and run the test
  12. The test results should display on the left pane of the Eclipse window

Setup Selenium, NUnit, and Visual Studio

Update

This article is still relevant but a more comprehensive guide exists at http://timothycope.com/c-selenium-automation. This new guide also covers Page Object Design Pattern (POM) and Selenium Server (Grid).

Background

Selenium automates browsers. That’s it! What you do with that power is entirely up to you. Primarily, it is for automating web applications for testing purposes, but is certainly not limited to just that. Boring web-based administration tasks can (and should!) also be automated as well.
http://docs.seleniumhq.org/

NUnit is a unit-testing framework for all .Net languages. Initially ported from JUnit, the current production release, version 2.6, is the seventh major release of this xUnit based unit testing tool for Microsoft .NET. It is written entirely in C# and has been completely redesigned to take advantage of many .NET language features, for example custom attributes and other reflection related capabilities. NUnit brings xUnit to all .NET languages.
http://www.nunit.org/

Install NUnit

You will need NUnit to execute your automated tests. Download the win MSI file and run it. Select a complete installation when prompted.

Setup Visual Studio

  1. Open Visual Studio
  2. Click File, click New, and select Project…
  3. In the left navigation pane, expand Templates, then Visual C#, and then select Class Library in the center window pane.
  4. In Package Manager Console, type Install-Package Selenium.WebDriverBackedSelenium
  5. In Package Manager Console, type Install-Package Selenium.Support
  6. In Package Manager Console, type Install-Package NUnit

Creating Your First Test

I renamed Class1.cs to AutomatedTest01.cs and that is reflected in the code below.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenQA.Selenium;
using OpenQA.Selenium.IE;
using NUnit.Framework;
using OpenQA.Selenium.Firefox;

namespace SeleniumClassLibrary
{
    [TestFixture]
    public class AutomatedTest01
    {

        IWebDriver driver;

        [TestFixtureSetUp] // http://www.nunit.org/index.php?p=testFixture&r=2.5
        public void TestSetUp()
        {
            // Set the IWebDriver to use FireFox
            driver = new FirefoxDriver();

            // Set the timeout to 30 seconds
            driver.Manage().Timeouts().ImplicitlyWait(new TimeSpan(0, 0, 30));

        }

        [Test] // http://www.nunit.org/index.php?p=test&r=2.5
        public void NavigateToGoogle()
        {
            // Navigate to URL
            driver.Navigate().GoToUrl("http://www.google.com");

            // Assert that the IWebDriver window's title is "Google"
            Assert.AreEqual("Google", driver.Title);
        }

        [TestFixtureTearDown] // http://www.nunit.org/index.php?p=fixtureTeardown&r=2.5
        public void FixtureTearDown()
        {
            // Closes all windows associated with the IWebDriver
            driver.Quit();
        }
    }
}

Save and build the project.

Run the Automated Test

  1. Open NUnit
  2. Click File and select Open Project…
  3. Find the .dll from your Visual Studio Project
  4. Click Run in the center window pane

Importing Code from Selenium IDE for Firefox

You can download the Firefox add-on that allows you to record-and-click basic webpage tasks.

  1. In Selenium IDE:
    1. Click File, select Export Test Case As…, and select C# / NUnit / WebDriver
  2. You can copy+paste the code into a new .cs file in your project or import the cs file
  3. Save and Build your project

Note: You may have to make some manual changes to the code to have it playback correctly in NUnit.

using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Support.UI;

namespace SeleniumClassLibrary
{
    // Genereated by Selenuim IDE for Firefox
    [TestFixture]
    public class AutomatedTest02
    {

        private IWebDriver driver;
        private StringBuilder verificationErrors;
        private string baseURL;
        private bool acceptNextAlert = true;

        [SetUp]
        public void SetupTest()
        {
            driver = new FirefoxDriver();
            baseURL = "http://timothycope.com/";
            verificationErrors = new StringBuilder();
        }

        [TearDown]
        public void TeardownTest()
        {
            try
            {
                driver.Quit();
            }
            catch (Exception)
            {
                // Ignore errors if unable to close the browser
            }
            Assert.AreEqual("", verificationErrors.ToString());
        }

        [Test]
        public void The01Test()
        {
            driver.Navigate().GoToUrl(baseURL + "/");
            Thread.Sleep(2500);
            driver.FindElement(By.LinkText("ABOUT TIMOTHY COPE")).Click();
            Thread.Sleep(2500);
            for (int second = 0; ; second++)
            {
                if (second >= 60) Assert.Fail("timeout");
                try
                {
                    if (IsElementPresent(By.XPath("//img[@alt='logo']"))) break;
                }
                catch (Exception)
                { }
                Thread.Sleep(1000);
            }
        }
        private bool IsElementPresent(By by)
        {
            try
            {
                driver.FindElement(by);
                return true;
            }
            catch (NoSuchElementException)
            {
                return false;
            }
        }

        private bool IsAlertPresent()
        {
            try
            {
                driver.SwitchTo().Alert();
                return true;
            }
            catch (NoAlertPresentException)
            {
                return false;
            }
        }

        private string CloseAlertAndGetItsText()
        {
            try
            {
                IAlert alert = driver.SwitchTo().Alert();
                string alertText = alert.Text;
                if (acceptNextAlert)
                {
                    alert.Accept();
                }
                else
                {
                    alert.Dismiss();
                }
                return alertText;
            }
            finally
            {
                acceptNextAlert = true;
            }
        }
    }
}

Solution on GitHub

You can download the project I made from GitHub:
https://github.com/kirbycope/SeleniumClassLibrary