What is Fluent Wait in Selenium WebDriver

HOME

Wait<WebDriver> wait =
        new FluentWait<>(driver)
            .withTimeout(Duration.ofSeconds(2))
            .pollingEvery(Duration.ofMillis(300))
            .ignoring(ElementNotInteractableException.class);

    wait.until(
        d -> {
          revealed.sendKeys("Displayed");
          return true;
        });

import org.openqa.selenium.By;
import org.openqa.selenium.ElementNotInteractableException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;

import java.time.Duration;

public class fluentwaitDemo {

    public static void main(String args[]) {

        WebDriver driver = new ChromeDriver();
        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
        driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
        driver.findElement(By.id("reveal")).click();

        WebElement revealTextBox = driver.findElement(By.id("revealed"));
        Wait<WebDriver> wait = new FluentWait<>(driver)
                        .withTimeout(Duration.ofSeconds(2))
                        .pollingEvery(Duration.ofMillis(300))
                        .ignoring(ElementNotInteractableException.class);

        wait.until(d -> {
                    revealTextBox.sendKeys("Selenium");
                    return true;
                });

        System.out.println("Input Text :" + revealTextBox.getDomProperty("value"));

        driver.quit();
    }
}

Wait wait = new FluentWait(driver)

  .withTimeout(Duration.ofSeconds(30))
  .pollingEvery(Duration.ofSeconds(5))
  .ignoring(NoSuchElementException.class);

WebElement foo = wait.until(new Function() {
  public WebElement apply(WebDriver driver) {
    return driver.findElement(By.id("foo"));
  } 
});

Below is an example which shows the use of Fluent Wait in real world
1) Launch new Browser and open https://www.rediff.com/
2) Click on Money Link present at the top center of the page
3) Sensex of different companies like S&P BSE Sensex, Nift 50, etc. appears at the center of the page
4) Don’t use Fluent Wait to find value of element S& BSE Sensex
5) Close the browser

package SeleniumTutorial;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class FluentWaitDemo {
      public static void main(String[] args) {

System.setProperty("webdriver.chrome.driver","C:\\Users\\SingVi04\\Desktop\\Drivers\\chromedriver_win32\\chromedriver.exe");
           WebDriver driver= new ChromeDriver();
           driver.manage().window().maximize();
           driver.get("https://www.rediff.com/");    
           driver.findElement(By.xpath("//a[@href ='https://money.rediff.com']")).click();
            
           String Message= driver.findElement(By.xpath("//*[@id='indmarquee']/div[1]/span[2]")).getText();
           System.out.println("Value of S&P BSE Bankex :"+Message);
      driver.quit();
     }
}

Output
Exception in thread "main" org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element
{"method":"xpath","selector":"//*[@id='indmarquee']/div[1]/span[2]"}
(Session info: chrome=78.0.3904.108)

Here, we can see that NoSuchElementException found, as the Web Element is dynamic. We need to wait for some time to find the Web Element.
In the below example, will use Fluent Wait to overcome the above stated issue.

import java.time.Duration;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;

import com.google.common.base.Function;
    public classFluentWaitDemo {
          public static void main(String[] args) {
 
System.setProperty("webdriver.chrome.driver","C:\\Users\\SingVi04\\Desktop\\Drivers\\chromedriver_win32\\chromedriver.exe");
         WebDriver driver = newChromeDriver();
          driver.manage().window().maximize();
          driver.get("https://www.rediff.com/");
 
          driver.findElement(By.xpath("//a[@href ='https://money.rediff.com']")).click();
           
          //Fluent Wait
          Wait wait = new FluentWait(driver)
                     .withTimeout(Duration.ofSeconds(15))  
                     .pollingEvery(Duration.ofSeconds(1))                           
                     .ignoring(NoSuchElementException.class);
 
                WebElement BSE_Sensex = wait.until(newFunction(){
                  public WebElement apply(WebDriver driver ) 
                  {
                      WebElement BSE_Bankex = driver.findElement(By.xpath("//*[@id='indmarquee']/div[1]/span[2]"));
           return BSE_Bankex;
                 }
          });
 
       String Message = BSE_Sensex.getText();
       System.out.println("Value of S&P BSE Bankex :"+Message);      
      }
}

Output 
Value of S&P BSE Bankex :42,597.43

Here,
Fluent Wait uses two parameters mainly – timeout value and polling frequency. In the above syntax we took time out value as 15 seconds and polling frequency as 2 seconds. The maximum amount of time (15 seconds) to wait for a condition and the frequency (2 seconds) to check the success or failure of a specified condition. 

If the element is located with in this time frame it will perform the operations else it will throw an “ElementNotVisibleException”

Few important points:-

1) NoSuchElementException. class – This class should be imported from org.openqa.selenium. By default Selenium shows 2 packages as shown in the image below.

If NoSuchElementException.class imported from java.util package, then we will see NoSuchElementException as shown below.

Wait wait = new FluentWait(WebDriver reference)
.withTimeout(timeout, SECONDS)
.pollingEvery(timeout, SECONDS)
.ignoring(Exception.class);

This is deprecate. So, do not use this syntax. Refer the below image for error

Implicit and Explicit Wait in Selenium WebDriver

HOME

 driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;

public class implicitDemo {

    public static void main(String args[]) {

        WebDriver driver = new ChromeDriver();
        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
        driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
        driver.findElement(By.id("adder")).click();
        WebElement added = driver.findElement(By.id("box0"));
        System.out.println("Color :" + added.getDomAttribute("class"));
        driver.quit();
    }

}

driver.manage().timeouts().implicitlyWait(TimeOut, TimeUnit.SECONDS);

Implicit wait will accept 2 parameters, the first parameter will accept the time as an integer value and the second parameter will accept the time measurement in terms of SECONDS, MINUTES, MILISECOND, MICROSECONDS, NANOSECONDS, DAYS, HOURS, etc.

Let me show how to use implicit wait in our program

import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
 
public class ImplicitWait_Example {
      public static void main(String[] args) {
                      
     System.setProperty("webdriver.gecko.driver","C:\\Users\\vibha\\Downloads\\geckodriver.exe");
      WebDriver driver = new FirefoxDriver();
                    
      //Implicit Wait
      driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
      driver.get("https://www.facebook.com");
      driver.findElement(By.name("email")).sendKeys("vibhasingh.verma");
          }
}

In the above example, we have waited for 30 sec, before redirecting the web page to the URL explicitly mentioned in the code.


Explicit Wait


An explicit wait is code you define to wait for a certain condition to occur before proceeding further in the code. The worst case of this is Thread.sleep(), which sets the condition to an exact time period to wait. There are convenience methods available to help write code that will only wait as long as required. 

WebDriverWait in combination with ExpectedCondition is one way to do this.

The explicit wait will tell the web driver to wait for certain conditions like visibilityOfElementLocated and maximum amount of time before throwing NoSuchElementException exception.

Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(2));
 wait.until(d -> revealed.isDisplayed());

package org.example;

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.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

public class explicitDemo {

    public static void main(String args[])  {

        WebDriver driver = new ChromeDriver();
        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
        driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
        driver.findElement(By.id("reveal")).click();

        WebElement revealTextBox = driver.findElement(By.id("revealed"));
        Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(3));
        wait.until(d -> revealTextBox.isDisplayed());

        revealTextBox.sendKeys("Happy");
        System.out.println("Input Text :" + revealTextBox.getDomProperty("value"));

        driver.quit();
    }
}

WebDriverWait wait = new WebDriverWait(WebDriverRefrence,TimeOut);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("Stats1_totalCount")));

Let me explain this with an example

import java.util.concurrent.TimeUnit;
 
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
 
public class ExplicitWaitExample {

            public static void main(String[] args) {
                        System.setProperty("webdriver.chrome.driver",
                                           "C:\\Users\\Vibha\\Desktop\\SeleniumKT\\chromedriver.exe");
                        // Create a new instance of the Firefox driver
                        WebDriver driver = new ChromeDriver();
                        driver.manage().window().maximize();
                        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
                        driver.get("https://configureselenium.blogspot.com/");
 
                        // Click on READ MORE link. New Page is opened
                        driver.findElement(By.linkText("READ MORE")).click();
 
                        // Explicit Wait
                        WebDriverWait wait = new WebDriverWait(driver, 60);
                    wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("Stats1_totalCount")));
                        String Count = driver.findElement(By.id("Stats1_totalCount")).getText();
                        System.out.println("Count is :" + Count);
                  driver.close();
            }
}

In the above example, we have used Explicit Wait. We are waiting for the web element – Stats1_totalCount for 60 seconds before performing the next operation.

The following are the Expected Conditions that can used in Explicit Wait

  1. alertIsPresent()
  2. elementSelectionStateToBe()
  3. elementToBeClickable()
  4. elementToBeSelected()
  5. frameToBeAvaliableAndSwitchToIt()
  6. invisibilityOfTheElementLocated()
  7. invisibilityOfElementWithText()
  8. presenceOfAllElementsLocatedBy()
  9. presenceOfElementLocated()
  10. textToBePresentInElement()
  11. textToBePresentInElementLocated()
  12. textToBePresentInElementValue()
  13. titleIs()
  14. titleContains()
  15. visibilityOf()
  16. visibilityOfAllElements()
  17. visibilityOfAllElementsLocatedBy()
  18. visibilityOfElementLocated()

Note:-  Do not mix implicit and explicit waits! Doing so can cause unpredictable wait times. For example, setting an implicit wait of 20 seconds and an explicit wait of 35 seconds could cause a timeout to occur after 25 seconds.

Fluent Wait

The Fluent wait will tell the web driver to wait for certain conditions like visibilityOfElementLocated as well as the frequency with which we want to check before throwing NoSuchElementException exception.

To know more about Fluent Wait, please click here

How to maximize and minimize the window in Selenium

HOME

driver.manage().window().maximize();

package org.example;

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

import java.time.Duration;

public class Maximize_Demo {

    public static void main(String args[])  {

        WebDriver driver = new ChromeDriver();
        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(4));
        driver.get("https://www.bing.com/");
        System.out.println("Page Title :" + driver.getTitle());
        driver.quit();
    }
}

driver.manage().window().minimize();

package org.example;

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

import java.time.Duration;

public class Minimize_Demo {

    public static void main(String args[]) {

        WebDriver driver = new ChromeDriver();
        driver.manage().window().minimize();
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(4));
        driver.get("https://www.bing.com/");
        System.out.println("Page Title :" + driver.getTitle());
        driver.quit();
    }
}

DataProviders in TestNG

HOME

In the last tutorial, I have explain the Parameters in TestNG which passes different test data to the test case as arguments. Similar to TestNG Parameters, DataProviders are a means to pass data to test scripts in TestNG. In this tutorial, I will explain about the DataProviders in TestNG.

What is DataProvider in TestNG?

The DataProvider in TestNG is another way to pass the parameters in the test function, the other one being TestNG parameters. Using DataProvider in TestNG, we can easily inject multiple values into the same test case. It comes inbuilt in TestNG and is popularly used in data-driven frameworks.

Syntax of DataProvider

@DataProvider (name = "name_of_dataprovider")
public Object[][] dpMethod() {
    return new Object [][] { values}
}
  •  A Data Provider is a method on the class that returns an array of array of objects.  This method is annotated with @DataProvider
  • A @Test method specifies its Data Provider with the dataProvider attribute. This name must correspond to a method on the same class annotated with @DataProvider(name=”…”) with a matching name.
  • TestNG dataprovider returns a 2d list of objects..An array of array of objects (Object[][]) where the first dimension’s size is the number of times the test method will be invoked and the second dimension size contains an array of objects that must be compatible with the parameter types of the test method.
  • DataProviders are not declared on top of the functions like TestNG parameters but have a method of their own, which in regular speaking terms called a dataprovider method. For example, dpMethod here.
  • The dataprovider name calls the dataprovider method, and if there is no name specified by the tester, then the dataprovider method is the default name used in the receiving @Test case.
  • Data providers can run in parallel with the attribute parallel.

Below is the basic example of using DataProvider in TestNG.

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.chrome.ChromeOptions;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class DataProvider_Demo {

    WebDriver driver;

    @DataProvider(name = "testData")
    public Object[][] dataProvFunc() {
        return new Object[][] { { "Selenium" }, { "TestNG" } };
    }

    @BeforeMethod
    public void setUp() {

        System.out.println("Start the test");
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--start-maximized");
        driver = new ChromeDriver(options);
        driver.get("https://www.bing.com/");
        
    }

    // Passing the dataProvider to the test method through @Test annotation
    @Test(dataProvider = "testData")
    public void search(String keyWord) {
        WebElement txtBox = driver.findElement(By.id("sb_form_q"));
        txtBox.sendKeys(keyWord);
        System.out.println("Keyword entered is : " + keyWord);
        txtBox.sendKeys(Keys.ENTER);
        System.out.println("Search result is displayed.");
    }

    @AfterMethod
    public void burnDown() {
        driver.quit();

        System.out.println("End the test");
    }

}

In the above example, I am passing two search keywords, viz “Selenium” and “TestNG” to the test method using the DataProvider method. You can run the code and check the output.

Here, Test is executed with two values, but we have run the test only once.

Inheriting DataProvider in TestNG

It is messy to have supporting methods like DataProvider and test code in one class. It is always preferred to declare the test case in one class and define TestNG parameters like DataProviders in another class. By default, the data provider will be looked for in the current test class or one of its base classes. If you want to put your data provider in a different class, it needs to be a static method or a class with a non-arg constructor, and you specify the class where it can be found in the dataProviderClass attribute.

Let us create separate classes for the DataProvider method and the test method, as shown below:

DataProvider Class

public class DPDemo {

	@DataProvider(name = "testData")
	public Object[][] dataProvFunc() {
		return new Object[][] { 
          { "Selenium" }, { "TestNG" }, { "Automation" } };
	}
}

We can see that all we did was create a DataProvider method in a Class and create a new class for Test Code.

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.chrome.ChromeOptions;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class DataProviderInheritance_Demo {

    WebDriver driver;

    @BeforeMethod
    public void setUp() {

        System.out.println("Start the test");
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--start-maximized");
        driver = new ChromeDriver(options);
        driver.get("https://www.bing.com/");

    }

    // Passing the dataProvider to the test method through @Test annotation
    @Test(dataProvider = "testData", dataProviderClass = DPDemo.class)
    public void search(String keyWord) {
        WebElement txtBox = driver.findElement(By.id("sb_form_q"));
        txtBox.sendKeys(keyWord);
        System.out.println("Keyword entered is : " + keyWord);
        txtBox.sendKeys(Keys.ENTER);
        System.out.println("Search result is displayed.");
    }

    @AfterMethod
    public void burnDown() {
        driver.quit();
        System.out.println("End the test");
    }

}

As you can see, to handle the inheritance, all we did was add an attribute to the test method (highlighted above), which specifies the class that has the DataProvider method. 

Passing Multiple Parameter Values in TestNG DataProviders

Passing multiple values is pretty similar to passing numerous parameters. The only difference is that we will pass various values to a single parameter so that a string of input(s) is sent in one go.

Let us quickly understand this concept with the help of the code as shown below.

DataProvider Class

public class DPDemo {

	@DataProvider(name = "testData")
	public Object[][] dataProvFunc() {
		return new Object[][] { { "Automation Tester", "2-5 years" }, { "Performance Tester", "3+ years" },
				{ "DevOps", "5+ years" } };
	}
}

Test Code – DataProviderInheritanceDemo

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.chrome.ChromeOptions;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class DataProviderInheritanceDemo {

    WebDriver driver;

    @BeforeMethod
    public void setUp() {

        System.out.println("Start the test");
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--start-maximized");
        driver = new ChromeDriver(options);
        driver.get("https://www.bing.com/");

    }

    // Passing the dataProvider to the test method through @Test annotation
    @Test(dataProvider = "testData", dataProviderClass = DPDemo.class)
    public void search(String keyWord1, String keyWord2) {

        WebElement txtBox = driver.findElement(By.id("sb_form_q"));
        txtBox.sendKeys(keyWord1, keyWord2);
        System.out.println("Keyword entered is : " + keyWord1 + " " + keyWord2);
        txtBox.sendKeys(Keys.ENTER);
        System.out.println("Search result is displayed.");
    }

    @AfterMethod
    public void burnDown() {
        driver.quit();
        System.out.println("End the test");
    }
}

Run the test script, and you will see both the values for the TestNG parameters being passed in one go.

We are done! Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!!

Deserialization – How to create JSON Object to JAVA Object Using Gson API

HOME

In this tutorial, I will explain the conversion of JSON Object (payload) to JAVA Object. We will use Gson API for the same purpose.

Before going through this tutorial, spend some time understanding Serialization using Gson API.

We can parse the JSON or XML response into POJO classes. After parsing into POJO classes, we can easily get values from the response easily. This is called De-serialization. For this, we can use any JSON parser APIs. Here, we are going to use Gson API.

To start with, add the below dependency to the project.

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.8.9</version>
</dependency>

Sample JSON Payload

{
  "firstName" : "Vibha",
  "lastName" : "Singh",
  "age" : 30,
  "salary" : 75000.0,
  "designation" : "Manager",
  "contactNumber" : "+91999996712",
  "emailId" : "abc123@test.com"
}

Let us create a class called Employee with a field name exactly (case-sensitive) the same as node names in the above JSON string because with the default setting while parsing JSON object to Java object, it will look on getter setter methods of field names. 

public class Employee {

	// private variables or data members of POJO class
	private String firstName;
	private String lastName;
	private int age;
	private double salary;
	private String designation;
	private String contactNumber;
	private String emailId;

	// Getter and setter methods
	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}

	public String getDesignation() {
		return designation;
	}

	public void setDesignation(String designation) {
		this.designation = designation;
	}

	public String getContactNumber() {
		return contactNumber;
	}

	public void setContactNumber(String contactNumber) {
		this.contactNumber = contactNumber;
	}

	public String getEmailId() {
		return emailId;
	}

	public void setEmailId(String emailId) {
		this.emailId = emailId;
	}

}

Gson class provides multiple overloaded fromJson() methods to achieve this. Below is a list of available methods:-

In the below test, I have mentioned the JSON Payload string in the test and used Gson API to deserialize the JSON payload to JAVA Object.

   @Test
	public void getDetailFromJson() {
		
		// De-serializing from JSON String
		String jsonString = "{\r\n" + "  \"firstName\": \"Tom\",\r\n" + "  \"lastName\": \"John\",\r\n"
				+ "  \"age\": 30,\r\n" + "  \"salary\": 50000.0,\r\n" + "  \"designation\": \"Lead\",\r\n"
				+ "  \"contactNumber\": \"+917642218922\",\r\n" + "  \"emailId\": \"abc@test.com\"\r\n" + "}";

		Gson gson = new Gson();
		// Pass JSON string and the POJO class
		Employee employee = gson.fromJson(jsonString, Employee.class);

		// Now use getter method to retrieve values
		System.out.println("Details of Employee is as below:-");
		System.out.println("First Name : " + employee.getFirstName());
		System.out.println("Last Name : " + employee.getLastName());
		System.out.println("Age : " + employee.getAge());
		System.out.println("Salary : " + employee.getSalary());
		System.out.println("designation : " + employee.getDesignation());
		System.out.println("contactNumber : " + employee.getContactNumber());
		System.out.println("emailId : " + employee.getEmailId());
		System.out.println("########################################################");

	}

The output of the above program is

We can get the JSON payload from a file present in a project under src/test/resources as shown in the below image.

public class EmployeeDeserializationGsonTest {

	@Test
	public void fromFile() throws FileNotFoundException {

		Gson gson = new Gson();
		// De-serializing from a json file
		String userDir = System.getProperty("user.dir");
		File inputJsonFile = new File(userDir + "\\src\\test\\resources\\EmployeePayloadUsingGson.json");
		FileReader fileReader = new FileReader(inputJsonFile);
		Employee employee1 = gson.fromJson(fileReader, Employee.class);

		// Now use getter method to retrieve values
		System.out.println("Details of Employee is as below:-");
		System.out.println("First Name : " + employee1.getFirstName());
		System.out.println("Last Name : " + employee1.getLastName());
		System.out.println("Age : " + employee1.getAge());
		System.out.println("Salary : " + employee1.getSalary());
		System.out.println("designation : " + employee1.getDesignation());
		System.out.println("contactNumber : " + employee1.getContactNumber());
		System.out.println("emailId : " + employee1.getEmailId());
		System.out.println("########################################################");
	}
}

The output of the above program is

We are done! Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!!

UnMarshalling- How to convert XML to Java Objects using JAXB

HOME

This tutorial explains how to use JAXB (Java Architecture for XML Binding) to convert an XML document to Java Objects.

The previous tutorial has explained the conversion of Java Objects to XML.

As of Java 11, JAXB is not part of the JRE anymore, and you need to configure the relevant libraries via your dependency management system, for example, either Maven or Gradle.

Configure the Java compiler level to be at least 11 and add the JAXB dependencies to your pom file.

<?xml version="1.0" encoding="UTF-8"?>
 
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
 
  <groupId>org.example</groupId>
  <artifactId>JAXBDemo</artifactId>
  <version>0.0.1-SNAPSHOT</version>
 
  <name>JAXBDemo</name>
  <url>http://www.example.com</url>
 
  <properties>  
 
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
  </properties>
 
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.2</version>
      <scope>test</scope>
  </dependency>
     
 <dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
    <version>2.3.3</version>
   </dependency>
 </dependencies>
    
</project>

Sample XML Structure

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<EmployeeDetails>
    <firstName>Terry</firstName>
    <lastName>Mathew</lastName>
    <gender>female</gender>
    <age>30</age>
    <maritalStatus>married</maritalStatus>
    <designation>Manager</designation>
    <contactNumber>+919999988822</contactNumber>
    <emailId>abc@test.com</emailId>
    <GrossSalary>75000.0</GrossSalary>
</EmployeeDetails>

Un-marshalling provides a client application the ability to convert XML data into JAXB-derived Java objects.

Let’s see the steps to convert XML document into java object.

  1. Create POJO Class
  2. Create the JAXBContext object
  3. Create the Unmarshaller objects
  4. Call the unmarshal method
  5. Use getter methods of POJO to access the data

Now, let us create the Java Objects (POJO) for the above XML.

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlRootElement(name = "EmployeeDetails")
@XmlAccessorType(XmlAccessType.FIELD)

//Define the order in which the fields are written in XML
@XmlType(propOrder = { "firstName", "lastName", "gender", "age", "maritalStatus", "designation", "contactNumber","emailId", "salary" })

public class Employee {

	private String firstName;
	private String lastName;
	private int age;

	@XmlElement(name = "GrossSalary")
	private double salary;
	private String designation;
	private String contactNumber;
	private String emailId;
	private String gender;
	private String maritalStatus;

	public Employee() {
		super();

	}

	// Getter and setter methods
	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}

	public String getDesignation() {
		return designation;
	}

	public void setDesignation(String designation) {
		this.designation = designation;
	}

	public String getContactNumber() {
		return contactNumber;
	}

	public void setContactNumber(String contactNumber) {
		this.contactNumber = contactNumber;
	}

	public String getEmailId() {
		return emailId;
	}

	public void setEmailId(String emailId) {
		this.emailId = emailId;
	}

	public String getGender() {
		return gender;
	}

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

	public String getMaritalStatus() {
		return maritalStatus;
	}

	public void setMaritalStatus(String maritalStatus) {
		this.maritalStatus = maritalStatus;
	}

	@Override
	public String toString() {
		return "Employee [FirstName=" + firstName + ", LastName=" + lastName + ", Age=" + age + ", Salary=" + salary
				+ ", Designation=" + designation + ", ContactNumber=" + contactNumber + ", EmailId=" + emailId
				+ ", Gender=" + gender + ", MaritalStatus=" + maritalStatus + "]";
	}
}

Create the following test program for reading the XML file. The XML file is present under src/test/resources.

Let’s use JAXB Unmarshaller to unmarshal our JAXB_XML back to a Java object:

import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import org.junit.Test;

public class JAXBDeserialization {
	
	@Test
	public void JAXBUnmarshalTest() {

		try {

			String userDir = System.getProperty("user.dir");
			File file = new File(userDir + "\\src\\test\\resources\\JAXB_XML.xml");
			JAXBContext jaxbContext = JAXBContext.newInstance(Employee.class);

			Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
			Employee employee = (Employee) jaxbUnmarshaller.unmarshal(file);

			System.out.println("FirstName: " + employee.getFirstName());
			System.out.println("LastName: " + employee.getLastName());
			System.out.println("Age: " + employee.getAge());
			System.out.println("Salary: " + employee.getSalary());
			System.out.println("Contact Number: " + employee.getContactNumber());
			System.out.println("Designation: " + employee.getDesignation());
			System.out.println("Gender: " + employee.getGender());
			System.out.println("EmailId: " + employee.getEmailId());
			System.out.println("MaritalStatus: " + employee.getMaritalStatus());

		} catch (JAXBException e) {
			e.printStackTrace();
		}

	}

	}

When we run the code above, we may check the console output to verify that we have successfully converted XML data into a Java object:

The output of the above program is

There is another simple way of unmarshalling the XML to Java Objects.

    @Test
	public void JAXBUnmarshalTest1() {

		try {

			String userDir = System.getProperty("user.dir");
			File file = new File(userDir + "\\src\\test\\resources\\JAXB_XML.xml");

			JAXBContext jaxbContext = JAXBContext.newInstance(Employee.class);
			Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
			Employee emp = (Employee) jaxbUnmarshaller.unmarshal(file);

			System.out.println(emp);

		} catch (JAXBException e) {
			e.printStackTrace();
		}
	}

When we run the code above, we may check the console output to verify that we have successfully converted XML data into a Java object:

The output of the above program is

We are done! Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!!

Setup Basic REST Assured Maven Project In Eclipse IDE

HOME

In the previous tutorial, I provided the Introduction of Rest Assured. In this tutorial, I will explain how to set up a basic Rest Assured Maven project in Eclipse IDE. Before starting, let us recap about Rest Assured.

What is Rest Assured?

REST Assured is a Java DSL for simplifying testing of REST-based services built on top of HTTP Builder. It supports POST, GET, PUT, DELETE, OPTIONS, PATCH, and HEAD requests. It can be used to validate and verify the response of these requests.

The Rest Assured library also provides the ability to validate the HTTP Responses received from the server. This makes Rest-Assured a very flexible library that can be used for testing.REST Assured can be used to test XML as well as JSON-based web services. REST Assured can be integrated with JUnit and TestNG frameworks for writing test cases for our application.

What is Maven?

Apache Maven is a software project management and comprehension tool. Based on the concept of a project object model (POM), Maven can manage a project’s build, reporting and documentation from a central piece of information.

Step 1- Download and Install Java

Rest-Assured needs Java to be installed on the system to run the tests. Click here to learn How to install Java.

Step 2 – Download and setup Eclipse IDE on the system

The Eclipse IDE (integrated development environment) provides strong support for Java developers. Click here to learn How to install Eclipse.

Step 3 – Setup Maven

To build a test framework, we need to add several dependencies to the project. Click here to learn How to install Maven.

Step 4 – Create a new Maven Project

Go to File -> New Project-> Maven-> Maven project ->Next

Step 4.1 – Select “Create a simple project”. Click on the Next Button.

Step 4.2 – Provide Group Id and Artifact Id and click on the finish button.

Group Id – com.example
Artifact Id – restassured_demo

Step 4.3Below is the structure of the Maven project in Eclipse.

Step 4.4 – This is the structure of POM.xml created for the project.

Step 5 – Add Rest Assured, and JUnit dependencies to the project

 <dependencies>
    <!-- REST Assured dependency -->
    <dependency>
        <groupId>io.rest-assured</groupId>
        <artifactId>rest-assured</artifactId>
        <version>5.5.1</version>
        <scope>test</scope>
    </dependency>

    <!-- JUnit dependency -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.2</version>
        <scope>test</scope>
    </dependency>
</dependencies>

 <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.14.0</version>
        <configuration>
          <source>17</source>
          <target>17</target>
        </configuration>
      </plugin>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>restassured_demo</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
 <dependencies>
    <!-- REST Assured dependency -->
    <dependency>
        <groupId>io.rest-assured</groupId>
        <artifactId>rest-assured</artifactId>
        <version>5.5.1</version>
        <scope>test</scope>
    </dependency>

    <!-- JUnit dependency -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.2</version>
        <scope>test</scope>
    </dependency>
</dependencies>

 <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.14.0</version>
        <configuration>
          <source>17</source>
          <target>17</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

Step 7 – Update Maven Project

Right-click on your project in the Eclipse Project Explorer. Choose `Maven` -> `Update Project…` and confirm to download the specified dependencies.

Below are the Rest Assured, and junit jar files present under Maven Dependencies.

package com.example.tests;

import org.junit.Test;

import static org.hamcrest.Matchers.equalTo;
import static io.restassured.RestAssured.given;

public class APITests {

	String BaseURL = "https://reqres.in/api/users";

	@Test
	public void getUser() {

		// Given
		given()

				// When
				.when().get(BaseURL + "/2")

				// Then
				.then().statusCode(200).statusLine("HTTP/1.1 200 OK")

				// To verify user of id 2
				.body("data.id", equalTo(2)).body("data.email", equalTo("janet.weaver@reqres.in"))
				.body("data.first_name", equalTo("Janet")).body("data.last_name", equalTo("Weaver"));
	}

}

Point to Remember

SpringBoot Tutorials

 

HOME

Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can “just run”. We take an opinionated view of the Spring platform and third-party libraries, so you can get started with minimum fuss. Most Spring Boot applications need minimal Spring configuration.

Chapter 1 Create your first SpringBoot application in IntelliJ
Chapter 2 SpringBoot Integration Test
Chapter 3 Integration Testing of Springboot with RestAssured
Chapter 4 Testing of SpringBoot REST Application using Serenity BDD and Rest Assured for GET Method
Chapter 5 Testing of SpringBoot REST Application using Serenity BDD and Rest Assured for POST Method to create a Resource
Chapter 6 Testing of SpringBoot REST Application using Serenity BDD and Rest Assured for PUT Method to update a Resource
Chapter 7 Testing of SpringBoot REST Application using Serenity BDD and Rest Assured for DELETE Method to delete a Resource
Chapter 8 Testing of SpringBoot Validation for RESTful Services
Chapter 9 Testing of SpringBoot Exception Handling
Chapter 10 SpringBoot WireMock
Chapter 11 SpringBoot Dependency Injection using Autowired

SpringBoot Testing with JUnit

Chapter 1 Integration Testing of Springboot with Cucumber and JUnit4
Chapter 2 Integration Testing of SpringBoot Application with Serenity BDD, Cucumber and JUnit4
Chapter 3 Testing of SpringBoot Application with Serenity and JUnit5
Chapter 4 Testing of SpringBoot Application with Serenity BDD, Cucumber and JUnit5
Chapter 5 Testing of SpringBoot Application with JUnit5

SpringBoot with TestNG

Chapter 1 Testing of SpringBoot Application with TestNG
Chapter 2 Integration Testing of Springboot with Cucumber and TestNG

SpringBoot with Gradle

Chapter 1 Testing of Gradle SpringBoot Application with Serenity, Cucumber and JUnit4
Chapter 2 Testing of Gradle SpringBoot Application with Serenity and JUnit5

CI/CD

Chapter 1 How to run SpringBoot tests with GitHub Actions
Chapter 2 How to run SpringBoot project in GitLab CI/CD

Serialization – How to create JSON Payload from Java Object – Jackson API

HOME

In this tutorial, I will explain the creation of JSON Object Payload with the help of POJO (Plain Old Java Object).

What is POJO?

POJO stands for Plain Old Java Object. It is a very simple object, and it has no bounds or we can say that it has no restrictions other than the Java language specification. Also, it does not require any classpath.

A big advantage of POJO is it increases the readability and reusability of our project code and developers find it easy when understanding the code. Also, POJO is easy to write and anyone can understand them easily.

Now let’s deep dive into some technical terms about the POJO. Below are a few points about the POJO are:

  1. A POJO should not have to extend prespecified classes.
  2. Secondly, a POJO should not have implemented any prespecified interface.
  3. Lastly, POJO should not contain prespecified annotations

A POJO class can follow some rules for better usability. These rules are:-

  1. Each variable should be declared as private just to restrict direct access.
  2. Each variable that needs to be accessed outside class may have a getter, a setter, or both methods. If the value of a field is stored after some calculations, then we must not have any setter method for that.
  3. It Should have a default public constructor.
  4. Can override toString(), hashcode, and equals() methods.

POJO classes are extensively used for creating JSON and XML payloads for API.

In the below example, let me create a simple JSON with some nodes which is actually a 1:1 mapping i.e. each key has a single value, and the type of values is mixed.

{
  "firstName" : "Vibha",
  "lastName" : "Singh",
  "age" : 30,
  "salary" : 75000.0,
  "designation" : "Manager",
  "contactNumber" : "+91999996712",
  "emailId" : "abc123@test.com"
}

Let us create variables in the POJO class now for the above JSON. Now, a class name Employee will be created with the private data members as mentioned in the above JSON. Since we have created all variables as private, then there should be a way to manipulate or retrieve these data. So we create the corresponding getter and setter methods for these data members.

It is very tedious to create getter and setter methods for all the data members for big JSON strings.  Every IDE gives you a shortcut to generate getter and setter methods.  Here, I am using Eclipse and creating these getter and setter methods.

Select all the data members and Right-click on the page. Then select Source and then select Generate Getter and Setter methods.

This opens a new screen as shown below.

You can select the data member for which you want to create the getter and setter method. I want to create the getter and setter methods for all the data members, so click on Select All and then click on the Generate Button. This will generate the getter and setter methods for all the data members.

Below is the sample code of the Employee table, which contains the data members needed for Employee JSON and their corresponding getter and setter methods.

public class Employee {

	// private variables or data members of POJO class
	private String firstName;
	private String lastName;
	private int age;
	private double salary;
	private String designation;
	private String contactNumber;
	private String emailId;

	// Getter and setter methods
	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}

	public String getDesignation() {
		return designation;
	}

	public void setDesignation(String designation) {
		this.designation = designation;
	}
	
	public String getContactNumber() {
		return contactNumber;
	}

	public void setContactNumber(String contactNumber) {
		this.contactNumber = contactNumber;
	}

	public String getEmailId() {
		return emailId;
	}

	public void setEmailId(String emailId) {
		this.emailId = emailId;
	}

}

Using the above POJO class, you can create any number of custom Employee objects and each object can be converted into a JSON Object and Each JSON object can be parsed into Employee POJO.

We will create a JSON object from POJO and vice versa now, which is generally called serialization and deserialization using Jackson APIs.

Serialization – Serialization is a process where you convert an Instance of a Class (Object of a class) into a Byte Stream. Here, we are converting Employee class object to JSON representation or Object

Deserialization – It is the reverse of serializing. In this process, we will read the Serialized byte stream from the file and convert it back into the Class instance representation. Here, we are converting a JSON Object to an Employee class object.

We are using Jackson API for Serialization and Deserialization. So, add the Jackson dependency to the project.

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.0</version>
</dependency>

What is ObjectMapper ?

ObjectMapper provides functionality for reading and writing JSON, either to and from basic POJOs (Plain Old Java Objects), or to and from a general-purpose JSON Tree Model (JsonNode), as well as related functionality for performing conversions. It is also highly customizable to work both with different styles of JSON content and to support more advanced object concepts such as polymorphism and object identity.

Now, let us create a Test Class to show Serialization.

public class EmployeeTest {

	@Test
	public void serializationTest()  {

		Employee employee = new Employee();
		employee.setFirstName("Vibha");
		employee.setLastName("Singh");
		employee.setAge(30);
		employee.setSalary(75000);
		employee.setDesignation("Manager");

		// Converting a Java class object to a JSON payload as string
		ObjectMapper mapper = new ObjectMapper();
		String employeeJson = mapper.writeValueAsString(employee);
		String employeePrettyJson = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(employee);
		System.out.println(employeeJson);
		System.out.println(employeePrettyJson);
   }
}try {
			String employeeJson = mapper.writeValueAsString(employee);
			System.out.println(employeeJson);
			String employeePrettyJson = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(employee);
			System.out.println(employeePrettyJson);
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		}	
	}

The output of the above program is

Here, ObjectMapper from fasterxml.jackson.databind is used for Serialization.

writeValueAsString() is a method that can be used to serialize any Java value as a String.

writerWithDefaultPrettyPrinter() is used to pretty-print the JSON output. It is a Factory method for constructing ObjectWriter that will serialize objects using the default pretty printer for indentation.

I hope this has helped to clear your doubts regarding POJO and how to create JSON objects using POJO.

We are done! Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!!

Filtering by tags in PyTest-BDD

HOME

@Login
Feature: Login Page

    @ValidCredentials
    Scenario: Successful Application Login
        Given User is on login page
        When User enter username "Admin" and password "admin123"
        Then User should be able to login successfully and new page open "Dashboard"

@ScenarioOutline
Feature: Scenario Outline Example

    @InvalidCredentials
    Scenario Outline: Invalid credentials generate error message
        Given User is on OrangeHome page
        When User enters username as "<username>" and password as "<password>"
        Then User should be able to see error message as "Invalid credentials"

      Examples:
       | username | password    |
       | admin    | admin12345  |
       | Admin123 | admin       |
       | 123      | admin       |


    @MissingUsername
    Scenario: Missing Username generates error
        Given User is on OrangeHome page
        When User enters username as " " and password as "admin123"
        Then User should be able to see error message as "Required" below the username field

pytest

[pytest]
markers =
    Login: mark all tests as login
    ValidCredentials: mark a test as a valid credentials (deselect with '-m "not ValidCredentials"')
	ScenarioOutline: mark all tests as ScenarioOutline
	InvalidCredentials: mark test as invalid credentials (deselect with '-m "not InvalidCredentials"')
	MissingUsername: mark test as missing username (deselect with '-m "not MissingUsername"')

 pytest -k "MissingUsername"

pytest -k  "Login"

pytest -m "ScenarioOutline and MissingUsername"

pytest -m "ValidCredentials or MissingUsername"

 pytest -m "not InvalidCredentials"