Saturday, March 21, 2020

Resst Assured Custom Filter

We can log all Request And Response using log.all() method in console but we can't log it within log file or can't customize the log what we need to print.

Here we will learn how we can configure the filter to store the request and response in logfile for future purpose like debug.

We will follow the below steps for creating the CustomFilter.

Step 1:

Below pom.xml file is required for sample RestAssured project

<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.api.automation</groupId>
    <artifactId>APITest</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <dependencies>
        <!-- https://mvnrepository.com/artifact/io.rest-assured/rest-assured -->
        <dependency>
            <groupId>io.rest-assured</groupId>
            <artifactId>rest-assured</artifactId>
            <version>4.1.1</version>
            <scope>test</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
            <scope>provided</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.testng/testng -->
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>6.14.3</version>
            <scope>test</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.10</version>
        </dependency>

    </dependencies>
</project>



Step 2:

Now we will create a class for CustomLoggingFilter, this class implements Filter class and override the filter method of Filter class.

package com.api.automation.test;

import java.io.PrintStream;
import java.io.StringWriter;
import java.nio.charset.Charset;

import org.apache.commons.io.output.WriterOutputStream;

import io.restassured.filter.Filter;
import io.restassured.filter.FilterContext;
import io.restassured.filter.log.LogDetail;
import io.restassured.internal.print.RequestPrinter;
import io.restassured.internal.print.ResponsePrinter;
import io.restassured.response.Response;
import io.restassured.specification.FilterableRequestSpecification;
import io.restassured.specification.FilterableResponseSpecification;

public class CustomLoggingFilter implements Filter {

   

    public Response filter(FilterableRequestSpecification requestSpec, FilterableResponseSpecification responseSpec,FilterContext ctx) {
      
        Response response = ctx.next(requestSpec, responseSpec);

        


        // Storing Request in String
        String requestString = RequestPrinter.print(requestSpec, requestSpec.getMethod(), requestSpec.getURI(), LogDetail.ALL, new PrintStream(new WriterOutputStream(new StringWriter(),Charset.defaultCharset())), true);
        


        // Storing Response in String
        String responseString = ResponsePrinter.print(response, response, new PrintStream(new WriterOutputStream(new StringWriter(),Charset.defaultCharset())), LogDetail.ALL, true);
        


        // Print request in String
        System.out.println("Print Request: " + requestString);
        


        // Print response in String
        System.out.println("Print Response: " + responseString);
        


        /*
         * Logging the response depends on response status code
         */

        


        /*
         * int statusCode = response.getStatusCode(); if (statusCode >= 400 &&
         * statusCode <= 500) {
         * System.out.println("****************************************" +
         * responseString); } else { System.out.println(" (" + statusCode+ ")"); }
         */

      
        return response;
    }
}

 
 

Step 3:

Now we will write the test class to implement the CustomLoggingFilter.

We will add this custom filter in RequestSpecification.

package com.api.automation.test;

import org.testng.annotations.Test;

import io.restassured.RestAssured;
import io.restassured.builder.RequestSpecBuilder;
import io.restassured.http.ContentType;
import io.restassured.specification.RequestSpecification;


public class ValidateAPI {

    @Test
    public void validateSimpleAPI() {
      
        RequestSpecification requestSpecification = new RequestSpecBuilder().setBaseUri("http://restapi.demoqa.com/utilities/weather/city/")
                .setContentType(ContentType.JSON)

                .addFilter(new CustomLoggingFilter())
                .build();
      
        RestAssured.given(requestSpecification).when().get("/Hyderabad").then();
        
    }
}

 
 

Sunday, March 1, 2020

DataTable Handling With Cucumber 4

Previously in older version of  Cucumber we can transform Datatable as per our own object easily but now we need to implement TypeRegistryConfigurer in our code.

Here we will discuss on it.

Step 1:

Create a Employee class as below

public class EmployeeDTO {

    private String username;
    private String password;

    public EmployeeDTO(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public String getUserName() {
        return username;
    }

    public void setUserName(String userName) {
        this.username = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPasword(String password) {
        this.password = password;
    }

}


Step 2: 

Now we need to implemnt TypeRegistryConfigurer as below

import java.util.List;
import java.util.Locale;
import java.util.Map;

import io.cucumber.core.api.TypeRegistry;
import io.cucumber.core.api.TypeRegistryConfigurer;
import io.cucumber.datatable.DataTableType;
import io.cucumber.datatable.TableEntryTransformer;
import io.cucumber.datatable.TableRowTransformer;
import io.cucumber.datatable.TableCellTransformer;

public class EmployeeRegistryConfigurer implements TypeRegistryConfigurer {


    @Override
    public Locale locale() {
        // TODO Auto-generated method stub
        return Locale.ENGLISH;
    }

//RowTransformer is List of Objects List<EmployeeDTO>  
    @Override
    public void configureTypeRegistry(TypeRegistry typeRegistry) {
        typeRegistry.defineDataTableType(new DataTableType(EmployeeDTO.class,new TableRowTransformer<EmployeeDTO>() {

            @Override
            public EmployeeDTO transform(List<String> row) throws Throwable {
                // TODO Auto-generated method stub
                return new EmployeeDTO(row.get(0), row.get(1));
            }
        }));
    }


//CellTransformer is List of List of Objects List<List<EmployeeDTO>> employeeDetails  
//    @Override
//    public void configureTypeRegistry(TypeRegistry typeRegistry) {
//        typeRegistry.defineDataTableType(new DataTableType(EmployeeDTO.class, new TableCellTransformer<EmployeeDTO>() {
//            @Override
//            public EmployeeDTO transform(String cell) throws Throwable {
//                return new EmployeeDTO(cell, cell);
//            }
//          
//        }));
      
  
//EntryTransformer is List of Maps of Keys to Values List<EmployeeDTO>  
//        @Override
//        public void configureTypeRegistry(TypeRegistry registry) {
//            registry.defineDataTableType(new DataTableType(EmployeeDTO.class, new TableEntryTransformer<EmployeeDTO>() {
//                @Override
//                public EmployeeDTO transform(Map<String, String> entry) throws Throwable {
//                    return new EmployeeDTO(entry.get("username"),entry.get("password"));
//                }
//            }));
//
//    }

}
Step 3:

Now we can call this as below:

public class Steps {

    @Given("UserName and Password.")
    public void username_and_Password() {
        System.out.println("Test");
    }

    @Given("UserName and Password as below.")
    public void username_and_Password_as_below(List<EmployeeDTO> employeeDetails) {
        System.out.println(employeeDetails.get(0).getUserName());
        System.out.println(employeeDetails.get(0).getPassword());
        System.out.println(employeeDetails.get(1).getUserName());
        System.out.println(employeeDetails.get(1).getPassword());
    }
}