selenium webdriver - continuous improvement – · pdf filecucumber-jvm is a mainstream...

26
Selenium WebDriver Last updated: 10 July 2017 © Pepgo Limited, 71-75 Shelton Street, Covent Garden, London, WC2H 9JQ, United Kingdom

Upload: trandan

Post on 03-Feb-2018

231 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Selenium WebDriver - Continuous Improvement – · PDF fileCucumber-JVM is a mainstream BDD (Behavior-Driven Development) tool used (in agile development) to implement this practice

Selenium WebDriver

Last updated: 10 July 2017

© Pepgo Limited, 71-75 Shelton Street, Covent Garden, London, WC2H 9JQ, United Kingdom

Page 2: Selenium WebDriver - Continuous Improvement – · PDF fileCucumber-JVM is a mainstream BDD (Behavior-Driven Development) tool used (in agile development) to implement this practice

Contents Assert and Verify ............................................................................................................................................... 4

Technology Stacks: ............................................................................................................................................ 4

Java ................................................................................................................................................................ 4

Microsoft .NET ............................................................................................................................................... 5

Additional tools ................................................................................................................................................. 5

Web page inspection tools ................................................................................................................................ 6

Running (a Selenium IDE produced HTML test suite) on various browsers ...................................................... 6

Locating Elements.............................................................................................................................................. 6

Determine if an element exists without throwing an error .............................................................................. 8

Get information from elements ........................................................................................................................ 9

Get the content of a whole page ....................................................................................................................... 9

Enter data in Editboxes...................................................................................................................................... 9

Clear data in Editboxes .................................................................................................................................... 10

The “submit()” method ................................................................................................................................... 10

Set information on Dropdown and Lists .......................................................................................................... 10

Clicking on Buttons and Links (and other web elements) ............................................................................... 11

Set information on Radio Buttons and Radio Groups ..................................................................................... 12

Set information on Checkboxes....................................................................................................................... 12

Working with Tables ........................................................................................................................................ 12

Check the status of an element ....................................................................................................................... 13

Mouse and Keyboard events ........................................................................................................................... 13

Synchronisation ............................................................................................................................................... 14

Set the Implicit Wait timeout to 10 Seconds ............................................................................................... 15

Explicit wait .................................................................................................................................................. 15

Set the default browser navigation timeout ................................................................................................... 16

Controlling browsers using “navigate” ............................................................................................................ 16

Cookies ............................................................................................................................................................ 16

Handling pop-up windows ............................................................................................................................... 16

Handling JavaScript alerts (pop ups) ............................................................................................................... 17

Handling OK/Cancel Message Boxes (=Confirm Box Alert) ............................................................................. 18

Handling an Input Box (Prompt Box Alert) ...................................................................................................... 18

Frames (including IFRAME) .............................................................................................................................. 18

Event handling ................................................................................................................................................. 18

Taking Screenshots in WebDriver .................................................................................................................... 18

Taking Screenshots with RemoteWebDriver or Grid ...................................................................................... 19

Page 3: Selenium WebDriver - Continuous Improvement – · PDF fileCucumber-JVM is a mainstream BDD (Behavior-Driven Development) tool used (in agile development) to implement this practice

Screenshots with screengrab or fireshot......................................................................................................... 19

The Page Object pattern (for building custom classes that encapsulate pages and/or business processes) . 19

Kill Windows processes ................................................................................................................................... 20

Dealing with I/O ............................................................................................................................................... 21

Remote execution ........................................................................................................................................... 21

Example conversion from local execution to remote execution: ............................................................... 21

Remote execution in various browsers ....................................................................................................... 22

Distributed Testing with Selenium Grid .......................................................................................................... 23

Setting supported browsers by a node ....................................................................................................... 24

Testing iOS and Android Apps using Appium .................................................................................................. 24

Headless browsing ........................................................................................................................................... 25

Alternative approach on Linux using “Xvfb” ............................................................................................... 26

Page 4: Selenium WebDriver - Continuous Improvement – · PDF fileCucumber-JVM is a mainstream BDD (Behavior-Driven Development) tool used (in agile development) to implement this practice

Assert and Verify There are two mechanisms for validating elements available on the application under test. The first is

“assert”; this allows the test to check if the element is on the page. If it is not available then the test will

stop on the step that failed. The second is “verify”; this also allows the test to check the element is on the

page, but if it isn't then the test will carry on executing.

In Selenium IDE, “assert” and “verify” can be added to elements with the context-menu.

Some of the “verify” and “assert” methods are:

verifyElementPresent

assertElementPresent

verifyElementNotPresent

assertElementNotPresent

verifyText

assertText

verifyAttribute

assertAttribute

verifyChecked

assertChecked

verifyAlert

assertAlert

verifyTitle

assertTitle

Technology Stacks:

Java Eclipse is the most popular IDE in the Java world

IntelliJ IDEA is another very popular IDE available for Java development from JetBrains. Unlike Eclipse,

IntelliJ IDEA is a commercial tool. However, JetBrains offers a community edition with limited features for

free use.

NetBeans is another popular cross-platform IDE from Oracle, primarily for Java development.

JUnit or NUnit are frameworks for creating data-driven tests

Apache POI is an API to work with Excel spreadsheets

Java IO and utility classes are used for file access

JDBC is used for database connections

Apache Maven is a software project management and comprehension tool. Maven is used to define project

structure, dependencies, build, and test management. It often incorporates Cucumber. Another important

benefit of using Maven is that you can get all the Selenium library files and their dependencies by configuring

the "pom.xml" file. Maven automatically downloads the necessary files from the repository while building the

project.

Apache Ant is a popular build management tool available for Java developers. It is similar to Apache Maven,

but does not support project management and dependency management features like Maven. It's a pure

build tool. Ant is another choice for running Selenium WebDriver tests from the command line or through

continuous integration (CI) tools such as Jenkins.

Page 5: Selenium WebDriver - Continuous Improvement – · PDF fileCucumber-JVM is a mainstream BDD (Behavior-Driven Development) tool used (in agile development) to implement this practice

Cucumber-JVM is a mainstream BDD (Behavior-Driven Development) tool used (in agile development) to

implement this practice in Java. Cucumber-JVM is based on the Cucumber framework, widely used in the

Ruby on Rails world. Cucumber-JVM allows developers, Quality Assurance (QA), and non-technical or

business participants to write features and scenarios in a plain text file using Gherkin language with minimal

restrictions about grammar in a typical Given, When, and Then structure. This feature file is then supported

by a step definition file, which implements automated steps to execute the scenarios written in a feature file.

Apart from testing API’s with Cucumber-JVM, we can also test UI level tests by combining Selenium

WebDriver.

JBehave is another famous framework for BDD in Java. Similar to Cucumber-JVM, JBehave allows the

writing of features as stories in the Gherkin language. Steps from the scenarios are later implemented in a

step definition file.

Jenkins is a popular continuous integration server in the Java development community. It is derived from the

Hudson CI server. It supports SCM tools including CVS, Subversion, Git, Mercurial, Perforce, and

ClearCase, and can execute Apache Ant and Apache Maven based projects as well as arbitrary shell scripts

and Windows batch commands. One of the important features of Jenkins is that it automatically triggers the

build, based on defined criteria.

Jenkins can be deployed to set up an automated testing environment where you can run Selenium

WebDriver tests unattended based on a defined schedule, or every time changes are submitted in SCM.

Jenkins also provides the ability to display test results by reading the results files generated by unit test

frameworks. It also archives these results, which can be used to generate various metrics over time.

Microsoft .NET You can also use Selenium along with Microsoft .NET by adding Selenium's NuGet package manager to the

project in Visual Studio. NuGet is a Visual Studio extension that makes it easy to install and update third-

party libraries and tools in Visual Studio.

The NUnit framework has been widely used by the Selenium WebDriver community to create test scripts with

Microsoft .NET bindings. Similar to the JUnit framework, the NUnit framework also supports data-driven

testing in the simplest manner.

Alternatively to NUnit, MSTEST, the unit testing framework provided by Microsoft Visual Studio is the

simplest way to parameterize the test scripts with Microsoft .NET bindings. MSTEST has in-built features to

support data-driven testing, which can be configured very easily. With the “DataSource” attribute, we can

specify the connection string or a configuration file to read data from a variety of sources including CSV File,

Excel spreadsheets, XML files, or databases.

SpecFlow.NET is a BDD (Bahavior-Driven Development) tool inspired by Cucumber (from the Java Stack)

and uses the same Gherkin language for writing specifications.

Additional tools Selenium will only work with web applications. If the web application needs to interact with the native UI (for

example when the web application provides a file upload feature that invokes native OS UI for selecting a

file), then tools like AutoIt can be used. AutoIt is a freeware BASIC-like scripting language designed for

automating the Windows GUI and general scripting. By using AutoIt, we can simulate a combination of

keystrokes, mouse movement, and window/control manipulation in order to automate. It is a very small,

self-contained utility. It runs on all versions of Windows operating system. AutoIt scripts can be compiled as

self-contained executables. AutoIt will only work on Microsoft Windows and it will not work with

RemoteWebDriver.

Page 6: Selenium WebDriver - Continuous Improvement – · PDF fileCucumber-JVM is a mainstream BDD (Behavior-Driven Development) tool used (in agile development) to implement this practice

Sikuli is another tool that can be used along with Selenium WebDriver for automating non-web UI. It uses

visual identification technology (=”screenshots”) to automate and test graphical user interfaces (GUI). The

Sikuli script automates anything you see as a user on the screen rather than an API.

Sikuli is supported on Windows, Linux, and Mac OSX operating systems. Similar to Selenium IDE, Sikuli

provides an IDE for script development and API that can be used within Java.

Sikuli works well for non-web UI. However, it also has certain limitations as it is not supported by

RemoteWebDriver. The Sikuli script might fail if it does not find a captured image due to overlapping

windows at runtime.

By using Sikuli, you can automate RIA technologies such as Flash and Silverlight, along with the Selenium

WebDriver.

Web page inspection tools Firefox: The built-in Firefox Developer Tools can be used to examine, edit, and debug HTML, CSS, and

JavaScript on the desktop and on mobile.

Google Chrome provides an in-built feature to analyse pages and elements. You can move the mouse over

a desired element on the page and right-click to open the pop-up menu, then select Inspect element option.

This will open Developer Tools in the browser and show information about the element. Chrome Developer

Tools also provide a feature where you can get XPath for an element by right-clicking on the desired element

in the tree and selecting the Copy XPath option from the pop-up menu. The Chrome extension “Xpath

Helper” is a great tool for verifying XPath selectors found through the Copy XPath option, as it highlights the

element that corresponds to the XPath selector in the browser.

Microsoft Internet Explorer and Microsoft Edge: Press <F12> for the developer tools.

Running (a Selenium IDE produced HTML test suite) on various browsers Install the standalone server5

Run from command prompt: “java -jar selenium-server-standalone-2.53.0.jar …””

Locating Elements Locating elements in Selenium WebDriver is done by using the “findElement()” and “findElements()”

methods provided by WebDriver and WebElement class.

The “findElement()” method returns a WebElement object based on a specified search criteria or throws

up an exception if it does not find any element matching the search criteria.

The “findElements()” method returns a list of WebElements matching the search criteria. If no elements

are found, it returns an empty list.

The “findElement()” and “FindElements()” methods throw up the

“NoSuchElementFoundException” exception when they fail to find the desired element using the

specified locator strategy

Page 7: Selenium WebDriver - Continuous Improvement – · PDF fileCucumber-JVM is a mainstream BDD (Behavior-Driven Development) tool used (in agile development) to implement this practice

Strategy Description

By ID Locates an element using the ID attribute

By name Locates an element using the Name attribute

By class name Locates an element using the (CSS style) Class attribute

By tag name Locates an element using the HTML tag (for example “Select”, “Input”, “List”,

“Button” etc.). The “Input” tag has multiple different types (such as “RADIO”,

“CHECKBOX”, “TEXTBOX”, “PASSWORD”) that need to be further filtered by

using the “type” attribute.

By link text Locates link using it’s text

By partial link text Locates link using it’s partial text

By CSS Locates element using the CSS selector.

The By CSS method is similar to the By XPath method in its usage, but the

difference is that it is slightly faster.

The following example uses two attributes on the <input> element:

WebElement previousButton =

driver.findElement(By.cssSelector("input[type='submit'][value='Login']"));

There is also a partial match syntax (a kind of “regular expressions”), featuring

“^=” (starting with), “$=” (ending with) and “*=” (containing).

Looking for text inside of an element:

WebElement cell =

driver.findElement(By.cssSelector("td:contains('MySearchText')"));

More examples:

To identify an element using the “div” element with “id #flrs”, use

the “#flrs” syntax.

To identify the child “anchor” element, use the “#flrs > a” syntax,

which will return the “link” element.

To identify the “anchor” element with its attribute, use the “#flrs >

a[a[href="/intl/en/about.html"]]” syntax.

By XPath Locates element using XPath query. However, this is the least preferable locator

strategy due its slow performance, as XPath provides the ability to search

elements bi-directionally (downwards in the hierarchy, as well as upwards).

In web browsers, the built-in developer tools can be used to identify the XPath

of elements.

XPath examples:

The root element is identified as “//”.

To identify all the “div” elements, the syntax will be “//div”.

Page 8: Selenium WebDriver - Continuous Improvement – · PDF fileCucumber-JVM is a mainstream BDD (Behavior-Driven Development) tool used (in agile development) to implement this practice

To identify the “link” tags that are within the “div” element, the syntax

will be “//div/a”.

To identify all the elements with a tag, use “*”. The syntax will be

“//div/*”.

To identify all the “div” elements that are at three levels down from the

root, use “//*/*/div”.

To identify specific elements, use attribute values of those elements,

such as “//*/div/a[@id='attrValue']”, which will return the

“anchor” element. This element is at third level from root within a “div”

element, and has an “id” value “attrValue”.

The following example searches for the “<DIV>” node (in the DOM) that

contains an attribute named “class” with the value "myclassname"):

//div[contains(@class,"myclassname")]

Example for finding a child element:

WebElement topLink = driver.findElement(By.id("div1")).findElement(By.linkText("top"));

Example to get all the links and print their targets by using the “findElements()” method:

@Test

public void testFindElements()

{

//Get all the links displayed on Page

List<WebElement> links = driver.findElements(By.tagName("a"));

//Verify there are four links displayed on the page

assertEquals(4, links.size());

//Iterate though the list of links and print target for each link

for(WebElement link : links)

System.out.println(link.getAttribute("href"));

}

Determine if an element exists without throwing an error Selenium WebDriver is really good at letting you know when an element does not exist. If it throws a

NoSuchElementException, then we know it's not there. You will need to handle these errors.

To get around this we can use the findElements() call, and then we just need to check that the size of

the list returned is 0. For example:

List<WebElement> elements = driver.findElements(By.Id("myElement"));

elements.size(); //This should be zero and can be checked accordingly

Page 9: Selenium WebDriver - Continuous Improvement – · PDF fileCucumber-JVM is a mainstream BDD (Behavior-Driven Development) tool used (in agile development) to implement this practice

Get information from elements

Method Result

getText(); Returns the value of the “innerText” attribute of the element.

We can also perform a partial match using Java String API methods such as

“contains()”, “startsWith()” , and “endsWith()”. We can use these methods in

the following way:

assertTrue(messageText.contains("color"));

assertTrue(messageText.startsWith("Click on"));

assertTrue(messageText.endsWith("will change"));

getAttribute() Retrieve an element’s attribute. Example:

assertEquals("justify",message.getAttribute("align"));

getCSSValue() Returns the value of a specified style attribute. Example:

String width = message.getCssValue("width");

assertEquals("150px",width);

getLocation() The “getLocation()” method can be executed on all the WebElements. It is used to

get the relative position of an element where it is rendered on the web page. This

position is calculated relative to the top-left corner of the web page of which the (x, y)

coordinates are assumed as (0, 0). This method can be of use if a test script tries to

validate the layout of a web page.

getSize() The “getSize()” method can also be applied on all the visible components of HTML.

It will return the width and height of the rendered WebElement.

getTagName() The “getTagName()” method can be taken on all the WebElements. This will return

the tag name of the WebElement. For example, in the following HTML code, “button”

is the tag name of the HTML element:

<button id="gbqfba" class="gbqfba" name="btnK" aria-label="Google Search">

Get the content of a whole page The “driver.getPageSource()” method gets the text of a whole page, for example:

if(driver.getPageSource().contains("Whatever you look for"))

{

...

}

Enter data in Editboxes Data can be entered by using the “sendKeys()” method, for example:

Page 10: Selenium WebDriver - Continuous Improvement – · PDF fileCucumber-JVM is a mainstream BDD (Behavior-Driven Development) tool used (in agile development) to implement this practice

driver.findElement(By.xpath("//input[@name='q']")) .sendKeys("hello");

Clear data in Editboxes The “clear()” method action is similar to the “sendKeys()” method, which is applicable for textbox and

textarea elements. It is used to erase the text that is entered, for example:

driver.findElement(By.xpath("//input[@name='q']")) .clear();

The “submit()” method The “submit()” method can be taken on a form or on an element within a form. This is used to submit a

form of a web page to the server hosting the web application, for example:

driver.findElement(By.xpath("//input[@name='q']")) .submit();

Set information on Dropdown and Lists Selenium WebDriver supports testing Dropdown and List controls using a special “Select” class instead of

the “WebElement” class.

A sample test for a Dropdown control:

@Test

public void testDropdown()

{

//Get the Dropdown as a Select using its name attribute

Select make = new Select(driver.findElement(By.name("make")));

//Verify Dropdown does not support multiple selection

assertFalse(make.isMultiple());

//Verify Dropdown has four options for selection

assertEquals(4, make.getOptions().size());

//With Select class we can select an option in Dropdown using Visible Text

make.selectByVisibleText("Honda");

assertEquals("Honda", make.getFirstSelectedOption().getText());

//or we can select an option in Dropdown using value attribute

make.selectByValue("Audi");

assertEquals("Audi", make.getFirstSelectedOption().getText());

//or we can select an option in Dropdown using index

make.selectByIndex(0);

assertEquals("BMW", make.getFirstSelectedOption().getText());

}

Page 11: Selenium WebDriver - Continuous Improvement – · PDF fileCucumber-JVM is a mainstream BDD (Behavior-Driven Development) tool used (in agile development) to implement this practice

Sample code to check the options in the Dropdown control:

//We will verify Dropdown has expected values as listed in a array

List<String> exp_options = Arrays.asList(new String[]{"BMW", "Mercedes",

"Audi","Honda"});

List<String> act_options = new ArrayList<String>();

//Retrieve the option values from Dropdown using getOptions() method

for(WebElement option : make.getOptions())

act_options.add(option.getText());

//Verify expected options array and actual options array match

assertArrayEquals(exp_options.toArray(),act_options.toArray());

For checking whether a specific option is available for selection, we can simply perform a check on the

“act_options” array list in the following way:

assertTrue(act_options.contains("BMW"));

A sample test for a List control which has multi-selection enabled.

@Test

public void testMultipleSelectList()

{

//Get the List as a Select using its name attribute

Select color = new Select(driver.findElement(By.name("color")));

//Verify List support multiple selection

assertTrue(color.isMultiple());

//Verify List has five options for selection

assertEquals(5, color.getOptions().size());

//Select multiple options in the list using visible text

color.selectByVisibleText("Black");

color.selectByVisibleText("Red");

color.selectByVisibleText("Silver");

//Deselect an option using visible text

color.deselectByVisibleText("Silver");

//Deselect an option using value attribute of the option

color.deselectByValue("rd");

//Deselect an option using index of the option

color.deselectByIndex(0);

}

Clicking on Buttons and Links (and other web elements) The “click()” method is used to click on Buttons and Links (and other web elements).

Page 12: Selenium WebDriver - Continuous Improvement – · PDF fileCucumber-JVM is a mainstream BDD (Behavior-Driven Development) tool used (in agile development) to implement this practice

Set information on Radio Buttons and Radio Groups Selenium WebDriver supports Radio Button and Radio Group controls using the “WebElement” class. We

can select and deselect the radio buttons using the “click()” method of the “WebElement” class and

check whether a radio button is selected or deselected using the “isSelected()” method

We can also get all the Radiobuttons from a Radio Group in a list using “findElements()” method along

with Radio Group identifier

Set information on Checkboxes Selenium WebDriver supports Checkbox control using the “WebElement” class. We can select or deselect a

checkbox using the “click()” method of the WebElement class and check whether a checkbox is selected

or deselected using the “isSelected()” method.

Working with Tables A table can be identified by using name, id or xpath and then the rows can be accessed one by one through

the “findElements()” method.

The first example finds all row elements from a given table. Please note that t stands for the table object that

has been found using the “findElements()” method.

List<WebElement> rows = t.findElements(By.tagName("tr"));

The second example illustrates how to find the column number for the given column name in a table.

First example:

int getColumnNumber(WebElement r, String columnName )

{

List<WebElement> cells = r.findElements(By.tagName("th"));

int c = 0;

for (WebElement cell : cells)

{

c=c+1;

System.out.println(c + " --> "+ cell.getText() );

if (columnName.equals(cell.getText())) break;

}

return c;

}

Page 13: Selenium WebDriver - Continuous Improvement – · PDF fileCucumber-JVM is a mainstream BDD (Behavior-Driven Development) tool used (in agile development) to implement this practice

The third example illustrates how to check, if the value in a given cell matches the desired value. The

function takes 3 parameters. The first parameter is the row element, the second parameter is the column

number, and third parameter is the expected value.

boolean verifyValue (WebElement r, int a, String expValue)

{

List<WebElement> mcells = r.findElements(By.tagName("td"));

int c = 0;

for (WebElement cell : mcells)

{

c=c+1;

if (c==a)

{

// get the value inside cell with the getText() method

if (expValue.equals(cell.getText())) return true;

}

}

return false;

}

Check the status of an element The WebElement class provides the following methods to check the state of an element:

Method Purpose

isEnabled() This method checks if an element is enabled. Returns true if enabled, else false for

disabled.

isSelected() This method checks if element is selected (radio button, checkbox, and so on). It returns

true if selected, else false for deselected.

isDisplayed() This method checks if element is displayed.

Mouse and Keyboard events The Actions class implements the builder pattern to create a composite action containing a group of other

actions, such as dragging-and-dropping, holding a key and then performing mouse operations.

Example: Let's create a test to select the multiple rows from different positions in a table using the Ctrl key.

We can select multiple rows by selecting the first row, then holding the Ctrl key, and then selecting another

row and releasing the Ctrl key. This will select the desired rows from the table.

@Tes

public void testRowSelectionUsingControlKey() {

List<WebElement> tableRows =

driver.findElements(By.xpath("//table[@class='iceDatTbl']/tbody/tr"));

//Select second and fourth row from table using Control Key.

//Row Index start at 0

Page 14: Selenium WebDriver - Continuous Improvement – · PDF fileCucumber-JVM is a mainstream BDD (Behavior-Driven Development) tool used (in agile development) to implement this practice

Actions builder = new Actions(driver);

builder.click(tableRows.get(1))

.keyDown(Keys.CONTROL)

.click(tableRows.get(3))

.keyUp(Keys.CONTROL)

.build().perform();

//Verify Selected Row table shows two rows selected

List<WebElement> rows =

driver.findElements(By.xpath("//div[@class='icePnlGrp

exampleBox']/table[@class='iceDatTbl']/tbody/tr"));

assertEquals(2,rows.size());

}

We can create a composite action that is ready to be performed by calling the “build()” method. Finally the

test will perform this composite action by calling the “perform()” method of the Actions class.

Double clicks can be implemented in the same way with the “doubleClick()” method.

Drag and Drop operations can be implemented in the same way with the “dragAndDrop()” (to move to a

target element) and the “dragAndDropBy()” (move by an offset) methods.

The “moveByOffset()” method is used to move the mouse from its current position to another point on the

web page.

The “clickAndHold()” method is another method of the Actions class that left-clicks on an element and

holds it without releasing the left button of the mouse. This method will be useful when executing operations

such as drag-and-drop.

The “release()” method is the one that can release the left mouse button on a WebElement.

The “moveToElement()” method is another method that helps to move the mouse cursor to a WebElement

on the web page.

The “contextClick()” method is also known as right-click. The context is nothing but a menu; a list of

items is associated to a WebElement based on the current state of the web page.

Selenium WebDriver als provides a JavascriptExecutor interface that can be used to execute arbitrary

JavaScript code within the context of the browser.

Synchronisation “WaitFor” Commands are very useful for AJAX. The “waitFor” commands will timeout after 30 seconds by

default.

Command Condition

waitForPageToLoad Delays execution until the page is fully loaded in the browser

waitForElementPresent Delays execution until the specified element is present on the page

waitForElementNotPresent Delays execution until the specified element is removed from the page

Page 15: Selenium WebDriver - Continuous Improvement – · PDF fileCucumber-JVM is a mainstream BDD (Behavior-Driven Development) tool used (in agile development) to implement this practice

waitForTextPresent Delays execution until the specified text is present on the page

waitForFrameToLoad Delays execution until the contents of the frame are fully loaded in the

browser

waitForAlertPresent Delays execution until an alert window is displayed on the page

A number of these commands are run implicitly when other commands are being executed. For example,

with respect to the “clickAndWait” command, when you click on an element, the “waitForPageToLoad”

command is also executed.

Set the Implicit Wait timeout to 10 Seconds driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

However, an implicit wait condition may slow down your tests when an application responds normally, as it

will wait for each element appearing in the DOM and increase the overall execution time. It is recommended

to avoid or minimize the use of an implicit wait condition. Minimize or avoid using an implicit wait condition in

your scripts and try to handle synchronization issues with an explicit wait condition, which provides more

control as compared to an implicit wait condition.

Explicit wait The Selenium WebDriver provides the “WebDriverWait” and “ExpectedCondition” classes for

implementing an explicit wait condition.

WebDriverWait wait = new WebDriverWait(driver, 10);

wait.until(ExpectedConditions.titleContains("Selenium"));

The “ExpectedCondition” class provides a set of predefined conditions to wait before proceeding further

in the code. The following table shows some common conditions that we frequently come across when

automating web browsers supported by the ”ExpectedCondition” class:

Predefined condition Selenium WebDriver (Java)

An element is visible and enabled elementToBeClickable(By locator)

An element is selected elementToBeSelected(WebElement element)

Presence of an element presenceOfElementLocated(By locator)

Specific text present in an element textToBePresentInElement(By locator,

java.lang.String text)

Element value textToBePresentInElementValue(By locator,

java.lang.String text)

Title titleContains(java.lang.String title)

Page 16: Selenium WebDriver - Continuous Improvement – · PDF fileCucumber-JVM is a mainstream BDD (Behavior-Driven Development) tool used (in agile development) to implement this practice

Set the default browser navigation timeout The following statement sets the navigation timeout as 50. This means that the Selenium script will wait for

maximum 50 seconds for a page to load. If page does not load within 50 seconds, it will throw an exception.

driver.manage().timeouts().pageLoadTimeout(50,TimeUnit.SECONDS);

Controlling browsers using “navigate” WebDriver talks to individual browsers natively. This way it has better control, not just on the web page, but

on the browser itself. Navigate is one such feature of WebDriver that allows the test script developer to work

with the browser's Back, Forward, and Refresh controls.

The method that is used for this purpose is “navigate()”, for example:

driver.navigate().back();

driver.navigate().forward();

driver.navigate().refresh();

Cookies WebDriver provides methods for handling cookies, for example “driver.manage().getCookies()” to

fetch all cookies that are loaded for a web page, or

“driver.manage().addCookie(CookieObjectName)” for adding cookie information to the driver.

Handling pop-up windows In Selenium WebDriver, testing pop-up windows involves identifying a pop-up window, switching the driver

context to the pop-up window, then executing steps on the pop-up window, and finally switching back to the

parent window.

The Selenium WebDriver allows us to identify a pop-up window by its “name” attribute or window handle and

switching between the pop-up window and the browser window is done using the

“Webdriver.switchTo().window()”method.

In the following example, a user can open a pop-up window by clicking on the Help button. In this case, the

developer has provided HelpWindow as its name:

@Test

public void testWindowPopup()

{

//Save the WindowHandle of Parent Browser Window

String parentWindowId = driver.getWindowHandle();

Page 17: Selenium WebDriver - Continuous Improvement – · PDF fileCucumber-JVM is a mainstream BDD (Behavior-Driven Development) tool used (in agile development) to implement this practice

//Clicking Help Button will open Help Page in a new Popup Browser Window

WebElement helpButton = driver.findElement(By.id("helpbutton"));

helpButton.click();

try {

//Switch to the Help Popup Browser Window

driver.switchTo().window("HelpWindow");

} catch (NoSuchWindowException e) {

e.printStackTrace();

}

//Verify the driver context is in Help Popup Browser Window

assertTrue(driver.getTitle().equals("Help"));

//Close the Help Popup Window

driver.close();

//Move back to the Parent Browser Window

driver.switchTo().window(parentWindowId);

//Verify the driver context is in Parent Browser Window

assertTrue(driver.getTitle().equals("Build my Car - Configuration"));

}

Handling JavaScript alerts (pop ups) The Selenium WebDriver provides an “Alert” class for handling alerts. To get the alert box displayed on the

screen as an instance of the “Alert” class, the “driver.switchTo().alert()” method is used as

follows:

Alert alert = driver.switchTo().alert();

A test might need to verify what message is displayed in an alert box. We can get the text from an alert box

by calling the “getText()” method of the “Alert” class as follows:

String textOnAlert = alert.getText();

An alert box is closed by clicking on the OK button; this can be done by calling the “accept()” method as

follows:

alert.accept();

Alternatively, an alert box can also be accessed without creating an instance of the “Alert” class by directly

calling desired methods as follows:

driver.switchTo().alert().accept();

Page 18: Selenium WebDriver - Continuous Improvement – · PDF fileCucumber-JVM is a mainstream BDD (Behavior-Driven Development) tool used (in agile development) to implement this practice

Handling OK/Cancel Message Boxes (=Confirm Box Alert) When a confirm box pops up, the user will have to click either on the OK or the Cancel button to proceed. If

the user clicks on the OK button, the box returns true. If the user clicks on the Cancel button, the box returns

false.

The handling is essentially the same as with an Alert Box. The “accept()” method clicks the OK button, the

“dismiss()” button clicks Cancel.

Handling an Input Box (Prompt Box Alert) An Input Box allows the input of a value and displays OK/Cancel boxes to proceed with the input or cancel it.

If the user clicks on the OK button, the box returns the input value. If the user clicks on the Cancel button,

the box returns null.

The handling is essentially the same as with an Alert Box. Input is sent via the “sendKeys()” method.

Frames (including IFRAME) Frames can be identified by an “ID” or “name” attribute, or by their index. The focus can be switched to a

frame by the “driver.switchTo().frame()” method. The “defaultContent()” method can then be

used to switch the focus back to the page.

Example of switching to a frame by the “ID” or “name” attribute:

driver.switchTo().frame("left");

Example of switching to a frame by it’s index:

driver.switchTo().frame(1);

Switch back to the page:

driver.switchTo().defaultContent();

Event handling Selenium WebDriver provides a very good framework for tracking the various events that happen while

running test scripts using WebDriver. Many navigation events that get fired before and after an event occurs

(such as before and after navigating to a URL, before and after browser back-navigation, and so on) can be

tracked and captured. To throw an event, WebDriver uses a class named “EventFiringWebDriver”, and

to catch that event, it provides an interface named “WebDriverEventListener”. The test script developer

should provide their own implementations for the overridden methods from the interface.

Taking Screenshots in WebDriver We can save the file object returned by the “getScreenshotAs()” method using the “copyFile()”

method of the FileUtils class from the “org.apache.commons.io.FileUtils” class.

Example:

Page 19: Selenium WebDriver - Continuous Improvement – · PDF fileCucumber-JVM is a mainstream BDD (Behavior-Driven Development) tool used (in agile development) to implement this practice

@Test

public void testTakesScreenshot()

{

try {

File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);

FileUtils.copyFile(scrFile, new File("c:\\tmp\\main_page.png"));

} catch (Exception e) {

e.printStackTrace();

}

}

The “TakesScreenshot” interface captures the screenshot of the entire page, current window, visible

portion of the page, or of the complete desktop window in their respective order as supported by the

browser.

Taking Screenshots with RemoteWebDriver or Grid “RemoteWebDriver” doesn't implement the “TakesScreenshot” interface. There are multiple ways to

work around this.

One way is to create an own “WebDriver” class that extends the “RemoteWebDriver” class and

implements the “TakesScreenshot” interface by providing the implementation for the

“getScreenshotAs()” method. Another ways is to use the "Augmenter" class.

Add the following code to the test using RemoteWebDriver:

driver = new Augmenter().augment(driver);

File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);

FileUtils.copyFile(scrFile, new File("c:\\tmp\\screenshot.png"));

Screenshots with screengrab or fireshot Screengrab is a Mozilla Firefox add-on and Google Chrome extension for screenshots.

Screengrab saves entire webpages as images. It can be used through the context menu (right-click).

Screengrab will capture the window, the entire page, just a selection, a particular frame... basically it saves

webpages as images - either to a file, or to the clipboard, or upload to internet.

Fireshot is another Mozilla Firefox add-on for the same purpose, but also available for Google Chrome and

Microsoft Internet Explorer, but it is only available for Microsoft Windows. Note that there is also a for-pay

version of FireShot available called FireShot Pro, that costs $59.95. It has more powerful features, such as

handling multiple captures simultaneously and unlimited levels of undo. When you download the free version

of FireShot, you get the full features of Pro, but it later reverts to the free version, if you don't pay for it.

The Page Object pattern (for building custom classes that encapsulate

pages and/or business processes) The Page Object pattern brings the following advantages:

It helps in building a layer of abstraction separating automation code, which knows about locating

application elements and the one which interacts with these elements for actual testing.

Page 20: Selenium WebDriver - Continuous Improvement – · PDF fileCucumber-JVM is a mainstream BDD (Behavior-Driven Development) tool used (in agile development) to implement this practice

It provides a central repository of pages from the application for tests.

It provides high maintainability and reduction in code duplication.

A Page Object is an object in a Java class.

A Factory method is just a fancy name for a method that instantiates objects. Like a factory, the job of the

factory method is to create -- or manufacture – objects.

Page Objects This is a technique where we split the test logic out into separate classes. This

allows us to create a Java class for each page and/or business process that we use

in an application.

Page Factory This allows us to centralise our WebElement variables in our Page objects so that

we remove a lot of the look up code. The elements get initialized when we call

PageFactory.initElements(); in our tests or anything else that may use that

code.

LoadableComponent The loadable component is an extension to the PageObject pattern. The

“LoadableComponent” class in the WebDriver library helps test case developers

to ensure that the page or a component of the page is loaded successfully. It

tremendously reduces the efforts to debug your test cases. The PageObject should

extend this “LoadableComponent” abstract class and, as a result, it is bound to

provide implementation for the following two methods:

protected abstract void load()

protected abstract void isLoaded() throws java.lang.Error

The page or component that has to be loaded in the “load()” and “isLoaded()”

methods determines whether or not the page or component is fully loaded. If it is

not fully loaded, it throws an error. The URL that has to be loaded is specified in the

“load()” method and the “isLoaded()” method validates whether or not the

correct page is loaded. However, it must be considered that the “isLoaded()”

method is called before the “load()” method (see following example)! The

“load()” method can also be used to reset the application to the initial state by

calling it again at the end of a custom method (see following example).

The “get()” method will make sure the component is loaded by invoking the

“isLoaded()” method.

Kill Windows processes We can close or kill any process running on the Windows OS by using the “tryToKillByName()” function

of the “WindowsUtils” class. We need to pass the name of process we wish to close.

WindowsUtils.tryToKillByName("firefox.exe");

The “WindowsUtils” class will search the specified process and kill any running instances. If the process

does not exist, an exception will be thrown up. However, the test will continue with the next steps.

Page 21: Selenium WebDriver - Continuous Improvement – · PDF fileCucumber-JVM is a mainstream BDD (Behavior-Driven Development) tool used (in agile development) to implement this practice

Dealing with I/O Selenium WebDriver provides three important classes to handle the filesystem.

Class Used for

FileHandler Copy files, create directories, delete files or directories, check if a file is a

zipped file, make a file executable, make a file writeable, read a file as a string,

check if a file is executable etc.

TemporaryFilesystem As the name suggests, the files that are created under temporary filesystem

are temporary; that is, the files are deleted as soon as the test script is

executed.

zip Allows zipping and unzipping of files.

Remote execution The “RemoteWebDriver” server is a component that listens on a port for various requests from a

“RemoteWebDriver” client. Once it receives the requests, it forwards them to any of the following: Firefox

Driver, IE Driver, or Chrome Driver, whichever is asked.

“selenium-server-standalone” is the “RemoteWebDriver” server. The following example command

starts a “RemoteWebDriver” server (version 2.53.0):

java –jar selenium-server-standalone-2.53.0.jar

Example conversion from local execution to remote execution: The following program code executes a script locally:

public class ExistingTest {

public static void main(String... args){

WebDriver driver = new FirefoxDriver();

}

}

The following program code will execute the script remotely:

package com.mydomain.myproject;

import java.net.MalformedURLException;

import java.net.URL;

import org.openqa.selenium.remote.DesiredCapabilities;

import org.openqa.selenium.remote.RemoteWebDriver;

public class UsingRemoteWebDriver {

public static void main(String... args){

DesiredCapabilities capabilities = new DesiredCapabilities();

capabilities.setBrowserName("firefox");

RemoteWebDriver remoteWD = null;

try {

remoteWD = new RemoteWebDriver(new

URL("http://10.172.10.1:4444/wd/hub"),capabilities);

} catch (MalformedURLException e) {

e.printStackTrace();

Page 22: Selenium WebDriver - Continuous Improvement – · PDF fileCucumber-JVM is a mainstream BDD (Behavior-Driven Development) tool used (in agile development) to implement this practice

}

remoteWD.get("http://www.google.com");

remoteWD.findElement(By.name("q")).sendKeys("Exampletext");

}

}

The remote server provides a web interface under the URL http://servername:4444/wd/hub, for example:

The following example configures the “RemoteWebDriver” to test an application on an iPad:

WebDriver driver = new RemoteWebDriver(new URL("http://localhost:3001/wd/hub"),

DesiredCapabilities.ipad());

Remote execution in various browsers The Mozilla Firefox driver comes along with the “RemoteWebDriver” server JAR file. It does not have to be

downloaded or started explicitly, unlike with Microsoft Internet Explorer driver or the Google Chrome driver.

Using “DesiredCapabilities”, you can specify the “RemoteWebDriver” server on which you want your

test script commands to be executed on Firefox browser, as shown in the following code:

DesiredCapabilities capabilities = new DesiredCapabilities();

capabilities.setBrowserName("firefox");

For the Microsoft Internet Explorer driver, you need to specify the path for the executable explicitly. Stopping

the “RemoteWebDriver” server and restarting it using the following command will do this:

C:\>java -Dwebdriver.ie.driver="C:\IEDriverServer.exe" -jar seleniumserver-

standalone-2.53.0.jar

Page 23: Selenium WebDriver - Continuous Improvement – · PDF fileCucumber-JVM is a mainstream BDD (Behavior-Driven Development) tool used (in agile development) to implement this practice

For the Google Chrome driver, you need to specify the path for the executable explicitly. Stopping the

“RemoteWebDriver” server and restarting it using the following command (one command line) will do this:

C:\>java -Dwebdriver.ie.driver="C:\IEDriverServer.exe"

-Dwebdriver.chrome.driver="C:\chromedriver.exe"

-jar selenium-server-standalone-2.53.0.jar

Distributed Testing with Selenium Grid

Selenium Grid allows us to run multiple instances of WebDriver or Selenium Remote Control (for legacy) in

parallel. It makes all these nodes appear as a single instance, so tests do not have to worry about the actual

infrastructure. Selenium Grid cuts down on the time required to run Selenium tests to a fraction of the time

that a single instance of Selenium would take to run and it is very easy to set up and use.

Selenium Grid is a testing infrastructure with several different platforms (such as Windows, Mac, Linux, and

so on) for your tests to execute, and these platforms are managed from a central point. The central point

known as hub, has the information of all the different testing platforms known as nodes, and assigns these

nodes to execute tests whenever the test scripts request.

The selenium-server-standalone package includes the Hub, WebDriver, and Selenium RC needed to run the

grid. We can use the same (selenium-server-standalone-2.xx.0.jar) JAR file to be started in the

hub mode on the hub machine, and a copy of the JAR file can be started in the node mode on every node

machine.

The hub is the central point of a Selenium Grid. It has a registry of all the registered nodes that are part of a

particular grid. The hub is again a Selenium server running in the hub mode listening on port 4444 of a

machine by default. The test scripts will try to connect to the hub on this port, just as any Remote WebDriver.

The hub will take care of rerouting the test script traffic to the appropriate test platform node. The hub can be

started with the following command:

java -jar selenium-server-standalone-2.53.0.jar -role hub

By default, a hub will send up to five test script requests to any registered node. When two nodes of the

same capabilities are registered with a hub, a test script request receives the node that is registered first with

Page 24: Selenium WebDriver - Continuous Improvement – · PDF fileCucumber-JVM is a mainstream BDD (Behavior-Driven Development) tool used (in agile development) to implement this practice

the hub. If the first registered node is busy handling other test script requests, only then the hub directs the

request to the second node with matching requested capabilities.

Nodes can be registered to the hub in two ways: Via command line or a JSON format configuration file. The

following example command starts a node and registers the node with a (previously started) hub running on

port 1111 on IP 192.0.0.23: java –jar selenium-server-standalone-2.53.0.jar –role node –hub http://192.0.0.23:1111/grid/register

If a script needs to be executed via a hub (instead of directly via a “RemoteWebDriver” call), then there is

no difference in the script program code compared to executing it directly using a “RemoteWebDriver” call

(as described previously in this document under the heading “Example conversion from local execution to

remote execution”. However, without specification, the hub will execute the script on any available platform

(Windows, Mac etc.). If a specific platform needs to be used, then the platform needs to be specified in the

capabilities of the script, for example:

capabilities.setPlatform(Platform.MAC);

To execute parallel tests, we need a testing framework that supports parallel runs of our tests, for example

TestNG or JUnit. The testing framework executes the tests by sending them to the hub, which distributes

them automatically to the registered nodes.

Setting supported browsers by a node By default, the number of browsers available for the hub used for every node is 11: five for Mozilla Firefox, 5

for Google Chrome, and 1 for Internet Explorer. This can be overridden by specifying the “-browser” option.

The following example registers a node supporting 3 Mozilla Firefox instances, 3 Google Chrome instances

and one Apple Safari instance with an (optional) node timeout of 300 seconds (one command line):

java -jar selenium-server-standalone-2.53.0.jar -role node -hub

http://172.16.87.131:1111/grid/register -browser

"browserName=firefox,maxInstances=3" -browser

"browserName=chrome,maxInstances=3" -browser "browserName=safari,maxInstances=1"

–nodeTimeout 300

Selenium Grid provides a configuration parameter "-registerCycle" to a node through which we can

specify the node to reregister itself automatically to the hub after a specified amount of time. If not specified,

the default time of reregistration is five seconds. This way, we really don't have to worry; even if the hub

crashes or restarts, our node will try to reregister every five seconds.

The parameter “browserTimeout” will cause a script to abort the browser session and start with the next

waiting test script, for example for a browser timeout of 60 seconds:

-browserTimeout 60

Testing iOS and Android Apps using Appium Appium ( http://appium.io/ ) is an open source test automation framework for use with native and hybrid

mobile apps. It drives iOS and Android apps using the WebDriver JSON wire protocol.

For automating iOS app tests, Appium uses Apple Instruments. According to Apple, Instruments is a

performance, analysis, and testing tool for dynamically tracing and profiling macOS and iOS code.

Page 25: Selenium WebDriver - Continuous Improvement – · PDF fileCucumber-JVM is a mainstream BDD (Behavior-Driven Development) tool used (in agile development) to implement this practice

Automating Android tests for your Android apps is similar to automating iOS apps tests. Google UI

Automator comes with the Android SDK.

Headless browsing There are several headless browsers, like ZombieJS, EnvJS, and PhantomJS (they tend to be written in

JavaScript – hence the JS in the names). PhantomJS is the most popular.

The “phantomjs” binary contains both the browser itself and the Selenium driver.

You could start PhantomJS the same way you start Google Chrome, but you don’t want that. Websites know

which browser you are using. And they know that humans use Chrome, Firefox, Safari, etc. But PhantomJS?

ZombieJS? Only bots use these. Hence many websites refuse to deal with headless browsers. We want the

website to think that we are using something else. To do that, we need to change the user-agent string using

the desired capabilities. The following example disguises as Google Chrome:

import org.openqa.selenium.phantomjs.PhantomJSDriver;

import org.openqa.selenium.phantomjs.PhantomJSDriverService;

import org.openqa.selenium.remote.DesiredCapabilities;

...

// In the variables declaration

protected static DesiredCapabilities dcap;

...

dcap = new DesiredCapabilities();

dcap.setCapability(PhantomJSDriverService.PHANTOMJS_PAGE_SETTINGS_PREFIX + "userAgent", "Mozilla/5.0

(Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110

Safari/537.36");

System.setProperty("phantomjs.binary.path", "/usr/bin/phantomjs");

driver = new PhantomJSDriver(dcap);

Page 26: Selenium WebDriver - Continuous Improvement – · PDF fileCucumber-JVM is a mainstream BDD (Behavior-Driven Development) tool used (in agile development) to implement this practice

And that’s it. The rest of your code doesn’t change. The only difference is that when you run your script you

won’t see any windows popping up.

Alternative approach on Linux using “Xvfb” Xvfb or X virtual framebuffer is a display server implementing the X11 display server protocol. In contrast to

other display servers Xvfb performs all graphical operations in memory without showing any screen output.

“Xvfb” can be used to run browsers (such as Mozilla Firefox) without an actual graphical display.