Showing posts with label WebDriver. Show all posts
Showing posts with label WebDriver. Show all posts

Friday, July 20, 2018

PageObejctModel in Selenium WebDriver

Page object model is a wonderful design pattern to abstract out Web Page elements and its actions from actual tests. We can use this way to build a test framework of the project and focus on business only in all the test cases.

Here is a demo for page object model.


package me.simplejavautomation.pages;

import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;

public class PercentageCalculatorPage {

    @FindBy(id = "A")
    private WebElement a;

    @FindBy(id = "B")
    private WebElement b;

    @FindBy(id = "C")
    private WebElement c;

    public WebElement getA() {
        return a;
    }

    public void setA(WebElement a) {
        this.a = a;
    }

    public WebElement getB() {
        return b;
    }

    public void setB(WebElement b) {
        this.b = b;
    }

    public WebElement getC() {
        return c;
    }

    public void setC(WebElement c) {
        this.c = c;
    }

}

package me.simplejavautomation;

import static org.junit.Assert.assertEquals;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.PageFactory;

import me.simplejavautomation.pages.PercentageCalculatorPage;

public class PageObjectTest {

    private WebDriver driver;

    @Before
    public void setUp() {
        driver = new ChromeDriver();
    }

    @After
    public void tearDown() {
        driver.quit();
    }

    @Test
    public void testPercentageCalculation() {
        // open http://www.percentagecalculator.co/ web site
        driver.get("http://www.percentagecalculator.co/");

        PercentageCalculatorPage pageObject = PageFactory
            .initElements(driver, PercentageCalculatorPage.class);
        pageObject.getA().sendKeys("10");
        pageObject.getB().sendKeys("100");

        assertEquals("10", pageObject.getC().getAttribute("value"));
    }

}

Thursday, July 19, 2018

Execute Javascript in Selenium WebDriver

To execute Javascript using Selenium WebDriver, we can use JavascriptExecutor interface to implement it. There are two methods in JavascriptExecutor interface.

  • executeScript(String, Object...)
  • executeAsyncScript(String, Object...)

Here is a simple test,


    @Test
    public void testJavascript() throws InterruptedException {
        // wait 10 seconds if web element is not present
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        JavascriptExecutor jsExecutor = (JavascriptExecutor) driver;
        jsExecutor.executeScript("alert('hello world');");
        TimeUnit.SECONDS.sleep(4);
        driver.switchTo().alert().accept();

        WebElement continents = (WebElement) jsExecutor
            .executeScript("return document.getElementById('continents')");
        assertNotNull(continents);

        String selectedContinent = jsExecutor
             .executeScript("return document.getElementById('continents').value")
             .toString();
        assertEquals("Asia", selectedContinent);
    }

Tuesday, July 17, 2018

Actions on WebElement in Selenium WebDriver

Actions is an interaction generator in Selenium WebDriver which allow us to operate complicated user interactions on web pages.
You can perform actions such as drag and drop, move, click, double-click, and tick and so on.

Here is an example of a demo of drag and drop, and move on a menu.

package me.simplejavautomation;

import static org.junit.Assert.assertEquals;

import java.util.concurrent.TimeUnit;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
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.interactions.Actions;

public class ActionsApiTest {

    private WebDriver driver;
    private String url;

    @Before
    public void setUp() {
        driver = new ChromeDriver();
        url = "http://simplejavautomation.blogspot.com/2018/07/demo-page-for-actions-in-selenium.html";
        // go to the demo page
        driver.get(url);
        // maximize the browser window
        driver.manage().window().maximize();
    }

    @After
    public void tearDown() {
        driver.quit();
    }

    @Test
    public void testDragAndDrop() throws InterruptedException {
        // wait 10 seconds if web element is not present
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

        WebElement from = driver.findElement(By.id("draggable"));
        WebElement to = driver.findElement(By.id("droppable"));

        Actions builder = new Actions(driver);
        // builder.clickAndHold(from).release(to).build().perform();
        builder.dragAndDrop(from, to).build().perform();
    }

    @Test
    public void testMenuClick() throws InterruptedException {
        // wait 10 seconds if web element is not present
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

        WebElement automation = driver.findElement(By.id("automation"));

        Actions builder = new Actions(driver);
        builder.moveToElement(automation).build().perform();

        driver.findElement(By.id("selenium")).click();

        assertEquals("Selenium",
             driver.findElement(By.id("selectedText")).getText());
    }

}

Demo Page for Actions in Selenium WebDriver

jQuery UI Droppable - Default functionality
 

Drag me to my target

Drop here

Monday, July 16, 2018

Using switchTo to switch Window, Alert, Frame

 Knowing how to deal with Windows, Alerts, and Frames are essential in Selenium WebDriver.

In Selenium WebDriver, it uses TargetLocator interface to handle this switch. You may use it to switch to,

  • Frame (using index, id or name, WebElement)
  • Alert
  • Window (using window handle)

Uses "driver.switchTo()" to get TargetLocator, and make sure using "driver.switchTo().defaultContent()" to switch back to main window.

Here is an example to demonstrate all these cases.


package me.simplejavautomation;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.util.List;
import java.util.concurrent.TimeUnit;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class SwitchApiTest {

    private WebDriver driver;
    private String url;

    @Before
    public void setUp() {
        driver = new ChromeDriver();
        url = "http://simplejavautomation.blogspot.com/2018/07/demo-page-for-selenium-webdriver-apis.html";
        // go to the demo page
        driver.get(url);
        // maximize the browser window
        driver.manage().window().maximize();
    }

    @After
    public void tearDown() {
        driver.quit();
    }

    @Test
    public void testSwitchWindow() {
        // wait 10 seconds if web element is not present
        driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);

        String currentWindow = driver.getWindowHandle();
        // find element
        driver.findElement(By.linkText("Selenium")).click();

        assertEquals(currentWindow, driver.getWindowHandle());

        String[] windowHandles = driver.getWindowHandles().toArray(new String[0]);
        assertTrue(windowHandles.length > 1);

        driver.switchTo().window(windowHandles[1]);
        assertEquals(windowHandles[1], driver.getWindowHandle());
    }

    @Test
    public void testSwitchAlert() {
        // wait 10 seconds if web element is not present
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

        // find element
        driver.findElement(By.id("simpleAlert")).click();

        Alert alert = driver.switchTo().alert();
        assertEquals("Simple Java Automation", alert.getText());
        alert.accept();

        driver.findElement(By.id("confirmAlert")).click();

        alert = driver.switchTo().alert();
        assertEquals("Simple Java Automation", alert.getText());
        alert.dismiss();

        driver.findElement(By.id("promptAlert")).click();

        alert = driver.switchTo().alert();
        assertEquals("Is Java Automation simple?", alert.getText());
        alert.sendKeys("Yes");
        alert.accept();
    }

    @Test
    public void testSwitchFrame() {
        JavascriptExecutor exe = (JavascriptExecutor) driver;
        int numberOfFrames = Integer.parseInt(exe.executeScript("return window.length").toString());
        assertEquals(6, numberOfFrames);

        // By finding all the web elements using iframe tag
        List<WebElement> iframeElements = driver.findElements(By.tagName("iframe"));
        assertEquals(6, iframeElements.size());

        // switch frame by index
        driver.switchTo().frame(0);
        // switch back
        driver.switchTo().defaultContent();
        // switch frame by id
        driver.switchTo().frame("iframeA");

        driver.switchTo().defaultContent();

        WebElement iframeB = driver.findElement(By.id("iframeB"));
        // switch frame by web element
        driver.switchTo().frame(iframeB);
        driver.switchTo().defaultContent();
    }

    @Test
    public void testSwitchFrame2() {
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

        // switch frame by id
        driver.switchTo().frame("iframeA");
        driver.findElement(By.id("street")).sendKeys("Whangaparaoa Rd");
        driver.findElement(By.id("suburb")).sendKeys("Red Beach");
        driver.findElement(By.id("submit")).click();

        Alert alert = driver.switchTo().alert();
        assertEquals("Street:Whangaparaoa Rd Suburb:Red Beach", alert.getText());
        alert.accept();

        // switch back
        driver.switchTo().defaultContent();

        // switch frame by index
        driver.switchTo().frame("iframeB");
        driver.findElement(By.id("city")).sendKeys("Auckland");
        driver.findElement(By.id("country")).sendKeys("New Zealand");
        driver.findElement(By.id("submit")).click();

        alert = driver.switchTo().alert();
        assertEquals("City:Auckland Country:New Zealand", alert.getText());
        alert.accept();
     
        driver.switchTo().defaultContent();
    }

}

Wait APIs in Selenium WebDriver

Sometimes we need to wait until a WebElement present so that we can do further test steps. Here are common Waits in Selenium WebDriver APIs.

  • Thread sleep 
  • Implicitly Wait 
  • FluentWait 
  • WebDriverWait 
  • AjaxWait (depends on how slow the ajax call, probably not the stable one)

Here is the sample test case.

package me.simplejavautomation;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.time.Duration;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Select;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;

public class WaitApiTest {

    private WebDriver driver;
    private String url;

    @Before
    public void setUp() {
        driver = new ChromeDriver();
        url = "http://simplejavautomation.blogspot.com/2018/07/demo-page-for-selenium-webdriver-apis.html";
        // go to the demo page
        driver.get(url);
        // maximize the browser window
        driver.manage().window().maximize();
    }

    @After
    public void tearDown() {
        driver.quit();
    }

    @Test(expected = NoSuchElementException.class)
    public void testImplicitlyWaitWithException() {
        // wait 10 seconds if web element is not present
        driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);

        // find element
        WebElement waitLink = driver.findElement(By.linkText("WebDriver Wait"));
        assertNotNull(waitLink);
    }

    @Test
    public void testImplicitlyWait() {
        // wait 10 seconds if web element is not present
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

        // find element
        WebElement waitLink = driver.findElement(By.linkText("WebDriver Wait"));
        assertNotNull(waitLink);
    }

    @Test
    public void testFluentWait() {
        Wait<WebDriver> wait = new FluentWait<WebDriver>(driver).withTimeout(Duration.ofSeconds(10))
                .pollingEvery(Duration.ofSeconds(1)).ignoring(NoSuchElementException.class);
        // find element
        WebElement waitLink = wait.until(new Function<WebDriver, WebElement>() {

            @Override
            public WebElement apply(WebDriver driver) {
                return driver.findElement(By.linkText("WebDriver Wait"));
            }

        });
        assertNotNull(waitLink);
    }

    @Test
    public void testWebDriverWait() {
        WebDriverWait wait = new WebDriverWait(driver, 10);

        // find element
        WebElement waitLink = wait.until(ExpectedConditions.elementToBeClickable(By.linkText("WebDriver Wait")));
        assertNotNull(waitLink);
    }

    @Test
    public void testHtmlWait() {
        driver.manage().timeouts().pageLoadTimeout(100, TimeUnit.SECONDS);
        driver.manage().timeouts().setScriptTimeout(100, TimeUnit.SECONDS);
    }

    @Test
    public void testAjaxWait() {
        Select citySelect = new Select(driver.findElement(By.id("cities")));
        citySelect.selectByVisibleText("London");

        driver.findElement(By.id("weather")).click();

        // wait ajax finish
        WebDriverWait wait = new WebDriverWait(driver, 10);
        wait.until(new Function<WebDriver, Boolean>() {
            @Override
            public Boolean apply(WebDriver t) {
                Boolean isJqueryCallDone = (Boolean) ((JavascriptExecutor) driver)
                        .executeScript("return jQuery.active==0");
                return isJqueryCallDone;
            }
        });

        // weather info retrieved
        WebElement weatherInfo = wait.until(new Function<WebDriver, WebElement>() {
            @Override
            public WebElement apply(WebDriver t) {
                WebElement info = driver.findElement(By.id("weatherInfo"));
                if (info != null) {
                    if (info.getText().startsWith("City:")) {
                        return info;
                    }
                    return null;
                }
                return info;
            }
        });
        assertTrue(weatherInfo.getText().startsWith("City: London"));
    }

}

Sunday, July 15, 2018

Getting to know about Selenium WebDriver APIs

Before writing the first case, we should know about Selenium WebDriver APIs. The most commonly used APIs are WebDriver, WebElement, Select, Navigation, Options, Window, Timeouts.

Here is a diagram to give you a general idea.
WebElement and Select.
You can find detail information for those interfaces through selenium java docs here, and documentation here.

We will create a simple test case to show you how to operate different web elements, such as text box, radio button, checkbox, select, multiple select, button, and table.

Before looking into the code, take few minutes to look at the demo site here.

package me.simplejavautomation;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.util.List;
import java.util.concurrent.TimeUnit;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
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.interactions.Actions;
import org.openqa.selenium.support.ui.Select;

public class WebDriverApiTest {

    private WebDriver driver;
    private String url;

    @Before
    public void setUp() {
        driver = new ChromeDriver();
        url = "http://simplejavautomation.blogspot.com/2018/07/demo-page-for-selenium-webdriver-apis.html";
    }

    @After
    public void tearDown() {
        driver.quit();
    }

    @Test
    public void testWebDriverApis() {
        driver.get(url);
        String expectedTitle = "Simple Java Automation: Demo Page for Selenium WebDriver APIs";
        String actualTitle = driver.getTitle();
        assertEquals(expectedTitle, actualTitle);

        String actualUrl = driver.getCurrentUrl();
        assertEquals(url, actualUrl);

        String pageSource = driver.getPageSource();
        assertTrue(pageSource.length() > 0);

        driver.findElement(By.linkText("Simple Java Automation")).click();

        driver.navigate().back();
        driver.navigate().forward();

        String expectedUrl = "http://simplejavautomation.blogspot.com/";
        actualUrl = driver.getCurrentUrl();
        assertEquals(expectedUrl, actualUrl);

        driver.navigate().to(url);
        driver.navigate().refresh();
        actualUrl = driver.getCurrentUrl();
        assertEquals(url, actualUrl);
    }

    @Test
    public void testWebElementApis() {
        // go to the demo page
        driver.get(url);
        // maximize the browser window
        driver.manage().window().maximize();

        // get FirstName, LastName, and Email input and send keys to them
        driver.findElement(By.name("firstname")).sendKeys("Tristan");
        driver.findElement(By.name("lastname")).sendKeys("Zhou");
        driver.findElement(By.name("email")).sendKeys("jiahuan.zhou@yahoo.com");

        // set Male radio button checked
        List sexRadios = driver.findElements(By.name("sex"));
        boolean isMaleSelected = sexRadios.get(0).isSelected();
        if (!isMaleSelected) {
            sexRadios.get(0).click();
        }

        // set experience to 5+
        WebElement expRadio = driver.findElement(By.id("exp-6"));
        expRadio.click();

        // set Automation Tester checked
        List professionChecks = driver.findElements(By.name("profession"));
        for (int i = 0; i < professionChecks.size(); i++) {
            String checkValue = professionChecks.get(i).getAttribute("value");
            if (checkValue.equalsIgnoreCase("Automation Tester")) {
                professionChecks.get(i).click();
                break;
            }
        }

        // check all Automation Tools
        driver.findElement(By.id("tool-0")).click();
        driver.findElement(By.xpath("//*[@value='Selenium IDE']")).click();
        driver.findElement(By.cssSelector("input[value='Selenium Webdriver']")).click();

        // choose Australia for Continents select box
        Select continentSelect = new Select(driver.findElement(By.id("continents")));
        continentSelect.selectByIndex(2);
        driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);
        continentSelect.selectByVisibleText("Australia");

        // select Browser and Navigation option
        Select commandSelect = new Select(driver.findElement(By.name("selenium_commands")));
        commandSelect.selectByIndex(0);
        driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);
        commandSelect.selectByVisibleText("Navigation");

        // click submit button
        driver.findElement(By.id("submit")).click();

        // validate all inputs which displays in the table
        assertEquals("Tristan", getCellValue(2));
        assertEquals("Zhou", getCellValue(3));
        assertEquals("jiahuan.zhou@yahoo.com", getCellValue(4));
        assertEquals("Male", getCellValue(5));
        assertEquals("5+", getCellValue(6));
        assertEquals("Automation Tester", getCellValue(7));
        assertEquals("QTP, Selenium IDE, Selenium Webdriver", getCellValue(8));
        assertEquals("Australia", getCellValue(9));
        assertEquals("Browser, Navigation", getCellValue(10));

        // move to the table element
        new Actions(driver).moveToElement(driver.findElement(By.id("summary"))).build().perform();

        // sleep 5 seconds
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * Get 2nd cell value for the row.
     * 
     * @param row
     * @return
     */
    private String getCellValue(int row) {
        return driver.findElement(By.xpath("//*[@id='summary']/tbody/tr[" + row + "]/td[2]")).getText();
    }

}

WebElement Locators and XPath

To access web element on the page, you have to know the id, or name, or path to locate them. There are several different ways to find them. For example,

  • Browser's built-in Inspector
  • FireBug & FirePath addon in Firefox Browser
  • WebDriver Element Locator addon in Firefox Browser
  • XPath Helper in Chrome

You may find the handiest tool for yourself while using them.

There are 8 explicit locators: id, name, identifier, dom, xpath, link, css and ui, but you don't need everything while writing the test case.

Here are some examples,

id: driver.findElement(By.id("username"));
namedriver.findElement(By.name("username"));
xpathdriver.findElement(By.xpath("//*[@id='username']"));
linkdriver.findElement(By.linkText("Link Text"));
cssdriver.findElement(By.cssSelector("input[id='username']"));

What is XPath
XPath is a language that describes a way to locate and process items in Extensible Markup Language (XML) documents by using an addressing syntax based on a path through the document’s logical structure or hierarchy.

There are two types of XPath,
Absolute xpath, start from root element: /html/body/div/div/section/div/a
Relative xpath, start from located element: //*[@id=’footer’]/div/a

More examples of XPath,
//img[contains(@src,’Profile’)]
//img[starts-with(@alt,’Visit Us On Linkedin’)]
//*[text()='Simple Java Automation']
//a[contains(text(), 'Java Automation')]
//*[@id=’username’]
//input[@id=’username’]
//form[@name=’loginForm’]/input
//*[@name=’loginForm’]/input

Friday, July 13, 2018

First test case using Selenium WebDriver

After setup Gradle project and web driver configuration, it's ready to write the first test case using Selenium WebDriver.

In this article, we are going to test a percentage calculator on the site Percentage Calculator. Here is the page looks like.


There are three text boxes on the page, if you type 10 and 100 in two blue text boxes, you will get 10 in the third text box, which means 10% of 100 equals 10.

Now we are creating the test case using JUnit in Eclipse.

1) Create a package
     Right click on "src/test/java" source folder, and choose New > Package.

    Type a package name in "Name" field and click the "Finish" button.

2) Create a Test Case
    Right click on "me.simplejavautomation" package, and choose New > JUnit Test Case.

    Type a class name in "Name" field and click the "Finish" button. And make sure to check the "setUp()" and "tearDown()" check-boxes.

3) Write Test Case
     Type the code below and will let you familiar with the selenium classes and interfaces.

4) Run the Test Case
    Right-click the Test Class or test method and choose Run As > JUnit Test. A new browser window will be opened and you will see,
    a) It navigates to the website http://www.percentagecalculator.co/
    b) The cursor moves on first text-box and types 10
    c) The cursor moves on second text-box and types 100
    d) The third text-box value changes to 10
    e) The browser is closed
    Then, you will get the green bar in the JUnit tab which shows you the test case passed.

5) How to identify the element on the page?
    Before we can find an element on the page using Web Driver, we need to identify the id, name, CSS or XPath on the element. Follow the steps below to find the right element id.
    a) Open the website using Google Chrome
    b) Press F12 or Ctrl+Shift+I to open Developer Tools
    c) Click the arrow button on the top left of Developer Tools window or Ctrl+Shif+C
    d) Point your mouse to the element you want on the page
    You may find the id, name, CSS on the web element and Properties tab on the right side. In this example, the first textbox's id is A. Then you can find ids for other two textboxes.

6) Run Test Case on other browsers
    To run the test case on different browsers, just instantiate the related Web Driver object in "setUp()" function.

Prerequisite for the First Test Case using Selenium WebDriver

Using Selenium WebDriver, we can test web applications against different browsers, such as Google Chrome, Mozilla Firefox, Internet Explorer and so on. You can find all supported browsers from here.

Before we start writing our first test case, there are several things we need to set up. We are going to use the latest version 3.13.0.

1) Download Web Drivers for each browser.
     In this article, we are going to test on three browsers, Google Chrome, Mozilla Firefox, and Internet Explorer. You can find web drivers from selenium website here. And download web driver zip file for each browser. And unzip all files into a folder in your machine.
    There should be three executable files in the folder after finished download, chromedriver.exe, geckodriver.exe, and IEDriverServer.exe.

2) Set property in Environment Variables
     In order to start web driver successfully, we need to enable these web drivers. The first option is to setup system environment variables in your machine.
     Open the "Environment Variables" from the Control Panel and add a new item into "Path", in this example the path is "D:\selenium-drivers", which is the location of web driver files.

      The second option is to config library path through System.setProperty function in the test case.
       System.setProperty("webdriver.chrome.driver", "Path to chromedriver.exe");
       System.setProperty("webdriver.gecko.driver", "Path to geckodriver.exe");
       System.setProperty("webdriver.ie.driver", "Path to IEDriverServer.exe");

       After we have done this, selenium should be able to find the web driver.

3) Enable protected mode for Internet Explorer
    You may find NoSuchElement exception when executing the test case on Internet Explorer. That probably you haven't enable protected mode in your IE settings.
     Open "Security" tab in "Internet Options", and check the Enable Protected Mode check-box. And make sure you have done this for all zones.

4) Using Win32 web driver for Internet Explorer
     You may find it slow to send a value to the input element when executing the test case on Internet Explorer. Try to download Win32 web driver.