H2Kinfosys Online Training Videos | IT Online Training Videos



Software Quality Assurance (QA) TrainingSELENIUM WEB AUTOMATION TESTING TOOLSELENIUM WEB-DRIVERTable of Contents:Selenium IntroductionSelenium Setup (WebDriver/RC/IDE): Selenium 2.0 WebDriver IntroductionArchitecture of Selenium WebDriverXPath for SeleniumCreate first Selenium WebDriver program in EclipseCross browser testing using Selenium WebDriverFirebug and Firepath SetupX-Path/CSS SelectorData Driven Test using Selenium WebDriverSelenium WebDriver ScriptsFrameworks with SeleniumSelenium Data Driven FrameworkSelenium Hybrid FrameworkFile Handling, Log4j, /Handling XLS,XML filesReading/Writing Text Files, and Properties File in JavaLog4j API for Logging and usage of Log4J in SeleniumReading data from XLS/XML files using Selenium WebDriver/JavaSubversion (SVN) SetupApache Maven SetupSelenium Project WorkRevision HistoryVer #DescriptionDateNotes13Added “Apache Maven for Selenium”7/24/1614Managing Links using Selenium WebDriver 9/1/1615Extracting all the dynamic links (total/size) on the page and print them9/6/1616Extracting dynamic links from specific area, click the link and get the page title and print them.9/8/1617How to debug a Selenium WebDriver script in Eclipse18How to handle dropdown list in Selenium with Select Class20Minor font / grammar changes21Support for Firefox is via Mozilla's geckodriver.Finding xPaths/CssSelectors in different browsers22Finding xPaths/CssSelectors in different browsers.23Selenium WebDriver with Data Driven script in Framework Structure.24Selenium WebDriver with Data Driven script using Excel with multiple rows of data4/14/17Selenium IntroductionWhat is Selenium:Selenium () is an open source (free) automation tool for web based applications and Selenium automates browsers. It work on following browsers: Mozilla Firefox, IE6+, Google Chrome, Opera8+ and Safari. And it works on multiple operating systems (OS): Windows, Mac, Linux/Unix and Many more…We can write selenium code in different programming languages: Java, C#, Ruby, Perl, Python, and PHP. Your web application can be developed in .NET but you can still develop selenium scripts using other than .NET which is Java/Perl/PHP. Selenium Components:Selenium IDE – Selenium 1.0 (RC) – Selenium 3.0/2.0 (WebDriver) – Selenium GridSelenium IDE: Integrated Development Environment; Record and Run tool with UI. Works only on Firefox browser. Cannot write any program logic like Loops, If/Else etc. Programming language is HTML + JavaScript.Selenium 1.0 RC: Old version of Selenium. Supports multiple browsers/languages. RC (Remote Control) has some limitations ie, we need to start/stop the selenium server.Selenium 3.0/2.0 WebDriver: New version of Selenium and it’s an enhanced ver of RC. Supports multiple browsers/languages. Architecture of WD is completely different from RC. In WD, we NO need to start the selenium server (like in RC), supports Android and iOS automation, it has listeners and Object extraction in Bulk. Selenium Grid: Runs parallel test cases on multiple machines and browsers. Assume, you have 100 test cases and need to test them against multiple browsers like IE, FF, Chrome and Safari. If it takes 8 hours to run all 100 tc’s against one browser, over all it will take 32 hrs (8x4) to cover all 4 browsers. Grid will help you to run all 100 test cases against all 4 browser parallel/at a time that way it will save time ie overall execution against all 4 browsers will be done in 8 hrs instead of 32 hrs. OR you can run 100 tc’s against 4 different machines: 1-50 on machine1, 51-100 on machine2 so that execution will take lesser time.Framework Architecture:Selenium Script 1, XLS File (TestData) Selenium Script 2, ---- Junit/TestNG -----> HTML Test ReportsSelenium Script N LoggingSelenium 3.0 / WebDriverThe biggest change in Selenium recently has been the inclusion of the WebDriver API. Driving a browser natively as a user would either locally or on a remote machine using the Selenium Server it marks a leap forward in terms of browser automation.Selenium WebDriver fits in the same role as RC did, and has incorporated the original 1.x bindings. It refers to both the language bindings and the implementations of the individual browser controlling code. This is commonly referred to as just "WebDriver" or sometimes as Selenium 2.0.Selenium 1.0 + WebDriver = Selenium 2.0. Dynamic testing (links/images/content changes in web sites) is possible in WebDriver.WebDriver is designed in a simpler and more concise programming interface along with addressing some limitations in the Selenium-RC API.WebDriver is a compact Object Oriented API when compared to Selenium1.0It drives the browser much more effectively and overcomes the limitations of Selenium 1.x which affected our functional test coverage, like the file upload or download, pop-ups and dialogs barrier.WebDriver overcomes the limitation of Selenium RC's Single Host origin policy.Single Host origin policy/ Same-origin policy:The same-origin policy is an important concept in the web application security model. Under the policy, a web browser permits scripts contained in a first web page to access data in a second web page, but only if both web pages have the same origin. An origin is defined as a combination of URI scheme, hostname, and port number. This policy prevents a malicious script on one page from obtaining access to sensitive data on another web page through that page's Document Object Model (DOM).Architecture of Selenium WebDriverGo to Javadoc /API Docs against Java in "Selenium Client & WebDriver Language Bindings" table.Java Doc / API Docs: This is nothing but Documentation of WebDriver. Each and every java class is defined inside the WebDriver. WebDriver is an Interface in Java.Click WebDriver link on left navigation bar: will see different Implementing Classes under "Interface WebDriver" like below: ChromeDriver, EdgeDriver, EventFiringWebDriver, FirefoxDriver, InternetExplorerDriver, MarionetteDriver, OperaDriver, RemoteWebDriver, SafariDriver.Look for Method Summary table:You will see close(), findElement(By by) etc...some of all of these will be used in Selenium WebDriver scripts.Selenium Setup: Selenium WebDriver Setup:Full setup need: Java, Eclipse, Selenium Server 3.0/WebDriver, Selenium Java Client, TestNGJAVA setup on Windows/Mac: Install Java/JDK SE Development Kit 8u191Accept license agreementDownload: Windows x64207.22 MB jdk-8u191-windows-x64.exeCopy the downloaded .zip file to relevant location (ex: C:/Selenium) and unzip it.Now setup environment variable with java/jdk paths: Setup the following environment variables in Syste and User variables> User variables:JAVA_HOMEC:\Program Files\Java\jdk1.8.0_191System variablesPathC:\Program Files\Java\jdk1.8.0_191\binRun the following commands on command prompt verify whether java/jdk setup done correctly: (you should not see any errors)java -versionjavac -versionEclipse setup on Windows OS:Install Eclipse: IDE for Java EE Developers 212 MB: Eclipse is an editor to develop java programs. Eclipse is the replacement for notepad or textpad.Check your laptop version (ex: Win7/8/10 32-bit or 64-bit by going to start—computer—right click properties)32-bit: : eclipse folder (right click on .zip folder, extract here), open the extracted folder, go to eclipse folder, and double click eclipse.exe or right click on eclipse.exe-> create shortcut-> move it to task bar on the bottom of the desktop.Now double click on eclipse from task bar.Note/Error: If you see error message "Java was started but returned exit code=13" then uninstall 64 bit eclipse and install 32 bit ver of eclipse OR following this video to fix this issue: Windows 10, though it is 64 bit, please install 32 bit if you have an issue with 64 bitEclipse setup on Mac OS:Go to this link Eclipse IDE for Java EE DevelopersFollow below video to setup Eclipse on Mac OS. WebDriver Setup:Download all required jar files for SeleniumGo to OR Selenium Server: Selenium Standalone Server - Download version?2.53.0 or or latest version ()Download Selenium Java client: Java 2.53.0 2016-03-15Note: You need to download Java client since you are going to write java code within Selenium. (Unzip the folder. You can find all jar file under: ex: selenium-2.53.0\libs)TestNG Setup:Configure with TestNG (TestNG will be configured per eclipse but not per project). Follow below steps to setup TestNG:NEW: (just use this)Open Eclipse-> Help -> Eclipse Marketplace -> Search for TestNG (in Find textbox enter TestNG and hit enter key)… you should see like below with icon Install: click on Install iconOLD:Open Eclipse-> Help -> Install New Software -> Enter TestNG URL (see below) ex: OR OR in “Work with:” , click Add and enter Name as , Location as click OK, and select the checkbox TestNG -> Next -> Next -> I Accept checkbox -> Finish.For more details, please refer: eclipse 3.4 or later ver, and above enter: eclipse 3.3, and above enter: to verify whether TestNG installed successfully in eclipse?Eclipse -> Window -> Show View -> Other..-> Java -> You must see TestNG (that means TestNG installed successfully in eclipse as a plug-in)TestNG will control the test cases. Create first Selenium WebDriver program in Eclipse:Crete new workspace and java project for WebDriver in Eclipse:Pre-requisites:Open Eclipse, and Create new Workspace “WebDriverWS”Create new Java Project with name: “WebDriverForSelenium” and click FinishConfigure with selenium jar files: Right click java project -> Properties -> Java Build Path -> Add External Jars button and add all .jar files for Selenium server (ex: selenium-server-standalone-2.49.1.jar) and Selenium Java Client (selenium-java-2.49.1.jar and all other .jars from selenium-2.49.1\libs).Click Finish.Automate 1st test case using Selenium WebDriver / Java:// Test Case: Verify user able to launch web site (ex: ) in a browser (ex: Chrome), get the title of the page (: Online Shopping ….) and close the browser. // Test Steps: 1. Open chrome Browser, 2. Enter the URL ,3. Get the title of the page 4. Close the browser.// Expected Results:1. Chrome browser should be opened2. web site should be opened3. Title of the page should be “: Online Shopping ….”3. Browser should be closed Now, create our first Selenium WebDriver script:Expand WebDriverForSelenium ->srcRight click on src -> New -> ClassName=TestAppCM and select the checkbox public static void…Click FinishPrepare the script like below://Chrome: (please remember / by heart / muck up)import org.openqa.selenium.WebDriver;import org.openqa.selenium.chrome.ChromeDriver;public class TestAppCM {public static void main(String[] args) {// Chrome ** - you need to download the chromedriver.exe ()// Download chromedriver_win32.zip for windows and unzip for .exeSystem.setProperty("webdriver.chrome.driver","C:\\Selenium\\0317\\SeleniumRC-WD\\ChromeDriver\\chromedriver.exe"); //location of the browser driverWebDriver cd = new ChromeDriver(); // Selenium will launch chrome browsercd.get(""); // this will launch in chrome browserSystem.out.println(cd.getTitle()); // this will print title of home page.cd.quit(); // this will close all opened windows within the chrome browser.}}//Run the script now: Right click on TestAppCM->Run As-> Java Application// Cntrl+Shift+O// Note: For Mac, .exe is not needed (ex: System.setProperty("webdriver.chrome.driver","C:\\Selenium\\0317\\SeleniumRC-WD\\ChromeDriver\\chromedriver");Firefox:Geckodriver for Firefox When you are using Selenium WebDriver, you have to download geckodriver to run your test on firefox browser (This was not required few months ago). Just like the other drivers(chromedriver/iedriver) available to Selenium, Mozilla Firefox has released geckodriver executable that will run alongside the firefox browser. Firefox version 48 & above will use geckodriver.?If you want to work with Firefox, you have to set the property now.? You can download geckodriver from Github and then you can extract and you will get .exe file.? HYPERLINK "" \t "_blank" windows 64-bit: geckodriver-v0.16.1-win64.zipFor windows 32-bit: geckodriver-v0.16.1-win32.zipFor Mac: geckodriver-v0.24.0-macos.tar.gzYou can place it on C:\\ and use as below -?Create a new class “TestAppFF” with public static like below://Firefox:import org.openqa.selenium.WebDriver;import org.openqa.selenium.firefox.FirefoxDriver;public class TestAppFF {public static void main(String[] args) throws InterruptedException {System.setProperty("webdriver.gecko.driver","C:\\Selenium\\0718\\SeleniumWD\\geckodriver.exe");WebDriver fd = new FirefoxDriver(); fd.get(""); System.out.println(fd.getTitle());Thread.sleep(5000);fd.quit();}}//Run the script now: Right click on TestAppFF->Run As-> Java ApplicationNote: If you see an error like this: Exception in thread "main" org.openqa.selenium.WebDriverException: Cannot find firefox binary in PATH. Make sure firefox is installed. OS appears to be: WIN10Solution/Fix is:Uninstall and Reinstall firefox OR setup the firefox home directory in system environment variable in Path.Find the location of firefox.exe and put that in System variables (Run-> search for Environment Variable and open it -> You will see Environment Variables dialog box. Look for System Variable table -> Path -> Edit and add the location of firefox.exe (ex: C:\Users\rsatraboina\AppData\Local\Mozilla Firefox but by default firefox should be located under C:\Program Files\Mozilla Firefox).Close and reopen Eclipse and then run the test again.----------//IE:// Note: You may see an error while running this script against IE, it all depends on how your browser setting enabled. Please try this: Go to IE-> Internet Options -> Security -> Enable checkbox for “Enable protected mode…” for all the zones (Internet, Local Intranet, Trusted Site, and Restricted Sites). Finally, set Zoom level to 100% by right clicking on the gear located at the top right corner and enabling the status-bar. Default zoom level is now displayed at the lower right.Note: Make sure, IE browser zoom is 100% (should not be more or less)Note: If you use Win10 or later, the browser will be Edge (not IE)//IEimport org.openqa.selenium.WebDriver;import org.openqa.selenium.ie.InternetExplorerDriver;public class TestAppIE {public static void main(String[] args) throws InterruptedException {// IE - you need to download the IEDriverServer.exe ( HYPERLINK "" - (32 bit Windows IE or 64 bit Windows IE))System.setProperty("webdriver.ie.driver","C:\\Selenium\\0317\\SeleniumRC-WD\\IEDriver\\IEDriverServer.exe");WebDriver id = new InternetExplorerDriver();id.get("");System.out.println(id.getTitle());Thread.sleep(5000); // this will wait for 5 seconds before it closes the browserid.quit();}}Note: Follow below steps/code if you have Win10/Edge browser:Microsoft edge driver download link download, we need to check the build numberOpen the edge browserGo to?Start?>?Settings?>?System?>?About?and locate the number next to Microsoft EdgeHTML on the screen. This is your build number. Having the correct version of WebDriver for your build ensures it runs correctly. Below are the screenshots. Download the Webdriver of similar version. I downloaded Release 17134 and is working. Below is the code.import org.openqa.selenium.WebDriver;import org.openqa.selenium.edge.EdgeDriver;public class TestAppIE {public static void main(String[] args) throws InterruptedException {// IE - you need to download the IEDriverServer.exe ( - (32 bit Windows IE or 64 bit Windows IE))System.setProperty("webdriver.edge.driver","C:\\Selenium\\USTSV\\0917\\WebDriver\\MicrosoftWebDriver.exe");WebDriver id = new EdgeDriver();id.get("");System.out.println(id.getTitle());Thread.sleep(5000); // this will wait for 5 seconds before it closes the browserid.quit();---------------------------------------------------------------------------------------------How to debug a Selenium WebDriver script in EclipseDebug is nothing but step by step execution of your program/script. Double click in beginning (front) of any of the line (8th line (ex: driver.get) out of 30 lines) in the script. You will see small blue icon (*) immediately in the beginning of the line. Then run the script in a debug mode by clicking Debug (* symbol) button next to run button OR right click on script -> Debug As->Java Application. Script will run until 8th line (where the small blue point is there) and stop and then you will get small dialog box with Yes and No buttons. Click Yes. You will see Variables tab. Now press F6 on the keyboard (for some keyboards, you have to press Fn + F6) OR click Step Over button (next to stop run) then rest of the script will be executed line by line. Observe the values in Variables tab or position the cursor on the highlighted line so that you will see the values. To exit Debug mode, click Java button on top right corner of Eclipse to go back to normal review. How to enable line numbers in eclipse:Go to Windows → Preferences → General → Editors ->Text Editors → select checkbox for “Show line numbers”. Click OK, then Apply changes. Then it will show the line count automatically. one of the easy way is using shortcuts like : Ctrl+F10, then press n "it show line number and hide line numbers.Import Javadoc into Eclipse Project for Selenium:Purpose: By position the cursor on any command (ex: driver, WebDriver, System.setProperty etc..) in Selenium script, it will show more details about command.Steps:Go to Javadoc against Java under “Selenium Client & WebDriver Language Bindings”You should see above link except index.html ie Eclipse, right click Project (ex: WebDriverForSelenium) -> Properties Select Java Build Path -> LibrariesExpand selenium server jar (ex: selenium-server-standalone-3.0.1.jar) -> Select Javadoc locationClick Edit and enter Validate -> OK -> Apply -> OKClose and reopen EclipseNow position the cursor on WebDriver command in Selenium scriptYou will see the documentation or more info about that specific command. HTML/CSS/XPath for Selenium ****On any web site, there are various objects like text box, image, button, link etc… having unique id or unique path (ex: SSN, Car Number plate etc)… the unique id or unique path is known as XPath. XPath offers html code with ID or Name or Value etc.. It’s always a good practice to use id instead of others. In future, though the SignIn button changed to Login, still your script will work and also, though the button changed to Chinese/Russian language still your script will work since ID never changes in code. In order to find xpath/address for an element/object, you can right click on any field (ex: username / password) -> inspect element (you will see html code in blue color)-> right click -> copy -> xpath or CSS selector or selector. For xpath you will see like this //*[@id="twotabsearchtextbox"] and for CSS selector or selector you will see like this: #twotabsearchtextboxInspecting elements in Chrome, Firefox and IE:Chrome: Right click on the field (ex: Google Search button) -> Inspect. You will see html code highlighted in gray color under Elements tab, right click on gray area and select Copy -> Copy Xpath and past it, you should see like this: //*[@id="lst-ib"]Firefox: In Firefox, right click on any field (ex: username / password) -> inspect element (you will see html code in blue color)-> right click -> copy -> xpath or CSS selector or selector. For xpath you will see like this //*[@id="twotabsearchtextbox"] and for CSS selector or selector you will see like this: #twotabsearchtextboxIE: Go to Settings -> F12 Developer Tools -> Dom Explorer -> Select Element -> Click on the object (text box or button or link etc) - OPTIONALNote: Please use Chrome browser to identify xpath or css selector---------------------------------------------------------------------------------------------Let’s create a new class (IdentifyingObjectsGmailFF.java) under the project WebDriverForSelenium and develop below code by using ID from outerHTML://Test Case: Verify will be opened in Firefox browser, clear the value in text box and enter qa@ and clear the email id from the text box and then click Next (SignIn) button.import org.openqa.selenium.WebDriver;import org.openqa.selenium.By;import org.openqa.selenium.WebElement;import org.openqa.selenium.firefox.FirefoxDriver;public class IdentifyingObjectsGmailFF {public static void main(String[] args) throws InterruptedException {System.setProperty("webdriver.gecko.driver","C:\\Selenium\\USTSV\\1207\\SeleniumWebDriver\\geckodriver.exe");WebDriver driver = new FirefoxDriver(); //driver.manage().window().maximize(); // this will maximize the windowdriver.get("");System.out.println(" opened");// Below are all new selenium web driver commandsWebElement emailField =driver.findElement(By.id("identifierId"));//this will identify the email text boxemailField.clear(); // this will clear the default value in the email id text box.System.out.println("Email field cleared");emailField.sendKeys("qa@"); // This will type value in a emailField text boxSystem.out.println("qa@ entered into email field");Thread.sleep(3000);emailField.clear();System.out.println("Email field cleared");WebElement nextButton = driver.findElement(By.id("identifierNext"));nextButton.click();Thread.sleep(3000);System.out.println("Next button clicked");driver.quit();System.out.println("Browser closed");}}// Run it now…. will be opened in Firefox and enter qa@ and clear the email id from the text box and then click Next (SignIn) button.Assignment:If you want to run the above script against Chrome browser, please modify the code like below: Copy/Past IdentifyingObjectsGmailFF.java as IdentifyingObjectsGmailChrome.javaimport org.openqa.selenium.By;import org.openqa.selenium.WebDriver;import org.openqa.selenium.WebElement;import org.openqa.selenium.chrome.ChromeDriver;public class IdentifyingObjectsGmailChrome {public static void main(String[] args) {System.setProperty("webdriver.chrome.driver", "C:\\QA\\AutomationTest\\SeleniumAdvanced\\chromedriver.exe");WebDriver driver = new ChromeDriver();driver.manage().window().maximize();driver.get("");WebElement emailField = driver.findElement(By.id("Email"));emailField.sendKeys("qa@"); // sendKeys will type value in //text boxemailField.clear();WebElement button = driver.findElement(By.name("signIn"));button.click();}}Note: You can find more details about every Selenium command (ex: sendKeys, WebElement etc) at: : Properties (ID/Name/Value etc..) of an object (Username/Password) doesn’t change for FF or IE or Chrome etc.. That means, the script created against one browser (ex: FF) can work against other browser (ex: Chrome) too (by making few changes in the code i.e, System.setProperty, and some import statements)We’ll use x-path instead of name/value/type/class. ID never change. Though name/value changes, script will still work if you use ID or x-path with ID. Selenium always suggest to use ID/X-path for all the objects … so that we can run the script against different languages L10N (Russian, Chinese, Hindi etc..) as well.Now let’s update above gmail login code with xpath like below:import org.openqa.selenium.By;import org.openqa.selenium.WebDriver;import org.openqa.selenium.WebElement;import org.openqa.selenium.firefox.FirefoxDriver;public class IdentifyingObjectsGmailFF {public static void main(String[] args) {System.setProperty("webdriver.gecko.driver","C:\\Selenium\\0517\\SeleniumWD\\geckodriver.exe");WebDriver driver = new FirefoxDriver();driver.manage().window().maximize(); // this will maximize the windowdriver.get("");// HTML//WebElement emailField = driver.findElement(By.id("identifierId"));// XPathWebElement emailField = driver.findElement(By.xpath("//*[@id='identifierId']"));emailField.sendKeys("qa@"); // This will type value in a text box//emailField.clear();// HTML//WebElement nextButton = driver.findElement(By.id("identifierNext"));// XpathWebElement nextButton = driver.findElement(By.xpath("//*[@id='identifierNext']"));nextButton.click();driver.quit();}}Generating css selectors: In order to automate a web application one needs to first locate the web element and then perform the function on that element. Selenium WebDriver supports different element locators like Id, XPath, cssSelector, className, tagName, name, linkText and partialLinkText.During the execution of selenium script, cssSelector is little faster (.2 or .3 milliseconds) than XPath. How to capture cssSelector in Chrome: Open Chrome browser, access , position the cursor in email id field. Right click -> Inspect -> You should see html code in blue color on right page. Right click -> Copy -> Copy Selector. You should see css selector like this: #identifierIdHow to capture cssSelector in Firefox (Not supported): Open Firefox browser, open , Change XPath to CSS (next to Highlight button). Click Inspect element and then position cursor on Email or Phone text box. You should see “#identifierId”.Create a new class Gmail_Css_Selectors.java under WebDriverForSelenium and copy/past above script and modify xpath with cssSelector:import org.openqa.selenium.By;import org.openqa.selenium.WebDriver;import org.openqa.selenium.WebElement;import org.openqa.selenium.firefox.FirefoxDriver;public class IdentifyingObjectsGmailFF {public static void main(String[] args) throws InterruptedException {System.setProperty("webdriver.gecko.driver","C:\\Selenium\\1217\\SeleniumWebDriver\\geckodriver.exe");WebDriver driver = new FirefoxDriver();driver.manage().window().maximize(); // this will maximize the windowdriver.get("");System.out.println(" opened");// Below are all new selenium web driver commands// HTML//WebElement emailField =driver.findElement(By.id("identifierId"));//this will identify the email text box// XPath// WebElement emailField =driver.findElement(By.xpath("//*[@id='identifierId']"));// CSS Selector WebElement emailField =driver.findElement(By.cssSelector("#identifierId"));emailField.clear(); // this will clear the default value in the email id text box.System.out.println("Email field cleared");emailField.sendKeys("qa@"); // This will type value in a emailField text boxSystem.out.println("qa@ entered into email field");Thread.sleep(3000);emailField.clear();System.out.println("Email field cleared");// HTML// WebElement button = driver.findElement(By.id("identifierNext"));// Xpath// WebElement button = driver.findElement(By.xpath("//*[@id='identifierNext']"));// CSS Selector WebElement nextButton = driver.findElement(By.cssSelector("#identifierNext"));nextButton.click();Thread.sleep(3000);System.out.println("Next button clicked");driver.quit();System.out.println("Browser closed");}}Automate below test case using Selenium WebDriver/XPathTestcase: Verify user able to do search with keyword iPhone using xPathSteps: Launch Chrome Browser, enter , enter iphone in search text box, click Go/Search button and also, click amazon logo button on top left corner and close the browser.Create a new class (amazonSearch) with public static with below code: import org.openqa.selenium.By;import org.openqa.selenium.WebDriver;import org.openqa.selenium.WebElement;import org.openqa.selenium.chrome.ChromeDriver;public class amazonSearch {public static void main(String[] args) throws InterruptedException {System.setProperty("webdriver.chrome.driver", "C:\\Selenium\\0718\\SeleniumWD\\chromedriver.exe");WebDriver driver = new ChromeDriver();driver.manage().window().maximize();driver.get("");System.out.println("amazon web site launched");Thread.sleep(3000);// searchBox: //*[@id="twotabsearchtextbox"]WebElement searchBox = driver.findElement(By.xpath("//*[@id='twotabsearchtextbox']"));searchBox.sendKeys("iphone"); // sendKeys will type value in //text boxSystem.out.println("keyword iphone entered into the text box");Thread.sleep(3000);// goButton: //*[@id="nav-search"]/form/div[2]/div/inputWebElement goButton = driver.findElement(By.xpath("//*[@id='nav-search']"));goButton.click();System.out.println("GO button clicked");Thread.sleep(8000);// amzLogo: //*[@id="nav-logo"]/a[1]/span[1]WebElement logoButton = driver.findElement(By.xpath("//*[@id='nav-logo']"));logoButton.click();System.out.println("Amazon logo button clicked");Thread.sleep(5000);driver.quit();}}Assignment: Verify user able to do search with keyword iPhone using xPathHandling Dynamic objects/ids on the web page:By using xPath/cssSelector, though the content on the news link (The 4 Biggest Announcements Apple Is About to Make) changes, still Selenium WebDriver can able to click since we are not using the link name instead we are using ID of the link and it never change.Data Driven / Parameterize Test using Selenium WebDriver **A methodology used to test an application during test cycles using externally stored or internally auto generated data for testing the application.The test scripts are executed and verified based on the data values stored in one or more central data sources or databases. The data sources can range from CSV files, Tab delimited values, fixed column value data set files, Excel files, XML files, data pools, ODBC sources, DAO objects, ADO objects, etc. Data-driven testing is the establishment of several interacting test scripts together with their related data sets in a framework used for testing an application. In this framework, variables are used for both input values and output verification values: navigation through the program, reading of the data sources, and logging of test status and information are all coded in the test script. In some cases, the logic executed in the script is also dependent on the data values.Data-Pools: A data pool is a collection of related data records. A data pool supplies data values to the variables in a test script during test script playback.Data-driven testing usually puts a layer of abstraction between the data and the test script, eliminating literal values in the test script. Since the data is separated from the test script, you can: ?Modify test data without affecting the test script ?Add new test cases by modifying the data, not the test script ?Share the test data with many test scriptsSelenium WebDriver with Data Driven script using Excel with multiple rows of data (Very Important) **Create a java class SearchChrome_DD_Test with below code and find the required files (poi jar files and excel test data etc) under G-Drive: Software Quality Assurance (SQA) Training\SQA-202 Automation Testing (Selenium 3.0 WebDriver Tool)\SeleniumFiles - SearchText-DD-Test.zip. Unzip the file, copy/past SearchTextData.xls under src folder in Eclipse and upload all .jar files from poi-3.15 and also, poi-3.15\lib and ooxml-lib folders in eclipse -> java build path -> libraries -> add external jars.Try vs Catch in Java: Try?block. The?try?block contains set of statements where an exception can occur. A try?block is always followed by a?catch?block, which handles the exception that occurs in associated?try?block. A?try?block must be followed by?catch?blocks or finally block or both.//Test Case: Search for different keywords (QA, Selenium etc) in and check the title of page is correct or not and then close the browser using Data Driven Test.import java.io.FileInputStream;import java.io.IOException;import org.apache.poi.hssf.usermodel.HSSFRow;import org.apache.poi.hssf.usermodel.HSSFSheet;import org.apache.poi.hssf.usermodel.HSSFWorkbook;import org.openqa.selenium.By;import org.openqa.selenium.WebDriver;import org.openqa.selenium.WebElement;import org.openqa.selenium.chrome.ChromeDriver; public class SearchChrome_DD_Test{ public static void main (String args[]) throws InterruptedException { try { // Open the Excel file FileInputStream fis = new FileInputStream("C:\\Selenium\\0317\\WebDriverSelenium\\WebDriverSelenium\\src\\SearchTextData.xls"); // Access the required test data sheet HSSFWorkbook wb = new HSSFWorkbook(fis); HSSFSheet sheet = wb.getSheet("testdata"); // Loop through all rows in the sheet // Start at row 1 as row 0 is our header row for(int count = 1;count<=sheet.getLastRowNum();count++){ HSSFRow row = sheet.getRow(count);// this will print T1 from column 0 ie TestCase System.out.println("Running test case " + row.getCell(0).toString()); // Run the test for the current test data row runTest(row.getCell(1).toString(),row.getCell(2).toString()); // this will read data from column 1 and 2 ie SearchString and PageTitle columns } fis.close(); } catch (IOException e) { System.out.println("Test data file not found"); } }public static void runTest(String SearchString, String PageTitle) throws InterruptedException {//create new Chrome driver System.setProperty("webdriver.chrome.driver", "C:\\Selenium\\0317\\SeleniumRC-WD\\ChromeDriver\\chromedriver.exe"); WebDriver driver = new ChromeDriver(); driver.manage().window().maximize(); // Start a browser driver and navigate to Google driver.get(""); // Enter the search string and send it WebElement element = driver.findElement(By.name("q")); element.sendKeys(SearchString); // SearchString is the column name there in SearchTextData.xls so that every iteration it will read/type keywords (ex: QA, Java etc) element.submit(); // .submit(); is nothing but pressing Enter key from keyboard within search box instead of clicking “Google Search” button. Thread.sleep(4000); // Check the title of the page if (driver.getTitle().equals(PageTitle)) { System.out.println("Page title is " + PageTitle + ", as expected"); } else { System.out.println("Expected page title was " + PageTitle + ", but was " + driver.getTitle() + " instead"); } //Close the browser driver.quit();}}Note: If have an issues running data driven program in Eclipse with extension (xlsx) excel file, please downloaded latest POI file from Apache POI website and run it.Assignment#1: Develop DD search script for Assignment#2: Develop DD search script for Selenium WebDriver/Java/TestNG/CSV file with Data Driven script in Framework Structure(Very Important) **Test Cases: Verify user can able to purchase flight tickets successfully for 2 different people.Open the Mercury Tours web site () andLogin using mercury/mercuryBuy ticket based on the passengers list in csv-data-file and thenLogout and close the browser. Steps to Run:Download Selenium-WebDriver-TestNG-DD-Test.zip from G Drive: SQA-202 Automation Testing -> SeleniumFiles, unzip, copy/past all 6 java files and 1 csv.txt data file in Eclipse project (WebDriverForSelenium) under src folder.Note: Please add TestNG library if you see an error and also, change the chromedriver.exe path and also update the driver path.If you don’t see Add TestNG library upon positioning cursor on error command (like @Test or import statement) then reinstall TestNG. (2) Open file main_loginBuyTicketLogout_DD.java in eclipse project folder (3) Right click mouse in the text area of above open file and choose 'Run as TestNG' (4) That's it -- Browser will open and run the test for 2 times. You can add more passengers or delete or modify any passenger line in the csv data file and this script will run fine.Managing Buttons and Input Fields using Selenium WebDriver How do you manage input fields and buttons? If you go to text field for “Enter your email”, what all can you do? You can type in a text field, clear the value of a text field, you can read the value of a text field. These are the 3 main actions we do on a text field usually. For typing “sendkeys”, for clearing, “.clear”, but how to read the value of a text field?Test Case: Print the default value in text box, print the value that is typed in a text box and print the name of the button.Open Eclipse and create a new class YahooMail with public static….import org.openqa.selenium.By;import org.openqa.selenium.WebDriver;import org.openqa.selenium.chrome.ChromeDriver;import org.openqa.selenium.firefox.FirefoxDriver;public class YahooMail {public static void main(String[] args) {// type, clear, read//create new Chrome driverSystem.setProperty("webdriver.chrome.driver", "C:\\Selenium\\0817\\SeleniumWD\\chromedriver_win32\\chromedriver.exe");WebDriver driver = new ChromeDriver();driver.manage().window().maximize();driver.get("");String text1 = driver.findElement(By.id("login-username")).getAttribute("placeholder");System.out.println(text1); // this will print the default value in the text box (ex: Enter your email)driver.findElement(By.id("login-username")).sendKeys("abc@");String text2 = driver.findElement(By.id("login-username")).getAttribute("value");System.out.println(text2); // this will print the value entered in username text box (ex: abc@)String text3 = driver.findElement(By.id("login-signin")).getAttribute("value");System.out.println(text3); // this will print the name/value in the login/next button (ex: Next)driver.quit(); // close the browser}}Managing Links using Selenium WebDriver Test Case: Verify user able to click Politics link/tab/button.Steps: Launch Chrome, open , capture the URL of the politics link and click politics link and then close the browser.Open Eclipse and create a new class (CNN) with public static….import java.util.concurrent.TimeUnit;import org.openqa.selenium.By;import org.openqa.selenium.WebDriver;import org.openqa.selenium.chrome.ChromeDriver; public class CNN {public static void main(String[] args) throws InterruptedException {// For Chrome - comment below 3 lines and enable above line if you want to run thru FirefoxSystem.setProperty("webdriver.chrome.driver", "C:\\Selenium\\Nov2016\\SeleniumWebDriver\\chromedriver.exe");WebDriver driver = new ChromeDriver();driver.manage().window().maximize();driver.manage().timeouts().implicitlyWait(40000, TimeUnit.SECONDS); // It will wait 40 seconds if the element is not present for all the "driver" commands, so that you no need to specify "Thread.sleep(3000);" in multiple places (30 seconds).driver.get(""); // this will launch website// TC#1: check the url of politics linkString url=driver.findElement(By.xpath("//a[text()='Politics']")).getAttribute("href");System.out.println(url); //This will print the URL of Politics ()// TC#2: click politics linkdriver.findElement(By.xpath("//a[text()='Politics']")).click(); // This will click Politics link.System.out.println(driver.getTitle()); // Get the title of the pagedriver.quit(); // close the browser}}Extracting all the dynamic links (total/size) on the page and print them If you are on any web site (ex: ), you will see different links (ex: News, Sport etc). Below script will let you count the total links and print them.Test Case: Verify total number of links there in the web site and print them and also check whether link is valid/visible or not.Create a new class (All_Links) with public static void…import java.io.File;import java.io.IOException;import java.util.List;import java.util.concurrent.TimeUnit;import org.mons.io.FileUtils;import org.openqa.selenium.OutputType;import org.openqa.selenium.By;import org.openqa.selenium.WebDriver;import org.openqa.selenium.WebElement;import org.openqa.selenium.chrome.ChromeDriver;public class All_Links {public static void main(String[] args) throws IOException {System.setProperty("webdriver.chrome.driver", "C:\\Selenium\\0317\\SeleniumRC-WD\\ChromeDriver\\chromedriver.exe");WebDriver driver = new ChromeDriver();driver.manage().window().maximize();driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);driver.get("");List<WebElement> allLinks = driver.findElements(By.tagName("a")); // "a" (anchor tag) is common property between all the links in the web page (use inspect to check that). You will get all the links in the list.System.out.println("Total links -> "+ allLinks.size()); // this will print the total number of tags ex: 299 (as of Oct 30th 2017)//*******************************// Print 100th link (index starts from 0)WebElement link100 = allLinks.get(99);System.out.println(link100); // this will print the URL (ex:politics)System.out.println(link100.getText()); // this will print the name of the link (ex: Politics)System.out.println("--- Above is the 100th LINK------");//*******************************// Print all the links in the web pagefor(int i=0;i<allLinks.size();i++){System.out.println(allLinks.get(i).getText()+" ---- "+allLinks.get(i).isDisplayed()); //isDisplayed will check whether the element (ex: link) visible to the user or not.// Some of the links will come out to be blank due to hidden, no text for the link since it's an image etc.."?" means links are in other language. False will show, if web element is not visible.}driver.quit(); // close the browser}}NOTE: Cntl+Shift+O (not zero) will add all missing import statements in the script and /or remove unwanted import statements.Extracting dynamic links from specific area, click the link and get the title and print them.TestCase: Verify user able to click all the links from a specific area (ex: popular categories), get the title of the page and print them.Steps: Open browser, enter url, identify popular categories section, count the total links there in the section (ex:12), click every link, get the title of the page, print link (repeat this for all the links there in popular categories section)Create a new class (Extract_Clik_Links) with public static void…import java.util.List;import java.util.concurrent.TimeUnit;import org.openqa.selenium.By;import org.openqa.selenium.WebDriver;import org.openqa.selenium.WebElement;import org.openqa.selenium.chrome.ChromeDriver;public class Extract_Clik_Links {public static void main(String[] args) {System.setProperty("webdriver.chrome.driver", "C:\\Selenium\\0317\\SeleniumRC-WD\\ChromeDriver\\chromedriver.exe");WebDriver driver = new ChromeDriver();driver.manage().window().maximize();driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS); driver.get("");WebElement box=driver.findElement(By.xpath("//*[@id='popular_cat']")); // ("//*[@id='popular_cat']") is the x-path for main header (this contains other sub-links like Christmas & New Year)List<WebElement> links = box.findElements(By.tagName("a"));// this will check how many links are there within that box/sectionSystem.out.println("Total links-> "+links.size()); // ex: 14 linksfor (int i=0; i<links.size(); i++) {System.out.println("--------------------");System.out.println(links.get(i).getText());links.get(i).click();System.out.println(driver.getTitle());// driver.navigate.back();driver.get("");// this will take you to the home pagebox=driver.findElement(By.xpath("//*[@id='popular_cat']"));links = box.findElements(By.tagName("a"));}}}How to handle dropdown list in Selenium with “Select” Class//Test Case?: Count the total number of options there in the drop down list box, and select one. The output is: It will count the total options, and show True for the option which is selected and rest of the options will show with Null.Verify total options 52 in dd list box.Verify user able to select Books from dropdown list boximport java.util.List;import java.util.concurrent.TimeUnit;import org.openqa.selenium.By;import org.openqa.selenium.WebDriver;import org.openqa.selenium.WebElement;import org.openqa.selenium.chrome.ChromeDriver;import org.openqa.selenium.support.ui.Select;public class DropDownListAZ {public static void main(String[] args) {System.setProperty("webdriver.chrome.driver", "C:\\Selenium\\0918\\WebDriver\\chromedriver_win32\\chromedriver.exe");WebDriver driver = new ChromeDriver();driver.manage().window().maximize();driver.get("");driver.manage().timeouts().implicitlyWait(50, TimeUnit.SECONDS); WebElement dropList=driver.findElement(By.xpath("//*[@id='searchDropdownBox']"));//dropList.sendKeys("Books"); // select Books from listboxSelect dropdown = new Select(dropList); // select Books from listboxdropdown.selectByVisibleText("Books");List<WebElement> options = dropList.findElements(By.tagName("option")); // it will show all available list / items dropdown list boxSystem.out.println("Total options -> "+ options.size()); // this will give the total count of list items in the dropdown box (ex:51 as of 1/22/18).for (int i=0; i<options.size();i++){System.out.println(options.get(i).getText()+" -- "+options.get(i).getAttribute("selected")); // check every list item and print true for selected item and null all non-selected items}driver.quit();}}Batch Test using TestNG.xmlNow, run multiple tests together as batch using testng.xml sequentially and/or parallelly (on a single local host). NOTE:1) You don't need Selenium Grid, if you want to run the scripts either sequentially or parallelly on a local host2) You need Selenium Grid, only if you want to run the scripts on remote machine (either sequentially or parallelly) TestAppCM2.java:import org.openqa.selenium.WebDriver;import org.openqa.selenium.chrome.ChromeDriver;import org.testng.annotations.Test;public class TestAppCM2 {//public static void main(String[] args) throws InterruptedException {@Test public void TestAppCM2Test() throws Exception{System.setProperty("webdriver.chrome.driver","C:\\Selenium\\0320\\WebDriver\\chromedriver_win32\\chromedriver.exe"); //location of the browser driverWebDriver cd = new ChromeDriver(); // Selenium will launch chrome browsercd.get(""); // this will launch in chrome browserSystem.out.println(cd.getTitle()); // this will print title of home page.Thread.sleep(2000);cd.quit(); // this will close all opened windows within the chrome browser.}}TestAppFF2.java://Firefox:import org.openqa.selenium.WebDriver;import org.openqa.selenium.firefox.FirefoxDriver;import org.testng.annotations.Test;public class TestAppFF2 {// public static void main(String[] args) throws InterruptedException {@Test public void TestAppFF2Test() throws Exception{System.setProperty("webdriver.gecko.driver","C:\\Selenium\\0320\\WebDriver\\geckodriver-v0.26.0-win64\\geckodriver.exe");WebDriver fd = new FirefoxDriver(); fd.get(""); System.out.println(fd.getTitle());Thread.sleep(3000);fd.quit();}}Run batch test serially: Copy/past testng1.xml from G Drive (SeleniumFiles) into java project, right click -> run as TestNG SuiteRun batch test parallelly:Copy/past testng2.xml from G Drive (SeleniumFiles) into java project, right click -> run as TestNG SuiteSubVersion (SVN) for SeleniumWhat is SVN?SVN stands for Subversion. Subversion is a free/open source “version control system” (VCS). It is primarily used to store current and previous versions of source code (ex: selenium scripts) and it allows for concurrent editing of those source files by multiple people. Subversion manages files and directories, and the changes made to them, over time. This allows you to recover older versions of your data or examine the history of how your data changed.Assume there are 25 test cases and there are 5 automation eng's. Each will get 5 tc's to automate. Once they develop scripts for test cases using Selenium WebDriver, they have to upload/merge the code in SVN for everyone to see / access all the scripts.Each automation eng will setup elipse and create a workspace (ex: SeleniumWorkspace1, SeleniumWorkspace2 etc...) in their local machine first and then upload/check-in to SVN. What if a new automation eng join's the team. Which workspace he/she will download/check-out from SVN? He/she don't download specific work space. All the automation eng's which upload/check-in and merge the code to SVN so that new the auto eng can download the whole project on to his/her local machine.Basically, once a day in the morning (or as and when needed), all automation eng's, will checkout /download the whole project into their local machine (from SVN) so that all will have entire project due to this, they may not see any errors/synchronization issues (auto eng 1 did some changes in his workspace ... these changes won't show up in SVN project until he/she check-in/upload the latest changes to SVN project).Note: Workspace is nothing but a Selenium Project created in Eclipse.All automation eng’s will upload their code to the SVN server (Centralized Repository where all automation code is saved). Every automation eng can upload and/or download the code.Setup of SVN Server and SVN ClientSliksvn: Sliksvn is a server where you can host/save your code so that everyone can upload / download the code from that server.Subversion is a version control system that will track all changes made to files and folders (directories).Benefits of using Version Control Tool: Subversion (or GitHub/MS Visual Source Safe etc..)This trackable way of working has a number of advantages:more developers can work on the same code at the same time,if a computer crashes, the code is still accessible to the developer through any other machine,everything you commit will be securely hosted on our servers which are frequently backed up,you can quickly revert to a previous (stable) version if an update breaks something or pesky bugs arise.SVN Server: HYPERLINK "" or name: qa_auto_selenium_repoRepository URL: : ramasqa8Password: itech16Once you login, you will see qa_auto_selenium_re - Revision 0: / By default the version is 0. Every time when you upload new files/folders, version will be incremented by 1.Note: I have subscribed for Free ver of SVN Server with 100 MB diskspace 1 repository and 1 user.SVN Client#1: Client which can upload your java files or projects to the SVN Server. TortoiesSVN: This is the UI interface thru which you can upload the code to the centralized repository there in SVN server. TortoiseSVN is an Apache? Subversion (SVN)? client, implemented as a Windows shell extension. It's intuitive and easy to use, since it doesn't require the Subversion command line client to run. And it is free to use, even in a commercial environment. Go to Windows 32 bit: Windows 64 bit: the file (ex: TortoiseSVN-1.9.4.27285-x64-svn-1.9.4.msi) is downloaded, double click and install.Smart SVN Client for Mac: smart svn for client: verify whether SVN Client successfully installed or not…. Do the following steps:Open File Explorer (C: drive) and right anywhereYou should able to see TortoiesSVN with bunch of options (ex: export, import etc)Let’s create a workspace & project in Eclipse and then upload to SVN server using SVN client (TortoiesSVN). Open Eclipse and Browse to the workspace (ex: C:\Selenium\0616\SeleniumAdvanced\SVNWS)Create a new Java Project (ex: SVNForSelenium)Create a new Class (ex: FirstSVNTest) with public static void…Add System.out.println ("My First SVN Test");public class FirstSVNTest {public static void main(String[] args) {// TODO Auto-generated method stubSystem.out.println ("My First SVN Test");}}Run the script.Now, let’s put this project into SVN server for all the automation eng’s to access it. Check-in means, upload code from local machine to SVN server.Check-out means, download code from SVN server to the local machine.Delete existing files first: (for practice purpose only)How to delete all the projects/folders/files from SVN Server?Go to the any folderRight click and select TortoiseSVN-> Repo-BrowserEnter OKEnter username/pwdSelect all the files/folders and right click DeleteClick OKOpen any browser (ff/chrome) and Go to your repo and refresh: will see blank and revision history will change from 1 to 2.Now, let’s check-in/upload the code to SVN server.Find the location of the project (in Eclipse) by right click on project name -> Properties Get the location / path of the project (ex: C:\Selenium\0616\SeleniumAdvanced\SVN-Workspace\ SeleniumSVN)Go to above locationRight click anywhereSelect TortoiseSVN->Import (upload)Enter URL of repository: Repository URL: User: ramasqa8 Password: itech16Project will be uploaded and SVN repository revision version will change from 0 to 1. And also we will get an email.If your other teammate wants to check-out/download the code from SVN to his/her local machine, the following steps to be done:Open File Explorer (ex: C:\Selenium\0616\SeleniumAdvanced\)Create a new folder (ex: CheckoutProject) Right click on the above folder (ex: CheckoutProject)Select TortoiseSVN-> ExportApache Maven for SeleniumWhat and Why Apache Maven?Apache Maven is a software project management and comprehension tool. Based on the concept of a project object model (POM), Maven can manage a project's build, reporting and documentation from a central piece of information.Maven is something similar to SVN. It’s not a good practice to upload/check-in selenium/log4j etc...jar’s to SVN. What if selenium jar ver changes from 2.53.1 to 2.54.2. You need to check-in new jars again from your local host to SVN. Otherwise, existing Selenium code may not work. For that, we’ll use Maven to solve this issue. When you use Maven, all you need to do is that, you need to just get all the .jar files of Selenium new version (ex: 2.54.2). So, Maven will let you check-out/download new ver of .jar files to your workspace/local host. SVN can run on any server (Windows/Unix etc) whereas Maven will run on community server like Apache etc..(these are all mostly open source servers).Selenium server is running on a server called Thoughtworks. Whenever there is new ver of selenium server (.jar’s), it will inform Maven server that, take the jar files from me and deploy to the server. Basically, all the .jar files will be given to the apache server. Apache deploy’s jar files to the server so you connect to the apache server to get the latest jar files. Whereas SVN will be used to store the java code/xml etc... But both will help you, when you work with team.Frameworks with SeleniumFrameworks help to structure our code and make maintenance easy. Without frameworks we will place all our code and data in same place which is neither re-usable nor readable. Using Frameworks, produce beneficial outcomes like increase code re-usage, higher portability, reduced script maintenance cost etc.There are mainly three type of frameworks created by Selenium WebDriver to automate manual test casesKeyword Driven Test Framework: In keyword driven test framework, all the operations and instructions are written in some external file like excel worksheet.*** Data Driven Test Framework: In data driven framework all of our test data is generated from some external files like excel, csv, XML or some database table.Hybrid Test Framework: Hybrid Test framework is a concept where we are using advantage of both Keyword and Data driven framework.Page Object Model (POM)Page Object Model is an Object Repository design pattern in Selenium WebDriver.The requirements (ex: Maven project, read data from XLS, implement tests and validations etc) for the page object model and the Data Driven framework are the same except the thing that we have to implement the page factory design pattern. In case of page object model, we have to use the concept of inheritance and encapsulation. Page Factory is an optimized way to create object repository in POM concept. Selenium Page Factory Pattern is like an extension to Page Object Model, but Page Factory is much enhanced model. To start with, we just need to import package ‘org.openqa.selenium.support.PageFactory’. Factory class can be used to make using Page Objects simpler and easier. We use Page Factory pattern to initialize web elements which are defined in Page Objects. ................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download