Selenium Tutorial for Beginners:
First Look
Tutorial | What is Selenium? Introduction to Selenium Automation Testing |
Tutorial | What is Selenium WebDriver? Difference with RC |
WebDriver Tutorial
It will be beneficial if you revisit Java, before reading tutorials on Webdriver
Tutorial | How to Download & Install Selenium WebDriver |
Tutorial | First Selenium Webdriver Script: JAVA Code Example |
Tutorial | Locators in Selenium IDE: CSS Selector, DOM, XPath, Link Text, ID |
Tutorial | Find Element and FindElements in Selenium WebDriver |
Tutorial | Selenium Form WebElement: TextBox, Submit Button, sendkeys(), click() |
Tutorial | How to Select CheckBox and Radio Button in Selenium WebDriver |
Tutorial | How to Click on Image in Selenium Webdriver |
Tutorial | How to Select Value from DropDown using Selenium Webdriver |
Tutorial | Locate Elements by Link Text & Partial Link Text in Selenium Webdriver |
Tutorial | Mouse Click & Keyboard Event: Action Class in Selenium Webdriver |
Tutorial | How to Upload & Download a File using Selenium Webdriver |
Tutorial | XPath in Selenium WebDriver: Complete Tutorial |
Tutorial | Alert & Popup Window Handling in Selenium WebDriver |
Tutorial | How to Handle Web Table in Selenium WebDriver |
Tutorial | Handling Dynamic Web Tables Using Selenium WebDriver |
Tutorial | Desired Capabilities in Selenium WebDriver |
Tutorial | How to Verify Tooltip using Selenium WebDriver |
Tutorial | How to Find All/Broken links using Selenium Webdriver |
Tutorial | Gecko (Marionette) Driver Selenium: Download, Install, Use with Firefox |
TestNG
Tutorial | How to Download & Install TestNG in Eclipse for Selenium WebDriver |
Tutorial | TestNG Tutorial: Annotations, Framework, Examples in Selenium |
Tutorial | TestNG Groups: Include, Exclude with Example - Selenium Tutorial |
Tutorial | TestNG @Test Priority in Selenium |
Tutorial | Parallel Execution in Selenium: Session Handling & TestNG Dependency |
Tutorial | TestNG: How to Run Multiple Test Suites in Selenium |
Tutorial | TestNG Listeners in Selenium: ITestListener & ITestResult Example |
Tutorial | How to Execute Failed Test Cases in TestNG: Selenium WebDriver |
Tutorial | TestNG Report Generation in Selenium WebDriver |
Tutorial | Customize, PDF & Email TestNG Reports in Selenium WebDriver |
Frameworks
Tutorial | Page Object Model (POM) & Page Factory: Selenium WebDriver Tutorial |
Tutorial | Dataprovider & TestNG XML: Parameterization in Selenium(Example) |
Tutorial | Read & Write Data from Excel File in Selenium Webdriver: POI & JXL |
Tutorial | How to Select Date from DatePicker/Calendar in Selenium Webdriver |
Advance Webdriver Stuff!
Tutorial | Selenium Grid Tutorial: Hub & Node (with Example) |
Tutorial | Maven & Jenkins Integration with Selenium: Complete Tutorial |
Tutorial | Selenium Automation Framework: Data Driven, Keyword Driven & Hybrid |
Tutorial | Database Testing using Selenium: Step by Step Guide |
Tutorial | Handling iFrames in Selenium Webdriver: switchTo() |
Tutorial | Cross Browser Testing using Selenium WebDriver |
Tutorial | How to Take Screenshot in Selenium WebDriver |
Tutorial | Log4j with Selenium Tutorial: Download, Install, Use & Example |
Tutorial | Selenium Headless Browser Testing: HTMLUnitDriver & PhantomJS |
Tutorial | Robot Class in Selenium Webdriver |
Tutorial | How to use AutoIT with Selenium Webdriver: File Upload Example |
Tutorial | How to Handle SSL Certificate in Selenium WebDriver |
Tutorial | How to Handle AJAX Call in Selenium Webdriver |
Tutorial | JavaScriptExecutor in Selenium WebDriver with Example |
Tutorial | Selenium Webdriver using Python: Tutorial with Example |
Tutorial | How to use IntelliJ IDEA & Selenium Webdriver |
Tutorial | Flash Testing with Selenium WebDriver |
Tutorial | Apache ANT with Selenium: Complete Tutorial |
Tutorial | How to Generate XSLT Report in Selenium Webdriver |
Tutorial | Github Integration with Selenium: Complete Tutorial |
Tutorial | Cookies Handling in Selenium WebDriver |
Tutorial | Using SoapUI with Selenium for Web Service Testing |
Tutorial | How to Create Firefox Profile in Selenium WebDriver |
Tutorial | Selenium with Cucumber (BDD Framework): Tutorial with Example |
Tutorial | How to Drag and Drop in Selenium WebDriver (EXAMPLE) |
Tutorial | Selenium C# Webdriver Tutorial: NUnit Example |
Tutorial | Creating Object Repository in Selenium WebDriver: XML & Properties file |
Tutorial | How to Scroll Down or UP a Page in Selenium Webdriver |
Tutorial | Sikuli Tutorial: How to use Sikuli with Selenium (EXAMPLE) |
Tutorial | XPath Contains, Sibling, Ancestor Functions in Selenium WebDriver |
Tutorial | Implicit, Explicit, & Fluent Wait in Selenium WebDriver |
Tutorial | Double click and Right Click in Selenium with Examples |
Selenium IDE Tutorial
Tutorial | How to Download & Install Selenium IDE for Firefox |
Tutorial | Selenium IDE Tutorial for Beginners |
Tutorial | How to use Selenium IDE with Scripts & Commands (Assert, Verify) |
Tutorial | Verify Element Present, waitFor, andWait in Selenium IDE |
Tutorial | Store Variables, Echo, Alert, PopUp handling in Selenium IDE |
Tutorial | Selenium Core Extensions (User-Extensions.js) |
Tutorial | Breakpoint & Start Point in Selenium IDE |
Tutorial | Maximize Browser in Selenium |
Must Check!
Tutorial | Top 100 Selenium Interview Questions & Answers |
Tutorial | Selenium vs HP UFT (QTP): What's the Difference? |
Tutorial | Top 15 Selenium Alternatives |
Live Selenium Project
Join | Live Selenium Project: Banking Domain |
Join | Live Ecommerce Project: Selenium Automation |
Selenium is a free (open source) automated testing suite for web applications across different browsers and platforms. It is quite similar to HP Quick Test Pro (QTP now UFT) only that Selenium focuses on automating web-based applications. Testing done using Selenium tool is usually referred as Selenium Testing.
Selenium is not just a single tool but a suite of software's, each catering to different testing needs of an organization. It has four components.
At the moment, Selenium RC and WebDriver are merged into a single framework to form Selenium 2. Selenium 1, by the way, refers to Selenium RC.
Since Selenium is a collection of different tools, it had different developers as well. Below are the key persons who made notable contributions to the Selenium Project
Primarily, Selenium was created by Jason Huggins in 2004. An engineer at ThoughtWorks, he was working on a web application that required frequent testing. Having realized that the repetitious Manual Testing of their application was becoming more and more inefficient, he created a JavaScript program that would automatically control the browser's actions. He named this program as the "JavaScriptTestRunner." Seeing potential in this idea to help automate other web applications, he made JavaScriptRunner open-source which was later re-named as Selenium Core. |
Same Origin policy prohibits JavaScript code from accessing elements from a domain that is different from where it was launched. Example, the HTML code in www.google.com uses a JavaScript program "randomScript.js". The same origin policy will only allow randomScript.js to access pages within google.com such as google.com/mail, google.com/login, or google.com/signup. However, it cannot access pages from different sites such as yahoo.com/search or guru99.com because they belong to different domains.
This is the reason why prior to Selenium RC, testers needed to install local copies of both Selenium Core (a JavaScript program) and the web server containing the web application being tested so they would belong to the same domain
Unfortunately; testers using Selenium Core had to install the whole application under test and the web server on their own local computers because of the restrictions imposed by the same origin policy. So another ThoughtWork's engineer, Paul Hammant, decided to create a server that will act as an HTTP proxy to "trick" the browser into believing that Selenium Core and the web application being tested come from the same domain. This system became known as the Selenium Remote Control or Selenium 1.
Selenium Grid was developed by Patrick Lightbody to address the need of minimizing test execution times as much as possible. He initially called the system "Hosted QA." It was capable of capturing browser screenshots during significant stages, and also of sending out Selenium commands to different machines simultaneously.
Shinya Kasatani of Japan created Selenium IDE, a Firefox extension that can automate the browser through a record-and-playback feature. He came up with this idea to further increase the speed in creating test cases. He donated Selenium IDE to the Selenium Project in 2006.
Simon Stewart created WebDriver circa 2006 when browsers and web applications were becoming more powerful and more restrictive with JavaScript programs like Selenium Core. It was the first cross-platform testing framework that could control the browser from the OS level.
In 2008, the whole Selenium Team decided to merge WebDriver and Selenium RC to form a more powerful tool called Selenium 2, with WebDriver being the core. Currently, Selenium RC is still being developed but only in maintenance mode. Most of the Selenium Project's efforts are now focused on Selenium 2.
It came from a joke which Jason cracked one time to his team. Another automated testing framework was popular during Selenium's development, and it was by the company called Mercury Interactive (yes, the company who originally made QTP before it was acquired by HP). Since Selenium is a well-known antidote for Mercury poisoning, Jason suggested that name. His teammates took it, and so that is how we got to call this framework up to the present.
Selenium Integrated Development Environment (IDE) is the simplest framework in the Selenium suite and is the easiest one to learn. It is a Firefox plugin that you can install as easily as you can with other plugins. However, because of its simplicity, Selenium IDE should only be used as a prototyping tool. If you want to create more advanced test cases, you will need to use either Selenium RC or WebDriver.
Selenium RC was the flagship testing framework of the whole Selenium project for a long time. This is the first automated web testing tool that allowed users to use a programming language they prefer. As of version 2.25.0, RC can support the following programming languages:
The WebDriver proves itself to be better than both Selenium IDE and Selenium RC in many aspects. It implements a more modern and stable approach in automating the browser's actions. WebDriver, unlike Selenium RC, does not rely on JavaScript for Automation. It controls the browser by directly communicating with it.
The supported languages are the same as those in Selenium RC.
Selenium Grid is a tool used together with Selenium RC to run parallel tests across different machines and different browsers all at the same time. Parallel execution means running multiple tests at once.
Features:
Because of their architectural differences, Selenium IDE, Selenium RC, and WebDriver support different sets of browsers and operating environments.
Selenium IDE | WebDriver | |
---|---|---|
BrowserSupport | Mozilla Firefox | Internet Explorer versions 6 to 11, both 32 and 64-bit Microsoft Edge version 12.10240 & above ( partial support some functionalities under development) Firefox 3.0 and above Google Chrome 12.0. and above Opera 11.5 and above Android - 2.3 and above for phones and tablets (devices & emulators) iOS 3+ for phones (devices & emulators) and 3.2+ for tablets (devices & emulators) HtmlUnit 2.9 and above |
Operating System | Windows,Mac OS X,Linux | All operating systems where the browsers above can run. |
Note: Selenium WebDriver is termed as the successor of Selenium RC which has been deprecated & officially announced by SeleniumHQ.
Tool | Why Choose? |
---|---|
Selenium IDE |
|
Selenium RC |
|
WebDriver |
|
Selenium Grid |
|
Quick Test Professional(QTP) is a proprietary automated testing tool previously owned by the company Mercury Interactive before it was acquired by Hewlett-Packard in 2006. The Selenium Tool Suite has many advantages over QTP as detailed below -
Advantages of Selenium over QTP
Selenium | QTP |
---|---|
Open source, free to use, and free of charge. | Commercial. |
Highly extensible | Limited add-ons |
Can run tests across different browsers | Can only run tests in Firefox, Internet Explorer and Chrome |
Supports various operating systems | Can only be used in Windows |
Supports mobile devices | QTP Supports Mobile app test automation (iOS & Android) using HP solution called - HP Mobile Center |
Can execute tests while the browser is minimized | Needs to have the application under test to be visible on the desktop |
Can execute tests in parallel. | Can only execute in parallel but using Quality Center which is again a paid product. |
QTP | Selenium |
---|---|
Can test both web and desktop applications | Can only test web applications |
Comes with a built-in object repository | Has no built-in object repository |
Automates faster than Selenium because it is a fully featured IDE. | Automates at a slower rate because it does not have a native IDE and only third party IDE can be used for development |
Data-driven testing is easier to perform because it has built-in global and local data tables. | Data-driven testing is more cumbersome since you have to rely on the programming language's capabilities for setting values for your test data |
Can access controls within the browser(such as the Favorites bar, Address bar, Back and Forward buttons, etc.) | Cannot access elements outside of the web application under test |
Provides professional customer support | No official user support is being offered. |
Has native capability to export test data into external formats | Has no native capability to export runtime data onto external formats |
Parameterization Support is built | Parameterization can be done via programming but is difficult to implement. |
Test Reports are generated automatically | No native support to generate test /bug reports. |
Though clearly, QTP has more advanced capabilities, Selenium outweighs QTP in three main areas:
WebDriver is a web automation framework that allows you to execute your tests against different browsers, not just Firefox, Chrome (unlike Selenium IDE).
WebDriver also enables you to use a programming language in creating your test scripts (not possible in Selenium IDE).
You can now use conditional operations like if-then-else or switch-case. You can also perform looping like do-while.
Following programming languages are supported by WebDriver
You do not have to know all of them. You just need to be knowledgeable in one. However, in this tutorial, we will be using Java with Eclipse as our IDE.
Before the advent of WebDriver in 2006, there was another, automation tool called Selenium Remote Control. Both WebDriver and Selenium RC have following features:
So how do they differ? Let us discuss the answers.
WebDriver's architecture is simpler than Selenium RC's.
WebDriver is faster than Selenium RC since it speaks directly to the browser uses the browser's own engine to control it.
Selenium RC is slower since it uses a Javascript program called Selenium Core. This Selenium Core is the one that directly controls the browser, not you.
WebDriver interacts with page elements in a more realistic way. For example, if you have a disabled text box on a page you were testing, WebDriver really cannot enter any value in it just as how a real person cannot.
Selenium Core, just like other JavaScript codes, can access disabled elements. In the past, Selenium testers complain that Selenium Core was able to enter values to a disabled text box in their tests. Differences in API
Selenium RC's API is more matured but contains redundancies and often confusing commands. For example, most of the time, testers are confused whether to use type or typeKeys; or whether to use click, mouseDown, or mouseDownAt. Worse, different browsers interpret each of these commands in different ways too!
WebDriver's API is simpler than Selenium RC's. It does not contain redundant and confusing commands.
WebDriver can support the headless HtmlUnit browser
HtmlUnit is termed as "headless" because it is an invisible browser - it is GUI-less.
It is a very fast browser because no time is spent in waiting for page elements to load. This accelerates your test execution cycles.
Since it is invisible to the user, it can only be controlled through automated means.
Selenium RC cannot support the headless HtmlUnit browser. It needs a real, visible browser to operate on.
Remember that WebDriver operates on the OS level. Also, remember that different browsers communicate with the OS in different ways. If a new browser comes out, it may have a different process of communicating with the OS as compared to other browsers. So, you have to give the WebDriver team quite some time to figure that new process out before they can implement it on the next WebDriver release.
However, it is up to the WebDriver's team of developers to decide if they should support the new browser or not.
Selenium RC automatically generates an HTML file of test results. The format of the report was pre-set by RC itself. Take a look at an example of this report below.
WebDriver has no built-in command that automatically generates a Test Results File. You would have to rely on your IDE's output window, or design the report yourself using the capabilities of your programming language and store it as text, HTML, etc.
In this tutorial, we will install Webdriver (Java only) and Configure Eclipse
Download and install the Java Software Development Kit (JDK) here.
Next –
This JDK version comes bundled with Java Runtime Environment (JRE), so you do not need to download and install the JRE separately.
Once installation is complete, open command prompt and type “java”. If you see the following screen you are good to move to the next step
Download latest version of "Eclipse IDE for Java Developers" here. Be sure to choose correctly between Windows 32 Bit and 64 Bit versions.
You should be able to download an exe file named "eclipse-inst-win64" for Setup.
Double-click on file to Install the Eclipse. A new window will open. Click Eclipse IDE for Java Developers.
After that, a new window will open which click button marked 1 and change path to "C:\eclipse". Post that Click on Install button marked 2
After successful completion of the installation procedure, a window will appear. On that window click on Launch
This will start eclipse neon IDE for you.
You can download the Selenium Java Client Driver here. You will find client drivers for other languages there, but only choose the one for Java.
This download comes as a ZIP file named "selenium-2.25.0.zip". For simplicity, extract the contents of this ZIP file on your C drive so that you would have the directory "C:\selenium-2.25.0\". This directory contains all the JAR files that we would later import on Eclipse.
3. Create a new project through File > New > Java Project. Name the project as "newproject".
A new pop-up window will open enter details as follow
4. In this step,
A pop-up window will open to name the package,
5. Create a new Java class under newpackage by right-clicking on it and then selecting- New > Class, and then name it as "MyClass". Your Eclipse IDE should look like the image below.
When you click on Class, a pop-up window will open, enter details as
This is how it looks like after creating class.
Now selenium WebDriver's into Java Build Path
In this step,
When you click on "Add External JARs.." It will open a pop-up window. Select the JAR files you want to add.
After selecting jar files, click on OK button.
Select all files inside the lib folder.
Select files outside lib folder
Once done, click "Apply and Close" button
6. Add all the JAR files inside and outside the "libs" folder. Your Properties dialog should now look similar to the image below.
7. Finally, click OK and we are done importing Selenium libraries into our project.
HTMLUnit and Firefox are two browsers that WebDriver can directly automate - meaning that no other separate component is needed to install or run while the test is being executed. For other browsers, a separate program is needed. That program is called as the Driver Server.
A driver server is different for each browser. For example, Internet Explorer has its own driver server which you cannot use on other browsers. Below is the list of driver servers and the corresponding browsers that use them.
You can download these drivers here
Browser | Name of Driver Server | Remarks |
HTMLUnit | HtmlUnitDriver | WebDriver can drive HTMLUnit using HtmlUnitDriver as driver server |
Firefox | Mozilla GeckoDriver | WebDriver can drive Firefox without the need of a driver server Starting Firefox 45 & above one needs to use gecko driver created by Mozilla for automation |
Internet Explorer | Internet Explorer Driver Server | Available in 32 and 64-bit versions. Use the version that corresponds to the architecture of your IE |
Chrome | ChromeDriver | Though its name is just "ChromeDriver", it is, in fact, a Driver Server, not just a driver. The current version can support versions higher than Chrome v.21 |
Opera | OperaDriver | Though its name is just "OperaDriver", it is, in fact, a Driver Server, not just a driver. |
PhantomJS | GhostDriver | PhantomJS is another headless browser just like HTMLUnit. |
Safari | SafariDriver | Though its name is just "SafariDriver", it is, in fact, a Driver Server, not just a driver. |
Summary
Aside from a browser, you will need the following to start using WebDriver
When starting a WebDriver project in Eclipse, do not forget to import the Java Client Driver files onto your project. These files will constitute your Selenium Library.
With new version of Selenium, there is no browser that you can automate without the use of a Driver Server.
Using the Java class "myclass" that we created in the previous tutorial, let us try to create a WebDriver script that would:
Below is the actual WebDriver code for the logic presented by the scenario above
Note: Starting Firefox 35, you need to use gecko driver created by Mozilla to use Web Driver. Selenium 3.0, gecko and firefox has compatibility issues and setting them correctly could become an uphill task. If the code does not work, downgrade to Firefox version 47 or below. Alternatively, you can run your scripts on Chrome. Selenium works out of the box for Chrome. You just need to change 3 lines of code to make your script work with Chrome or Firefox
package newproject; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; //comment the above line and uncomment below line to use Chrome //import org.openqa.selenium.chrome.ChromeDriver; public class PG1 { public static void main(String[] args) { // declaration and instantiation of objects/variables System.setProperty("webdriver.firefox.marionette","C:\\geckodriver.exe"); WebDriver driver = new FirefoxDriver(); //comment the above 2 lines and uncomment below 2 lines to use Chrome //System.setProperty("webdriver.chrome.driver","G:\\chromedriver.exe"); //WebDriver driver = new ChromeDriver(); String baseUrl = "http://demo.guru99.com/test/newtours/"; String expectedTitle = "Welcome: Mercury Tours"; String actualTitle = ""; // launch Fire fox and direct it to the Base URL driver.get(baseUrl); // get the actual value of the title actualTitle = driver.getTitle(); /* * compare the actual title of the page with the expected one and print * the result as "Passed" or "Failed" */ if (actualTitle.contentEquals(expectedTitle)){ System.out.println("Test Passed!"); } else { System.out.println("Test Failed"); } //close Fire fox driver.close(); } }
To get started, you need to import following two packages:
If your test needs more complicated actions such as accessing another class, taking browser screenshots, or manipulating external files, definitely you will need to import more packages.
Normally, this is how a driver object is instantiated.
A FirefoxDriver class with no parameters means that the default Firefox profile will be launched by our Java program. The default Firefox profile is similar to launching Firefox in safe mode (no extensions are loaded).
For convenience, we saved the Base URL and the expected title as variables.
WebDriver's get() method is used to launch a new browser session and directs it to the URL that you specify as its parameter.
The WebDriver class has the getTitle() method that is always used to obtain the page title of the currently loaded page.
This portion of the code simply uses a basic Java if-else structure to compare the actual title with the expected one.
The "close()" method is used to close the browser window.
If you use this command without closing all browser windows first, your whole Java program will end while leaving the browser window open.
There are two ways to execute code in Eclipse IDE.
If you did everything correctly, Eclipse would output "Test Passed!"
Locating elements in WebDriver is done by using the "findElement(By.locator())" method. The "locator" part of the code is same as any of the locators previously discussed in the Selenium IDE chapters of these tutorials. Infact, it is recommended that you locate GUI elements using IDE and once successfully identified export the code to webdriver.
Here is a sample code that locates an element by its id. Facebook is used as the Base URL.
package newproject; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; public class PG2 { public static void main(String[] args) { System.setProperty("webdriver.firefox.marionette","C:\\geckodriver.exe"); WebDriver driver = new FirefoxDriver(); String baseUrl = "http://www.facebook.com"; String tagName = ""; driver.get(baseUrl); tagName = driver.findElement(By.id("email")).getTagName(); System.out.println(tagName); driver.close(); System.exit(0); } }
We used the getTagName() method to extract the tag name of that particular element whose id is "email". When run, this code should be able to correctly identify the tag name "input" and will print it out on Eclipse's Console window.
Summary for locating elements
Variation | Description | Sample |
---|---|---|
By.className | finds elements based on the value of the "class" attribute | findElement(By.className("someClassName")) |
By.cssSelector | finds elements based on the driver's underlying CSS Selector engine | findElement(By.cssSelector("input#email")) |
By.id | locates elements by the value of their "id" attribute | findElement(By.id("someId")) |
By.linkText | finds a link element by the exact text it displays | findElement(By.linkText("REGISTRATION")) |
By.name | locates elements by the value of the "name" attribute | findElement(By.name("someName")) |
By.partialLinkText | locates elements that contain the given link text | findElement(By.partialLinkText("REG")) |
By.tagName | locates elements by their tag name | findElement(By.tagName("div")) |
By.xpath | locates elements via XPath | findElement(By.xpath("//html/body/div/table/tbody/tr/td[2]/table/ tbody/tr[4]/td/table/tbody/tr/td[2]/table/tbody/tr[2]/td[3]/ form/table/tbody/tr[5]")) |
By.cssSelector() does not support the "contains" feature. Consider the Selenium IDE code below -
In Selenium IDE above, the entire test passed. However in the WebDriver script below, the same test generated an error because WebDriver does not support the "contains" keyword when used in the By.cssSelector() method.
Instead of using the long "driver.findElement(By.locator())" syntax every time you will access a particular element, we can instantiate a WebElement object for it. The WebElement class is contained in the "org.openqa.selenium.*" package.
Clicking is perhaps the most common way of interacting with web elements. The click() method is used to simulate the clicking of any element. The following example shows how click() was used to click on Mercury Tours' "Sign-In" button.
Following things must be noted when using the click() method.
Get commands fetch various important information about the page/element. Here are some important "get" commands you must be familiar with.
get() Sample usage: |
|
getTitle() Sample usage: |
|
getPageSource() Sample usage: |
|
getCurrentUrl() Sample usage: |
|
getText() Sample usage: |
|
These commands allow you to refresh,go-into and switch back and forth between different web pages.
navigate().to() Sample usage: |
|
navigate().refresh() Sample usage: |
|
navigate().back() Sample usage: |
|
navigate().forward() Sample usage: |
|
close() Sample usage: |
|
quit() Sample usage: |
|
To clearly illustrate the difference between close() and quit(), try to execute the code below. It uses a webpage that automatically pops up a window upon page load and opens up another after exiting.
Notice that only the parent browser window was closed and not the two pop-up windows.
But if you use quit(), all windows will be closed - not just the parent one. Try running the code below and you will notice that the two pop-ups above will automatically be closed as well.
package newproject; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; public class PG3 { public static void main(String[] args) { System.setProperty("webdriver.firefox.marionette","C:\\geckodriver.exe"); WebDriver driver = new FirefoxDriver(); driver.get("http://www.popuptest.com/popuptest2.html"); driver.quit(); // using QUIT all windows will close } }
To access GUI elements in a Frame, we should first direct WebDriver to focus on the frame or pop-up window first before we can access elements within them. Let us take, for example, the web page http://demo.guru99.com/selenium/deprecated.html
This page has 3 frames whose "name" attributes are indicated above. We wish to access the "Deprecated" link encircled above in yellow. In order to do that, we must first instruct WebDriver to switch to the "classFrame" frame using the "switchTo().frame()"method. We will use the name attribute of the frame as the parameter for the "frame()" part.
package newproject; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; public class PG4 { public static void main(String[] args) { System.setProperty("webdriver.firefox.marionette","C:\\geckodriver.exe"); WebDriver driver = new FirefoxDriver(); driver.get("http://demo.guru99.com/selenium/deprecated.html"); driver.switchTo().frame("classFrame"); driver.findElement(By.linkText("Deprecated")).click(); driver.close(); } }
After executing this code, you will see that the "classFrame" frame is taken to the "Deprecated API" page, meaning that our code was successfully able to access the "Deprecated" link.
WebDriver allows pop-up windows like alerts to be displayed, unlike in Selenium IDE. To access the elements within the alert (such as the message it contains), we must use the "switchTo().alert()" method. In the code below, we will use this method to access the alert box and then retrieve its message using the "getText()" method, and then automatically close the alert box using the "switchTo().alert().accept()" method.
First, head over to http://jsbin.com/usidix/1 and manually click the "Go!" button there and see for yourself the message text.
Lets see the WebDriver code to do this-
package mypackage; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; public class myclass { public static void main(String[] args) { System.setProperty("webdriver.firefox.marionette","C:\\geckodriver.exe"); WebDriver driver = new FirefoxDriver(); String alertMessage = ""; driver.get("http://jsbin.com/usidix/1"); driver.findElement(By.cssSelector("input[value=\"Go!\"]")).click(); alertMessage = driver.switchTo().alert().getText(); driver.switchTo().alert().accept(); System.out.println(alertMessage); driver.quit(); } }
On the Eclipse console, notice that the printed alert message is:
There are two kinds of waits.
To start using an implicit wait, you would have to import this package into your code.
Then on the instantiation part of your code, add this.
Explicit waits are done using the WebDriverWait and ExpectedCondition classes. For the following example, we shall wait up to 10 seconds for an element whose id is "username" to become visible before proceeding to the next command. Here are the steps.
Step 1
Import these two packages:
Step 2
Declare a WebDriverWait variable. In this example, we will use "myWaitVar" as the name of the variable.
Step 3
Use myWaitVar with ExpectedConditions on portions where you need the explicit wait to occur. In this case, we will use explicit wait on the "username" (Mercury Tours HomePage) input before we type the text "tutorial" onto it.
Following methods are used in conditional and looping operations --
The ExpectedConditions class offers a wider set of conditions that you can use in conjunction with WebDriverWait's until() method.
Below are some of the most common ExpectedConditions methods.
When using isEnabled(), isDisplayed(), and isSelected(), WebDriver assumes that the element already exists on the page. Otherwise, it will throw a NoSuchElementException. To avoid this, we should use a try-catch block so that the program will not be interrupted.
WebElement txtbox_username = driver.findElement(By.id("username")); try{ if(txtbox_username.isEnabled()){ txtbox_username.sendKeys("tutorial"); } } catch(NoSuchElementException nsee){ System.out.println(nsee.toString()); }
If you use explicit waits, the type of exception that you should catch is the "TimeoutException".
Note:
driver.get() : It's used to go to the particular website , But it doesn't maintain the browser History and cookies so , we can't use forward and backward button , if we click on that , page will not get schedule
driver.navigate() : it's used to go to the particular website , but it maintains the browser history and cookies, so we can use forward and backward button to navigate between the pages during the coding of Testcase
The different types of Locators in Selenium IDE
There are commands that do not need a locator (such as the "open" command). However, most of them do need Locators.
The choice of locator depends largely on your Application Under Test. In this tutorial, we will toggle between Facebook, new tours.demoaut on the basis of locators that these applications support. Likewise in your Testing project, you will select any of the above-listed locators based on your application support.
This is the most common way of locating elements since ID's are supposed to be unique for each element.
Target Format: id=id of the element
For this example, we will use Facebook as our test app because Mercury Tours do not use ID attributes.
Step 1. Since this tutorial was created, Facebook has changed their Login Page Design. Use this demo page http://demo.guru99.com/test/facebook.html for testing. Inspect the "Email or Phone" text box using Firebug and take note of its ID. In this case, the ID is "email."
Step 2. Launch Selenium IDE and enter "id=email" in the Target box. Click the Find button and notice that the "Email or Phone" text box becomes highlighted with yellow and bordered with green, meaning, Selenium IDE was able to locate that element correctly.
Locating elements by name are very similar to locating by ID, except that we use the "name=" prefix instead.
Target Format: name=name of the element
In the following demonstration, we will now use Mercury Tours because all significant elements have names.
Step 1. Navigate to http://demo.guru99.com/test/newtours/ and use Firebug to inspect the "User Name" text box. Take note of its name attribute.
Here, we see that the element's name is "userName".
Step 2. In Selenium IDE, enter "name=userName" in the Target box and click the Find button. Selenium IDE should be able to locate the User Name text box by highlighting it.
Filters can be used when multiple elements have the same name. Filters are additional attributes used to distinguish elements with the same name.
Target Format: name=name_of_the_element filter=value_of_filter
Let's see an example -
Step 1. Log on to Mercury Tours using "tutorial" as the username and password. It should take you to the Flight Finder page shown below.
Step 2. Using Firebug, notice that the Round Trip and One Way radio buttons have the same name "tripType." However, they have different VALUE attributes so we can use each of them as our filter.
Step 3.
Step 4. Click the Find button and notice that Selenium IDE is able to highlight the One Way radio button with green - meaning that we are able to access the element successfully using its VALUE attribute.
Step 5. Press the "X" key in your keyboard to execute this click command. Notice that the One Way radio button became selected.
You can do the exact same thing with the Round Trip radio button, this time, using "name=tripType value=roundtrip" as your target.
This type of locator applies only to hyperlink texts. We access the link by prefixing our target with "link=" and then followed by the hyperlink text.
Target Format: link=link_text
In this example, we shall access the "REGISTER" link found on the Mercury Tours homepage.
Step 1.
Step 2.
Step 3. Copy the link text in Firebug and paste it onto Selenium IDE's Target box. Prefix it with "link=".
Step 4. Click on the Find button and notice that Selenium IDE was able to highlight the REGISTER link correctly.
Step 5. To verify further, enter "clickAndWait" in the Command box and execute it. Selenium IDE should be able to click on that REGISTER link successfully and take you to the Registration page shown below.
CSS Selectors are string patterns used to identify an element based on a combination of HTML tag, id, class, and attributes. Locating by CSS Selector is more complicated than the previous methods, but it is the most common locating strategy of advanced Selenium users because it can access even those elements that have no ID or name.
CSS Selectors have many formats, but we will only focus on the most common ones.
When using this strategy, we always prefix the Target box with "css=" as will be shown in the following examples.
Again, we will use Facebook's Email text box in this example. As you can remember, it has an ID of "email," and we have already accessed it in the "Locating by ID" section. This time, we will use a CSS Selector with ID in accessing that very same element.
Syntax |
Description |
---|---|
css=tag#id |
|
Keep in mind that the ID is always preceded by a hash sign (#).
Step 1. Navigate to www.facebook.com. Using Firebug, examine the "Email or Phone" text box.
At this point, take note that the HTML tag is "input" and its ID is "email". So our syntax will be "css=input#email".
Step 2. Enter "css=input#email" into the Target box of Selenium IDE and click the Find button. Selenium IDE should be able to highlight that element.
Locating by CSS Selector using an HTML tag and a class name is similar to using a tag and ID, but in this case, a dot (.) is used instead of a hash sign.
Syntax |
Description |
---|---|
css=tag.class |
|
Step 1. Go to the demo page http://demo.guru99.com/test/facebook.html and use Firebug to inspect the "Email or Phone" text box. Notice that its HTML tag is "input" and its class is "inputtext."
Step 2. In Selenium IDE, enter "css=input.inputtext" in the Target box and click Find. Selenium IDE should be able to recognize the Email or Phone text box.
Take note that when multiple elements have the same HTML tag and name, only the first element in source code will be recognized. Using Firebug, inspect the Password text box in Facebook and notice that it has the same name as the Email or Phone text box.
The reason why only the Email or Phone text box was highlighted in the previous illustration is that it comes first in Facebook's page source.
This strategy uses the HTML tag and a specific attribute of the element to be accessed.
Syntax |
Description |
---|---|
css=tag[attribute=value] |
|
Step 1. Navigate to Mercury Tours' Registration page (http://demo.guru99.com/test/newtours/register.php) and inspect the "Last Name" text box. Take note of its HTML tag ("input" in this case) and its name ("lastName").
Step 2. In Selenium IDE, enter "css=input[name=lastName]" in the Target box and click Find. Selenium IDE should be able to access the Last Name box successfully.
When multiple elements have the same HTML tag and attribute, only the first one will be recognized. This behavior is similar to locating elements using CSS selectors with the same tag and class.
Syntax | Description |
---|---|
css=tag.class[attribute=value] |
|
Step 1. Go to the demo page http://demo.guru99.com/test/facebook.html and use Firebug to inspect the 'Email or Phone' and 'Password' input boxes. Take note of their HTML tag, class, and attributes. For this example, we will select their 'tabindex' attributes.
Step 2. We will access the 'Email or Phone' text box first. Thus, we will use a tabindex value of 1. Enter "css=input.inputtext[tabindex=1]" in Selenium IDE's Target box and click Find. The 'Email or Phone' input box should be highlighted.
Step 3. To access the Password input box, simply replace the value of the tabindex attribute. Enter "css=input.inputtext[tabindex=2]" in the Target box and click on the Find button. Selenium IDE must be able to identify the Password text box successfully.
As you may have noticed, HTML labels are seldom given id, name, or class attributes. So, how do we access them? The answer is through the use of their inner texts. Inner texts are the actual string patterns that the HTML label shows on the page.
Syntax |
Description |
---|---|
css=tag:contains("inner text") |
|
Step 1. Navigate to Mercury Tours' homepage (http://demo.guru99.com/test/newtours/) and use Firebug to investigate the "Password" label. Take note of its HTML tag (which is "font" in this case) and notice that it has no class, id, or name attributes.
Step 2. Type css=font:contains("Password:") into Selenium IDE's Target box and click Find. Selenium IDE should be able to access the Password label as shown in the image below.
Step 3. This time, replace the inner text with "Boston" so that your Target will now become "css=font:contains("Boston")". Click Find. You should notice that the "Boston to San Francisco" label becomes highlighted. This shows you that Selenium IDE can access a long label even if you just indicated the first word of its inner text.
The Document Object Model (DOM), in simple terms, is the way by which HTML elements are structured. Selenium IDE is able to use the DOM in accessing page elements. If we use this method, our Target box will always start with "dom=document..."; however, the "dom=" prefix is normally removed because Selenium IDE is able to automatically interpret anything that starts with the keyword "document" to be a path within the DOM anyway.
There are four basic ways to locate an element through DOM:
Let us focus on the first method - using the getElementById method. The syntax would be:
Syntax |
Description |
---|---|
document.getElementById("id of the element") |
id of the element = this is the value of the ID attribute of the element to be accessed. This value should always be enclosed in a pair of parentheses (""). |
Step 1. Use this demo page http://demo.guru99.com/test/facebook.html Navigate to it and use Firebug to inspect the "Keep me logged in" check box. Take note of its ID.
We can see that the ID we should use is "persist_box".
Step 2. Open Selenium IDE and in the Target box, enter "document.getElementById("persist_box")" and click Find. Selenium IDE should be able to locate the "Keep me logged in" check box. Though it cannot highlight the interior of the check box, Selenium IDE can still surround the element with a bright green border as shown below.
The getElementById method can access only one element at a time, and that is the element with the ID that you specified. The getElementsByName method is different. It collects an array of elements that have the name that you specified. You access the individual elements using an index which starts at 0.
|
getElementById
|
|
getElementsByName
|
Syntax |
Description |
---|---|
document.getElementsByName("name")[index] |
|
Step 1. Navigate to Mercury Tours' Homepage and login using "tutorial" as the username and password. Firefox should take you to the Flight Finder screen.
Step 2. Using Firebug, inspect the three radio buttons at the bottom portion of the page (Economy class, Business class, and First class radio buttons). Notice that they all have the same name which is "servClass".
Step 3. Let us access the "Economy class" radio button first. Of all these three radio buttons, this element comes first, so it has an index of 0. In Selenium IDE, type "document.getElementsByName("servClass")[0]" and click the Find button. Selenium IDE should be able to identify the Economy class radio button correctly.
Step 4. Change the index number to 1 so that your Target will now become document.getElementsByName("servClass")[1]. Click the Find button, and Selenium IDE should be able to highlight the "Business class" radio button, as shown below.
As mentioned earlier, this method will only apply if the element you are accessing is contained within a named form.
Syntax |
Description |
---|---|
document.forms["name of the form"].elements["name of the element"] |
|
Step 1. Navigate to Mercury Tours homepage (http://demo.guru99.com/test/newtours/) and use Firebug to inspect the User Name text box. Notice that it is contained in a form named "home."
Step 2. In Selenium IDE, type "document.forms["home"].elements["userName"]" and click the Find button. Selenium IDE must be able to access the element successfully.
This method applies even when the element is not within a named form because it uses the form's index and not its name.
Syntax |
Description |
---|---|
document.forms[index of the form].elements[index of the element] |
|
We shall access the "Phone" text box within Mercury Tours Registration page. The form in that page has no name and ID attribute, so this will make a good example.
Step 1. Navigate to Mercury Tours Registration page and inspect the Phone text box. Notice that the form containing it has no ID and name attributes.
Step 2. Enter "document.forms[0].elements[3]" in Selenium IDE's Target box and click the Find button. Selenium IDE should be able to access the Phone text box correctly.
Step 3. Alternatively, you can use the element's name instead of its index and obtain the same result. Enter "document.forms[0].elements["phone"]" in Selenium IDE's Target box. The Phone text box should still become highlighted.
XPath is the language used when locating XML (Extensible Markup Language) nodes. Since HTML can be thought of as an implementation of XML, we can also use XPath in locating HTML elements.
Advantage: It can access almost any element, even those without class, name, or id attributes.
Disadvantage: It is the most complicated method of identifying elements because of too many different rules and considerations.
Fortunately, Firebug can automatically generate XPath locators. In the following example, we will access an image that cannot possibly be accessed through the methods we discussed earlier.
Step 1. Navigate to Mercury Tours Homepage and use Firebug to inspect the orange rectangle to the right of the yellow "Links" box. Refer to the image below.
Step 2. Right click on the element's HTML code and then select the "Copy XPath" option.
Step 3. In Selenium IDE, type one forward slash "/" in the Target box then paste the XPath that we copied in the previous step. The entry in your Target box should now begin with two forward slashes "//".
Step 4. Click on the Find button. Selenium IDE should be able to highlight the orange box as shown below.
Method |
Target Syntax |
Example |
---|---|---|
By ID | id= id_of_the_element | id=email |
By Name | name=name_of_the_element | name=userName |
By Name Using Filters | name=name_of_the_elementfilter=value_of_filter | name=tripType value=oneway |
By Link Text | link=link_text | link=REGISTER |
Tag and ID | css=tag#id | css=input#email |
Tag and Class | css=tag.class | css=input.inputtext |
Tag and Attribute | css=tag[attribute=value] | css=input[name=lastName] |
Tag, Class, and Attribute | css=tag.class[attribute=value] | css=input.inputtext[tabindex=1] |
Interaction with a web page requires a user to locate the web element. Find Element command is used to uniquely identify a (one) web element within the web page. Whereas, Find Elements command is used to uniquely identify the list of web elements within the web page. There are multiple ways to uniquely identify a web element within the web page such as ID, Name, Class Name, Link Text, Partial Link Text, Tag Name and XPATH.
Find Element command takes in the By object as the parameter and returns an object of type WebElement. By object in turn can be used with various locator strategies such as ID, Name, Class Name, XPATH etc. Below is the syntax of FindElement command in Selenium web driver.
WebElement elementName = driver.findElement(By.LocatorStrategy("LocatorValue"));
Locator Strategy can by any of the following values.
Locator Value is the unique value using which a web element can be identified. It is the responsibility of developers and testers to make sure that web elements are uniquely identifiable using certain properties such as ID or name.
Example:
WebElement loginLink = driver.findElement(By.linkText("Login"));
Find Elements command takes in By object as the parameter and returns a list of web elements. It returns an empty list if there are no elements found using the given locator strategy and locator value. Below is the syntax of find elements command.
List<WebElement> elementName = driver.findElements(By.LocatorStrategy("LocatorValue"));
Example:
List<WebElement> listOfElements = driver.findElements(By.xpath("//div"));
Below are the major differences between find element and find elements commands.
Find Element | Find Elements |
---|---|
Returns the first most web element if there are multiple web elements found with the same locator | Returns a list of web elements |
Throws exception NoSuchElementException if there are no elements matching the locator strategy | Returns an empty list if there are no web elements matching the locator strategy |
It will only find one web element | It will find a collection of elements whose match the locator strategy. |
Not Applicable | Each Web element is indexed with a number starting from 0 just like an array |
The following application is used for demo purpose
http://demo.guru99.com/test/ajax.html
Scenario:
1. Open the AUT
2. Find and click radio button
package com.sample.stepdefinitions; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; public class NameDemo { public static void main(String[] args) { // TODO Auto-generated method stub System.setProperty("webdriver.chrome.driver", "D:\\3rdparty\\chrome\\chromedriver.exe"); WebDriver driver = new ChromeDriver(); driver.manage().window().maximize(); driver.get("http://demo.guru99.com/test/ajax.html"); // Find the radio button for “No” using its ID and click on it System.out.println (By.Name("name")); } }
Scenario:
1. Open the URL for Application Under Test
2. Find the text of radio buttons and print it onto the output console
package com.sample.stepdefinitions; import java.util.List; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; public class NameDemo { public static void main(String[] args) { System.setProperty("webdriver.chrome.driver", "X://chromedriver.exe"); WebDriver driver = new ChromeDriver(); driver.get("http://demo.guru99.com/test/ajax.html"); List<WebElement> elements = driver.findElements(By.name("name")); System.out.println("Number of elements:" +elements.size()); for (int i=0; i<elements.size();i++){ System.out.println("Radio button text:" + elements.get(i).getAttribute("value")); } } }
Summary:
Forms are the fundamental web elements to receive information from the website visitors. Web forms have different GUI elements like Text boxes, Password fields, Checkboxes, Radio buttons, dropdowns, file inputs, etc.
We will see how to access these different form elements using Selenium Web Driver with Java. Selenium encapsulates every form element as an object of WebElement.It provides API to find the elements and take action on them like entering text into text boxes, clicking the buttons, etc. We will see the methods that are available to access each form element.
In this tutorial, we will see how to identify the following form elements
Selenium Web Driver encapsulates a simple form element as an object of WebElement.
There are various techniques by which the WebDriver identifies the form elements based on the different properties of the Web elements like ID, Name, Class, XPath, Tagname, CSS Selectors, link Text, etc.
Web Driver provides the following two methods to find the elements.
Let's see the code snippets to get a single element – Text Field in a web page as an object of WebElement using findElement() method. We shall cover the findElements() method of finding multiple elements in subsequent tutorials.
Step 1: We need to import this package to create objects of Web Elements
Step 2: We need to call the findElement() method available on the WebDriver class and get an object of WebElement.
Refer below to see how it is done.
Input boxes refer to either of these two types:
The method findElement() takes one parameter which is a locator to the element. Different locators like By.id(), By.name(), By.xpath(), By.CSSSelector() etc. locate the elements in the page using their properties like`````` id, name or path, etc.
You can use plugins like Fire path to get help with getting the id, xpath, etc. of the elements.
Using the example site http://demo.guru99.com/test/login.html given below is the code to locate the "Email address" text field using the id locator and the "Password "field using the name locator.
To enter text into the Text Fields and Password Fields, sendKeys() is the method available on the WebElement.
Using the same example of http://demo.guru99.com/test/login.html site, here is how we find the Text field and Password fields and enter values into them.
The clear() method is used to delete the text in an input box. This method does not need a parameter. The code snippet below will clear out the text from the Email or Password fields
The buttons can be accessed using the click() method.
In the example above
Submit buttons are used to submit the entire form to the server. We can either use the click () method on the web element like a normal button as we have done above or use the submit () method on any web element in the form or on the submit button itself.
When submit() is used, WebDriver will look up the DOM to know which form the element belongs to, and then trigger its submit function.
Here is the complete working code
import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.*; public class Form { public static void main(String[] args) { // declaration and instantiation of objects/variables System.setProperty("webdriver.chrome.driver","G:\\chromedriver.exe"); WebDriver driver = new ChromeDriver(); String baseUrl = "http://demo.guru99.com/test/login.html"; driver.get(baseUrl); // Get the WebElement corresponding to the Email Address(TextField) WebElement email = driver.findElement(By.id("email")); // Get the WebElement corresponding to the Password Field WebElement password = driver.findElement(By.name("passwd")); email.sendKeys("abcd@gmail.com"); password.sendKeys("abcdefghlkjl"); System.out.println("Text Field Set"); // Deleting values in the text box email.clear(); password.clear(); System.out.println("Text Field Cleared"); // Find the submit button WebElement login = driver.findElement(By.id("SubmitLogin")); // Using click method to submit form email.sendKeys("abcd@gmail.com"); password.sendKeys("abcdefghlkjl"); login.click(); System.out.println("Login Done with Click"); //using submit method to submit the form. Submit used on password field driver.get(baseUrl); driver.findElement(By.id("email")).sendKeys("abcd@gmail.com"); driver.findElement(By.name("passwd")).sendKeys("abcdefghlkjl"); driver.findElement(By.id("SubmitLogin")).submit(); System.out.println("Login Done with Submit"); //driver.close(); } }
If you encounter NoSuchElementException() while finding elements, it means that the element is not found in the page at the point the Web driver accessed the page.
Element | Command | Description |
---|---|---|
Input Box | sendKeys() | used to enter values onto text boxes |
clear() | used to clear text boxes of its current value | |
Links | click() | used to click on the link and wait for page load to complete before proceeding to the next command. |
Submit Button | submit() |
In this tutorial, we will see how to identify the following form elements
Radio Buttons too can be toggled on by using the click() method.
Using http://demo.guru99.com/test/radio.html for practise, see that radio1.click() toggles on the "Option1" radio button. radio2.click() toggles on the "Option2" radio button leaving the "Option1" unselected.
Toggling a check box on/off is also done using the click() method.
The code below will click on Facebook's "Keep me logged in" check box twice and then output the result as TRUE when it is toggled on, and FALSE if it is toggled off.
isSelected() method is used to know whether the Checkbox is toggled on or off.
Here is another example: http://demo.guru99.com/test/radio.html
Here is the complete working code
import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.*; public class Form { public static void main(String[] args) { // declaration and instantiation of objects/variables System.setProperty("webdriver.chrome.driver","G:\\chromedriver.exe"); WebDriver driver = new ChromeDriver(); driver.get("http://demo.guru99.com/test/radio.html"); WebElement radio1 = driver.findElement(By.id("vfb-7-1")); WebElement radio2 = driver.findElement(By.id("vfb-7-2")); //Radio Button1 is selected radio1.click(); System.out.println("Radio Button Option 1 Selected"); //Radio Button1 is de-selected and Radio Button2 is selected radio2.click(); System.out.println("Radio Button Option 2 Selected"); // Selecting CheckBox WebElement option1 = driver.findElement(By.id("vfb-6-0")); // This will Toggle the Check box option1.click(); // Check whether the Check box is toggled on if (option1.isSelected()) { System.out.println("Checkbox is Toggled On"); } else { System.out.println("Checkbox is Toggled Off"); } //Selecting Checkbox and using isSelected Method driver.get("http://demo.guru99.com/test/facebook.html"); WebElement chkFBPersist = driver.findElement(By.id("persist_box")); for (int i=0; i<2; i++) { chkFBPersist.click (); System.out.println("Facebook Persists Checkbox Status is - "+chkFBPersist.isSelected()); } //driver.close(); } }
If you encounter NoSuchElementException() while finding elements, it means that the element is not found in the page at the point the Web driver accessed the page.
Element | Command | Description |
---|---|---|
Check Box, Radio Button | click() | used to toggle the element on/off |
Image links are the links in web pages represented by an image which when clicked navigates to a different window or page.
Since they are images, we cannot use the By.linkText() and By.partialLinkText() methods because image links basically have no link texts at all.
In this case, we should resort to using either By.cssSelector or By.xpath. The first method is more preferred because of its simplicity.
In the example below, we will access the "Facebook" logo on the upper left portion of Facebook's Password Recovery page.
We will use By.cssSelector and the element's "title" attribute to access the image link. And then we will verify if we are taken to Facebook's homepage.
package newproject; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; public class MyClass { public static void main(String[] args) { String baseUrl = "https://www.facebook.com/login/identify?ctx=recover"; System.setProperty("webdriver.chrome.driver","G:\\chromedriver.exe"); WebDriver driver = new ChromeDriver(); driver.get(baseUrl); //click on the "Facebook" logo on the upper left portion driver.findElement(By.cssSelector("a[title=\"Go to Facebook home\"]")).click(); //verify that we are now back on Facebook's homepage if (driver.getTitle().equals("Facebook - log in or sign up")) { System.out.println("We are back at Facebook's homepage"); } else { System.out.println("We are NOT in Facebook's homepage"); } driver.close(); } }
Result
Conclusion:
This is all to clicking images. Accessing image link is done using By.cssSelector() and By.xpath() methods.
Links Matching a Criterion
Links can be accessed using an exact or partial match of their link text. The examples below provide scenarios where multiple matches would exist and would explain how WebDriver would deal with them.
In this tutorial, we will learn the available methods to find and access the Links using Webdriver. Also, we will discuss some of the common problems faced while accessing Links and will further discuss on how to resolve them.
Here is what you will learn-
Accessing links using their exact link text is done through the By.linkText() method. However, if there are two links that have the very same link text, this method will only access the first one. Consider the HTML code below
When you try to run the WebDriver code below, you will be accessing the first "click here" link
Code:
import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; public class MyClass { public static void main(String[] args) { String baseUrl = "http://demo.guru99.com/test/link.html"; System.setProperty("webdriver.chrome.driver","G:\\chromedriver.exe"); WebDriver driver = new ChromeDriver(); driver.get(baseUrl); driver.findElement(By.linkText("click here")).click(); System.out.println("title of page is: " + driver.getTitle()); driver.quit(); } }
Here is how it works-
As a result, you will automatically be taken to Google.
Accessing links using a portion of their link text is done using the By.partialLinkText() method. If you specify a partial link text that has multiple matches, only the first match will be accessed. Consider the HTML code below.
When you execute the WebDriver code below, you will still be taken to Google.
Code:
import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; public class P1 { public static void main(String[] args) { String baseUrl = "http://demo.guru99.com/test/accessing-link.html"; System.setProperty("webdriver.chrome.driver","G:\\chromedriver.exe"); WebDriver driver = new ChromeDriver(); driver.get(baseUrl); driver.findElement(By.partialLinkText("here")).click(); System.out.println("Title of page is: " + driver.getTitle()); driver.quit(); } }
So, how to get around the above problem? In cases where there are multiple links with the same link text, and we want to access the links other than the first one, how do we go about it?
In such cases, generally, different locators viz... By.xpath(), By.cssSelector() or By.tagName() are used.
Most commonly used is By.xpath(). It is the most reliable one but it looks complex and non-readable too.
The parameters for By.linkText() and By.partialLinkText() are both case-sensitive, meaning that capitalization matters. For example, in Mercury Tours' homepage, there are two links that contain the text "egis" - one is the "REGISTER" link found at the top menu, and the other is the "Register here" link found at the lower right portion of the page.
Though both links contain the character sequence "egis," one is the "By.partialLinkText()" method will access these two links separately depending on the capitalization of the characters. See the sample code below.
Code
public static void main(String[] args) { String baseUrl = "http://demo.guru99.com/test/newtours/"; System.setProperty("webdriver.chrome.driver","G:\\chromedriver.exe"); WebDriver driver = new ChromeDriver(); driver.get(baseUrl); String theLinkText = driver.findElement(By .partialLinkText("egis")) .getText(); System.out.println(theLinkText); theLinkText = driver.findElement(By .partialLinkText("EGIS")) .getText(); System.out.println(theLinkText); driver.quit(); }
The latest HTML5 standard allows the <a> tags to be placed inside and outside of block-level tags like <div>, <p>, or <h3>. The "By.linkText()" and "By.partialLinkText()" methods can access a link located outside and inside these block-level elements. Consider the HTML code below.
The WebDriver code below accesses both of these links using By.partialLinkText() method.
Code:
import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; public class MyClass { public static void main(String[] args) { String baseUrl = "http://demo.guru99.com/test/block.html"; System.setProperty("webdriver.chrome.driver","G:\\chromedriver.exe"); WebDriver driver = new ChromeDriver(); driver.get(baseUrl); driver.findElement(By.partialLinkText("Inside")).click(); System.out.println(driver.getTitle()); driver.navigate().back(); driver.findElement(By.partialLinkText("Outside")).click(); System.out.println(driver.getTitle()); driver.quit(); } }
The output above confirms that both links were accessed successfully because their respective page titles were retrieved correctly.
In this tutorial, we will learn handling Keyboard and Mouse Event in Selenium Webdriver
Handling special keyboard and mouse events are done using the Advanced User Interactions API. It contains the Actions and the Action classes that are needed when executing these events. The following are the most commonly used keyboard and mouse events provided by the Actions class.
Method | Description |
---|---|
clickAndHold() | Clicks (without releasing) at the current mouse location. |
contextClick() | Performs a context-click at the current mouse location. (Right Click Mouse Action) |
doubleClick() | Performs a double-click at the current mouse location. |
dragAndDrop(source, target) | Performs click-and-hold at the location of the source element, moves to the location of the target element, then releases the mouse. Parameters: source- element to emulate button down at. target- element to move to and release the mouse at. |
dragAndDropBy(source, x-offset, y-offset) | Performs click-and-hold at the location of the source element, moves by a given offset, then releases the mouse. Parameters: source- element to emulate button down at. xOffset- horizontal move offset. yOffset- vertical move offset. |
keyDown(modifier_key) | Performs a modifier key press. Does not release the modifier key - subsequent interactions may assume it's kept pressed. Parameters: modifier_key - any of the modifier keys (Keys.ALT, Keys.SHIFT, or Keys.CONTROL) |
keyUp(modifier _key) | Performs a key release. Parameters: modifier_key - any of the modifier keys (Keys.ALT, Keys.SHIFT, or Keys.CONTROL) |
moveByOffset(x-offset, y-offset) | Moves the mouse from its current position (or 0,0) by the given offset. Parameters: x-offset- horizontal offset. A negative value means moving the mouse left. y-offset- vertical offset. A negative value means moving the mouse down. |
moveToElement(toElement) | Moves the mouse to the middle of the element. Parameters: toElement- element to move to. |
release() | Releases the depressed left mouse button at the current mouse location |
sendKeys(onElement, charsequence) | Sends a series of keystrokes onto the element. Parameters: onElement - element that will receive the keystrokes, usually a text field charsequence - any string value representing the sequence of keystrokes to be sent |
In the following example, we shall use the moveToElement() method to mouse-over on one Mercury Tours' table rows. See the example below.
The cell shown above is a portion of a <TR> element. If not hovered, its color is #FFC455 (orange). After hovering, the cell's color becomes transparent. It becomes the same color as the blue background of the whole orange table.
Step 1: Import the Actions and Action classes.
Step 2: Instantiate a new Actions object.
Step 3: Instantiate an Action using the Actions object in step 2.
In this case, we are going to use the moveToElement() method because we are simply going to mouse-over the "Home" link. The build() method is always the final method used so that all the listed actions will be compiled into a single step.
Step 4: Use the perform() method when executing the Action object we designed in Step 3.
Below is the whole WebDriver code to check the background color of the <TR> element before and after the mouse-over.
package newproject; import org.openqa.selenium.*; import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.interactions.Action; import org.openqa.selenium.interactions.Actions; public class PG7 { public static void main(String[] args) { String baseUrl = "http://demo.guru99.com/test/newtours/"; System.setProperty("webdriver.firefox.marionette","C:\\geckodriver.exe"); WebDriver driver = new FirefoxDriver(); driver.get(baseUrl); WebElement link_Home = driver.findElement(By.linkText("Home")); WebElement td_Home = driver .findElement(By .xpath("//html/body/div" + "/table/tbody/tr/td" + "/table/tbody/tr/td" + "/table/tbody/tr/td" + "/table/tbody/tr")); Actions builder = new Actions(driver); Action mouseOverHome = builder .moveToElement(link_Home) .build(); String bgColor = td_Home.getCssValue("background-color"); System.out.println("Before hover: " + bgColor); mouseOverHome.perform(); bgColor = td_Home.getCssValue("background-color"); System.out.println("After hover: " + bgColor); driver.close(); } }
The output below clearly states that the background color became transparent after the mouse-over.
You can build a series of actions using the Action and Actions classes. Just remember to close the series with the build() method. Consider the sample code below.
public static void main(String[] args) { String baseUrl = "http://www.facebook.com/"; WebDriver driver = new FirefoxDriver(); driver.get(baseUrl); WebElement txtUsername = driver.findElement(By.id("email")); Actions builder = new Actions(driver); Action seriesOfActions = builder .moveToElement(txtUsername) .click() .keyDown(txtUsername, Keys.SHIFT) .sendKeys(txtUsername, "hello") .keyUp(txtUsername, Keys.SHIFT) .doubleClick(txtUsername) .contextClick() .build(); seriesOfActions.perform() ; }
Summary
In this tutorial, we will learn How to deal with file uploads and downloads.
For this section, we will use http://demo.guru99.com/test/upload/ as our test application. This site easily allows any visitor to upload files without requiring them to sign up.
Uploading files in WebDriver is done by simply using the sendKeys() method on the file-select input field to enter the path to the file to be uploaded.
Handle File upload popup in Selenium Webdriverhandle file upload popup in selenium webdriver
Let's say we wish to upload the file "C:\newhtml.html". Our WebDriver code should be like the one shown below.
package newproject; import org.openqa.selenium.*; import org.openqa.selenium.firefox.FirefoxDriver; public class PG9 { public static void main(String[] args) { System.setProperty("webdriver.firefox.marionette","C:\\geckodriver.exe"); String baseUrl = "http://demo.guru99.com/test/upload/"; WebDriver driver = new FirefoxDriver(); driver.get(baseUrl); WebElement uploadElement = driver.findElement(By.id("uploadfile_0")); // enter the file path onto the file-selection input field uploadElement.sendKeys("C:\\newhtml.html"); // check the "I accept the terms of service" check box driver.findElement(By.id("terms")).click(); // click the "UploadFile" button driver.findElement(By.name("send")).click(); } }
After running this script, you should be able to upload the file successfully and you should get a message similar to this.
Remember following two things when uploading files in WebDriver
WebDriver has no capability to access the Download dialog boxes presented by browsers when you click on a download link or button. However, we can bypass these dialog boxes using a separate program called "wget".
Wget is a small and easy-to-use command-line program used to automate downloads. Basically, we will access Wget from our WebDriver script to perform the download process.
Step 1: In your C Drive, create a new folder and name it as "Wget".
Download wget.exe from here and Place it in the Wget folder you created from the step above.
Step 2: Open Run by pressing windows key + "R" ; type in "cmd & click ok
Type in the command "cd /" to move to the root directory
Step 3: Type in the command to check whether the given setup is working
cmd /c C:\\Wget\\wget.exe -P C: --no-check-certificate http://demo.guru99.com/selenium/msgr11us.exe
There seems to be an issue writing into C drive.
Step 4: You need to debug the wget errors in command line before you execute the code using Selenium Webdriver. These errors will persist in Eclipse and the error messages will not be as informative. Best to first get wget working using command line. If it works in command line it will definitely work in Eclipse.
In our example, as show in step 3, there is a problem writing into C drive. Let's change the download location to D drive and check results.
cmd /c C:\\Wget\\wget.exe -P D: --no-check-certificate http://demo.guru99.com/selenium/msgr11us.exe
Messenger was downloaded successfully.
Before you proceed further don't forget to delete the downloaded file
In the following example, we will use WebDriver and wget to download a popular chat software called Yahoo Messenger. Our base URL shall be http://demo.guru99.com/test/yahoo.html.
Step 1
Import the "java.io.IOException" package because we will have to catch an IOException later in Step 4.
Step 2
Use getAttribute() to obtain the "href" value of the download link and save it as a String variable. In this case, we named the variable as "sourceLocation".
Step 3
Set-up the syntax for wget using the following command.
Step 4
Initiate the download process by calling wget from our WebDriver code.
To sum it all up, your WebDriver code could look like the one shown below.
package newproject; import java.io.IOException; import org.openqa.selenium.*; import org.openqa.selenium.firefox.FirefoxDriver; public class PG8 { public static void main(String[] args) { System.setProperty("webdriver.firefox.marionette","C:\\geckodriver.exe"); String baseUrl = "http://demo.guru99.com/test/yahoo.html"; WebDriver driver = new FirefoxDriver(); driver.get(baseUrl); WebElement downloadButton = driver.findElement(By .id("messenger-download")); String sourceLocation = downloadButton.getAttribute("href"); String wget_command = "cmd /c C:\\Wget\\wget.exe -P D: --no-check-certificate " + sourceLocation; try { Process exec = Runtime.getRuntime().exec(wget_command); int exitVal = exec.waitFor(); System.out.println("Exit value: " + exitVal); } catch (InterruptedException | IOException ex) { System.out.println(ex.toString()); } driver.close(); } }
After executing this code, check your D drive and verify that the Yahoo Messenger installer was successfully downloaded there.
Summary
In Selenium automation, if the elements are not found by the general locators like id, class, name, etc. then XPath is used to find an element on the web page .
In this tutorial, we will learn about the xpath and different XPath expression to find the complex or dynamic elements, whose attributes changes dynamically on refresh or any operations.
In this tutorial, you will learn-
XPath is defined as XML path. It is a syntax or language for finding any element on the web page using XML path expression. XPath is used to find the location of any element on a webpage using HTML DOM structure. The basic format of XPath is explained below with screen shot.
Syntax for XPath:
XPath contains the path of the element situated at the web page. Standard syntax for creating XPath is.
Xpath=//tagname[@attribute='value']
To find the element on web pages accurately there are different types of locators:
XPath Locators | Find different elements on web page |
ID | To find the element by ID of the element |
Classname | To find the element by Classname of the element |
Name | To find the element by name of the element |
Link text | To find the element by text of the link |
XPath | XPath required for finding the dynamic element and traverse between various elements of the web page |
CSS path | CSS path also locates elements having no name, class or ID. |
There are two types of XPath:
1) Absolute XPath
2) Relative XPath
It is the direct way to find the element, but the disadvantage of the absolute XPath is that if there are any changes made in the path of the element then that XPath gets failed.
The key characteristic of XPath is that it begins with the single forward slash(/) ,which means you can select the element from the root node.
Below is the example of an absolute xpath expression of the element shown in the below screen.
Absolute xpath:
html/body/div[1]/section/div[1]/div/div/div/div[1]/div/div/div/div/div[3]/div[1]/div/h4[1]/b
For Relative Xpath the path starts from the middle of the HTML DOM structure. It starts with the double forward slash (//), which means it can search the element anywhere at the webpage.
You can start from the middle of the HTML DOM structure and no need to write long xpath.
Below is the example of a relative XPath expression of the same element shown in the below screen. This is the common format used to find element through a relative XPath.
Relative xpath: //*[@class='featured-box']//*[text()='Testing']
What are XPath axes.
XPath axes search different nodes in XML document from current context node. XPath Axes are the methods used to find dynamic elements, which otherwise not possible by normal XPath method having no ID , Classname, Name, etc.
Axes methods are used to find those elements, which dynamically change on refresh or any other operations. There are few axes methods commonly used in Selenium Webdriver like child, parent, ancestor, sibling, preceding, self, etc.
XPath expression select nodes or list of nodes on the basis of attributes like ID , Name, Classname, etc. from the XML document as illustrated below.
Xpath=//input[@name='uid']
Here is a link to access the page http://demo.guru99.com/v1/
Some more basic xpath expressions:
Xpath=//input[@type='text'] Xpath= //label[@id='message23'] Xpath= //input[@value='RESET'] Xpath=//*[@class='barone'] Xpath=//a[@href='http://demo.guru99.com/'] Xpath= //img[@src='//cdn.guru99.com/images/home/java.png']
Contains() is a method used in XPath expression. It is used when the value of any attribute changes dynamically, for example, login information.
The contain feature has an ability to find the element with partial text as shown in below example.
In this example, we tried to identify the element by just using partial text value of the attribute. In the below XPath expression partial value 'sub' is used in place of submit button. It can be observed that the element is found successfully.
Complete value of 'Type' is 'submit' but using only partial value 'sub'.
Xpath=//*[contains(@type,'sub')]
Complete value of 'name' is 'btnLogin' but using only partial value 'btn'.
Xpath=//*[contains(@name,'btn')]
In the above expression, we have taken the 'name' as an attribute and 'btn' as an partial value as shown in the below screenshot. This will find 2 elements (LOGIN & RESET) as their 'name' attribute begins with 'btn'.
Similarly, in the below expression, we have taken the 'id' as an attribute and 'message' as a partial value. This will find 2 elements ('User-ID must not be blank' & 'Password must not be blank') as its 'name' attribute begins with 'message'.
Xpath=//*[contains(@id,'message')]
In the below expression, we have taken the "text" of the link as an attribute and 'here' as a partial value as shown in the below screenshot. This will find the link ('here') as it displays the text 'here'.
Xpath=//*[contains(text(),'here')] Xpath=//*[contains(@href,'guru99.com')]
In OR expression, two conditions are used, whether 1st condition OR 2nd condition should be true. It is also applicable if any one condition is true or maybe both. Means any one condition should be true to find the element.
In the below XPath expression, it identifies the elements whose single or both conditions are true.
Xpath=//*[@type='submit' OR @name='btnReset']
Highlighting both elements as "LOGIN " element having attribute 'type' and "RESET" element having attribute 'name'.
In AND expression, two conditions are used, both conditions should be true to find the element. It fails to find element if any one condition is false.
Xpath=//input[@type='submit' and @name='btnLogin']
In below expression, highlighting 'LOGIN' element as it having both attribute 'type' and 'name'.
Start-with function finds the element whose attribute value
changes on refresh or any operation on the webpage. In this expression, match the starting text of the attribute is used to find the element whose attribute changes dynamically. You can also find the element whose attribute value is static (not changes).
For example -: Suppose the ID of particular element changes dynamically like:
Id=" message12"
Id=" message345"
Id=" message8769"
and so on.. but the initial text is same. In this case, we use Start-with expression.
In the below expression, there are two elements with an id starting "message"(i.e., 'User-ID must not be blank' & 'Password must not be blank'). In below example, XPath finds those element whose 'ID' starting with 'message'.
Xpath=//label[starts-with(@id,'message')]
In this expression, with text function, we find the element with exact text match as shown below. In our case, we find the element with text "UserID".
Xpath=//td[text()='UserID']
These XPath axes methods are used to find the complex or dynamic elements. Below we will see some of these methods.
For illustrating these XPath axes method, we will use the Guru99 bank demo site.
Selects all elements in the document of the current node( ) [ UserID input box is the current node] as shown in the below screen.
Xpath=//*[@type='text']//following::input
There are 3 "input" nodes matching by using "following" axis- password, login and reset button. If you want to focus on any particular element then you can use the below XPath method:
Xpath=//*[@type='text']//following::input[1]
You can change the XPath according to the requirement by putting [1],[2]…………and so on.
With the input as '1', the below screen shot finds the particular node that is 'Password' input box element.
The ancestor axis selects all ancestors element (grandparent, parent, etc.) of the current node as shown in the below screen.
In the below expression, we are finding ancestors element of the current node("ENTERPRISE TESTING" node).
Xpath=//*[text()='Enterprise Testing']//ancestor::div
There are 13 "div" nodes matching by using "ancestor" axis. If you want to focus on any particular element then you can use the below XPath, where you change the number 1, 2 as per your requirement:
Xpath=//*[text()='Enterprise Testing']//ancestor::div[1]
You can change the XPath according to the requirement by putting [1], [2]…………and so on.
Selects all children elements of the current node (Java) as shown in the below screen.
Xpath=//*[@id='java_technologies']/child::li
There are 71 "li" nodes matching by using "child" axis. If you want to focus on any particular element then you can use the below xpath:
Xpath=//*[@id='java_technologies']/child::li[1]
You can change the xpath according to the requirement by putting [1],[2]…………and so on.
Select all nodes that come before the current node as shown in the below screen.
In the below expression, it identifies all the input elements before "LOGIN" button that is Userid and password input element.
Xpath=//*[@type='submit']//preceding::input
There are 2 "input" nodes matching by using "preceding" axis. If you want to focus on any particular element then you can use the below XPath:
Xpath=//*[@type='submit']//preceding::input[1]
You can change the xpath according to the requirement by putting [1],[2]…………and so on.
Select the following siblings of the context node. Siblings are at the same level of the current node as shown in the below screen. It will find the element after the current node.
xpath=//*[@type='submit']//following-sibling::input
One input nodes matching by using "following-sibling" axis.
Selects the parent of the current node as shown in the below screen.
Xpath=//*[@id='rt-feature']//parent::div
There are 65 "div" nodes matching by using "parent" axis. If you want to focus on any particular element then you can use the below XPath:
Xpath=//*[@id='rt-feature']//parent::div[1]
You can change the XPath according to the requirement by putting [1],[2]…………and so on.
Selects the current node or 'self' means it indicates the node itself as shown in the below screen.
One node matching by using "self " axis. It always finds only one node as it represents self-element.
Xpath =//*[@type='password']//self::input
In the below expression, it identifies all the element descendants to current element ( 'Main body surround' frame element) which means down under the node (child node , grandchild node, etc.).
Xpath=//*[@id='rt-feature']//descendant::a
There are 12 "link" nodes matching by using "descendant" axis. If you want to focus on any particular element then you can use the below XPath:
Xpath=//*[@id='rt-feature']//descendant::a[1]
You can change the XPath according to the requirement by putting [1],[2]…………and so on.
Summary:
XPath is required to find an element on the web page as to do an operation on that particular element.
In this tutorial, we will learn about different types of alert found in web applicationTesting and how to handle Alert in Selenium WebDriver. We will also see how do we accept and reject the alert depending upon the alert types.
In this tutorial, you will learn-
Alert is a small message box which displays on-screen notification to give the user some kind of information or ask for permission to perform certain kind of operation. It may be also used for warning purpose.
Here are few alert types:
1) Simple Alert
This simple alert displays some information or warning on the screen.
2) Prompt Alert.
This Prompt Alert asks some input from the user and selenium webdriver can enter the text using sendkeys(" input…. ").
3) Confirmation Alert.
This confirmation alert asks permission to do some type of operation.
Alert interface provides the below few methods which are widely used in Selenium Webdriver.
1) void dismiss() // To click on the 'Cancel' button of the alert.
driver.switchTo().alert().dismiss();
2) void accept() // To click on the 'OK' button of the alert.
driver.switchTo().alert().accept();
3) String getText() // To capture the alert message.
driver.switchTo().alert().getText();
4) void sendKeys(String stringToSend) // To send some data to alert box.
driver.switchTo().alert().sendKeys("Text");
You can see a number of Alert methods are displayed as shown in below screen suggested by Eclipse.
We can easily switch to alert from the main window by using Selenium's .switchTo() method.
Now we automate the given below scenario.
In this scenario, we will use Guru99 demo site to illustrate Selenium Alert handling.
Step 1) Launch the web browser and open the site "http://demo.guru99.com/test/delete_customer.php "
Step 2) Enter Any Customer id.
Step 3) After entering the customer ID, Click on the "Submit" button.
Step 4) Reject/accept the alert.
Handling Alert in Selenium Webdriver using above scenario
import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.NoAlertPresentException; import org.openqa.selenium.Alert; public class AlertDemo { public static void main(String[] args) throws NoAlertPresentException,InterruptedException { System.setProperty("webdriver.chrome.driver","G:\\chromedriver.exe"); WebDriver driver = new ChromeDriver(); // Alert Message handling driver.get("http://demo.guru99.com/test/delete_customer.php"); driver.findElement(By.name("cusid")).sendKeys("53920"); driver.findElement(By.name("submit")).submit(); // Switching to Alert Alert alert = driver.switchTo().alert(); // Capturing alert message. String alertMessage= driver.switchTo().alert().getText(); // Displaying alert message System.out.println(alertMessage); Thread.sleep(5000); // Accepting alert alert.accept(); } }
Output :
When you execute the above code, it launches the site. Try to delete Customer ID by handling confirmation alert that displays on the screen, and thereby deleting customer id from the application.
In automation, when we have multiple windows in any web application, the activity may need to switch control among several windows from one to other in order to complete the operation. After completion of the operation, it has to return to the main window i.e. parent window. We will see this further in the article with an example.
In selenium web driver there are methods through which we can handle multiple windows.
Driver.getWindowHandles();
To handle all opened windows by web driver, we can use "Driver.getWindowHandles()" and then we can switch window from one window to another in a web application. Its return type is Iterator<String>.
Driver.getWindowHandle();
When the site opens, we need to handle the main window by driver.getWindowHandle(). This will handle the current window that uniquely identifies it within this driver instance. Its return type is String.
To handle multiple windows in Selenium WebDriver, We follow the following steps.
Now, we will automate the given below scenario to see how to handle multiple windows using Selenium Webdriver.
In this scenario, we will use "Guru99" demo site to illustrate window handling.
Step 1) Launch the site.
Launch the browser and open the site " http://demo.guru99.com/popup.php "
Step 2) Click on link "Click Here ".
When the user clicks on the " Click Here " link, new child window opens.
Step 3) New Child Window opens.
A new window opens, ask the user to enter email id and submit the page.
Step 4) Enter your email ID and submit.
Step 5) Display the Access Credentials on submitting the page.
When you execute the code, you will see the child window is open in new tab.
Handling multiple windows in selenium webdriver using above scenario.
import java.util.Iterator;
import java.util.Set;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
public class WindowHandle_Demo {
public static void main(String[] args) throws InterruptedException {
WebDriver driver=new FirefoxDriver();
//Launching the site.
driver.get("http://demo.guru99.com/popup.php");
driver.manage().window().maximize();
driver.findElement(By.xpath("//*[contains(@href,'popup.php')]")).click();
String MainWindow=driver.getWindowHandle();
// To handle all new opened window.
Set<String> s1=driver.getWindowHandles();
Iterator<String> i1=s1.iterator();
while(i1.hasNext())
{
String ChildWindow=i1.next();
if(!MainWindow.equalsIgnoreCase(ChildWindow))
{
// Switching to Child window
driver.switchTo().window(ChildWindow);
driver.findElement(By.name("emailid"))
.sendKeys("gaurav.3n@gmail.com");
driver.findElement(By.name("btnLogin")).click();
// Closing the Child Window.
driver.close();
}
}
// Switching to Parent window i.e Main Window.
driver.switchTo().window(MainWindow);
}
}
Output:
When you execute the above code, it launches the site and on clicking the link "Click here," it opens up a child window in a new tab. You can close the child window, and switch to the parent window once the operation is completely done. Hence handling more than one window in the application.
Conclusion:
There are times when we need to access elements (usually texts) that are within HTML tables. However, it is very seldom for a web designer to provide an id or name attribute to a certain cell in the table. Therefore, we cannot use the usual methods such as "By.id()", "By.name()", or "By.cssSelector()". In this case, the most reliable option is to access them using the "By.xpath()" method.
In This Tutorial, you will learn-
Consider the HTML code below.
We will use XPath to get the inner text of the cell containing the text "fourth cell."
Step 1 - Set the Parent Element (table)
XPath locators in WebDriver always start with a double forward slash "//" and then followed by the parent element. Since we are dealing with tables, the parent element should always be the <table> tag. The first portion of our XPath locator should, therefore, start with "//table".
Step 2 - Add the child elements
The element immediately under <table> is <tbody> so we can say that <tbody> is the "child" of <table>. And also, <table> is the "parent" of <tbody>. All child elements in XPath are placed to the right of their parent element, separated with one forward slash "/" like the code shown below.
Step 3 - Add Predicates
The <tbody> element contains two <tr> tags. We can now say that these two <tr> tags are "children" of <tbody>. Consequently, we can say that <tbody> is the parent of both the <tr> elements.
Another thing we can conclude is that the two <tr> elements are siblings. Siblings refer to child elements having the same parent.
To get to the <td> we wish to access (the one with the text "fourth cell"), we must first access the second <tr> and not the first. If we simply write "//table/tbody/tr", then we will be accessing the first <tr> tag.
So, how do we access the second <tr> then? The answer to this is to use Predicates.
Predicates are numbers or HTML attributes enclosed in a pair of square brackets "[ ]" that distinguish a child element from its siblings. Since the <tr> we need to access is the second one, we shall use "[2]" as the predicate.
If we won't use any predicate, XPath will access the first sibling. Therefore, we can access the first <tr> using either of these XPath codes.
Step 4 - Add the Succeeding Child Elements Using the Appropriate Predicates
The next element we need to access is the second <td>. Applying the principles we have learned from steps 2 and 3, we will finalize our XPath code to be like the one shown below.
Now that we have the correct XPath locator, we can already access the cell that we wanted to and obtain its inner text using the code below. It assumes that you have saved the HTML code above as "newhtml.html" within your C Drive.
public static void main(String[] args) { String baseUrl = "http://demo.guru99.com/test/write-xpath-table.html"; WebDriver driver = new FirefoxDriver(); driver.get(baseUrl); String innerText = driver.findElement( By.xpath("//table/tbody/tr[2]/td[2]")).getText(); System.out.println(innerText); driver.quit(); } }
The same principles discussed above applies to nested tables. Nested tables are tables located within another table. An example is shown below.
To access the cell with the text "4-5-6" using the "//parent/child" and predicate concepts from the previous section, we should be able to come up with the XPath code below.
The WebDriver code below should be able to retrieve the inner text of the cell which we are accessing.
public static void main(String[] args) { String baseUrl = "http://demo.guru99.com/test/accessing-nested-table.html"; WebDriver driver = new FirefoxDriver(); driver.get(baseUrl); String innerText = driver.findElement( By.xpath("//table/tbody/tr[2]/td[2]/table/tbody/tr/td[2]")).getText(); System.out.println(innerText); driver.quit(); }
The output below confirms that the inner table was successfully accessed.
If the element is written deep within the HTML code such that the number to use for the predicate is very difficult to determine, we can use that element's unique attribute instead.
In the example below, the "New York to Chicago" cell is located deep into Mercury Tours homepage's HTML code.
In this case, we can use the table's unique attribute (width="270") as the predicate. Attributes are used as predicates by prefixing them with the @ symbol. In the example above, the "New York to Chicago" cell is located in the first <td> of the fourth <tr>, and so our XPath should be as shown below.
Remember that when we put the XPath code in Java, we should use the escape character backward slash "\" for the double quotation marks on both sides of "270" so that the string argument of By.xpath() will not be terminated prematurely.
We are now ready to access that cell using the code below.
public static void main(String[] args) { String baseUrl = "http://demo.guru99.com/test/newtours/"; WebDriver driver = new FirefoxDriver(); driver.get(baseUrl); String innerText = driver.findElement(By .xpath("//table[@width=\"270\"]/tbody/tr[4]/td")) .getText(); System.out.println(innerText); driver.quit(); }
If the number or attribute of an element is extremely difficult or impossible to obtain, the quickest way to generate the XPath code is using Inspect Element.
Consider the example below from Mercury Tours homepage.
Step 1
Use Firebug to obtain the XPath code.
Step 2
Look for the first "table" parent element and delete everything to the left of it.
Step 3
Prefix the remaining portion of the code with double forward slash "//" and copy it over to your WebDriver code.
The WebDriver code below will be able to successfully retrieve the inner text of the element we are accessing.
public static void main(String[] args) { String baseUrl = "http://demo.guru99.com/test/newtours/"; WebDriver driver = new FirefoxDriver(); driver.get(baseUrl); String innerText = driver.findElement(By .xpath("//table/tbody/tr/td[2]" + "//table/tbody/tr[4]/td/" + "table/tbody/tr/td[2]/" + "table/tbody/tr[2]/td[1]/" + "table[2]/tbody/tr[3]/td[2]/font")) .getText(); System.out.println(innerText); driver.quit(); }
Summary
There are two types of HTML tables published on the web-
Below is an example of a dynamic table of Sales. Based on input date filters, number of rows will get altered. So, it is dynamic in nature.
Handling static table is easy, but dynamic table is a little bit difficult as rows and columns are not constant.
In this tutorial, you will learn-
Before we locate web element, first let's understands-
What is a web element?
Web elements are nothing but HTML elements like textbox, dropdowns radio buttons, submit buttons, etc. These HTML elements are written with start tag and ends with an end tag.
For Example,
<p> My First HTML Document</p>.
Steps for getting X-path of web element that we want to locate.
Step 1) In Chrome, Go to http://demo.guru99.com/test/web-table-element.php
Step 2) Right click on web element whose x-path is to be fetched. In our case, right click on "Company" Select Inspect option. The following screen will be shown -
Step 3) Right Click on highlighted web element > Select Copy -> Copy x-path option.
Step 4) Use the copied X-path "//*[@id="leftcontainer"]/table/thead/tr/th [1]" in Selenium WebDriver to locate the element.
When the table is dynamic in nature, we cannot predict its number of rows and columns.
Using Selenium web driver, we can find
Below is program for fetching total number of rows and columns of web table.
import java.text.ParseException; import java.util.List; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; public class Noofrowsandcols { public static void main(String[] args) throws ParseException { WebDriver wd; System.setProperty("webdriver.chrome.driver","G://chromedriver.exe"); wd= new ChromeDriver(); wd.get("http://demo.guru99.com/test/web-table-element.php"); //No.of Columns List col = wd.findElements(By.xpath(".//*[@id=\"leftcontainer\"]/table/thead/tr/th")); System.out.println("No of cols are : " +col.size()); //No.of rows List rows = wd.findElements(By.xpath(".//*[@id='leftcontainer']/table/tbody/tr/td[1]")); System.out.println("No of rows are : " + rows.size()); wd.close(); } }
Code Explanation:
.
Output:
Let's assume we need 3rd row of the table and its second cell's data. See the table below-
In above table, data is regularly updated after some span of time. The data you try retrieve will be different from the above screenshot. However, the code remains the same. Here is sample program to get the 3rd row and 2nd column's data.
import java.text.ParseException; import java.util.List; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import java.util.concurrent.TimeUnit; public class RowandCell { public static void main(String[] args) throws ParseException { WebDriver wd; System.setProperty("webdriver.chrome.driver","G://chromedriver.exe"); wd= new ChromeDriver(); wd.get("http://demo.guru99.com/test/web-table-element.php"); wd.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS); WebElement baseTable = wd.findElement(By.tagName("table")); //To find third row of table WebElement tableRow = baseTable.findElement(By.xpath("//*[@id=\"leftcontainer\"]/table/tbody/tr[3]")); String rowtext = tableRow.getText(); System.out.println("Third row of table : "+rowtext); //to get 3rd row's 2nd column data WebElement cellIneed = tableRow.findElement(By.xpath("//*[@id=\"leftcontainer\"]/table/tbody/tr[3]/td[2]")); String valueIneed = cellIneed.getText(); System.out.println("Cell value is : " + valueIneed); wd.close(); } }
Code Explanation:
Output:
In this example, we will get the maximum of all values in a particular column.
Refer the following table -
Here is the code
import java.text.ParseException; import java.util.List; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import java.text.NumberFormat; public class MaxFromTable { public static void main(String[] args) throws ParseException { WebDriver wd; System.setProperty("webdriver.chrome.driver","G://chromedriver.exe"); wd= new ChromeDriver(); wd.get("http://demo.guru99.com/test/web-table-element.php"); String max; double m=0,r=0; //No. of Columns List col = wd.findElements(By.xpath(".//*[@id='leftcontainer']/table/thead/tr/th")); System.out.println("Total No of columns are : " +col.size()); //No.of rows List rows = wd.findElements(By.xpath (".//*[@id='leftcontainer']/table/tbody/tr/td[1]")); System.out.println("Total No of rows are : " + rows.size()); for (int i =1;i<rows.size();i++) { max= wd.findElement(By.xpath("html/body/div[1]/div[5]/table/tbody/tr[" + (i+1)+ "]/td[4]")).getText(); NumberFormat f =NumberFormat.getNumberInstance(); Number num = f.parse(max); max = num.toString(); m = Double.parseDouble(max); if(m>r) { r=m; } } System.out.println("Maximum current price is : "+ r); } }
Code Explanation:
OutPut
Consider the following table http://demo.guru99.com/test/table.html
The number of columns for each row is different.
Here row number 1, 2 and 4 have 3 cells, and row number 3 has 2 cells, and row number 5 has 1 cell.
We need to get values of all the cells
Here is the code:
import java.text.ParseException; import java.util.List; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import java.util.concurrent.TimeUnit; import org.openqa.selenium.chrome.ChromeDriver; public class NofRowsColmns { public static void main(String[] args) throws ParseException { WebDriver wd; System.setProperty("webdriver.chrome.driver","G://chromedriver.exe"); wd = new ChromeDriver(); wd.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS); wd.get("http://demo.guru99.com/test/table.html"); //To locate table. WebElement mytable = wd.findElement(By.xpath("/html/body/table/tbody")); //To locate rows of table. List < WebElement > rows_table = mytable.findElements(By.tagName("tr")); //To calculate no of rows In table. int rows_count = rows_table.size(); //Loop will execute till the last row of table. for (int row = 0; row < rows_count; row++) { //To locate columns(cells) of that specific row. List < WebElement > Columns_row = rows_table.get(row).findElements(By.tagName("td")); //To calculate no of columns (cells). In that specific row. int columns_count = Columns_row.size(); System.out.println("Number of cells In Row " + row + " are " + columns_count); //Loop will execute till the last cell of that specific row. for (int column = 0; column < columns_count; column++) { // To retrieve text from that specific cell. String celtext = Columns_row.get(column).getText(); System.out.println("Cell Value of row number " + row + " and column number " + column + " Is " + celtext); } System.out.println("-------------------------------------------------- "); } } }
Code Explanation:
Output:
Summary
The article is contributed by Kanchan Kulkarni.
The desired capability is a series of key/value pairs that stores the browser properties like browsername, browser version, the path of the browser driver in the system, etc. to determine the behaviour of the browser at run time.
In this tutorial, you will learn-
Every Testing scenario should be executed on some specific testing environment. The testing environment can be a web browser,Mobile device, mobile emulator, mobile simulator, etc.
The Desired Capabilities Class helps us to tell the webdriver, which environment we are going to use in our test script.
The setCapability method of the DesiredCapabilities Class, which is explained in the later part of the tutorial, can be used in Selenium Grid. It is used to perform a parallel execution on different machine configurations.
Ex: Grid
It is used to set the browser properties (Ex. Chrome, IE), Platform Name (Ex. Linux, Windows) that are used while executing the test cases.
In the case of mobile automation, as we perform the tests on different varieties of mobile devices, the Mobile Platform (ex. iOS, Android) Platform Version (Ex. 3.x,4.x in Android) can be set.
The above emulator example shows the platform set which is android and the platform version set which is IceCream Sandwich (4.x).
Desired Capabilities are more useful in cases like:
Here we will see a different type of desired capabilities methods and see how to use one of this method "setCapability Method".
public java.lang.String getBrowserName()
public void setBrowserName(java.lang.String browserName)
public java.lang.String getVersion()
public void setVersion(java.lang.String version)
public Platform getPlatform()
public Platform setPlatform()
The getCapability method of the DesiredCapabilities class can be used to get the capability that is in use currently in the system.
public java.lang.Object getCapability(java.lang.String capabilityName)
The setCapability() method of the Desired Capabilities class can be used to set the device name, platform version, platform name, absolute path of the app under test (the .apk file of the app(Android) under test), app Activity (in Android) and appPackage(java).
"setCapability method" in Java has the below declarations:
setCapability : public void setCapability(java.lang.String capabilityName,boolean value)
setCapability :public void setCapability(java.lang.String capabilityName,java.lang.String value)
setCapability :public void setCapability(java.lang.String capabilityName,Platform value)
setCapability :public void setCapability(java.lang.String key,java.lang.Object value)
Let us consider an example where we want to run our Test Case on Internet explorer browser to open www.gmail.com website using Selenium Webdriver.
Following is the code.
importorg.openqa.selenium.WebDriver; importorg.openqa.selenium.ie.InternetExplorerDriver; public class IEtestforDesiredCapabilities { public static void main(String[] args) { WebDriver IEdriver = new InternetExplorerDriver(); driver.manage().window().maximize(); driver.get("http://gmail.com"); driver.quit(); } }
Now run this code from Eclipse and check out the console.
Output:
It will throw the following error when above code is executed. The error occurs because the path to the browser driver (IE in the above case) is not set.The browser could not be located by the selenium code.
The path to the driver executable must be set by the webdriver.ie.driver system property; formore information, see http://code.google.com/p/selenium/wiki/InternetExplorerDriver. The latest version can be downloaded from http://code.google.com/p/selenium/downloads/list
Dec 11, 201212:59:43PM org.openqa.selenium.ie.InternetExplorerDriverServer initializeLib
WARNING: This method of starting the IE driver is deprecated and will be removed in selenium 2.26. Please download the IEDriverServer.exe from http://code.google.com/p/selenium/downloads/list and ensure that it is in your PATH.
Solution:
The solution for the above problem is given in the warning section of the error itself.
importorg.openqa.selenium.WebDriver; importorg.openqa.selenium.ie.InternetExplorerDriver; importorg.openqa.selenium.remote.DesiredCapabilities; public class IEtestforDesiredCapabilities { public static void main(String[] args) { //it is used to define IE capability DesiredCapabilities capabilities = DesiredCapabilities.internetExplorer(); capabilities.setCapability(CapabilityType.BROWSER_NAME, "IE"); capabilities.setCapability(InternetExplorerDriver. INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS,true); System.setProperty("webdriver.ie.driver", "C:\\IEDriverServer.exe"); //it is used to initialize the IE driver WebDriver driver = new InternetExplorerDriver(capabilities); driver.manage().window().maximize(); driver.get("http://gmail.com"); driver.quit(); } }
Code Explanation:
In the code above,
Output:
The test case on Internet explorer browser will run successfully using Selenium Webdriver.
Conclusion
The Desired Capabilities class will help to set an environment to define the behaviour of the browser/environment on which the test can be executed.
It helps to launch our application in the desired environment having the capabilities that we desire to use.
This article is contributed by Krithika Ramkumar
The tooltip is a text that appears when a mouse hovers over an object like a link, an image, a button, text area, etc. in a web page. The text often gives more information about the object on which it appears.
Tooltips were traditionally implemented as a 'title' attribute to an element. The value of this attribute was shown as a tooltip on mouse-hover. This is a static text giving information of the element with no styling.
Now, there are many plugins available for 'tool tips' implementation. Advanced tooltips with styling, rendering, images and links are being implemented using JavaScript/JQuery plugins or using CSS Tooltips.
Advanced User Interactions API provides the API for user actions like drag and drop, hovering, multi selecting, key press and release and other actions using keyboard or mouse on a webpage.
You can refer this link for more details on the API.
Here, let's see how to use a couple of classes and methods we would need to move a slider element by an offset.
Step 1) In order to use the API, the following packages/classes needs to be imported:
Step 2) Create an object of "Actions" class and build the Sequence of user actions. Actions class is used to build the sequence of user actions like moveToElement(), dragAndDrop() etc. Various methods related to user actions are provided by API.
The driver object is provided as a parameter to its constructor.
Step 3) Create an Action Object using the build() method of "Actions" class. Call the perform() method to execute all the actions built by the Actions object(builder here).
We have seen how to use some of the user Actions methods provided by the API - clickAndHold(element), moveByOffset(10,0), release(). The API provides many such methods.
Refer to the link for more details.
Let's see the demonstration of accessing and verifying the tool tips in the simple scenario
For this case, let's take the example site - http://demo.guru99.com/test/social-icon.html.
We will try to verify the tooltip of the "github" icon at the top right of the page.
In order to do it, we will first find the element and get its 'title' attribute and verify with the expected tool tip text.
Since, we are assuming the tool tip is in the "title" attribute, we are not even automating the mouse hover effect but simply retrieving the attribute's value using the "getAttribute()" method.
Here is the code
import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.*; public class ToolTip { public static void main(String[] args) { String baseUrl = "http://demo.guru99.com/test/social-icon.html"; System.setProperty("webdriver.chrome.driver","G:\\chromedriver.exe"); WebDriver driver = new ChromeDriver(); driver.get(baseUrl); String expectedTooltip = "Github"; // Find the Github icon at the top right of the header WebElement github = driver.findElement(By.xpath(".//*[@class='soc-ico show-round']/a[4]")); //get the value of the "title" attribute of the github icon String actualTooltip = github.getAttribute("title"); //Assert the tooltip's value is as expected System.out.println("Actual Title of Tool Tip"+actualTooltip); if(actualTooltip.equals(expectedTooltip)) { System.out.println("Test Case Passed"); } driver.close(); } }
Explanation of code
There are a plenty of JQuery plugins available to implement the tooltips, and each one has a slightly different form of implementation.
Some plugins expect the tooltip HTML to be present all the time next to the element for which the tooltip is applicable whereas the others create a dynamic "div" tag, which appears on the fly while hovering over the element.
For our demonstration, let's consider the "jQuery Tools Tooltip" way of tooltip implementation.
Here in the URL – http://demo.guru99.com/test/tooltip.html you can see the demo where on mouse hovering over "Download now", we get an advanced tooltip with an image, callout background, a table and a link inside it which is clickable.
If you look at the source below, you can see that the div tag representing the tooltip is always present next to the "Download now" link's tag. But, the code inside the script tag below controls when it needs to popup.
Let's try to verify just the link text in the tooltip for our demonstration here.
We will first find the WebElement corresponding to the "Download now". Then using the Interactions API, we will move to the element (mouse-hover). Next, we will find the WebElement that corresponds to the link inside the displayed tooltip and verify it against the expected text.
Here is the code
import org.openqa.selenium.interactions.Action; import org.openqa.selenium.interactions.Actions; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.*; public class JqueryToolTip { public static void main(String[] args) { String baseUrl = "http://demo.guru99.com/test/tooltip.html"; System.setProperty("webdriver.chrome.driver","G:\\chromedriver.exe"); WebDriver driver = new ChromeDriver(); String expectedTooltip = "What's new in 3.2"; driver.get(baseUrl); WebElement download = driver.findElement(By.xpath(".//*[@id='download_now']")); Actions builder = new Actions (driver); builder.clickAndHold().moveToElement(download); builder.moveToElement(download).build().perform(); WebElement toolTipElement = driver.findElement(By.xpath(".//*[@class='box']/div/a")); String actualTooltip = toolTipElement.getText(); System.out.println("Actual Title of Tool Tip "+actualTooltip); if(actualTooltip.equals(expectedTooltip)) { System.out.println("Test Case Passed"); } driver.close(); } }
Code Explanation
In this tutorial, you have learnt how to access Tooltips using Selenium Web driver.
The term Gecko stands for a Web Browser engine that is inbuilt within Mozilla Firefox browser. Gecko driver acts as a proxy between Web Driver enabled clients(Eclipse, Netbeans, etc.) and Mozilla Firefox browser. In short, Gecko driver acts as a link between Selenium Web Driver tests and Mozilla Firefox browser.
Before Selenium 3, Mozilla Firefox browser was the default browser for Selenium. After Selenium 3, testers need to initialize the script to use Firefox using GeckoDriver explicitly. Selenium uses W3C Webdriver protocol to send requests to GeckoDriver, which translates them into a protocol named Marionette. Firefox will understand the commands transmitted in the form of Marionette protocol and executes them.
Selenium Webdriver version 2.53 is not compatible with Mozilla Firefox version 47.0+. The Firefox driver used in earlier versions of Mozilla Firefox will be discontinued, and only the GeckoDriver implementation would be used. Hence testers are forced to use GeckoDriver if they want to run automated tests on Mozilla Firefox version 47.0+. But the big question - what is the advantage?
The major advantage of using GeckoDriver as opposed to the default Firefox driver is Compatibility. GeckoDriver uses W3C WebDriver protocol to communicate with Selenium. W3C is a universally defined standard for Web Driver. This means Selenium Developers (People who code Selenium base) need not create a new version of Web Driver for each browser version. The same Web Driver can be used for multiple browser versions. Hence, GeckoDriver is preferred compared to the earlier implementation of Firefox driver.
Gecko Driver is available as an executable file that can be downloaded on the system. The following are the list of steps to download gecko driver.
Step 1 ) At this page https://github.com/mozilla/geckodriver/releases ,Select the appropriate version for GeckoDriver download based on your operating system
Step 2) Once the ZIP file download is complete, extract the contents of ZIP File onto a file folder
Step 3) Note the location where you extracted the driver. Location will be used later to instantiate the driver.
There are three different ways to initialize GeckoDriver.
1. Using DesiredCapabilities:
First, set the system property for Gecko Driver.
Syntax:
System.setProperty("webdriver.gecko.driver","Path to geckdriver.exe file");
Example:
System.setProperty("webdriver.gecko.driver","D:\\Downloads\\GeckoDriver.exe");
Next, set Desired Capabilities.
Desired Capabilities help Selenium to understand the browser name, version and operating system to execute the automated tests. Below is the code to set gecko driver using DesiredCapabilities class.
DesiredCapabilities capabilities = DesiredCapabilities.firefox(); capabilities.setCapability("marionette",true);
Here is the complete code
System.setProperty("webdriver.gecko.driver", driverPath); DesiredCapabilities capabilities = DesiredCapabilities.firefox(); capabilities.setCapability("marionette",true); driver= new FirefoxDriver(capabilities);
2. Using marionette property:
Gecko driver can also be initialized using marionette property as below
System.setProperty("webdriver.firefox.marionette","D:\\Downloads\\GeckoDriver.exe");
If gecko driver is initialized using the above method, code for desired capabilities is not required.
3. Using FirefoxOptions:
Mozilla Firefox version 47+ has marionette driver as a legacy system. Taking advantage of this, marionette driver can be called using Firefox Options as below
FirefoxOptions options = new FirefoxOptions(); options.setLegacy(true);
package com.guru99.demo; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.remote.DesiredCapabilities; public class GeckoDriverDemo { String driverPath = "D:\\Guru99Demo\\GeckoDriver.exe"; public WebDriver driver; @Before public void startBrowser() { System.setProperty("webdriver.gecko.driver", driverPath); DesiredCapabilities capabilities = DesiredCapabilities.firefox(); capabilities.setCapability("marionette", true); driver = new FirefoxDriver(capabilities); } @Test public void navigateToUrl() { driver.get("http://demo.guru99.com/selenium/guru99home/"); } @After public void endTest() { driver.quit(); } }
Code Explanation:
@Before method:
Initially, we need to set the system property for gecko driver to the geckdriver.exe file download location. We need to set the marionette property to true for Selenium to use Marionette protocol to communicate with Gecko Driver. Finally, we need to start the Firefox browser instance using the object for Desired Capabilities.
The below statements help to achieve the above task.
System.setProperty("webdriver.gecko.driver", driverPath); DesiredCapabilities capabilities = DesiredCapabilities.firefox(); capabilities.setCapability("marionette",true); driver= new FirefoxDriver(capabilities);
@Test method:
We are navigating to user-specified URL using the inbuilt "get" method provided by Selenium web driver. The below statement help to achieve the same.
driver.get("http://demo.guru99.com/selenium/guru99home/");
@After method:
Finally, we are closing the browser instance using the quit method.
driver.quit();
Non-gecko driver script used before Selenium 3 was straightforward. We need to create an instance of Firefox driver and use the instance variable.
@Before public void startBrowser() { driver = new FirefoxDriver(); }
To convert to gecko, you need to simply add one line of code
@Before public void startBrowser() { System.setProperty("webdriver.firefox.marionette", "D:\\Downloads\\GeckoDriver.exe"); driver = new FirefoxDriver(); }
Following is a list of common exceptions that occur while using Gecko Driver and with resolution.
1. The path to driver executable must be set by webdriver.gecko.driver system property:
This exception occurs when user tries to instantiate Firefox driver without setting the system property for gecko driver. This is usually done by beginners to Selenium who are not aware of the changes made from Selenium 3 to Selenium previous versions.
The resolution for the above exception is to set the system property for gecko driver with the location of geckodriver.exe file as below
System.setProperty("webdriver.gecko.driver", "D:\\Downloads\\geckodriver.exe");
Please note that you need to set the property of gecko driver before creating an instance of Mozilla Firefox driver.
2. Firefox Not Connected Exception:
org.openqa.selenium.firefox.NotConnectedException: Unable to connect to host 127.0.0.1 on port 7055 after 45000 ms.
This exception usually occurs when Firefox version has been upgraded to the latest version. The resolution for this exception is to update the selenium jar file and gecko driver to the latest version and use the same.
3. Session Not Created Exception:
org.openqa.selenium.SessionNotCreatedException: Unable to create new remote session.
This exception occurs due to compatibility issues between Selenium and Gecko driver. Gecko driver works with Firefox version 47 or above. It can be resolved by updating Firefox version to 47 or above.
4. Connection Refused Exception:
WebDriver Exception: Connection Refused
This exception is the message generated when web driver is unable to establish a connection with Firefox. It can be resolved using any one of the following techniques.
Following is a step by step guide to install TestNG in Eclipse
Step 1:
Step 2: In the Eclipse Marketplace dialog box, type TestNG in the search box and press the search button( magnifying glass) or press enter key
Step 3: Click Install
Step 4: A new window for feature selection will open, Do not change anything and Click on confirm button
Step 5:
Step 6: If you encounter a Security warning, just click OK
Wait for the installation to finish
Step 7: When Eclipse prompts you for a restart, just click Yes.
Step 8: After the restart, verify if TestNG was indeed successfully installed. Click Window > Preferences and see if TestNG is included on the Preferences list.
That's it to TestNG Installation
TestNG is an automation testing framework in which NG stands for "Next Generation". TestNG is inspired from JUnit which uses the annotations (@).
Beside above concept, you will learn more on TestNG, like what are the Advantages of TestNG, how to create test methods using @test annotations, how to convert these classes into testing suite file and execute through the eclipse as well as from the command line.
In this tutorial, you will learn
Default Selenium tests do not generate a proper format for the test results. Using TestNG we can generate test results.
Most Selenium users use this more than Junit because of its advantages. There are so many features of TestNG, but we will only focus on the most important ones that we can use in Selenium. Following are key features of TestNG
There are three major advantages of TestNG over JUnit:
Annotations in TestNG are lines of code that can control how the method below them will be executed. They are always preceded by the @ symbol. A very early and quick example is the one shown below.
Annotations will be discussed later in the section named "Annotations used in TestNG,"so it is perfectly ok if you do not understand the above example just yet. It is just important to note for now that annotations in TestNG are easier to code and understand than in JUnit.
The ability to run tests in parallel is available in TestNG but not in JUnit, so it is the more preferred framework of testers using Selenium Grid.
Before we create a test case, we should first setup a new TestNG Project in Eclipse and name it as "FirstTestNGProject".
Step 1: Click File > New > Java Project
Step 2: Type "FirstTestNGProject" as the Project Name then click Next.
Step 3: We will now start to import the TestNG Libraries onto our project. Click on the "Libraries" tab, and then "Add Library…"
Step 4: On the Add Library dialog, choose "TestNG" and click Next.
Step 5: Click Finish.
You should notice that TestNG is included on the Libraries list.
Step 6: We will now add the JAR files that contain the Selenium API. These files are found in the Java client driver that we downloaded from http://docs.seleniumhq.org/download/ when we were installing Selenium and Eclipse in the previous chapters.
Then, navigate to where you have placed the Selenium JAR files.
After adding the external JARs, your screen should look like this.
Step 7: Click Finish and verify that our FirstTestNGProject is visible on Eclipse's Package Explorer window.
Now that we are done setting up our project, let us create a new TestNG file.
Step 1: Right-click on the "src" package folder then choose New > Other…
Step 2: Click on the TestNG folder and select the "TestNG class" option. Click Next.
Step 3: Type the values indicated below on the appropriate input boxes and click Finish. Notice that we have named our Java file as "FirstTestNGFile".
Eclipse should automatically create the template for our TestNG file shown below.
Let us now create our first Test Case that will check if Mercury Tours' homepage is correct. Type your code as shown below.
package firsttestngpackage; import org.openqa.selenium.*; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.Assert; import org.testng.annotations.*; public class firsttestngfile { public String baseUrl = "http://demo.guru99.com/test/newtours/"; String driverPath = "C:\\geckodriver.exe"; public WebDriver driver ; @Test public void verifyHomepageTitle() { System.out.println("launching firefox browser"); System.setProperty("webdriver.firefox.marionette", driverPath); driver = new FirefoxDriver(); driver.get(baseUrl); String expectedTitle = "Welcome: Mercury Tours"; String actualTitle = driver.getTitle(); Assert.assertEquals(actualTitle, expectedTitle); driver.close(); } }
Notice the following.
You may have multiple test cases (therefore, multiple @Test annotations) in a single TestNG file. This will be tackled in more detail later in the section "Annotations used in TestNG."
To run the test, simply run the file in Eclipse as you normally do. Eclipse will provide two outputs – one in the Console window and the other on the TestNG Results window.
The Console window in Eclipse gives a text-based report of our test case results while the TestNG Results window gives us a graphical one.
TestNG has the ability to generate reports in HTML format.
Step 1: After running our FirstTestNGFile that we created in the previous section, right-click the project name (FirstTestNGProject) in the Project Explorer window then click on the "Refresh" option.
Step 2: Notice that a "test-output" folder was created. Expand it and look for an index.html file. This HTML file is a report of the results of the most recent test run.
Step 3: Double-click on that index.html file to open it within Eclipse's built-in web browser. You can refresh this page any time after you rerun your test by simply pressing F5 just like in ordinary web browsers.
In the previous section, you have been introduced to the @Test annotation. Now, we shall be studying more advanced annotations and their usages.
We can use multiple @Test annotations in a single TestNG file. By default, methods annotated by @Test are executed alphabetically. See the code below. Though the methods c_test, a_test, and b_test are not arranged alphabetically in the code, they will be executed as such.
Run this code and on the generated index.html page, click "Chronological view."
If you want the methods to be executed in a different order, use the parameter "priority". Parameters are keywords that modify the annotation's function.
TestNG will execute the @Test annotation with the lowest priority value up to the largest. There is no need for your priority values to be consecutive.
The TestNG HTML report will confirm that the methods were executed based on the ascending value of priority.
Aside from "priority," @Test has another parameter called "alwaysRun" which can only be set to either "true" or "false." To use two or more parameters in a single annotation, separate them with a comma such as the one shown below.
@Test(priority = 0, alwaysRun = true)
@BeforeTest and @AfterTest
@BeforeTest |
methods under this annotation will be executed prior to the first test case in the TestNG file. |
@AfterTest |
methods under this annotation will be executed after all test cases in the TestNG file are executed. |
Consider the code below.
package firsttestngpackage; import org.openqa.selenium.*; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.Assert; import org.testng.annotations.*; public class firsttestngfile { public String baseUrl = "http://demo.guru99.com/test/newtours/"; String driverPath = "C:\\geckodriver.exe"; public WebDriver driver ; @BeforeTest public void launchBrowser() { System.out.println("launching firefox browser"); System.setProperty("webdriver.firefox.marionette", driverPath); driver = new FirefoxDriver(); driver.get(baseUrl); } @Test public void verifyHomepageTitle() { String expectedTitle = "Welcome: Mercury Tours"; String actualTitle = driver.getTitle(); Assert.assertEquals(actualTitle, expectedTitle); } @AfterTest public void terminateBrowser(){ driver.close(); } }
Applying the logic presented by the table and the code above, we can predict that the sequence by which methods will be executed is:
The placement of the annotation blocks can be interchanged without affecting the chronological order by which they will be executed. For example, try to rearrange the annotation blocks such that your code would look similar to the one below.
package firsttestngpackage; import org.openqa.selenium.*; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.Assert; import org.testng.annotations.*; public class firsttestngfile { public String baseUrl = "http://demo.guru99.com/test/newtours/"; String driverPath = "C:\\geckodriver.exe"; public WebDriver driver ; @AfterTest //Jumbled public void terminateBrowser(){ driver.close(); } @BeforeTest //Jumbled public void launchBrowser() { System.out.println("launching firefox browser"); System.setProperty("webdriver.firefox.marionette", driverPath); driver = new FirefoxDriver(); driver.get(baseUrl); } @Test //Jumbled public void verifyHomepageTitle() { String expectedTitle = "Welcome: Mercury Tours"; String actualTitle = driver.getTitle(); Assert.assertEquals(actualTitle, expectedTitle); } }
Run the code above and notice that
@BeforeMethod and @AfterMethod
@BeforeMethod |
methods under this annotation will be executed prior to each method in each test case. |
@AfterMethod |
methods under this annotation will be executed after each method in each test case. |
In Mercury Tours, suppose we like to verify the titles of the target pages of the two links below.
The flow of our test would be:
The code below illustrates how @BeforeMethod and @AfterMethod are used to efficiently execute the scenario mentioned above.
package firsttestngpackage; import org.openqa.selenium.*; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.Assert; import org.testng.annotations.*; @Test public class firsttestngfile { public String baseUrl = "http://demo.guru99.com/test/newtours/"; String driverPath = "C:\\geckodriver.exe"; public WebDriver driver; public String expected = null; public String actual = null; @BeforeTest public void launchBrowser() { System.out.println("launching firefox browser"); System.setProperty("webdriver.firefox.marionette", driverPath); driver= new FirefoxDriver(); driver.get(baseUrl); } @BeforeMethod public void verifyHomepageTitle() { String expectedTitle = "Welcome: Mercury Tours"; String actualTitle = driver.getTitle(); Assert.assertEquals(actualTitle, expectedTitle); } @Test(priority = 0) public void register(){ driver.findElement(By.linkText("REGISTER")).click() ; expected = "Register: Mercury Tours"; actual = driver.getTitle(); Assert.assertEquals(actual, expected); } @Test(priority = 1) public void support() { driver.findElement(By.linkText("SUPPORT")).click() ; expected = "Under Construction: Mercury Tours"; actual = driver.getTitle(); Assert.assertEquals(actual, expected); } @AfterMethod public void goBackToHomepage ( ) { driver.findElement(By.linkText("Home")).click() ; } @AfterTest public void terminateBrowser(){ driver.close(); } }
After executing this test, your TestNG should report the following sequence.
Simply put, @BeforeMethod should contain methods that you need to run before each test case while @AfterMethod should contain methods that you need to run after each test case.
@BeforeSuite: The annotated method will be run before all tests in this suite have run.
@AfterSuite: The annotated method will be run after all tests in this suite have run.
@BeforeTest: The annotated method will be run before any test method belonging to the classes inside the tag is run.
@AfterTest: The annotated method will be run after all the test methods belonging to the classes inside the tag have run.
@BeforeGroups: The list of groups that this configuration method will run before. This method is guaranteed to run shortly before the first test method that belongs to any of these groups is invoked.
@AfterGroups: The list of groups that this configuration method will run after. This method is guaranteed to run shortly after the last test method that belongs to any of these groups is invoked.
@BeforeClass: The annotated method will be run before the first test method in the current class is invoked.
@AfterClass: The annotated method will be run after all the test methods in the current class have been run.
@BeforeMethod: The annotated method will be run before each test method.
@AfterMethod: The annotated method will be run after each test method.
@Test: The annotated method is a part of a test case
TestNG is a Testing framework that covers different types of test designs like unit, functional, end to end, UI and integration test.
You can run a single or multiple packages (package here means to encapsulate a group of classes in a proper director format) by creating XML and run it through maven.
In this tutorial, you will learn-
We use groups in Testng when,
In below example, we have shown the syntax of how to use groups in the XML file.
@Test (groups = { "bonding", "strong_ties" })
Here we are using 2 group names i.e. "bonding" and "strong_ties" (these are logical name that can be altered as per your wish).
<groups> tag defines the starting of groups in XML.
Customize your XML to pick the mentioned group from the test classes. Below mentioned is the syntax of how to declare groups in XML file e.g.
<groups> <run> <include name="bonding" /> </run> </groups>
So, let us assume that there are 10 test methods in a class.
Out of them,
Moving forward, we are going to set maven/Java path and use the Eclipse IDE to demonstrate the usage of groups using XML files in Java based maven project.
Please refer https://www.guru99.com/maven-jenkins-with-selenium-complete-tutorial.html
https://www.guru99.com/install-java.html
Multiple tags are used in a sequence to build a working testNG xml like <suite>, <test> and <class>
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> <suite name="Suite"> <test name="Guru 99 Smoke Test Demo"> <groups> <run> <include name="strong_ties" /> </run> </groups> <classes> <class name="com.group.guru99.TC_Class1" /> </classes> </test> </suite>
We will be using this XML for upcoming video downside.
Suppose you are finding the usage of group mechanism complex then testNG XML facilitate the functionality to exclude/include a test.
Exclude Tag: Syntax for exclude tag <exclude name="${TEST_CASE_NAME}" /> Include Tag: Syntax for include tag <include name="${TEST_CASE_NAME}" />
Note: We can include/exclude multiple test cases once at a time, and it works with Groups as well.
Explanation of the Java Code and XML with the group, exclude and include the tag in XML.
Note: Each step which you code should be declared in separate methods, but when executed, it will execute test methods depending upon the entries in the XML file.
Method 1: Initialize Browser and launch URL (tc01LaunchURL())
Method 2: Verify Login Page Heading (tc02VerifyLaunchPage())
Method 3: Enter userName and Password on login form (tc03EnterCredentials())
Method 4: Verify the presence of Manager ID on User Dashboard (tc04VerifyLoggedInPage())
Method 5: Verify few more links on User DashBoard (tc05VerifyHyperlinks())
Code for our scenario:
package com.group.guru99; import java.util.concurrent.TimeUnit; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.Assert; import org.testng.annotations.Test; public class TC_Class1 { public static final WebDriver webDriver = new FirefoxDriver();; String launchPageHeading = "//h3[text()='Guru99 Bank']"; final String userName_element = "//input[@name='uid']", password_element = "//input[@name='password']", signIn_element = "//input[@name='btnLogin']"; final String userName_value = "mngr28642", password_value = "ydAnate"; final String managerID = "//td[contains(text(),'Manger Id')]"; final String newCustomer = "//a[@href='addcustomerpage.php']", fundTransfer = "//a[@href='FundTransInput.php']"; /** * This test case will initialize the webDriver */ @Test(groups = { "bonding", "strong_ties" }) public void tc01LaunchURL() { webDriver.manage().window().maximize(); webDriver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS); webDriver.get("http://www.demo.guru99.com/V4/"); } /** * Will check the presence of Heading on Login Page */ @Test(groups = { "bonding" }) public void tc02VerifyLaunchPage() { Assert.assertTrue(webDriver.findElement(By.xpath(launchPageHeading)).isDisplayed(), "Home Page heading is not displayed"); System.out.println("Home Page heading is displayed"); } /** * This test case will enter User name, password and will then click on * signIn button */ @Test(groups = { "bonding", "strong_ties" }) public void tc03EnterCredentials() { webDriver.findElement(By.xpath(userName_element)).sendKeys(userName_value); webDriver.findElement(By.xpath(password_element)).sendKeys(password_value); webDriver.findElement(By.xpath(signIn_element)).click(); } /** * This test case will verify manger's ID presence on DashBoard */ @Test(groups = { "strong_ties" }) public void tc04VerifyLoggedInPage() { Assert.assertTrue(webDriver.findElement(By.xpath(managerID)).isDisplayed(), "Manager ID label is not displayed"); System.out.println("Manger Id label is displayed"); } /** * This test case will check the presence of presence of New customer link * And FundTransfer link in Left pannel */ @Test(groups = { "bonding" }) public void tc05VerifyHyperlinks() { Assert.assertTrue(webDriver.findElement(By.xpath(newCustomer)).isEnabled(), "New customer hyperlink is not displayed"); System.out.println("New customer hyperlink is displayed"); Assert.assertTrue(webDriver.findElement(By.xpath(fundTransfer)).isEnabled(), "Fund Transfer hyperlink is not displayed"); System.out.println("Fund Transfer hyperlink is displayed"); } }
Please Note: The credentials are only valid for 20 days, so if you are trying to run code on your local machine, so you might face invalid credentials error. Please find below steps to generate your login credentials:
Explanation of Code:
As mentioned above, we have created 5 test cases for performing each action in independent methods.
You can observe that to every method, we have associated a group parameter holding some value in it.
Basically, these are the name of the differentiating groups i.e. "strong_ties" & "bonding".
So overall, we have 4 scenarios;
Please download code from the mentioned URL, it will contain all type of testXML:
Conclusion
We have learned here relatively a new way for running test cases using XML in Maven project.
We started by providing a brief introduction on testNG and continued with the full technical specification of Groups, exclude and include.
TestNG is a Testing framework, that covers different types of test designs like a unit test, functional test, end to end test, UI test and integration test.
You can run a single or multiple test cases in your Testng code.
If test priority is not defined while, running multiple test cases, TestNG assigns all @Test a priority as zero(0).
Now, while running; lower priorities will be scheduled first.
In this tutorial, you will learn -
Let's take a scenario where sequencing will be required in order to pass all test cases:
Scenario: Generate a code where you are required to perform a Google search with a specific keyword say "Facebook". Now, verify that Browser title is changed to "Facebook - Google Search".
Note: Each step which you code should be in separate methods
Method 1: Open Browser say Firefox (openBrowser())
Method 2: Launch Google.com (launchGoogle())
Method 3: Perform a search using "Facebook" (performSearchAndClick1stLink())
Method 4: Verify Google search page title (FaceBookPageTitleVerification())
Code for our scenario:
import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.Assert; import org.testng.annotations.Test; public class Priority_In_testNG { WebDriver driver; // Method 1: Open Brower say Firefox @Test public void openBrowser() { driver = new FirefoxDriver(); } // Method 2: Launch Google.com @Test public void launchGoogle() { driver.get("http://www.google.co.in"); } // Method 3: Perform a search using "Facebook" @Test public void peformSeachAndClick1stLink() { driver.findElement(By.xpath(".//*[@title='Search']")).sendKeys("Facebook"); } // Method 4: Verify Google search page title. @Test public void FaceBookPageTitleVerification() throws Exception { driver.findElement(By.xpath(".//*[@value='Search']")).click(); Thread.sleep(3000); Assert.assertEquals(driver.getTitle().contains("Facebook - Google Search"), true); } }
Explanation of Code
As mentioned above we have created 4 test cases for performing each action in an independent methods.
Now run this code using testNG as shown in the video you will find all the Test Case are failing. The reason for failure: as there is a dependency of previous test case to pass, only than current running test case will be passed.
In this case,
PASSED: openBrowser FAILED: FaceBookPageTitleVerification FAILED: launchGoogle FAILED: peformSeachAndClick1stLink
If we don’t mention any priority, testng will execute the @Test methods based on alphabetical order of their method names irrespective of their place of implementation in the code.
package com.guru.testngannotations; import org.testng.annotations.Test; public class TestNG_Priority_Annotations { @Test public void c_method(){ System.out.println("I'm in method C"); } @Test public void b_method(){ System.out.println("I'm in method B"); } @Test public void a_method(){ System.out.println("I'm in method A"); } @Test public void e_method(){ System.out.println("I'm in method E"); } @Test public void d_method(){ System.out.println("I'm in method D"); } }
Output
I'm in method A I'm in method B I'm in method C I'm in method D I'm in method E
Though we defined the methods in a random manner (c, b, a, e, d), testng executed the methods based on their method names by considering alphabetical order and the same was reflected in the output as well.
As you have seen in the previous example that sequencing required in order to pass this scenario, so we will be modifying the previous piece of code with Priority Parameter so that each test should run against to the priority assigned to them.
Now as you can see we have assigned the Priority to each test case means test case will the lower priority value will be executed first.
Priority in testNG in action
import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.Assert; import org.testng.annotations.Test; public class Priority_In_testNG { WebDriver driver; // Method 1: Open Browser say Firefox @Test (priority=1) public void openBrowser() { driver = new FirefoxDriver(); } // Method 2: Launch Google.com @Test (priority=2) public void launchGoogle() { driver.get("http://www.google.co.in"); } // Method 3: Perform a search using "Facebook" @Test (priority=3) public void peformSeachAndClick1stLink() { driver.findElement(By.xpath(".//*[@title='Search']")).sendKeys("Facebook"); } // Method 4: Verify Google search page title. @Test (priority=4) public void FaceBookPageTitleVerification() throws Exception { driver.findElement(By.xpath(".//*[@value='Search']")).click(); Thread.sleep(3000); Assert.assertEquals(driver.getTitle().contains("Facebook - Google Search"), true); } }
Explanation of Code
After assigning priority to each testcases, run the above code using testNG as shown in Video-2 mentioned below.
Here, you can see that test cases are prioritized. Test case having lower priority are executed first i.e. now there is a sequential execution according to priority in the test cases. Hence, all test cases are passing now.
Note the console of eclipse:
Output :
PASSED: openBrowser PASSED: launchGoogle PASSED: peformSearchAndClick1stLink PASSED: FaceBookPageTitleVerification
Number 0 has the highest priority(it’ll be executed first) and the priority goes on based on the given number i.e., 0 has the highest priority than 1. 1 has the highest priority than 2 and so on.
package com.guru.testngannotations; import org.testng.annotations.Test; public class TestNG_Priority_Annotations { @Test(priority=6) public void c_method(){ System.out.println("I'm in method C"); } @Test(priority=9) public void b_method(){ System.out.println("I'm in method B"); } @Test(priority=1) public void a_method(){ System.out.println("I'm in method A"); } @Test(priority=0) public void e_method(){ System.out.println("I'm in method E"); } @Test(priority=3) public void d_method(){ System.out.println("I'm in method D"); } }
Output
I'm in method E I'm in method A I'm in method D I'm in method C I'm in method B
Here we have provided the priorities as 0,1,3,6,9. So, method having 0 as priority is executed first and then method having priority-1 and so on. Here alphabetical order method name won’t be considered as we provided the priorities
There may be a chance that methods may contain same priority. In those cases, testng considers the alphabetical order of the method names whose priority is same.
package com.guru.testngannotations; import org.testng.annotations.Test; public class TestNG_Priority_Annotations { @Test(priority=6) public void c_method(){ System.out.println("I'm in method C"); } @Test(priority=9) public void b_method(){ System.out.println("I'm in method B"); } @Test(priority=6) public void a_method(){ System.out.println("I'm in method A"); } @Test(priority=0) public void e_method(){ System.out.println("I'm in method E"); } @Test(priority=3) public void d_method(){ System.out.println("I'm in method D"); } }
Output
I'm in method E I'm in method D I'm in method A I'm in method C I'm in method B
Here ‘e’ and ‘d’ are executed based on their priority values. But the methods ‘a’ and ‘c’ contains the same priority value(6). So, here testng considers the alphabetical order of ‘a’ and ’c’ and executes them accordingly.
In this case, we’ll cover two cases in one testng class.
package com.guru.testngannotations; import org.testng.annotations.Test; public class TestNG_Priority_Annotations { @Test() public void c_method(){ System.out.println("I'm in method C"); } @Test() public void b_method(){ System.out.println("I'm in method B"); } @Test(priority=6) public void a_method(){ System.out.println("I'm in method A"); } @Test(priority=0) public void e_method(){ System.out.println("I'm in method E"); } @Test(priority=6) public void d_method(){ System.out.println("I'm in method D"); } }
Output:
I'm in method B I'm in method C I'm in method E I'm in method A I'm in method D
PASSED: b_method PASSED: c_method PASSED: e_method PASSED: a_method PASSED: d_method
Explanation:
First preference: Non-prioritized methods: ‘c’ and ‘b’: Based on alphabetical order ‘b’ was executed first and then ‘c’.
Second preference: Prioritized methods: ‘a’, ‘e’ and ‘d’: ‘e’ was executed first as it was having highest priority(0). As the priority of ‘a’ and ‘d’ methods were same, testng considered the alphabetical order of their methods names. So, between them, ‘a’ was executed first and then ‘d’.
Case-sensitive in TestNG
Just for your information there is a standard syntax for defining priority in testNG i.e. @Test (priority=4), suppose you are defining it in some other syntax say @Test (PRIORITY=1) then your IDE will show it as a compilation error. Refer image below:
Conclusion:
As you have seen that if there is a requirement to run a set of test-case in specific sequence then it can be easily done using Priority using testNG as a run tool.
This tutorial is made possible due to contributions of Ramandeep Singh and Rama Krishna Gadde
To understand how to run scripts in parallel, let's first understand
During test execution, the Selenium WebDriver has to interact with the browser all the time to execute given commands. At the time of execution, it is also possible that, before current execution completes, someone else starts execution of another script, in the same machine and in the same type of browser.
In such situation, we need a mechanism by which our two different executions should not overlap with each other. This can be achieved using Session Handling in Selenium.
If you check the source code of Selenium WebDriver, you will find a variable named as 'sessionId'. Whenever we create a new instance of a WebDriver object, a new 'sessionId' will be generated and attached with that particular Firefox/Chrome/IE Driver ().
So anything we do after this will execute only in that particular Firefox browser session.
As this is an in-built functionality, there is no explicit need to assign the session id
Code Example: Here two different sessions will be generated for two different WebDriver.
import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; public class SessionHandling { public static void main(String...strings ){ //First session of WebDriver WebDriver driver = new FirefoxDriver(); //Goto guru99 site driver.get("http://demo.guru99.com/V4/"); //Second session of WebDriver WebDriver driver2 = new FirefoxDriver(); //Goto guru99 site driver2.get("http://demo.guru99.com/V4/"); } }
There are situations where you want to run multiple tests at the same time.
In such cases, one can use "parallel" attribute
The parallel attribute of suite tag can accept four values:
tests | All the test cases inside <test> tag of Testing xml file will run parallel. |
classes | All the test cases inside a Java class will run parallel |
methods | All the methods with @Test annotation will execute parallel. |
instances | Test cases in same instance will execute parallel but two methods of two different instances will run in different thread. |
The attribute thread-count allows you to specify how many threads should be allocated for this execution.
Complete Example: In this Example, three test cases will run parallel and fill login data in http://demo.guru99.com
The Complete project will look like:
TestGuru99MultipleSession.java
import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.testng.annotations.Test; public class TestGuru99MultipleSession { @Test public void executSessionOne(){ //First session of WebDriver System.setProperty("webdriver.chrome.driver","chromedriver.exe"); WebDriver driver = new ChromeDriver(); //Goto guru99 site driver.get("http://demo.guru99.com/V4/"); //find user name text box and fill it driver.findElement(By.name("uid")).sendKeys("Driver 1"); } @Test public void executeSessionTwo(){ //Second session of WebDriver System.setProperty("webdriver.chrome.driver","chromedriver.exe"); WebDriver driver = new ChromeDriver(); //Goto guru99 site driver.get("http://demo.guru99.com/V4/"); //find user name text box and fill it driver.findElement(By.name("uid")).sendKeys("Driver 2"); } @Test public void executSessionThree(){ //Third session of WebDriver System.setProperty("webdriver.chrome.driver","chromedriver.exe"); WebDriver driver = new ChromeDriver(); //Goto guru99 site driver.get("http://demo.guru99.com/V4/"); //find user name text box and fill it driver.findElement(By.name("uid")).sendKeys("Driver 3"); } }
TestNG.XML
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> <suite name="TestSuite" thread-count="3" parallel="methods" > <test name="testGuru"> <classes> <class name="TestGuru99MultipleSession"> </class> </classes> </test> </suite>
You can set order and dependency of Test Case execution.
Suppose you have two test cases , 'testGuru99TC1' and 'testGuru99TC2' and you want to execute test case 'testGuru99TC2' before 'testGuru99TC1'. In that case we will use 'dependsOnMethods' attribute to make dependency and order of execution.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> <suite name="TestSuite" thread-count="3" parallel="methods" > <test name="testGuru"> <classes> <class name="TestGuru99MultipleSession"> <include value="testGuru99TC1" dependsOnMethods=" testGuru99TC2"/> <include value="testGuru99TC2"/> </class> </classes> </test> </suite>
There are two main listeners.
In this tutorial, we will discuss on Testng Listeners. Here is what you will learn-
Listener is defined as interface that modifes the default TestNG's behavior. As the name suggests Listeners "listen" to the event defined in the selenium script and behave accordingly. It is used in selenium by implementing Listeners Interface. It allows customizing TestNG reports or logs. There are many types of TestNG listeners available.
There are many types of listeners which allows you to change the TestNG's behavior.
Below are the few TestNG listeners:
Above Interface are called TestNG Listeners. These interfaces are used in selenium to generate logs or customize the Testing reports.
In this tutorial, we will implement the ITestListener.
ITestListener has following methods
In this test scenario, we will automate Login process and implement the 'ItestListener'.
For the above test scenario, we will implement Listener.
Step 1) Create class "Listener_Demo" and implements 'ITestListener '. Move the mouse over redline text, and Eclipse will suggest you 2 quick fixes as shown in below screen:
Just click on "Add unimplemented methods". Multiple unimplemented methods (without a body) is added to the code. Check below-
package Listener_Demo; import org.testng.ITestContext ; import org.testng.ITestListener ; import org.testng.ITestResult ; public class ListenerTest implements ITestListener { @Override public void onFinish(ITestContext arg0) { // TODO Auto-generated method stub } @Override public void onStart(ITestContext arg0) { // TODO Auto-generated method stub } @Override public void onTestFailedButWithinSuccessPercentage(ITestResult arg0) { // TODO Auto-generated method stub } @Override public void onTestFailure(ITestResult arg0) { // TODO Auto-generated method stub } @Override public void onTestSkipped(ITestResult arg0) { // TODO Auto-generated method stub } @Override public void onTestStart(ITestResult arg0) { // TODO Auto-generated method stub } @Override public void onTestSuccess(ITestResult arg0) { // TODO Auto-generated method stub } }
Let's modify the 'ListenerTest' class. In particular, we will modify following methods-
onTestFailure, onTestSkipped, onTestStart, onTestSuccess, etc.
The modification is simple. We just print the name of the Test.
Logs are created in the console. It is easy for the user to understand which test is a pass, fail, and skip status.
After modification, the code looks like-
package Listener_Demo; import org.testng.ITestContext; import org.testng.ITestListener; import org.testng.ITestResult; public class ListenerTest implements ITestListener { @Override public void onFinish(ITestContext Result) { } @Override public void onStart(ITestContext Result) { } @Override public void onTestFailedButWithinSuccessPercentage(ITestResult Result) { } // When Test case get failed, this method is called. @Override public void onTestFailure(ITestResult Result) { System.out.println("The name of the testcase failed is :"+Result.getName()); } // When Test case get Skipped, this method is called. @Override public void onTestSkipped(ITestResult Result) { System.out.println("The name of the testcase Skipped is :"+Result.getName()); } // When Test case get Started, this method is called. @Override public void onTestStart(ITestResult Result) { System.out.println(Result.getName()+" test case started"); } // When Test case get passed, this method is called. @Override public void onTestSuccess(ITestResult Result) { System.out.println("The name of the testcase passed is :"+Result.getName()); } }
Step 2) Create another class "TestCases" for the login process automation. Selenium will execute this 'TestCases' to login automatically.
package Listener_Demo; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.Assert; import org.testng.annotations.Listeners; Import org.testng.annotations.Test; public class TestCases { WebDriver driver= new FirefoxDriver(); // Test to pass as to verify listeners . @Test public void Login() { driver.get("http://demo.guru99.com/V4/"); driver.findElement(By.name("uid")).sendKeys("mngr34926"); driver.findElement(By.name("password")).sendKeys("amUpenu"); driver.findElement(By.name("btnLogin")).click(); } // Forcefully failed this test as to verify listener. @Test public void TestToFail() { System.out.println("This method to test fail"); Assert.assertTrue(false); } }
Step 3) Next, implement this listener in our regular project class i.e. "TestCases". There are two different ways to connect to the class and interface.
The first way is to use Listeners annotation (@Listeners) as shown below:
@Listeners(Listener_Demo.ListenerTest.class)
We use this in the class "TestCases" as shown below.
So Finally the class " TestCases " looks like after using Listener annotation:
package Listener_Demo; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.Assert; import org.testng.annotations.Listeners; import org.testng.annotations.Test; @Listeners(Listener_Demo.ListenerTest.class) public class TestCases { WebDriver driver= new FirefoxDriver(); //Test to pass as to verify listeners. @Test public void Login() { driver.get("http://demo.guru99.com/V4/"); driver.findElement(By.name("uid")).sendKeys("mngr34926"); driver.findElement(By.name("password")).sendKeys("amUpenu"); driver.findElement(By.id("")).click(); } //Forcefully failed this test as verify listener. @Test public void TestToFail() { System.out.println("This method to test fail"); Assert.assertTrue(false); } }
The project structure looks like:
Step 4): Execute the "TestCases " class. Methods in class "ListenerTest " are called automatically according to the behavior of methods annotated as @Test.
Step 5): Verify the Output that logs displays at the console.
Output of the 'TestCases' will look like this:
[TestNG] Running: C:\Users\gauravn\AppData\Local\Temp\testng-eclipse--1058076918\testng-customsuite.xml Login Test Case started The name of the testcase passed is:Login TestToFail test case started This method to test fail The name of the testcase failed is:TestToFail PASSED: Login FAILED: TestToFail java.lang.AssertionError: expected [true] but found [false]
If project has multiple classes adding Listeners to each one of them could be cumbersome and error prone.
In such cases, we can create a testng.xml and add listeners tag in XML.
This listener is implemented throughout the test suite irrespective of the number of classes you have. When you run this XML file, listeners will work on all classes mentioned. You can also declare any number of listener class.
Summary:
Listeners are required to generate logs or customize TestNG reports in Selenium Webdriver.
In this tutorial, you will learn-
Prepare the Project
Step 1) In Eclipse, Create Java project by clicking on new Java Project
Step 2) In this step,
When you click on finish button. The "TestProject" java project is created. The "TestProject" will look like this.
Step 3) Open that newly created project. You will able to see the "src" folder in Package Explorer.
Step 4) In this step,
After clicking on "finish" the project structure will look like this:
Step 5) In this step,
A new window will open.
Step 6) In this step,
Here, you are creating two classes ex: DemoA, DemoB.
First Create Class DemoA.
When you click on "Finish" Button. Then it will going to create class like this:
Similarly, create class DemoB, When you click on "Finish" Button class will look like below-
Step 7) If you have installed TestNG library just click on Java Project--->Properties.
Step 8) Now in properties window,
Next
Then Click on "finish" button.
After this, write the following code.
For Class DemoA
Code Explanation:
This line will going to maximize the Browser window.
This line will enter the specified URL in the URL field.
This line will going to identify the "Google" search box and enter the data you sent using sendKeys method.
Output: The above program contains the errors, so it is not possible to execute.
Similarly for Class DemoB,
The red color underlined words are the errors here. Because you have not yet added the jar file that contains these classes and interfaces. In order to remove the errors present in the above code add the corresponding jar file. Right click on the Java Project and Select "Properties".
Step 8) In the property window,
After this step, all the errors will be removed automatically. If not then place the mouse over the code which is showing errors and import all necessary classes and interfaces.
For @test if it is still showing errors then place the mouse over there. It will show the possible options. Then click on add TestNG Library option. Similarly do it for other 'class' also.
After writing your code inside both the classes i.e. DemoA, DemoB go to the next step.
Step 9) In this step,
(Testng and Selenium-server-standalone jar file need to be downloaded from web and store it inside your system. You need to manually go to that folder and copy these two jars and right click on 'lib' folder present in eclipse and click on paste)
Step 10) In this step,
1. Select the parent folder
2. Give the Folder name as 'lib' and (The primary purpose of adding these two jar files in the lib folder is that, while executing from the command prompt you can tell the compiler that the required jar files for the execution of the program are present in this location. If you want to execute testng.xml from eclipse then this lib folder is not at all required)
3. Click on 'finish' button
Testng and Selenium-server-standalone jar file need to be downloaded from web and store it inside your system. You need to manually go to that folder and copy these two jars and right click on 'lib' folder present in eclipse and click on paste
After creating a folder, next step will be converting our programs that are DemoA and DemoB into Testng.xml file.
Step 1) In this step,
Step 2) A new window will open. In this window, enter details like
Then the testng.xml file created under the java project, and it will look like this.
(if you want to run that testng.xml file then Right click on that testng.xml file present on the left navigation pane in Package Explorer and click on run as TestNG Suite. )
Step 3) The testng.xml suite file will look like this:
If you want to execute DemoA class first, then remove that complete line and add it before DemoB class like this:
Step 4) After executing the testng.xml file, it will display the result in the following manner. (Since you have not written any executable statements using System.out.println() so it is not printing anything on the console window).
This is one of the ways you will execute test through the eclipse, if you want to execute the same testng.xml suite file that contains two class file such as DemoA, DemoB from the command prompt you need to follow the below steps.
Now open the command prompt and go to the Project workspace.
You need to find the location of the Project Space
Step 1) First right click on the Java Project and Select the properties option. In properties window select option resource.
Step 2) Now when you click on "resource" link, present in the left navigation pane. It will show where exactly the project is stored
The project workspace is C:\Users\User\Desktop\Guru99\TestProject. So you are changing directory to that particular location.
Step 3) Then type the following command. (This command is generic command)
java –cp "path of lib folder present in workspace\*; path of bin folder present in project workspace; path of testng.jar file present in lib folder of project workspace" org.testng.TestNG testng.xml
but for our project you need to write the following command.
Java –cp "C:\Users\User\Desktop\Guru99\TestProject\lib\*; C:\Users\User\Desktop\Guru99\TestProject\bin" org.testng.TestNG testng.xml
Step 4) Then press the Enter. Both the classes DemoA and DemoB will start their execution. Finally, it will display the result on the command prompt.
If you want to execute only failed test cases through the Eclipse, then first refresh the project.
Step 1) Right click on the java project (Demo A and B). Select the refresh option or simply select the java project and press F5.
Step 2) Then you will able to see the test-output folder. In that folder, you have a file with name testng-failed.xml.
Step 3) Right-click on this file and click on run as and select the option called "testNG suite".
Suppose if you have three test cases if all the test cases are executed successfully means you are not able to see this folder under the test-output folder. This folder will appear only when one of the test case is failed. Then run this file, it will going to run only failed test cases.
Step 1) To run failed test cases in command prompt. Open the command prompt and go to the Project workspace.
My project workspace is C:\Users\User\Desktop\Guru99\TestProject. So you will be changing directory to that particular location.
Step 2) Type the following command. (This command is generic command)
java –cp "path of lib folder present in workspace\*; path of bin folder present in project workspace; path of testing.jar file present in lib folder of project workspace" org.testng.TestNG test-output/testng-failed.xml
For our project, you need to write the following command.
Java –cp "C:\Users\User\Desktop\Guru99\TestProject\lib\*; C:\Users\User\Desktop\Guru99\TestProject\bin" org.testng.TestNG test-output/testng-failed.xml
Step 3) Then press the Enter. It will going to run only failed classes and display corresponds to that class only.
In the above class i.e. DemoB just change the code like this.
driver.findElement(By.name("a")).sendKeys("Bye");
The above code will not going to find any element. So, it will throw the exception. But in our program, you are not handling the exception so our program will stop executing the remaining code. Because of this reason, the ClassB will going to fail.
Summary:
This article is contributed by Sandeep Batageri
Report generation is very important when you are doing the Automation Testing as well as for Manual Testing.
Selenium web driver is used for automating the web-application, but it won't generate any reports.
In this tutorial, you will learn-
The output report of testng will look like below if both the classes are passed:
Consider the scenario in where you are intentionally failing the test case i.e. DemoB class. Then convert both the classes into testng.xml suite file and run it. Then the result will look like this. It will show the failed test cases.
This is result for DemoB class:
Similarly, result for the Class DemoA will look like this:
The result will look like this:
Along with these report generated methods, you can use object.properties file to store the system generated logs as well as user generated logs. But one of the simplest ways to store log information in testing is using Reporter Class.
Reporter is a class present in TestNG. It provides 4 different methods to store log information they are:
Example:
Create Two classes such as DemoA and DemoB and write the following code inside the classes.
For Class DemoA;
For Class DemoB:
Similarly, you will have an Output for Demo B project as well.
2. In test-output folder open the index.html. It will look like:
Click on reporter output. It will open logging info whatever written in the test methods.
Click on the Times. It will going to show how much time it took to run the test method present in class.