Ankit_Add

Tuesday, December 26, 2017

Widely used TestNG Annotations

Before talking about annotations we should talk a little bit about why TestNG is required and what is the need for using any test management frameworks in our test.
All the tests are designed to allow you to quickly verify your application using a very large and diverse set of different data inputs. So test management tools are responsible for managing our test and provide many functionalities or you can say methods we can directly use in Test and no need to write the logic again like comparing two objects, pre-setup for Test, passing a different set of data and many more.
TestNG use annotations for configuration in the test like creating data, pass data, setUp, cleanup and many more. Annotation is a Java feature and you can read more about annotation. So let’s see what annotations are there in TestNG.
Annotations, a form of metadata, provide data about a program that is not part of the program itself. Annotations have no direct effect on the operation of the code they annotate.

TestNG Annotations and Execution order:

@BeforeTest and @AfterTest

@BeforeTest - Run before any test method in the class inside the tag is run.
@AfterTest - Run after all the test methods in the class inside the tag have run.
package com.tutorial.testng;

import org.testng.annotations.*;

public class TestngAnnotations {

    @BeforeTest
    public void beforeTest() {
        System.out.println("In @BeforeTest");
    }

    @Test()
    public void testMethod1() {
        System.out.println("In @Test - testMethod1");
    }

    @AfterTest
    public void afterTest() {
        System.out.println("In @AfterTest");
    }
}
In @BeforeTest
In @Test - testMethod1
In @AfterTest

@BeforeMethod and @AfterMethod

@BeforeMethod - Run before each @test method.
@AfterMethod - Run after each @test method.
package com.tutorial.testng;

import org.testng.annotations.*;

public class TestngAnnotations {

    @BeforeTest
    public void beforeTest() {
        System.out.println("In @BeforeTest");
    }

    @BeforeMethod
    public void beforeMethod() {
        System.out.println("In @BeforeMethod");
    }

    @Test()
    public void testMethod1() {
        System.out.println("In @Test - testMethod1");
    }

    @AfterMethod
    public void afterMethod() {
        System.out.println("In @AfterMethod");
    }

    @AfterTest
    public void afterTest() {
        System.out.println("In @AfterTest");
    }
}
In @BeforeTest
In @BeforeMethod
In @Test - testMethod1
In @AfterMethod
In @AfterTest

@BeforeClass and @AfterClass

@BeforeClass - Run before the first @test method in the current class.
@AfterClass - Run after all the @test methods in the current class.
package com.tutorial.testng;

import org.testng.annotations.*;

public class TestngAnnotations {
    @BeforeClass
    public void beforeClass() {
        System.out.println("In @BeforeClass");
    }

    @BeforeTest
    public void beforeTest() {
        System.out.println("In @BeforeTest");
    }

    @BeforeMethod
    public void beforeMethod() {
        System.out.println("In @BeforeMethod");
    }

    @Test()
    public void testMethod1() {
        System.out.println("In @Test - testMethod1");
    }

    @AfterMethod
    public void afterMethod() {
        System.out.println("In @AfterMethod");
    }

    @AfterTest
    public void afterTest() {
        System.out.println("In @AfterTest");
    }

    @AfterClass
    public void afterClass() {
        System.out.println("In @AfterClass");
    }
}
In @BeforeTest
In @BeforeClass
In @BeforeMethod
In @Test - testMethod1
In @AfterMethod
In @AfterClass
In @AfterTest

@BeforeSuite and @AfterSuite

@BeforeSuite - Run before all @tests in the current suite. @AfterSuite - Run after all @tests in the current suite.
package com.tutorial.testng;

import org.testng.annotations.*;

public class TestngAnnotations {
    @BeforeSuite()
    public void beforeSuite() {
        System.out.println("In @BeforeSuite");
    }

    @BeforeClass
    public void beforeClass() {
        System.out.println("In @BeforeClass");
    }

    @BeforeTest
    public void beforeTest() {
        System.out.println("In @BeforeTest");
    }

    @BeforeMethod
    public void beforeMethod() {
        System.out.println("In @BeforeMethod");
    }

    @Test()
    public void testMethod1() {
        System.out.println("In @Test - testMethod1");
    }

    @AfterMethod
    public void afterMethod() {
        System.out.println("In @AfterMethod");
    }

    @AfterTest
    public void afterTest() {
        System.out.println("In @AfterTest");
    }

    @AfterClass
    public void afterClass() {
        System.out.println("In @AfterClass");
    }

    @AfterSuite
    public void afterSuite() {
        System.out.println("In @AfterSuite");
    }
}
In @BeforeSuite
In @BeforeTest
In @BeforeClass
In @BeforeMethod
In @Test - testMethod1
In @AfterMethod
In @AfterClass
In @AfterTest
PASSED: testMethod1

===============================================
    Default test
    Tests run: 1, Failures: 0, Skips: 0
===============================================

In @AfterSuite

===============================================
Default suite
Total tests run: 1, Failures: 0, Skips: 0
===============================================

Working example of TestNG

TestNG is a test management framework inspired from JUnit and NUnit frameworks. TestNG provided and introduced new functionalities and features which make TestNg very powerful and mostly used test management framework in Java programming language. As per the creator of TestNG Mr. Cédric Beust NG stands for next generation.
TestNG can be used in all the phases of testing like Unit testing, integration testing or system testing. TestNG provides better support compare to Junit and other frameworks as the new release and bug fixes are very frequent compared to Junit. TestNG is supported by a variety of tools and plug-ins like (Eclipse, IntelliJ IDEA, Maven, Ant etc.

How to use TestNG?

TestNG can be used as the maven dependency in our project or TestNg can be placed in the build path as the jar file.In this article, we will be using maven as dependency management tool.
Tools we will use:
  • TestNG
  • Maven
  • Eclipse

TestNG maven Dependency

We need to add TestNG dependency in to our Pom.xml file. Pom is an XML file that contains information about the project and configuration details used by Maven to build the project.
<dependency>
  <groupId>org.testng</groupId>
  <artifactId>testng</artifactId>
  <version>6.11</version>
  <scope>test</scope>
</dependency>
You can get the latest version and dependency detail from the maven central repository.

How to use TestNG in My Test Class?

Create an Addition class for adding two integer values:
package com.tutorial.testng;

public class Addition {

    public int addValues(int a, int b) {
        return a + b;
    }
}
Now we are going to create Test Class:
package com.tutorial.testng;

import org.testng.Assert;
import org.testng.annotations.Test;
import com.tutorial.testng.Addition;

public class TestngIntroductionTest {

    @Test
    public void verifyAdditionOfIntegers() {

        Addition obj = new Addition();
        int additionResult = obj.addValues(5, 4);

        Assert.assertNotNull(additionResult);
        Assert.assertEquals(additionResult, 9);
    }
}
This is a simple class where @Test is defined as Test method. So every method annoted by @Test in our class will be considered as Test method or test case sometime.

How to run my Test Class?

Now the next step is running our Test and for that, we will use Eclipse TestNG plugin which is an IDE.
Install TestNG Eclipse plugin:
To run and use TestNg in eclipse IDE we need to install the TestNG plugin in our Eclipse application. If you don’t have TestNG installed already, you can follow the steps mentioned in the TestNg official download or eclipse guide.
Now to Run our test Right Click on the Test Class and click Run As -> TestNG Test.
testng-eclipse-test-run
After successfully running the Test, You will see the test results in two places:
Eclipse TestNG plugin View:testng-plugin-test-result
Eclipse Console View:console-test-result

Monday, December 18, 2017

Capture Full page Screenshots using Chrome Browser

While working everyone feels the need of taking full-page screenshots but Its always hard to take the full page screenshot as normal screenshot works on the page area which is in the frame. Like on Mac we use Command + Shift + 4 and select the area and take the screenshot but in this method, we can not scroll down and take the part hidden in the screenshot. Like I took a screenshot of BBC.com website here.
screenshot-with-frame-only
Screenshot covers only the part of the website which is in the frame and in focus and we can not scroll down. Now we will use the Google Chrome in build screenshot capturing tools which are very easy to use. I took a screenshot of the same BBC.com website using the chrome tool and following is the result.
full-page-screenshot-of-bbc-website
Looks nice!!!
So how we can use Google developer tools to take this screenshot, Follow the simple steps below. On Mac 1. Do Alt + Command + I which will open the Developers tool. 2. Now do Command + Shift + P and search for “Capture Screenshot” 3. Select the option of taking the screenshot from the list appeared.
google-Chrome-Dev-tool
After selecting the option from the list Screenshot file would be downloaded automatically to your Downloads folder on the local machine.
Following is the GIF I made to show how it looks like in Chrome developer tool.capture-screenshot gif-in-action

Wednesday, December 13, 2017

How ChromeDriver works in the background?

ChromeDriver is a Chromium project and ChromeDriver code is inside the Chromium repository. Chromium is an open source project started by Google to provide source code for Chrome browser. Chromium projects are divided into mainly two projects Chromium browser and Chromium OS which is an open source project for OS based browsers, you can watch What is Chrome OS Video for more information.
Chromium dev teams are now responsible for the maintenance of the ChromeDriver code and updates which we use with Selenium WebDriver for automating Chrome. As it’s an open source project you can also contribute. In my previous articles I have explained about how ChromeDriver can be used with Selenium WebDriver and How ChromeDriver uses JSON Wire Protocol and perform actions on Chrome.
In this article, we are going to deep-dive into ChromeDriver and try to understand how it works in the background and what technology is been used for making ChromeDriver so cool.
ChromeDriver is made in C++ programming language and uses the Chrome DevToolwhich is a debugging and profiling tool made for Chrome DevTool has defined a set of standard protocols named as Chrome DevTools protocols which can be used by any tools to an instrument, inspect, debug Chrome browser. The protocol API’s are too used for sending the request to chrome dev tool for any debugging. So ChromeDriver also uses and follows the Chrome DevTools Protocols internally to send and receive the request to devTool for performing actions on browser.

What happens when we start ChromeDriver Server:

So to perform any of the actions on the browser the ChromeDrier server should be started.
//src/chrome/test/chromedriver/server/chromedriver_server.cc file which is a C++ file where main method start the execution and start an HTTP server using HttpServer Classinside the same namespace file which is accepting WebDriver protocol requests. ChromeDriver always starts on port no 9515.chromedriver-main-method-with-portno
when you run your test you should have noticed in console or logs, there are messages about ChromeDriver version with starting on the port are also coming from the same file. In below screenshot, I have highlighted the printf() message in the red color.
chromedriver-server-start-messages

WebDriver Protocol URL’s to C++ functions:

There is //src/chrome/test/chromedriver/server/http_handler.cc file which is responsible for handling your requests coming from the Selenium WebDriver which is nothing but JsonWireProtocol requests. This is the namespace file http_handler.cccontains variable for strong sessions and methods like commandMapping, WrapToCommand, PreperaingRequest etc. types of methods.chromedriver-session-storage-variable
If we send a request to find element command with the following POST URL, this is the place where this request is been handled and wrapped in to command for ChromeDev Tool Protocol. Let’s take an example of finding a WebElement, Send Text to the Element HTTP request or command explained below.
WebDriver Code: driver.findElement(By.name("q")).sendKeys("chrome");
Post URL: http://severIP:9515/session/:sessionID/element/:elementID/value Request Body:
{"value":["chrome"]}
http_handler.ccchromedriver-server-http-handler-command-mapping
You should check out more commands wrapping in the http_handler.cc in ChromeDriver codebase URL.

Chrome DevTools Protocol Commands:

When you start running your WebDriver test ChromeDriver server generates a log file in the system Temp location and you can check the Request and response server is receiving. In log files, you can find the Commands sent to the Chrome DevTool. For example, the Mouse Click ChromeDevTool commands look like below:
DEVTOOLS COMMAND Input.dispatchMouseEvent (id=32) {
   "button": "left",
   "clickCount": 1,
   "modifiers": 0,
   "type": "mousePressed",
   "x": 534,
   "y": 411
}
The same Input.dispatchMouseEvent used to click on elements request is described in DevTool Protocol document, where we can compare the JSON request from above in the screenshot below.chromeDevTool-mouse-click-command
So just to click on an Element there are many steps and commands executed in the background and I hope this article would be able to give a start for reading more details.

Monday, December 11, 2017

Browser automation using ChromeDriver and Postman

If you are using WebDriver or learning how to use Selenium for test automation, you must be using some programming language like Java or PHP, etc. for automation and performing actions on browsers like Chrome. But in this article we are not going to use WebDriver Client Like Java or PHP, etc. and we will perform actions like open URL, Click Button or Enter Text using ChromeDriver and PostMan tool.
I am going to use JSON Wire Protocol for driving chrome driver. You can read more in details about what is JSON Wire Protocol in my old posts.

Download ChromeDriver and PostMan

The first step is to download the ChromeDrive executable from Google ChromeDriver Page. If you already have ChromeDriver downloaded, you can use the same executable. I am going to use the ChromeDrive for MAC OS here in this article. Windows users can also download the .exe file and perform all the steps.
We also need to download Postman. PostMan is a super cool tool for API development. You can send and receive API request from PostMan. you can read more about Postman Download Page.

Start ChromeDriver on Terminal:

After downloading ChromeDriver we need to first start the ChromeDriver executable on the local machine.
$ Downloads ./chromedriver

Starting ChromeDriver 2.33.506 (8a06c39c9173bfb1a2) on port 9515
Only local connections are allowed.
Now we have a successfully running ChromeDriver. Please pay attention to the port no in the Starting message of ChromeDriver. It always starts on 9515 by default and start listening on the same port.

Open Google Chrome Browser:

Now open Postman which is installed on your machine and you should make a POST call to ChromeDriver.create-webdriver-session-from-postman
Request Body:
{
    "desiredCapabilities": {
        "caps": {
            "nativeEvents": false,
            "browserName": "chrome",
            "version": "",
            "platform": "ANY"
        }
    }
}
Response:
{
    "sessionId": "05567e0fc54f5859a7418632a8988cc7",
    "status": 0,
    "value": {
        "acceptSslCerts": true,
        "browserName": "chrome",
        "chrome": {
            "chromedriverVersion": "2.33.506 (8a06c39c9173bfb1a2)",
            "userDataDir": "/var/folders/v2/5jldd5952fng_t6cbl3064csc8p6dn/T/.org.chromium.Chromium.0ETZRP"
        },
        "cssSelectorsEnabled": true,
        "pageLoadStrategy": "normal",
        "platform": "Mac OS X",
        "version": "62.0.3202.94",
    }
}
You should save the SessionID from the Response you received as we are going to need SessionID for further communication.

Now let’s redirect to the URL:

Now As you can see the ChromeBrowser is open and ready to open any URL. We need to do POST call again with the session ID which we saved from our last API response.You can replace the sessionID which I have used within the request.
get-url-post-request-from-postman
Request Body:
{"url":"https://www.google.com"}
Response:
{
    "sessionId": "05567e0fc54f5859a7418632a8988cc7",
    "status": 0,
    "value": null
}

Now let’s find an Element on the page:

Now we have the URL opened in our chrome browser and lets find the search textBox from the page in our next request.post-request-find-searchButton-postman
Request Body:
{"using":"name","value":"q"}
Response:
{
    "sessionId": "05567e0fc54f5859a7418632a8988cc7",
    "status": 0,
    "value": {
        "ELEMENT": "0.1450256429796304-1"
    }
}
You should save the ELEMENT value from the response as this is the Element ID and we need to pass this in next request

Now let’s send the value “Chrome” to this search Element textBox:

Now we have received the elementID of the SearchTextBox and now we can send any Text to this TextBox using the POST call.
Request Body:
{"value":["chrome"]}
Response:
{
    "sessionId": "05567e0fc54f5859a7418632a8988cc7",
    "status": 0,
    "value": null
}

Now Quit Driver instance:

Now to Quit Driver session and close the Chrome Browser, we should send the DELETE request with the session ID.
Response:
{
    "sessionId": "05567e0fc54f5859a7418632a8988cc7",
    "status": 0,
    "value": null
}
I have used JsonWireProtocol standards about requests to perform few actions on the browser. You can try to perform more actions using the PostMan tool.
If you don’t want to use PostMan tool for API requests and you can use Java as programming language with any HTTPClient available.