Forum Discussion

sonya_m's avatar
sonya_m
SmartBear Alumni (Retired)
5 years ago

API Masterminds - How do you use event handlers?

Hi everyone! 

 

Most probably, many of you know about the event handlers functionality in ReadyAPI. It lets you execute a custom Groovy script when an event occurs. For example, if you want to pre-process a request before it’s sent to the server, you would use the RequestFilter.filterRequest event handler, and if you would like to pre-process a response before it’s displayed in the Response Editor and before it’s verified with assertions, you would use the RequestFilter.afterRequest event. 

 

I’ve got a couple of nice examples of the RequestFilter.afterRequest usage.  

  • An XML response payload contains a CDATA section. Within this section, you have content that is known to be a well-formed XML and you’d like to apply XML-specific assertions to it. What you can do is to unwrap CDATA with the following code snippet: 

 

def response = context.httpResponse.responseContent;
response = response.replaceAll("<!\\[CDATA\\[","").replaceAll("]]>","");
context.httpResponse.responseContent = response;
  • A JSON response payload contains a string value that is known to be an escaped JSON string.

For this response

{
  "applicationResponse" : "{\"header\":{\"status\":\"OK\"},\"response\":{\"id\": 1,\"date\":\"03-26-2020\"}}"
}

the code to unescape the value of the "applicationResponse" property can be as follows:

import groovy.json.JsonSlurper
import groovy.json.JsonOutput

def response = context.httpResponse.responseContent

try{
  def jsonSlurper = new JsonSlurper()
  def responseObj = jsonSlurper.parseText(response)
  def applicationResponseVal = responseObj.applicationResponse
  def applicationResponseValUnescaped = applicationResponseVal.replaceAll("\\\\", "");
  responseObj.applicationResponse = jsonSlurper.parseText(applicationResponseValUnescaped)
  log.info(JsonOutput.toJson(responseObj))
  context.httpResponse.responseContent = JsonOutput.toJson(responseObj)
}
catch (e){
  log.info("The response was not modified " + e)
}

In the above examples, ReadyAPI will try to pre-process every response in your project. If this is not what you need, you can limit the scope of the handler by specifying a target for it. Refer to this KB article for more examples of filters. 

 

Questions:

Do you use event handlers?

Do you use filtering by target?

What are the most common scenarios for your testing process? 

 

 

  • nmrao's avatar
    nmrao
    Champion Level 3

    This is yet an another powerful feature in the product. And uses are numerous depending on the need.

    Event handling allows user to do many things on demand yet dynamically & granular and here some general use cases
    - manipulate the requests & responses before submitting the request and after step respectively.
    - adding common headers such as Authentication / token / jms headers
    - filter by request type so that not all requests being processed.

    It's just awesome feature.

    However, this feature is limited to Pro software only.
    I am a fan of Open Source edition. Came up with below extension (couple of years ago) so that the events feature can be leveraged for SoapUI OS too.

    https://github.com/nmrao/soapuiExtensions

      • sonya_m's avatar
        sonya_m
        SmartBear Alumni (Retired)

        HimanshuTayal nmrao  Awesome!

        That's exactly why I love community events - useful information is posted everyday for people to reference in the future. 

  • Not everytime but once i explored and then used Event Handler in below scenario:

     

    We were having 1000+ test cases and the Automation suite was too old in those 1000+ test cases 500+ test cases were having DB connection, in starting everything was fine but one day DB team told us that we are creating lot of open connections, so we start exploring why our scripts are not closing

     

    Everything was fine but connection was not getting closed for Failed scripts, so we updated our scripts by use of Event Handler.

     

    What we did is create DB object on TestSuiteRunListner.beforeTestCase

    import com.mongodb.MongoClient;
    import com.mongodb.MongoClientURI;
    
    
    def url = context.expand( '${mongourl}' )
    MongoClientURI client = new MongoClientURI(url);
    MongoClient mongoClient = new MongoClient(client);
    
    context.setProperty("mongoClient", mongoClient)
    
    log.info "executed before"

     

    and close db on TestSuiteRunListner.afterTestCase

    context.mongoClient.close()
    log.info "Executed After"

    That was my real case example, which help me in creating lesser connection every time our Project gets executed.