Where we learn technology

Author: Mandeep Kaur (Page 1 of 2)

Building a Test Automation Framework Using Cypress with Cucumber

 
 

 

 

                                          ~Source: Google

Introduction:

In this Article, We are going to learn about creating UI Test automation framework with Cucumber BDD Approach.

What is BDD ?

  • Behaviour-driven development is an Agile software development process that fosters collaboration between developers, software testers, and the non-technical, business side in a software development process.
  • It asserts how an application should behave from the end user’s perspective.

Why Cypress ?

  • Front end testing tool built for the modern web applications.
  • Because of its Architectural design, Cypress delivers fast, consistent and reliable test execution compared to other Automation tools
  • Cypress takes snapshots as your tests run. We can hover over each command in the Command Log to see exactly what happened at each step. 
  • Cypress automatically waits for commands and assertions before moving on. 
  • Ability to test edge test cases by Mocking the server response.

Cypress Project Setup with Cucumber:

  • Download Node js from https://nodejs.org/en/download/ as per your operating system, as the cypress is built on the node js.
  • Create a folder and import the folder in any editor atom, sublime or visual studio code and open the terminal.
  • Setup a new npm package : npm init, this will create package.json in your project.
  • Open the terminal and enter npm install cypress cypress-cucumber-preprocessor, this will install cypress and cucumber in your project.
  • Dependencies should get added in package.json file.
  • Execute a command npx cypress open and you will be displayed with these folders in editor’s Left Pane.

Editor Left Pane

To enable the cucumber preprocessor plugin:

Open cypress/plugins/index.js and this snippet

const cucumber = require('cypress-cucumber-preprocessor').default

module.exports = (on, config) => {
  on('file:preprocessor', cucumber())
}

Add support for feature files to your Cypress configuration

cypress.json{
  "testFiles": "**/*.feature"
}

Add this section to your package.json:

"cypress-cucumber-preprocessor": {
  "nonGlobalStepDefinitions": true
}
To bind our step definitions to our features files.

Cucumber Feature File:

feature file can contain a scenario or can contain many scenarios in a single feature file but it usually contains a list of scenarios in English format using some BDD keywords and the language is called “Gherkin“.

Steps:

  • Create a folder under the Integration folder as CucumberTests
  • Create a file login.feature and click login.feature and type Feature and the syntax for the same will get poped up automatically:

Type Feature in feature file

Provide Feature name, Feature Description and Type Scenario and give Scenario name.

Feature File

Let’s try to understand the Feature File:

After the Scenario, we need to write certain statements with Keywords Given, When, Then, And also But. 

  • Given: It describes the pre-requisite for the test to be executed.
  • When: It defines the trigger point for any test scenario execution.
  • Then: It holds the expected result for the test to be executed.
  • And: It provides the logical AND condition between any two statements
  • But: It signifies logical OR condition between any two statements.

Now, We have to create the step definition for the test written in the feature file:

Since we have feature file with us, now we have to create step definition file for the same :

  • Create a folder login, remember folder name should be the same as the name of feature file. 
  • login.feature is the feature file name and folder should have name as login
  • Under the login folder, create a loginSteps.js file and start Mapping the test steps with feature file test cases.

and folder in left pane and step definition would look like below:

Step Definition in loginSteps.js

Hit the command npx cypress run and output on console will be displayed as below:

Output after Running feature file

and to run in Test runner enter the command npx cypress open in the terminal and then run feature file and will be displayed as below:

Step Definitions with Dynamic Parameters:

Say, when you have to pass username and password as dynamic values below is the code snippets to be followed

Feature: Login Tests

Login Test Cases

Scenario: Login with valid credentials

Given Login to the application
When I type username as "username"
And I type password as "password"
Then click Login
And See the homepage

import { Given , And , Then , When} from "cypress-cucumber-preprocessor/steps";

Given('Login to the application', () => {
   cy.visit('http://zero.webappsecurity.com/login.html')
  })
  
  When('I type username as {string}',username=> {
    cy.get('#user_login').type(username)
  })
  And('I type password as {string}',password=> {
    cy.get('#user_password').type(password)
  })
  Then('click Login', () => {
    cy.get('input[name="submit"]').click()
  })
  And('See the homepage', () => {
    cy.get('a:contains("Zero Bank")').should('be.visible')
  })
  

and In the Test Runner, it will be shown as with proper Given, When, Then and And statements:

Test Runner when passed Dynamic values

Concept of Grouping and Filtering of Test Cases/ Smart Tagging:

when you have multiple scenarios and wanted to check few test cases to run, just put @focus on the specific scenarios you want to run:

@focus on 1st sceanrio

and it skips the other test case in Test Runner.

Also, you can tag your test cases with @smoke and @Regression test cases and run the particular scenarios from your command line with the below command :

  ./node_modules/.bin/cypress-tags run -e TAGS=’not @Smoke and (@Regression or @Sanity)’

Hooks Support in cypress and cucumber:

  • The cypress-cucumber-preprocessor supports both Mocha’s before/beforeEach/after/afterEach hooks and Cucumber’s Before and After hooks.
  • Cucumber Before hooks run after all Mocha before and beforeEach hooks have completed and the Cucumber After hooks run before all the Mocha afterEach and after hooks.
  • As we are using Mocha test framework with cucumber and cypress, it’s always good to go with Mocha hooks.

Let’s begin to Explore Data Driven Testing with cucumber:

Feature File:

Feature: Login Tests

Login Test Cases

Scenario: Login with multiple credentials
Given Login to the application
When I type the credentials
| uname | pword |
| username | password |
| hello | world |
Then click Login

To pass multiple test data set, you define the test set in tabular form like done above:

import { Given , And , Then , When} from "cypress-cucumber-preprocessor/steps";

Given('Login to the application', () => {
   cy.visit('http://zero.webappsecurity.com/login.html')
  })
  
  When('I type the credentials',function(dataTable) {
    cy.get('#user_login').type(dataTable.rawTable[1][0])
    cy.get('#user_password').type(dataTable.rawTable[1][1])
    cy.get('#user_login').type(dataTable.rawTable[2][0])
    cy.get('#user_password').type(dataTable.rawTable[2][1])
  })

  Then('click Login', () => {
    cy.get('input[name="submit"]').click()
  })


 

Let’s try to understand the code:

To fetch the test data, just write dataTable in function and as I have defined 2D array, fetch first username as dataTable.rawTable[1][0] that means raw one and 0 coloumn and it will fetch username as “username”.

Generating HTML Cucumber Reports:

Add below code snippet in package.json

 "cypress-cucumber-preprocessor": {
    "cucumberJson": {
      "generate": true,
      "outputFolder": "cypress/cucumber-json",
      "filePrefix": "",
      "fileSuffix": ".cucumber"
    }
  }

and remember we have already have cypress-cucumber-preprocessor “nonGlobalStepDefinitions”: true, after that cucumberJson should be put in package.json and output will be generated under cypress/cucumber-json.

cucumber.json file:

login.cucumber.json

And to create HTML report : Install this plugin with the following command:

  • npm install multiple-cucumber-html-reporter –save-dev
  • Add cucumberHTMLReport.js file under your parent project and paste the below code:

const report = require('multiple-cucumber-html-reporter');

report.generate({
	jsonDir: './path-to-your-json-output/',
	reportPath: './path-where-the-report-needs-to-be/',
	metadata:{
        browser: {
            name: 'chrome',
            version: '60'
        },
        device: 'Local test machine',
        platform: {
            name: 'ubuntu',
            version: '16.04'
        }
    },
    customData: {
        title: 'Run info',
        data: [
            {label: 'Project', value: 'Custom project'},
            {label: 'Release', value: '1.2.3'},
            {label: 'Cycle', value: 'B11221.34321'},
            {label: 'Execution Start Time', value: 'Nov 19th 2017, 02:31 PM EST'},
            {label: 'Execution End Time', value: 'Nov 19th 2017, 02:56 PM EST'}
        ]
    }
});

Configure jsonDir and reportPath as or the way you want :

Now, we need to execute this js file to get the HTML Report , just hit the command as node cucumberHTMLReport.js

Output for HTML Report

Open this file in browser to get full-fledge HTML report:

HTML Report with Features, Scenarios and Run info with how total test cases, passed, failed state.

 

For the code reference, please clone the project from:

https://github.com/MandeepKaur2020/CypressFrameworkBDD.git

References:

Conclusion:

In this write up, we learnt about how to create test automation framework using cypress with cucumber and generated some good HTML Reports.

Blog Contributors:

Author:  Mandeep Kaur
Mandeep, having 5+ years of Testing experience in automation using Selenium (Java) and Cypress. Expertise in API using Rest Assured, HTTP Client and Performance testing using JMeter.

https://www.linkedin.com/in/mandeepkaur93/

Reviewer: Naveen Khunteta 
https://www.linkedin.com/in/naveenkhunteta

 

 

 

 

HTTP POST Method Using RestAssured

 

                      ~ Image Source:google/.sashido.io/

Introduction

In this article, we are going to learn about the HTTP Post Method in detail and various ways to create a post payload, in addition to that, we will also learn how to validate Post Response using RestAssured.

Writing post Method

Let’s start writing our first positive scenario :

  1. Given Accept the given content in JSON format
  2. with content type as JSON
  3. and Body
  4. when I performed the Post Request
  5. Then status Code should be 200 OK
  6. And The response should have name as given in JSON body

 

Code with Positive test case

  • As depicted in the screenshot, Primarily, to hit the JSON HTTP post request we need to have JSON Body and passing the JSON body as a string in Body function would suffice our need.
  • This means, once we have the body, we can simply pass our endpoint here in the .post function and once it is successful, we need to assert whether we get the expected output or not.
  • Below is the code for same:

Note: Content type can be XML if you are using XML, else it would be JSON

package com.restassured.tests;

import io.restassured.http.*;
import org.apache.http.HttpStatus;
import org.testng.annotations.Test;

import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;

/**
 * @Author: Mandeep Kaur
 */
public class PostMethodTest {

    @Test
    public void sampleTest() {

        // Json Body to pass in the request
        String jsonBody = "{" +
                "   \"name\":\"Test Automation\",\n" +
                "   \"gender\":\"Male\",\n" +
                "   \"email\":\"testAutomation3@gmail.com\",\n" +
                "   \"status\":\"Active\"\n" +
                "}";

        given().header("authorization", "Bearer 0431655cfe7ba40a791e0ce32d83ad33363348919c11627f409a3228f205e15f")
                .accept(ContentType.JSON)
                .contentType(ContentType.JSON)
                .and()
                .body(jsonBody)
                .when()
                .post("https://gorest.co.in/public-api/users")   //hit the post end point
                .then().
                assertThat()
                .statusCode(HttpStatus.SC_OK)
                .and()
                .body("data.name", equalTo("Test Automation")); // Match the output actual to expected

    }
}

Another scenario is the negative case:

Would be if we send the same request, then it should return the response code as “422” and message as email has already been taken because to create user every time unique email should be passed:

Code with negative test case when an email is already existing

JSON Object

Now, the other way of creating the payload/ request is through JSON Object:

JSONObject is an unordered collection of key and value pairs, resembling Java’s native Map implementations.

  • Keys are unique Strings that cannot be null
  • Values can be anything from a Boolean, Number, String, JSONArray or even a JSONObject.NULL object
  • A JSONObject can be represented by a String enclosed within curly braces with keys and values separated by a colon, and pairs separated by a comma
  • It has several constructors with which to construct a JSONObject

Instead of sending the hardcode JSON body, we can send customize data along with post request.

For this scenario,  what we need to do is :

Add this maven dependency in your project

Json Dependency

After that manipulate below JSON request to JSON Object:

{
"name":"Test Automation",
"gender":"Male",
"email":"testAutomation6@gmail.com",
"status":"Active"
}

And here’s the below code for the same :

Post Request by JSONObject

package com.restassured.tests;

import org.json.JSONObject;
import org.junit.Test;
import io.restassured.http.ContentType;
import static io.restassured.RestAssured.given;

/**
 * 
 * @author Mandeep kaur
 *
 */

public class SamplePostRestTest {

	@Test
	public void createUser_whenSuccess() {


		JSONObject jsonObject = new JSONObject();

		//insert key value pair to jsonObject
		jsonObject.put("name", "Test Automation");
		jsonObject.put("gender", "Male");
		jsonObject.put("email", "testAutomation14@gmail.com");
		jsonObject.put("status", "Active");

		String resp=  given().log().all().header("authorization", "Bearer 0431655cfe7ba40a791e0ce32d83ad33363348919c11627f409a3228f205e15f23")
				.accept(ContentType.JSON)
				.contentType("application/json")
				.and()
				.body(jsonObject.toString())
				.post("https://gorest.co.in/public-api/users")   //hit the post end point
				.thenReturn().asString();

		System.out.println(resp);

	}
}

As can be seen, We can use JSONObject and insert the values in the attribute just like hashMap in java and later on, can pass the JSON object in String. After that, validations can be performed accordingly:

And From hashMap also we can create JSON Object like below:

Map<String, String> map = new HashMap<>();
map.put("name", "Test Automation");
map.put("gender", "Male");
map.put("email", "testAutomation14@gmail.com");
map.put("status", "Active");
JSONObject jo = new JSONObject(map);

and this jo object reference can simply be passed in the request.

Since this nature of post request is quite simple, so for the complex request, you need to modify the request as per given specification.

Let’s take a small example:

[
    "Employee",
    {
        "city": "chicago",
        "name": "john",
        "age": "36"
    }
]

Now here it is having array and then a JSON object :

To build this request we need to have this below structure:

JSONArray jsonArray = new JSONArray();
jsonArray.put("Employee");

JSONObject jo = new JSONObject();
jo.put("name", "john");
jo.put("age", "22");
jo.put("city", "chicago");

jsonArray.put(jo);

To illustrate the example above, we first need to create the JSON object and insert values in it, once done then we need to pass this object in JSON Array which again comes from org.json package(below-detailed description of JSONArray), JSON array has its own element as “Employee” which can also be inserted using put() method and finally we can insert this JSONArray into request body like below

JSONArray is an ordered collection of values, resembling Java’s native Vector implementation.

  • Values can be anything from a Number, String, Boolean, JSONArray, JSONObject or even a JSONObject.NULL object
  • It’s represented by a String wrapped within Square Brackets and consists of a collection of values separated by commas
  • Like JSONObject, it has a constructor that accepts a source string and parses it to construct a JSONArray

package com.restassured.tests;

import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.Test;
import io.restassured.http.ContentType;
import static io.restassured.RestAssured.given;

/**
 * 
 * @author Mandeep kaur
 *
 */

public class SamplePostRestTest {

	@Test
	public void createUser_whenSuccess() {


		JSONArray jsonArray = new JSONArray();
		jsonArray.put("Employee");

		JSONObject jo = new JSONObject();
		jo.put("name", "john");
		jo.put("age", "22");
		jo.put("city", "chicago");

		jsonArray.put(jo);

		 given().log().all().header("authorization", "Bearer 0431655cfe7ba40a791e0ce32d83ad33363348919c11627f409a3228f205e15f23")
				.accept(ContentType.JSON)
				.contentType("application/json")
				.and()
				.body(jsonArray.toString())
				.post("https://gorest.co.in/public-api/users")   //hit the post end point
				.thenReturn().asString();

             }
	}

If there will be any issues with JSON Object, We will get below exception:

 

JSON Exception

The JSONException is the standard exception thrown by this package whenever any error is encountered. This is used across all classes from this package. The exception is usually followed by a message that states what exactly went wrong.

Object Mapping:

Lastly, the other method where payloads can be really complexed, we can go for Object Mapping:

We need to follow below steps :

  • Create a Mapping class also called POJO class (Plain Old Java Objects) and this process is called serialization as we are going to convert the object to the body.
  • Create an object of Mapping class
  • Initialise the values available in the mapping class
  • Send the object along with post request

Let’s analyse the below code

{
“name”:”Test Automation”,
“gender”:”Male”,
“email”:”testAutomation6@gmail.com”,
“status”:”Active”
}

To Create the mapping class, I would say go to  JSONToJavaObject, paste the JSON request and get the Mapping class. As done below:

JsonToPOJO

Mapping class

And our createUser Mapping class will look like this:

package com.restassured.vo;

public class createUserDO  {

    private String name;
    private String gender;
    private String email;
    private String status;


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

  
}

Now, the second step is to create an object of Mapping class:

  • createUserDO cu = new createUserDO();
  • Initialised the values via setters i.e setName(“Test Automation”) available in the mapping class.
  • and finally, we sent the object in the post call

package com.restassured.tests;


import org.junit.Test;

import com.restassured.vo.createUserDO;

import io.restassured.http.ContentType;
import static io.restassured.RestAssured.given;

/**
 * 
 * @author Mandeep kaur
 *
 */

public class SamplePostRestTest {

	@Test
	public void createUser_whenSuccess() {
	createUserDO cu = new createUserDO();
        cu.setName("Test Automation");
        cu.setGender("Female");
        cu.setEmail("testAutomation25@gmail.com");
        cu.setStatus("Active");
        
		String resp =  given().log().all().header("authorization", "Bearer 0431655cfe7ba40a791e0ce32d83ad33363348919c11627f409a3228f205e15f")
				.accept(ContentType.JSON)
				.contentType("application/json")
				.and()
				.body(cu)
				.post("https://gorest.co.in/public-api/users")   //hit the post end point
				.thenReturn().asString();
		
		System.out.println(resp);

             }
	}

POST Method via Mapping class

Note: if we need to have logs to verify things, we can simply use log().all() and it can display information on a console like below:

Logs on Console

Since we have converted our object to the body, now to validate the response we can use the process called deserialization of response body, which means converting response body to object.

To do that, the first thing is to create a mapping class for response JSON body, you use the same converter as above json2pojo schema and below code how it is to be done:

Deserialization of Response body

package com.restassured.tests;

import static io.restassured.RestAssured.given;

import org.junit.Test;
import org.testng.Assert;

import com.restassured.vo.CreateUserDO;
import com.restassured.vo.ResponseDataObjects;

import io.restassured.http.ContentType;

/**
 * 
 * @author Mandeep kaur
 *
 */

public class SamplePostRestTest {

	@Test
	public void createUser_whenSuccess() {


		CreateUserDO cu = new CreateUserDO();
        cu.setName("Test Automation");
        cu.setGender("Female");
        cu.setEmail("testAutomation1465@gmail.com");
        cu.setStatus("Active");
        
        
      ResponseDataObjects responseDataObjects =  given().log().all().header("authorization", "Bearer 0431655cfe7ba40a791e0ce32d83ad33363348919c11627f409a3228f205e15f")
				.accept(ContentType.JSON)
				.contentType("application/json")
				.and()
				.body(cu)
				.post("https://gorest.co.in/public-api/users")   //hit the post end point
				.thenReturn().as(ResponseDataObjects.class);
		
		      Assert.assertEquals("Test Automation",responseDataObjects.getData().getName());
        
       

             }
	}

Till .post function we were clear what needs to be performed, the next step is thenReturn(), basically, to fetch the response body after that, as (the method )will take the mapping class(ResponseDataObjects ) to deserialize the response and this will return us the object of our mapping class.

And this class can be used to fetch all the information later on, for validations and verification checks.

Our JSON Response

{
    "code": 201,
    "meta": null,
    "data": {
        "id": 1493,
        "name": "Test Automation",
        "email": "testAutomation701@gmail.com",
        "gender": "Male",
        "status": "Active",
        "created_at": "2021-01-07T12:30:58.987+05:30",
        "updated_at": "2021-01-07T12:30:58.987+05:30"
    }
}

And correspondence POJO class:

Note: we need to use @JsonIgnoreProperties(ignoreUnknown=true)as  is applicable at deserialization of JSON to Java object (POJO) only

package com.restassured.vo;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class ResponseDataObjects {

    private Integer code;
    private Object meta;
    private Data data;

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public Object getMeta() {
        return meta;
    }

    public void setMeta(Object meta) {
        this.meta = meta;
    }

    public Data getData() {
        return data;
    }

    public void setData(Data data) {
        this.data = data;
    }
    
}

package com.restassured.vo;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Data {

	
    private Integer id;
    private String name;
    private String email;
    private String gender;
    private String status;
    private String createdAt;
    private String updatedAt;
    
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(String createdAt) {
        this.createdAt = createdAt;
    }

    public String getUpdatedAt() {
        return updatedAt;
    }

    public void setUpdatedAt(String updatedAt) {
        this.updatedAt = updatedAt;
    }

}

Conclusion:

In this article, we have learnt how to create a payload using various ways such as via string, JSON Object and with object Mapping and how to fetch the response using Deserialization.

Blog Contributors:

Author:  Mandeep Kaur
Mandeep, having 5+ years of Testing experience in automation using Selenium (Java). Expertise in API and Performance testing using JMeter.
https://www.linkedin.com/in/mandeepkaur93
 
Reviewer: Naveen Khunteta 
https://www.linkedin.com/in/naveenkhunteta

HTTP GET method using RestAssured

Get Request And Response
~Image Source : google / sashido.io

  1. Introduction

In this article, we are going to learn about the Get Request in detail, in addition to that, we will also learn how to validate Get Response using RestAssured.

2. Writing Get Method:

Let’s first get started with the simple example – Fetch user details and handle the response:

Assume application is up and running , let’s perform some action using when()

As we can see return type of when() is RequestSender ~https://javadoc.io/doc/io.rest-assured/

and RequestSender Interface Implements Classes as:RequestSpecificationImplTestSpecificationImpl

And in RequestSpecificationImpl class we have below methods such as get() :

Get Methods

Now, Let’s write the Get Method Code:

package com.restassured.testcases;

import static io.restassured.RestAssured.given;

import io.restassured.http.ContentType;
import io.restassured.response.Response;
import org.testng.annotations.Test;

/**
 *
 * @author Mandeep Kaur
 *
 */
public class SampleGetTest {

   @Test
    public void getTest() {

        /*
         * given application is up and running and performing the GET request with get(URL)
         * and printing the response 
         *
         */
        Response response =given().header("authorization", "Bearer 0431655cfe7ba40a791e0ce32d83ad33363348919c11627f409a3228f205e19f").when()
                .get("https://gorest.co.in/public-api/users");

        //Printing the response
        System.out.println(response.asString());
} }

In the above code ,it is clearly seen that we need header in order to execute get request and it takes key-value pair where Key as authorisation and value as Bearer access_token , get (URL ) and simply print the response and output will be like below and stored in response object.

User details are coming in response what’s more the details of test cases if it’s passed, failed depends on the test case written:

Output on the console and test case is passed and marked as green.

In order to validate status code , below code needs to be executed:

package com.restassured.testcases;

import static io.restassured.RestAssured.given;

import io.restassured.http.ContentType;
import io.restassured.response.Response;
import org.apache.http.HttpStatus;
import org.testng.annotations.Test;

/**
 * @author Mandeep Kaur
 */
public class SampleGetTest {

    @Test
    public void getTest() {

        /*
         * given application is up and running and performing the GET request with get(url)
         * with header then status code should be 200 OK
         *
         */
        given().header("authorization", "Bearer 0431655cfe7ba40a791e0ce32d83ad33363348919c12327f409a3228f205e19f").when()
                .get("https://gorest.co.in/public-api/users").then().assertThat().statusCode(HttpStatus.SC_OK);
    }
}

It can be inferred from the above code, if expected code is 200 ok then to validate it , we can use .assertThat and statusCode: HttpStatus.SC_OK without using 200 hard code value as it is, we can use HttpStatus interface variable from package org.apache.http; Similarly, the other statuses from Interface HttpStatus can be fetched like below:

Since, we have validated the status code, Let’s validate the response content also content level validation. Once we received the response , how we will validate that the content is proper or not ?

So, rest assured uses hamcrest Framework for validation.

Inside org.hamcrest package there is a class called Matchers and this class contains all the methods which we can be used for our validation purpose. Below are the methods of Matchers class and you can navigate here to learn more about Matchers class :

Go to Library org.hamcrest > Matchers Class> Methods

Matchers Class under org.hamcrest package

Let’s see the below code:

package com.restassured.testcases;

import static io.restassured.RestAssured.given;

import io.restassured.http.ContentType;
import io.restassured.response.Response;
import org.testng.annotations.Test;
import static org.hamcrest.Matchers.*;

/**
 * @author Mandeep Kaur
 */
public class SampleGetTest {
    @Test
    public void getTest() {

        /*
         * given application is up and running and performing the GET request with get(url)
         * Then response should have first email as given below
         */
        given().header("authorization", "Bearer 0431655cfe7ba40a791e0ce32d83ad33363348919c11627f409a3228f205e15f0394504395435").when()
                .get("https://gorest.co.in/public-api/users").
                then().
        body("data.email[0]",equalToIgnoringCase("dhawan_dharani@macejkovic.co"));


    }
}

After hitting the get endpoint , in the body we are validating whether the first email in our response matches to the given email given above in the code and here equalToIgnoringCase comes from the matches Class of hamcrest framework. what it does is where both actual value is equal to expected value irrespective of case.

If both the values matched we will get our test case passed otherwise it will failed as actual value is not getting matched with expected value.

Here’s the json response , for which our code matched perfectly:

Json Response

If not matched the expected value, then we will get the error as below:

and if multiple values to be validated , we can validate like below using comma  :

By now , You must be wondering why did i use data.email[0] for this we need to learn Json Path.

And another way of validating it with hasItem method of hamcrest and if it list needs to be validated then hasItems method will be used:

HasItem Method

hasSize to use when to check how many element a particular json array contains. For Example:

 "data": {
        "data1":[
            "id": 6,
            "name": "Dharani Dhawan",
            "email": "dhawan_dharani@macejkovic.co",
            "gender": "Female",
            "status": "Active",
]}

Now this contains 5 elements so size will be 5.

and in body we can assert :

.body(“data.data1”,hasSize(5));

3. JsonPath Class :

Another way of validating the response with JsonPath Class:

JsonPath class comes from the package

package io.restassured.path.json;

Let’s see the below code to gain deep understanding of it :

Extracting Values from jsonPath

package com.restassured.testcases;

import static io.restassured.RestAssured.given;
import io.restassured.http.ContentType;
import io.restassured.path.json.JsonPath;
import org.testng.Assert;
import org.testng.annotations.Test;
import static org.hamcrest.Matchers.*;

/**
 * @author Mandeep Kaur
 */
public class SampleGetTest {
    @Test
    public void getTest() {

        /*
         * given application is up and running and performing the GET request with get(url)
         * Then response should have first email as given below
         */
       String resp= given().header("authorization", "Bearer 0431655cfe7ba40a791e0ce32d83ad33363348919c11627f409a3228f205e15f84985934850948")
               .accept(ContentType.JSON)
               .when().get("https://gorest.co.in/public-api/users").
                thenReturn().asString();

        JsonPath jsonpath= new JsonPath(resp);
        Assert.assertEquals("dhawan_dharani@macejkovic.co",jsonpath.getString("data.email[0]"));
    }
}

In this code, we fetched the response and store it in string variable.

Now, this variable needs to be passed as a JsonPath constructor, once this is done

we need to use testNg assertions to check our actual response is matched with expected Response.

Actual Value : given above as email

and jsonpath.getString for fetching the value of particular  Key:

data.email[0] : means Json Object starts with label data and email is comes under that label and JsonPath is same like Xpath where we transverse from root element to parent /sibling so on.

Since we need out first value to be matched me just used email[0].

To fetch int or other values it can be fetched like this :


Fetch values from jsonPath

4.Conclusion:

To conclude, We learnt to write our very first get Request Method and tried to validate our response with hamcrest framework and jsonPath Class .

Blog Contributors:

Author:  Mandeep Kaur
Mandeep, having 5+ years of Testing experience in automation using Selenium (Java). Expertise in API and Performance testing using JMeter.
https://www.linkedin.com/in/mandeepkaur93 
 
Reviewer: Naveen Khunteta 
https://www.linkedin.com/in/naveenkhunteta

 

 

 

 

Introduction To Rest Assured

1. Overview :

In this article, we will learn about automating our first API using Rest Assured and various terms linked with API.

2. API

Before proceeding any further , let’s try to understand what is API .

  • API: Application Programming Interface is nothing but public functions that can be called and executed by other programs, these other programs can be programs running in the same computer or those running in a different computer altogether.

Why do we need API or what does it offers :

  1. Abstraction 
  2. Contractual Obligations between client and backend

Let’s try to understand with the help of an example: 

Consider an ATM Machine, you are provided with multiple options such as checking account balance, cash deposit or withdrawal and statement, etc. So here you get all things by a push of few buttons.

Here APIs  play a Key Role in abstracting you from the backend services. Also performing any operations such as cash withdrawal you need to provide your ATM pin and the amount to be withdrawn.

The withdrawal would be allowed only if your pin is correct and have sufficient balance money in your account and it is within the bank transactional limit for the day. So these are some business rules defined and these are nothing but contractual obligations that an API defines and that has to be fulfilled.

So, in short, if both the business and data logic can be re-used in some other application. Then this application is called a web service.

3. Web Service:

It is an interoperable software system designed to support machine-to-machine interaction over a network. The three necessary conditions for any web application to become a web service:

  1. Interoperability: Any Java, DotNet, PHP, or C++ application, etc.., should be able to interact with the web application.
  2. Application-to-application interaction: For example, Jet Airways in its web application uses a different bank’s payment gateway to make payments. Here, banks have extended their applications over the network to be accessed by the jet airways application. Thus, the bank application is acting as a web service.
  3. Communication must be over a network

Now that you have understood the web service and API, the next important term you need to understand is the API endpoint

  1. It is a location from which an API can access the resource that it needs to carry out the functionality.
  2. It is a unique URL for communications between the client-side and server-side.

By now you have understood that web services are capable of communicating with web applications with the help of API endpoints.

Now the question is what does this API endpoint contain that makes any web server understand the requests from the UI and how to respond back?

The two things that make it possible are the request and response that is passed with every API call.

So now it’s imperative to understand how request and response exchange takes place between a client (Browser) and a server

You must have heard the terms SOAP and Rest, Let’s try to understand these first in detail:

4.SOAP Architecture:

So today many applications built in many programming language . For example there is web applications designed in JAVA, some are in .dot net and some in PHP.All these 

  • Application collect and store data, and this data needs to be exchanged among different applications.
  • But this exchange among these heterogeneous applications would be very complex.
  • So, one of the methods to combat this complexity is to bring a common language which is XML i.e. Extensible Markup Language
  • But there for no specific standard on how to use XML across all the programming language for data exchange

So this is where SOAP or Simple Object Access Protocol comes into the picture.

Here are a few reasons for using SOAP architecture:

  1. SOAP is considered a light-weight protocol that is used by applications for data exchange. Also, since SOAP is particularly based on XML, which in itself is a lightweight data exchange language, so it falls in the same category as a protocol.
  2. SOAP is designed to be platform and operating system independent. It can work with programming languages on both Windows and Linux platforms.
  3. It is based on the  HTTP protocol, which is the default protocol used by all web applications. Therefore, there is no customization required to run the web services built on the SOAP protocol to work on the World Wide Web.
  4. It helps in Exposing business functionality over the internet.

 Some limitations with SOAP architecture such as:

  1. The HTTP protocol is not used to its full extent.
  2. A resource representation is done only in XML which is fast, but still can be considered slower than many of its competing technologies such as JSON.
  3. Working with SOAP requires you to write a proper XML structure almost every time, even for extremely simple tasks. This makes your work lengthy and a bit complex.
  4. The above-mentioned limitations can overcome with the introduction of REST(Representational State Transfer) architecture.

5. Rest Architecture:

Let’s look at some characteristics of the REST architecture:

  1. It makes the best use of the HTTP protocol. The request and response sent are proper HTTP request and response. So, the request contains proper HTTP methods while the response contains proper status codes.
  2. It is a style for designing loosely-coupled web services.
  3. It relies on the stateless, client-server protocol, for example, HTTP. So, it does not store any client’s session on the server-side and thus making the REST APIs less complex to develop and maintain.

6. HTTP Protocol:

We have talked a lot about HTTP protocol, but we still don’t know what exactly is this HTTP or even protocol for that matter. 

So, whenever you enter any URL in the address bar of your browser, the browser translates that URL into a request message according to the specified protocol and then sends it to the server.

There are many predefined HTTP methods that can be used while sending HTTP requests.
Most common HTTP methods:

  1. GET :asks the server to retrieve a resource. You can think of a resource as some data or file on the server
  2. POST : asks the server to create a new resource
  3. PUT: asks the server to update a resource
  4. DELETE: asks the server to delete a resource
  5. PATCH: used to update a portion of an already existing resource

Then there are two different categorisation of HTTP methods:

  1. Safe: Safe methods are those that can be cached and prefetched without any repercussions to the resource. This means that there is no change expected in the resource by the client. So, GET is safe, while PUT, POST, DELETE PATCH are not.
  2. Idempotent: An idempotent HTTP method is one that if called many times will provide the same outcome. It does not matter if the method is called only once or multiple times. The result will always be the same. GET, PUT, DELETE methods are idempotent.

The response from the server is accompanied by a status code. This status code is important as it tells the client how to interpret the server response. Here are some of the common status codes –

  1. 1XX – informational
  2. 2XX – success
  3. 3XX – redirection
  4. 4XX – client error
  5. 5XX – server error

Some of the common HTTP status are:

  1. 201 (CREATED)
  2. 200 (OK)
  3. 401 (UNAUTHORIZED)
  4. 403 (FORBIDDEN)
  5. 400 (BAD_REQUEST)
  6. 404 (NOT_FOUND)

Figure: Sending a Request and getting the Response

Further, you can read about what happens when you type a URL and press enter.

https://medium.com/@maneesha.wijesinghe1/what-happens-when-you-type-an-url-in-the-browser-and-press-enter-bb0aa2449c1a

Till now we have learned about API, Web Services, SOAP and Rest, HTTP protocol, and methods, Now it’s the perfect time to know about Rest Assured.

7.Rest Assured:

  • REST Assured is an open-source Java library for validation of REST web services.
  • It is flexible and easy to use and supports all the Http Methods such as GET, POST, PUT, etc.
  • It supports BDD (Behavior-Driven Development) by using test notation, Given, When, and Then, which makes the tests human readable.
  • Rest Assured API uses the “Hamcrest” framework for validation.Which we will learn it in detail

8. Creating a simple Rest Assured Program:

Pre-requisites:

JDK 8 , Maven, Eclipse IDE

Let’s get started by creating the first project. Open Eclipse IDE and create a new project.

  1. Click on new –> Maven Project → create simple project → Next

2. Provide group id and Artifact id and click on finish:

Now , configure testNg and Rest Assured library in your pom File:

Once , libraries are added then create a class under src/test/java and create a test method in it:

Here’s the code:



package com.restassured.testcases; import org.testng.annotations.Test; import io.restassured.http.ContentType; import static io.restassured.RestAssured.*; /** * * @author Mandeep Kaur * */ public class SampleTest { @Test public void sampleLogin() { /* * Given application is up and running When i perform the GET request using the * given url Then the status code should be 200 Ok And the response body should * be in Json Format * */ given().accept(ContentType.JSON).header("user-key", "cde67df2673438bb2fae8dc7e205e98451903940394343").when() .get("https://developers.zomato.com/api/v2.1/categories").then().statusCode(200); } }  
  • Before concluding let’s understand few above terms quickly:

    • Rest Assured framework follows the BDD approach.
    • Given keyword defines the precondition
    • When keyword defines the action to be performed
    • Then keyword defines the outcome of the previous step
    • And keyword defines the additional outcome.
    In the above program, the Given application is up and running, the header is passed with a valid user key when performing the GET request using the given URL Then the status code should be 200 Ok And the response body should be in JSON Format (ContentType.Json)

and now run the project using mvn install command and output will be displayed as:

Conclusion:

To encapsulate, we have learned about API and it’s various terminologies, also created our first rest assured test 🙂

Blog Contributors:

Author:  Mandeep Kaur
Mandeep, having 5+ years of Testing experience in automation using Selenium (Java). Expertise in API and Performance testing using JMeter.
https://www.linkedin.com/in/mandeepkaur93
 
Reviewer: Naveen Khunteta 
https://www.linkedin.com/in/naveenkhunteta

 

 

 

 

Actions Class in selenium WebDriver for User Actions

1.Overview

In this article, we are going to explore the most fundamental phenomenon that is Actions class in selenium WebDriver.

2. Actions Class

  • We have performed single actions like sendKeys, click event till now.
  • But there are events where we need to perform multiple actions like drag and drop, right-click or pressing a key from the keyboard etc.
  • So here comes the Actions class to deal with such composite actions.
  • By selenium documentation, they have defined the Actions class as:

Actions Class
  • In simple terms, Actions class handles various types of keyword and mouse events and is available under package 
import org.openqa.selenium.interactions.Actions;
  • Syntax:
Actions actions = new Actions(driver);
  • For creating an object of an action class, you need to pass the driver object to the constructor of action class like the following :

Methods in Actions Class

Now, you can perform any composite actions as shown above with the action object. We will see a couple of examples below where composite actions are being performed.

To Note: There are two major methods in actions class are build and perform.

build() compiles all the steps into a single step and then perform() executes the step, also for single-step perform() method can be used, then there is no need to execute the build() method.

3. Mouse Hover with Actions class

  • A mouse hovers cause an event to trigger actions such as where a user places a mouse over a particular element like hovering over a tab or link. 
  • moveToElement is the method used for hovering action:

Mouse Hovering Methods

Let’s understand moveToElement(WebElement target) by code:

package com.selenium.sessions;

import org.junit.jupiter.api.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;

/**
 * 
 * @author Mandeep kaur
 * @Date May 19,2020
 */
public class ActionClass {

	@Test
	public void performsActionClass() throws InterruptedException {

		String path = System.getProperty("user.dir");
		System.setProperty("webdriver.chrome.driver", path + "/src/main/resources/chromedriver");

		System.setProperty("webdriver.chrome.silentOutput", "true");
		WebDriver driver = new ChromeDriver();

		driver.get("https://www.makemytrip.com/visa/");

		// Locate more element on the web page
		WebElement moreObj = driver.findElement(By.xpath("//li[10]/a/span[2]/span[1]"));

		Thread.sleep(1000);

		// Locate International Hotels once hovered over more element
		WebElement moveToInternationalHotels = driver.findElement(By.xpath("//li[10]/div/a[3]"));

		Actions action = new Actions(driver);

		// hover to More element then hover to International hotel and build the steps
		// in singe unit and perform the step
		action.moveToElement(moreObj).moveToElement(moveToInternationalHotels).build().perform();

		Thread.sleep(1000);
		driver.close();

	}

}

Explanation :

First, we found out the elements where mouse hovering is required i.e more element and other is International hotels.

Then we are hovering over these elements with the moveToElement method, post that we build these steps it in a single unit using build() method and execute it with perform() method.

And we can see the above code output as:

Now, Let’s proceed with other method moveToElement(target, xOffset, yOffset);

This method is used to take the mouse on particular points on target elements.

The following is an example to deal with a slider:

Now the scenario is we need to move this slider, but how do we do that?

Let’s see the below code first to achieve this task:

package com.selenium.sessions;

import org.junit.jupiter.api.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;

/**
 * 
 * @author Mandeep kaur
 * @Date May 19,2020
 */
public class ActionClass {

	@Test
	public void moveToElementOffset_whenSuccess() throws InterruptedException {

		String path = System.getProperty("user.dir");
		System.setProperty("webdriver.chrome.driver", path + "/src/main/resources/chromedriver");

		System.setProperty("webdriver.chrome.silentOutput", "true");
		WebDriver driver = new ChromeDriver();

		driver.get("https://jqueryui.com/slider/");

		// Get the location of IFrame
		WebElement iFrame = driver.findElement(By.xpath("//iframe[@class='demo-frame']"));

		driver.switchTo().frame(iFrame);

		// get the slider element
		WebElement slider = driver.findElement(By.xpath("//div[@id='slider']"));

		// Get the location of X,Y coordinates
		System.out.println(slider.getLocation());

		Thread.sleep(1000);

		Actions action = new Actions(driver);

		// move the element on target by X , Y coordinates
		action.moveToElement(slider, 8, 8).click().build().perform();

		Thread.sleep(1000);

		driver.close();
	}

}

Let’s break the code into the statement to get the clarity of the concept:

  1. First, we need to locate the frame, as the slider is present in the frame.

Let’s discuss little about iFrames, what are these:

  • iFrames stands for an inline frame. It is like another web page within a web page. 
  • In this case, a different document is used to embed within the current HTML document.
  • when you execute any method say findByElement for an element present in an iFrame, it will throw an exception as an element not found. 
  • For this, we first need to switch the focus to the frame to get the Element.
  • Syntax: driver.switchTo().frame();

Switching to Frame

And most importantly how we will get to know that frame is present or not, for that you need to right-click on the element and you will get View Frame Source like below

And in DOM you will get to see an iFrame tag

where <iframe> tag states an inline frame.

We can switch to the frame by index , by frame name or id or by WebElement.

2. In the above code, we have to switch the frame with WebElement.

3. Find the target element and get the location of X and Y coordinates by using getLocation().

4. Once we got the coordinates then we can slide the cursor accordingly by passing the target, x and y coordinates:

action.moveToElement(slider, 8, 8).click().build().perform(); 

 As can be seen below our slider has moved with coordinates given:

4. Drag And Drop with Actions Class

Now, there are situations where we need to perform drag and drop operation. We can also perform this scenario with the action class.

  • There is a method called dragAndDrop which drags a source element and drops on a target element.
  • We need to solve the scenario given below

Drag and Drop Image

So, here we just have to put “Drag me to my target” box to “Dropped!” box

Let’s do it by code:

Code for Drag and Drop

package com.selenium.sessions;

import org.junit.jupiter.api.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;

/**
 * 
 * @author Mandeep kaur
 * @Date May 19,2020
 */
public class ActionClass {

	@Test
	public void dragAndDropExample_whenSuccess() throws InterruptedException {

		String path = System.getProperty("user.dir");
		System.setProperty("webdriver.chrome.driver", path + "/src/main/resources/chromedriver");

		System.setProperty("webdriver.chrome.silentOutput", "true");
		WebDriver driver = new ChromeDriver();

		driver.get("https://jqueryui.com/droppable/");

		// Get the location of IFrame
		WebElement iFrame = driver.findElement(By.xpath("//iframe[@class='demo-frame']"));

		driver.switchTo().frame(iFrame);

		// get the source element 
		WebElement source = driver.findElement(By.id("draggable"));

		// get the target element 
		WebElement target = driver.findElement(By.id("droppable"));

		Thread.sleep(1000);

		//create an object of Action class
		Actions action = new Actions(driver);
		
		// perform drag and Drop operation
		action.dragAndDrop(source, target).build().perform();

		Thread.sleep(1000);
		
		driver.close();

	}

}

So, it’s pretty clear from the above code that first it requires us to switch to the iframe as the elements are present in an iframe. Then we have to find our source and target element and just perform dragAndDrop Operation on it as has been done for you above.

And the output will be shown as follows:

 We can also have another example where certain actions need to be performed from Keyboard. User has to send some inputs from the Keyboard.

Let’s see this happening in the following example in the code:

As described in the above code, first we find the elements where keyboard actions have to be performed then with movetoElement function we move to userName element and KeyDown function to  press the shift key and sending the userName in upper case, post that KeyUp function  to  release the shift key and next we are highlighting the userName

In the end, we are clicking on signUp button with the help of Enter Key.

package com.selenium.sessions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Action;
import org.openqa.selenium.interactions.Actions;

/**
 *
 * @author Mandeep kaur
 * @Date May 19,2020
 */
public class ActionClass {

@Test
public void keyBoardEvents_whenSuccess() {

String path = System.getProperty(“user.dir”);
System.setProperty(“webdriver.chrome.driver”, path + “/src/main/resources/chromedriver”);

System.setProperty(“webdriver.chrome.silentOutput”, “true”);
WebDriver driver = new ChromeDriver();

driver.get(“https://www.facebook.com/“);

WebElement userName = driver.findElement(By.xpath(“//*[@name=’firstname’]”));

WebElement signUp = driver.findElement(By.xpath(“//*[@name=’websubmit’]”));

// In this step, we are moving the userName element and KeyDown function press
// the shift key and sends the userName and KeyUp function perform release the
// Key and next we are highlighting the userName


Actions builder = new Actions(driver);
builder.moveToElement(userName).click().keyDown(userName, Keys.SHIFT).sendKeys(userName, “testuser”)
.keyUp(userName, Keys.SHIFT).doubleClick(userName).build().perform();

// Enter the sign up keys after we passed the userName

signUp.sendKeys(Keys.ENTER);

driver.close();
}
}

5.Conclusion

In this article, we learnt about Actions class and how we can perform various composite actions using actions classes.

Thanks for reading it! 

Cheers!!

Naveen AutomationLabs

Blog Contributors:

Author:  Mandeep Kaur

Mandeep, having 5+ years of Testing experience in automation using Selenium (Java). Expertise in API and Performance testing using JMeter.

https://www.linkedin.com/in/mandeepkaur93

Reviewer: Naveen Khunteta

https://www.linkedin.com/in/naveenkhunteta

Handling Browser Window PopUp in Selenium WebDriver

1. Overview

In this article, we will discuss the concept of browser window popup also the practical implementation to handle the browser window popup with selenium web driver.

2. Browser window Popup

  • Browser window popup is a window popup that suddenly pops up on after clicking on some link or on selecting an option. It just likes another web page where maximization and minimization of the web page can be done.
  • This is having its own title and url or it could be an advertisement pop up also.
  • When do we need to handle this browser window popup: if the scenario is something like: you click on some link on the main window (parent window) and some other screen pops out just another webpage (child window ), now child window demands to submit some important information and press OK once information is filled.
  • Let’s see how the browser window appears:

Browser window popup Example

3. Steps to deal with browser window popup

1. Operate on the main window that opens the popup window. For instance, click on some link on the main window.

2. Need to know the name or id of the popup window. The window Id can be fetched from Window Handler API available in selenium. it uniquely identifies the address of all the windows open at a time. Below are the methods to handle the windows:

Syntax:

driver.getWindowHandle();

  • This function allows the handling of the current window by getting the current window Handle.
  • It returns the type String.
  • On the selenium official site, this is defined as


String parentWindowObj = driver.getwindowhandle();

driver.getwindowhandles();

  • As the method name suggests windowHandles, that means there are multiple windows and to handle all these opened windows we have to use this function.
  • It returns the Set of String.
    • Set<String> handles = driver.getwindowhandles();
  • Set stores the unique values and handle of all the windows that will be unique.
  • Below description clearly says the same:
  • Set values are not stored based on the index, so to iterate over the set, we need to use the Iterator to get the handler values and this method will give you an iterator of string.
  • This Iterator will be available in java. util package.
Iterator<String> it = handler.iterator();

//get the window ID for Parent a& Child now
String parentWindowID = it.next();
String childWindowID = it.next();

3. switch the driver to the popup window

driver.switchTo.window(childWindowID);

4. Perform some actions in the popup window such as get the title or close the button/tab etc.

driver.switchTo().window(childWindowID);
String title = driver.getTitle();
System.out.println("child window title is : " + title);

//close the pop up window now by using driver.close() method.
driver.close();

tip: Make sure, you are using close() to close the pop up. If you use quit() it will close parent and child both.
This is the basic difference between close() & quit().

5. Switch back to the parent window by passing the parentWindowID.

driver.switchTo().window(parentWindowID);
String title = driver.getTitle();
System.out.println("parent window title is : " + title);

//close the parent window by using quit:
driver.quit();

Let’s see the below code for a complete understanding of the concept:

Full code to handle Browser window popup:
package SeleniumSessions;

import java.util.Iterator;
import java.util.Set;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import io.github.bonigarcia.wdm.WebDriverManager;

public class BrowserWindowPopUp {

public static void main(String[] args) {

WebDriverManager.chromedriver().setup();
WebDriver driver = new ChromeDriver();

driver.get(“http://www.popuptest.com/goodpopups.html”);

driver.findElement(By.linkText(“Good PopUp #3”)).click();

Set<String> handles = driver.getWindowHandles();

Iterator<String> it = handles.iterator();

String parentWindowID = it.next();
System.out.println(“parent window id is : ” + parentWindowID);

String childWindowID = it.next();
System.out.println(“child pop up window id is : ” + childWindowID);

driver.switchTo().window(childWindowID);

System.out.println(“child window title is ” + driver.getTitle());

driver.close();

driver.switchTo().window(parentWindowID);
System.out.println(“parent window title is ” + driver.getTitle());

}

}

Important Tip:

One thing to notice here is that we have to come back to parent window if any further actions have to performed on Parent window. Without switching to parent window will not allow us to perform any action on parent window page.

Let’s add another example to get more understanding of the concept:

Suppose four windows are open and we want to switch to the third window.  

  • First Approach: using Set and iterator we have already seen above.
  • Second Approach: Using ArrayList. The benefit of this approach is you can easily deal with any window. The parent window will start with an index 0.

Let’s see the code with ArrayList:

package SeleniumSessions;

import java.util.ArrayList;

import java.util.Set;

import org.openqa.selenium.By;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.chrome.ChromeDriver;

public class BrowserWindowHandleList {

public static void main(String[] args) {

System.setProperty(“webdriver.chrome.driver”, “/Users/NaveenKhunteta/Downloads/chromedriver”);

WebDriver driver = new ChromeDriver();

driver.get(“http://www.popuptest.com/goodpopups.html”);

driver.findElement(By.linkText(“Good PopUp #3”)).click();

Set<String> handles = driver.getWindowHandles();

ArrayList<String> ar = new ArrayList<String>(handles);

System.out.println(ar);

String parentWindowID = ar.get(0);

System.out.println(parentWindowID);

String childWindowID = ar.get(1);

System.out.println(childWindowID);

driver.switchTo().window(childWindowID);

System.out.println(“child window title is “ + driver.getTitle());

driver.close();

driver.switchTo().window(parentWindowID);

System.out.println(“parent window title is “ + driver.getTitle());

}

}

 

And we’ll get the output as following:

As can be seen through the above code, you can easily browse through the windows following this approach.

6. Conclusion

We have learnt to handle  browser window popup using windowhandler API in Selenium WebDriver. We have solved this use cases by using Set and List both.

That’s about it.



Cheers!!

Naveen AutomationLabs

Blog Contributors:

Author:  Mandeep Kaur

Mandeep, having 5+ years of Testing experience in automation using Selenium (Java). Expertise in API and Performance testing using JMeter.
https://www.linkedin.com/in/mandeepkaur93
 
Reviewer: Naveen Khunteta 
https://www.linkedin.com/in/naveenkhunteta

JS Alert Popup, Auth Pop Up and File Upload Pop Up Handling in Selenium WebDriver

1.Introduction

In this article, we’re going to illustrate how to handle alert or javascript Popup using selenium WebDriver.

2. Basics

Let’s get started by understanding what are these alerts or javascript popups.

  • Javascript Alert/popup is a notification/warning or message displayed on the User interface in box format to notify the user about some information or asks for permission to perform certain kind of operations.
  • Alert is a method in javascript and  displays an alert box with a specified message and an OK button.
  • what do we need to generate this alert on UI is simply open inspect window and click on console and type alert(“Hi this is an automation User!!”) . 
  • you will be able to see the popup similar to this:

3. Types of Alerts

  1. Simple Alert
  2. Confirmation Alert
  3. Prompt Alert

Let’s have a look at the first one:

Simple Alert:

This alert is called simple alert because it just notifies the user some information or warning with an “OK” or “Close” button as shown in the following image.

  • The above popup can not be handled with finding XPath of OK Button as we can not inspect or spy over this button.
  • So, to handle the above Popup, we need to look at Alert interface of selenium WebDriver

Alert Interface

  • Alert is an interface in selenium provide some methods to handle the alert
  • Syntax:
  • Alert alert= driver.switchTo().alert();
  • To handle the Alert, we first need to switch to alert using switchTo() method.
  • WebDriver interface contains method switchTo() which has return as interface and contains method alert() which has return type as Alert interface. 
  • RemoteAlert class in RemoteWebDriver class implement this Alert Interface
  • For complete code reference, visit over
  • RemoteWebDriver Implementation
  • alert() switches to the alert and return an alert reference and throw “NoAlertPresentException” if no alert exists.
  • Next, Let’s what actions we can perform once we switched to an alert

1.void dismiss(): This method clicks on the ‘Cancel’ button of the alert or dismiss the popup . It returns void.

Syntax:

driver.switchTo().alert().dismiss();

2.void accept(): This method click on the ‘OK’ button of the alert and returns void

Syntax:

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

3.String getText() : This method captures the alert message and returns the String.

Syntax:

driver.switchTo().alert().getText();

4.void sendKeys(String Text):This method passes some data to alert input text and it returns void 

Syntax:

driver.switchTo().alert().sendKeys(“Text”);

Back to simple alert , let’s see following snippet code

 

Simple Alert

As can be seen, for simple Alert we just need to click on OK button and with one statement by switching to alert and accepting it we can achieve this scenario.

  • Confirmation Alert

  • Confirmation Alert is the alert which asks for confirmation from the user to perform certain actions.
  • User can opt for OK or Cancel button based on the requirements and also we can not inspect over this alert also.
  • Let’s see how it looks like

Following code snippet for the same:

package com.example.automation;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

/**
 * @author Mandeep Kaur
 * @Date 6 May,2020
 */
public class SeleniumConfig {
    public static void main(String[] args) throws InterruptedException {
        String path = System.getProperty("user.dir");
        System.setProperty("webdriver.chrome.silentOutput", "true");
        System.setProperty("webdriver.chrome.driver", path + "/chromedriver");
        WebDriver driver = new ChromeDriver();

        driver.get("https://testuserautomation.github.io/Alerts/");
        driver.findElement(By.xpath("//button[2]")).click();

       Alert alert = driver.switchTo().alert();
       System.out.println(alert.getText());
        //For OK button in alert, accept the PopUp
        alert.accept();
        Thread.sleep(2000);
        WebElement text =driver.findElement(By.xpath("//*[@id='demo']"));
        //verify the text after accepting the popUp
        System.out.println(text.getText());
        driver.close();

    }
}

As shown in the code, we have accepted the alert and verify the text we got after running the above piece of code and we get output similar to:

  • Prompt Alert

  • This Alert is to get input from the user in the form of text.
  • From the above methods, we have to use alert.sendKeys() method to send the text in an alert
  • After entering the input, the user can press the OK or Cancel Button.
  • Let’s prompt Alert on UI

 

prompt Alert

Now , see the code snippet for the same:

package com.example.automation;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;


/**
 * @author Mandeep Kaur
 * @Date 6 May,2020
 */
public class SeleniumConfig {
    public static void main(String[] args) throws InterruptedException {
        String path = System.getProperty("user.dir");
        System.setProperty("webdriver.chrome.silentOutput", "true");
        System.setProperty("webdriver.chrome.driver", path + "/chromedriver");
        WebDriver driver = new ChromeDriver();

        driver.get("https://testuserautomation.github.io/Alerts/");
        driver.findElement(By.xpath("//button[3]")).click();

       Alert alert = driver.switchTo().alert();
       System.out.println(alert.getText());
       //Send Text to the Alert
        alert.sendKeys("TestAutomationUser!!");
        //For OK button in alert, accept the PopUp
        alert.accept();
        Thread.sleep(2000);
        WebElement text =driver.findElement(By.xpath("//*[@id='test']"));
        //verify the text after accepting the popUp
        System.out.println(text.getText());
        driver.close();

    }
}

We can see that here before accepting the Popup, we have sent the “TestAutomationUser” to the alert and verified the text after we accepted the popup and output will be like following

 
 
 
Do we have some other pop ups as well? 
Answer is YESSS…
 
 
Now, there are few other Popups such as Authentication popup and window-based  popup like file Upload , we need to have strong understanding to tackle such popups :
Let’s quickly discuss about Basic Authentication Popup First: 
 
1) Basic Authentication popup : It asks user to enter username and password to the popup  when the browser gets launched and it looks like something :
As can be comprehended from the above snapshot that we need to pass username and password and we can’t spy over this popup.
Let’s look at below code snippet to handle this popup

 

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

/**
* @author Mandeep Kaur
* @Date 6 May,2020
*/
public class SeleniumConfig {
public static void main(String[] args) throws InterruptedException {
String path = System.getProperty(“user.dir”);
System.setProperty(“webdriver.chrome.silentOutput”, “true”);
System.setProperty(“webdriver.chrome.driver”, path + “/chromedriver”);
WebDriver driver = new ChromeDriver();

//send username : admin and password: admin in url before launching the browser
driver.get(“https://admin:admin@the-internet.herokuapp.com/basic_auth”);

//validate if popup is closed successfully and capture the text

WebElement successMessage = driver.findElement(By.xpath(“//div[@class=’example’]//p”));

System.out.println(successMessage.getText());

}
}

It’s pretty clear from the above code that we just need to pass the username and password in the URL and after “@” the complete URL, after that, we can verify the success message, this is how we can achieve our goal.

2) Window-based File Upload popup :

Window-based popup interacts with window operations, selenium doesn’t provide direct support to handle this type of popup  but there is a workaround to operate on such cases. let’s look down to understand this in detail:

Window/ Mac-based popup appears like this once you click on choose file:

Let’s see the code to handle this popup:

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

/**
* @author Mandeep Kaur
* @Date 6 May,2020
*/
public class SeleniumConfig {
public static void main(String[] args) throws InterruptedException {
String path = System.getProperty(“user.dir”);
System.setProperty(“webdriver.chrome.silentOutput”, “true”);
System.setProperty(“webdriver.chrome.driver”, path + “/chromedriver”);
WebDriver driver = new ChromeDriver();

//launch the url
driver.get(“https://the-internet.herokuapp.com/upload”);

//inspect over the choose file element and send File from your directory to it
WebElement uploadFile = driver.findElement(By.xpath(“//input[@name=’file’]”));
uploadFile.sendKeys(“/Users/Documents/index.html”);

//click on upload button
driver.findElement(By.xpath(” //input[@class=’button’]”)).click();

//verify the message
WebElement successMessage= driver.findElement(By.xpath(“//div[@class=’example’]//h3”));
System.out.println(successMessage.getText());

driver.close();
}
}

Explanation:

1. We first need to inspect over choose file Button and capture XPath, HTML to look like below where it should have <input> tag and type should be file:

<input id=”file-upload” type=”file” name=”file” xpath=”1″>

 

2. Next, need to send File to upload using sendKeys(String fileNameWithExtension);

3. It will upload the file and we can verify the file is uploaded or not by capturing the success message like following:

4. Conclusion

In this write-up, we have learnt about javascript alerts, a few other types of popups and various ways to handle all these popups.

 

That’s all for this post, hope you have learnt about PopUps 🙂

 

Cheers!!

Naveen AutomationLabs

 

Blog Contributors:

Author:  Mandeep Kaur
Mandeep, having 5+ years of Testing experience in automation using Selenium (Java). Expertise in API and Performance testing using JMeter.
https://www.linkedin.com/in/mandeepkaur93
 
Reviewer: Naveen Khunteta 
https://www.linkedin.com/in/naveenkhunteta

 

Difference between ImplicitlyWait, ExplicitWait and FluentWait in Selenium WebDriver

1.Overview

In this article, we’ll look at the most fundamental mechanism in selenium – synchronisation(wait).

2. Synchronisation in Selenium

  • Synchronisation helps the user to troubleshoot issues when launching or navigating to different web pages while executing the selenium scripts.
  • When the entire web page gets refreshed or elements are getting re-loaded there should be synchronisation between the selenium scripts, script execution speed and web application speed.
  • At times, there can be a lot of Ajax components or some images and when we want to interact with these elements it may not visible. Thus, a time fall back can be seen in such cases and we get an exception as “ElementNotVisibleException“.
  • Selenium doesn’t provide any default synchronisation but it provides synchronisation in the form of different types of waits which we will see below.

3. Different Types of waits in Selenium WebDriver

  • Implicit Wait
  • Explicit Wait
  • Fluent Wait

These waits are dynamic waits. To understand the statement let’s consider a situation when you have given a TimeOut value of 20 seconds. If the element is loaded in 5 seconds, then rest 15 seconds will be ignored.

Let’s have a look at each one of these commands:

  1. Implicit Wait

As per Selenium Documentation, An implicit wait is to tell WebDriver to poll the DOM for a certain amount of time when trying to find an element or elements if they are not immediately available. The default setting is 0. Once set, the implicit wait is set for the life of the WebDriver object instance.

  • Implicit wait waits for a certain time till page gets loaded. After setting a particular time web driver will wait for that time before throwing an exception “No Such Element Exception“.
  • Implicitly wait is applied globally, which means it is always available for all the web elements throughout the driver instance.
  • Syntax: driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
  • Implicitly accepts two parameters the first parameter time: 10 given as timeout wait and other is TimeUnit can be given in seconds, minutes, hours days just put dot key after TimeUnit, we can see all the options available.

Implicit Wait
 

So do I need to use Implicitly Wait? Answer is really NO..

Dis-advantages of Implicitly Wait:

  • undocumented and practically undefined behaviour.
  • runs in the remote part of selenium (the part controlling the browser).
  • only works on find element(s) methods.
  • returns either element found or (after timeout) not found.
  • if checking for absence of element must always wait until timeout.
  • cannot be customised other than global timeout.

This list is gathered from observations and reading bug reports and cursory reading of selenium source code.

Let me tell you one thing : <Always use explicit wait. Forget that implicit wait exists>                                              --Naveen Khunteta

2. Explicit Wait

Explicit wait is of two types:

a) WebDriverWait (Class) : 

b) FluentWait (Class)

Both are classes and implements Wait interface.

WebDriverWait class is an extension of FluentWait class. It doesn’t have its own methods.

  • Explicit wait waits for a certain condition till specific element is not loaded.
  • Its implementation is given by WebDriverWait Class in selenium with some expected conditions.
  • This can be useful when certain elements on the webpage are not available immediately and need some time to load for e.g when you click on some submit button after you fill some registration form, then it takes some time in processing and displaying the data on UI.
  • Selenium has its predefined conditions provided in ExpectedConditions class.
  • Below is the syntax to define explicit wait and the expected conditions to be selected based on our needs:

Expected Conditions

So do I need to use Explicit Wait? Answer is YESSSS..

  • documented and defined behaviour.
  • runs in the local part of selenium (in the language of your code).
  • works on any condition you can think of.
  • returns either success or timeout error.
  • can define absence of element as success condition.
  • can customise delay between retries and exceptions to ignore.

Fluent Wait:

As per Official Selenium API Documentation, FluentWait is:

An implementation of the Wait interface that may have its timeout and polling interval configured on the fly.

Each FluentWait instance defines the maximum amount of time to wait for a condition, as well as the frequency with which to check the condition. Furthermore, the user may configure the wait to ignore specific types of exceptions whilst waiting, such as NoSuchElementExceptions when searching for an element on the page.

  • FluentWait is used when we can define the maximum time to wait for a condition, It also defines the frequency with which WebDriver will check if the condition appears before throwing the “ElementNotVisibleException”.
  • We can configure the wait to ignore specific types of exceptions while waiting, such as NoSuchElementException when searching for an element on the page.
  • The fluent wait is a class and an implementation of Wait interface and also parent class of WebDriverWait.
  • We can customise the below apply method to give any conditions based on our specifications.

Syntax:

Let’s below code snippet :

Code for Fluent Wait

package com.example.automation;

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.*;
import java.time.Duration;
import java.util.function.Function;

/**
 * @author Mandeep Kaur
 * @Date 2 May,2020
 */
public class SeleniumConfig {
    public static void main(String[] args) {
        String path = System.getProperty("user.dir");
        System.setProperty("webdriver.chrome.silentOutput", "true");
        System.setProperty("webdriver.chrome.driver", path + "/chromedriver");
        WebDriver driver = new ChromeDriver();
        driver.get("https://www.facebook.com/");
        // Create object of WebDriverWait class

        Wait wait = new FluentWait(driver)
                //Wait for the condition
                .withTimeout(Duration.ofSeconds(10))
                //checking for its presenceonce every 5 seconds.
                .pollingEvery(Duration.ofSeconds(5))
                //Which will ignore the Exception
                .ignoring(Exception.class);

        WebElement element = wait.until(new Function<WebDriver, WebElement>() {
            @Override
            public WebElement apply(WebDriver driver) {
                return driver.findElement(By.name("lastname"));

            }
        });
        element.sendKeys("Martin");
    }
}

Explanation:

To put it simply, Fluent Wait looks for a web element repeatedly at regular intervals until timeout happens or until the object is found.

  • The above code defines time out value as 10 seconds and polling frequency as 5 seconds that means for every 5 seconds it keeps on checking for element.
  • It directs WebDriver to wait for a maximum of 10 seconds to verify a specific condition. If the condition occurs during those 10 seconds, it will perform the next step in the test script. If not, it will throw an “ElementNotVisibleException”.

So when should I use FluentWait?

  • When you do not see suitable expected wait condition in explicit wait.
  • To handle dynamic AJAX web elements with polling mechansim
  • You need to do more than just waiting along with Polling Mechanism, IgnoredException and when you want to create your own custom wait condition (in apply method) for non WebDriver use cases as well.
So can I use FluentWait features like, polling interval, ignoreAll with WebDriverWait? 
Ans
: Yes, of course you can do that, as I have explained earlier WebDriverWait is child class of FluentWait, so it has access on all parent class public methods.

Refer this WebDriver API on GIT:

https://github.com/SeleniumHQ/selenium/blob/master/java/client/src/org/openqa/selenium/support/ui/FluentWait.java

Final Conclusion:

a. Wait is an Interface in Selenium and having only one method declaration:

public interface Wait {

until(Function<? super F, T> isTrue);

}

b. FluentWait is a class which is implementing Wait Interface, it’s having its own methods shown above and overridden until() method from the wait Interface. 

public class FluentWait implements Wait<T> { }

c. WebDriverWait is extending FluentWait class but has no methods init except one overridden method, that is: timeoutException(){}.

WebDriverWait can use all the methods of FluentWait class – pollingEvery(), withMessage(), ignoreAll etc..

FluentWait can be used for both WebDriver and non WebDriver use cases. It just needs a condition – waitForCondition.

3. Concept of Thread.sleep()

  • It is a static wait and execution of the scripts will be on hold till specified time configured in the function.
  • Thread is a class in JAVA and sleep is static method.
  • sleep() methods accept duration in milliseconds. ( 1 s= 1000 ms).
  • It throws  IllegalArgumentException – if the value of ms is negative.
  • sleep() throws a checked exception which we must either throw or handle it using try catch like done below
  • Syntax:

try{
Thread.sleep(5000);
}
catch(InterruptedException e){
}

Note: it’s never a good idea to use thread.sleep () as unlike dynamic waits it will wait for the entire time configured in the function till the element gets loaded.

4. PageLoadTimeOut & SetScriptTimeOut property

PageLoadTimeOut

  • PageLoadTimeOut is focused on the time a webpage needs to be loaded – the page load timeout limits the time that the script allows for a web page to be displayed.
  • If the page loads within the time, then the script continues. If the page does not load within the timeout the script will be stopped by a TimeoutException.
  • The timeout is set at the driver level. After creating the driver instance with the appropriate driver capabilities.
  • Syntax :

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

SetScriptTimeOut

  • From WebDriver documentation: setScriptTimeout(long time, java.util.concurrent.TimeUnit unit) sets the amount of time to wait for an asynchronous script to finish execution before throwing an error.
  • This works only for Async scripts (executeAsyncScript: calls which takes some time to respond back)
  • Syntax:

driver.manage().timeouts().setScriptTimeout(1, TimeUnit.SECONDS);

5. Conclusion:

In this article , we learnt about the various waits in selenium WebDriver.

Some References taken from:

 
Blog Contributors:
Author:  Mandeep Kaur
Mandeep, having 5+ years of Testing experience in automation using Selenium (Java). Expertise in API and Performance testing using JMeter.
https://www.linkedin.com/in/mandeepkaur93
 
Reviewer: Naveen Khunteta 
https://www.linkedin.com/in/naveenkhunteta

Handle DropDown using select Class in selenium

Handle DropDown using select Class in selenium

 

1. Overview

In this article, we’ll explore the select class from the org.openqa.selenium.support.ui.Select package to work on Drop-Down.

2. Type of DropDowns/DropBox/ListBox

There are generally two types of DropDowns

  1. Single select DropDown
  2. Multi-select DropDown

  • Single select DropDown when we can select only one option from the DropDown list like below:

Values to select will be displayed like this:

  • Multi-select DropDown when we can select more than one option from the DropDown list like below

3. Role of Select Class in Selenium:

  • The Select class is a WebDriver class which provides the implementation of the HTML

  • This class can be found under org.openqa.selenium.support.ui.Select package.

  • Select is an ordinary class as any other class , so its object is created by passing the WebElement to its constructor.

  • It will throw error as asking to add arguments to the command:

            Syntax : Select select = new Select(); 

So, specify the web element location using the select Element as done below:

Declaring the dropDown element as an instance of the Select class

Let’s find out what operations we can perform with the help of this Select class reference i.e. selectFromDropDownObj

 

Select Methods

As it can be seen from the above figure, we can select/deselect the values from the drop-down list based on our requirements.

Let’s explore some of the above methods to get better understanding of the same:

We can select our drop-down values with these below methods

  1. selectByIndex
  2. SelectByVisibleText
  3. selectByValue

Let’s examine the below code first:

  • selectByIndex (int index): This Function takes an index value from drop-down list and it starts from 0 for the first value and returns void.
  • selectByVisibleText(String text): This Function takes text in String format from the drop-down list and returns void.
  • selectByValue(String value): For this first inspect the element from DOM and select the value as shown below:

Note : The Most preferred way is to select by byVisibleText() because in ByIndex(),  index can be changed for dynamic drop down values but it can be used for static dropdown values like Month, Year and Date. 

Let’s explore getOptions Method:

Syntax:

List<WebElementallOptionsObj =selectFromDropDownObj.getOptions();

for(WebElement getAllOptions:allOptionsObj)
System.out.println(getAllOptions.getText());

This will print all the options contains in the DropDown and we get our Output same as below:

 

console Output

Another useful Method isMultiple:

This method tells us whether dropDown is single select or multi-select, it doesn’t accept anything and returns a boolean value.

 

isMultiple()

Now, if requirements changed that selected value needs to be deselected then we can perform below actions on the same.

  • deselectByIndex(int index) : void –Deselect the option at the given index.
  • deselectByValue(String Value): void –Deselect the matching option with given argument Value.
  • deselectByVisibleText(String Text) : void – Deselect the matching option with given argument Text.

Now, let’s jump into the second Type of DropDown i.e Multi-select:

Before that let’s take a glance at below code

 

select Multiple options

  1. In the above code , we first inspect the select element and then as usual instead of one select methods we can use more than one select methods. 
  2. One catchy method here is getFirstSelectedOption() it returns the WebElement and display which value from the dropdown is selected first by using getText.

That’s it we have mastered over the select class.

Below code for your reference and output of the same:

 

and output on the browser will be similar to :

package com.example.automation;
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;
import java.util.List;
/**
* @author Mandeep Kaur
* @Date 29 April,2020
*/
*/
*/
public class SeleniumConfig {

public static void main(String[] args) throws InterruptedException {

String path = System.getProperty(“user.dir”);
System.setProperty(“webdriver.chrome.silentOutput”, “true”);
System.setProperty(“webdriver.chrome.driver”, path + “/chromedriver”);

WebDriver driver = new ChromeDriver();
driver.get(“https://testuserautomation.github.io/DropDown/”);

//inspect over the Drop Down menu
WebElement selectCitiesObj = driver.findElement(By.xpath(“//select[@name=’Cities’]”));
Select selectFromDropDownObj = new Select(selectCitiesObj);

//select by index , index will start from 0 for first value
selectFromDropDownObj.selectByIndex(0);

//select by value, value to be found in HTML DOM
selectFromDropDownObj.selectByValue(“Texas”);

//select by Text given in the dropDownList
selectFromDropDownObj.selectByVisibleText(“CA”);

//getOptions : to get all the options from the drop-down
List allOptionsObj = selectFromDropDownObj.getOptions();

for (WebElement getAllOptions : allOptionsObj)
System.out.println(getAllOptions.getText());

//isMultiple : is it multi select drop-down if no then it returns false:
boolean isSuccess = selectFromDropDownObj.isMultiple();
System.out.println(isSuccess);

//MultiSelect DropDown
WebElement selectBillsObj = driver.findElement(By.xpath(“//select[@id=’Bill’]”));
Select selectBillFromDropDownObj = new Select(selectBillsObj);

selectBillFromDropDownObj.selectByValue(“Travel”);
System.out.println(selectBillFromDropDownObj.getFirstSelectedOption().getText());
selectBillFromDropDownObj.selectByIndex(3);
driver.close();

}
}

4.Conclusion

In this article , we have learnt about the handling of drop-down using select class in selenium.

Cheers!!

Naveen AutomationLabs

Blog Contributors:

Author:  Mandeep Kaur
Mandeep, having 5+ years of Testing experience in automation using Selenium (Java). Expertise in API and Performance testing using JMeter.
https://www.linkedin.com/in/mandeepkaur93
 
Reviewer: Naveen Khunteta 
https://www.linkedin.com/in/naveenkhunteta

 

 

 

 

Handling of Dynamic Web Table in Selenium

  1. Overview

In this article , we will learn to handle Dynamic Web Table in Selenium WebDriver .

2. Basic Concepts:

  • A table with rows and columns on a web page is called a web table. In HTML, a table is created using  tag. 
  • Table contains  headers represented as, rows asand Coloums as tag
  • There are two types of web Tables

  1. Static web table: Number of rows and columns will be static means constant that will not be changed. Here we just need to find the WebElement of the particular row or column and simply can perform operations on the cell.
  2. Dynamic table: Number of rows and columns will be dynamic. It will be kept on changing based on data and this the area where we will be focussing on.

3. Ways to Handle Dynamic WebTable:

  1. The standard way where we will iterate over the rows and columns and reach to a particular cell and get the cell value.
  2. By using custom XPath

Before proceeding further, let’s see how dynamic table looks like :

Table with checkbox , rows and coloumns

And below is the HTML representation of the above web table:

So, based on the data input we can increase or decrease our number of rows or columns.

Since we have seen what a web table is and how it is created, now let’s take the simple scenario :

1)click on checkbox where firstName is Will and remember it’s a dynamic table, hence “WILL” now on 3rd row can be shifted to other row based on the insertion or deletion of data.

  • Let’s implement it by First Method:

Let’s accomplish this task first by looking at the code snippet below

We’ll break this code into steps to get a deeper understanding of it:

Step1 : Capture xpath of the FirstName Row and observe the pattern

  • First Row xpath: //table/tbody/tr[2]/td[2] –>jessica
  • second Row xpath: //table/tbody/tr[3]/td[2] –>Ammy 
  • Third Row xpath: //table/tbody/tr[4]/td[2] –>Will and so on
  • Here can we say that our rowis getting changed and our columnis constant.

Step2: Catch before and after XPath from the point our row started changing as done in the code.

Step 3: Now, we have captured the before and after XPath.Find out the total row size by size() function of the java collections.

Step 4: Start iterating over the rows, start the row index with 2 as the first row would be reserved for headers.

Step 5:Get the text of all the rows and store it to the variable firstNames and print it to see if we are able to capture it

Step 6 : Final step of our task , that click the checkbox where FirstName is Will

For this step, we put one condition that if firstNames contains WILL then only checkbox has to be clicked. if it exists it will click the checkbox prior to WILL.

Since WILL is existing in the table , it will click the checkbox and we can capture it from the browser:

and our output on the console is similiar to following :

  • By Second Method : with Custom XPath

We can achieve our task with single statement :

 driver.findElement(By.xpath(“//td[contains(text(),’Will’)]//preceding-sibling::td//input[@type=’checkbox’]”)).click();

yes , that ‘it , below code for your reference

Let’s try to understand this method :

firstly visit over XPath_Axes , here you will get to know how to traverse from one node to another node.

Next, in the above we have spied over FirstName with text Will and we found out Will Sibling is td when we proceed upwards and then we get our input as a checkbox and from here we can simply capture it.

4. Which Method to choose

As can be conveyed from the above methods, the custom method is the best way to handle web dynamic table :

Reasons :

  1. In the First Method, it’s a lengthy method whereas the second method is just a single line statement
  2. In the first Method, we had to use for loop with conditions and then selecting the value, on the other hand, we need not have to use for loop
  3. As we are iterating through till all the rows it makes code slower in the first Method considering the other method can be seen fast, dynamic and efficient

Code Snippet with both methods :

package com.example.automation;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
/**
@author Mandeep Kaur
@Date 28 April,2020
*/
public class SeleniumConfig {
public static void main(String[] args) {
String path = System.getProperty("user.dir"); System.setProperty("webdriver.chrome.silentOutput", "true"); System.setProperty("webdriver.chrome.driver", path + "/chromedriver");
WebDriver driver = new ChromeDriver(); driver.get("https://testuserautomation.github.io/WebTable/");
// Method 1
String before_xpath = "//table/tbody/tr["; String after_xpath = "]/td[2]";
List rows = driver.findElements(By.xpath("//table/tbody/tr"));
int rowSize = rows.size();
System.out.println(rowSize);
for (int i = 2; i <= rowSize; i++) {
String firstNames = driver.findElement(By.xpath(before_xpath + i + after_xpath)).getText();
System.out.println(firstNames);
// Now click the checkBox where first Name would be Will
if (firstNames.contains("Will")) {
// click the checkBox
driver.findElement(By.xpath("//tbody/tr[" + i + "]/td[1]/input")).click(); System.out.println("candidate has been selected");
break;
}
}
// Method 2 : By custom xpath:
driver.findElement(By.xpath("//td[contains(text(),'Will')]//preceding-sibling::td//input[@type='checkbox']")) .click();
driver.close();
}
}

5. Conclusion

In this article , we learnt about how to handle dynamic Web Tables.


Cheers!!

Naveen AutomationLabs

Blog Contributors:

Author:  Mandeep Kaur
Mandeep, having 5+ years of Testing experience in automation using Selenium (Java). Expertise in API and Performance testing using JMeter.
https://www.linkedin.com/in/mandeep-kaur-486ba9106
 
Reviewer: Naveen Khunteta 
https://www.linkedin.com/in/naveenkhunteta

 

 

 

 

« Older posts