Search code examples
karateweb-api-testing

Karate API Testing - How do we extract values from Content-Type: text/html kind of response?


I have a request which includes graphQL query in body.

When I post it, it returns a response with Content-Type →text/html; charset=utf-8 and some other Usual headers. The txt/html response includes usually two things:

  1. ColDefs as the first row
  2. metadata in the second row

Now I need to validate that ColDefs appears always in the first row. The second row contains metadata.

How do I make sure that the response first row always contains colDefs and second-row contains metadata info?

Response:

{
    "colDefs": [{
        "entityAttributeId": "abc",
        "headerName": "xyz",
        "field": "2",
        "entityPath": "",
        "entityId": "mna"
    }, {
        "entityAttributeId": "abc",
        "headerName": "abc",
        "field": "3",
        "entityPath": "abc",
        "entityId": "abc"
    }
        
]
} {
    "1": "1000",
    "2": "abc",
    "3": "abc",
    "4": 12,
    "5": "6457.T",
    "6": "123",
    "7": "abc"
} {
    "1": "123",
    "2": "abc",
    "3": "abc",
    "4": 123,
    "5": "123",
    "6": "",
    "7": "abc"
} 

When I try to print, the karate response, it is not printing second-row(metadata) contents, it is just printing colDefs.

Karate Response:

{
    "colDefs": [{
        "entityAttributeId": "abc",
        "headerName": "xyz",
        "field": "2",
        "entityPath": "",
        "entityId": "mna"
    }, {
        "entityAttributeId": "abc",
        "headerName": "abc",
        "field": "3",
        "entityPath": "abc",
        "entityId": "abc"
}

Steps to replicate:

URL: some URL

Headers: Content-Type = 'application/json'

(sending explicitly in karate feature ) ,

Request Body

{
"query": "query($someid: [String]) {some(someid:$someid) {someid someNm someVariable {someVariable someVariableid otherVariable{ otherVariable1 { variable CUSIP issuer { someVariable2 }}}}}}",
        "variables": {
            "someid": ["1090"]
        },
        "includeMetadata": false
    }       
    
Response Header:  Connection →keep-alive
Content-Length →86488
Content-Type →text/html; charset=utf-8
   

Response Body:

{
    "colDefs": [{
        "entityAttributeId": "abc",
        "headerName": "xyz",
        "field": "2",
        "entityPath": "",
        "entityId": "mna"
    }, {
        "entityAttributeId": "abc",
        "headerName": "abc",
        "field": "3",
        "entityPath": "abc",
        "entityId": "abc"
    }
        
]
} {
    "1": "1000",
    "2": "abc",
    "3": "abc",
    "4": 12,
    "5": "6457.T",
    "6": "123",
    "7": "abc"
} {
    "1": "123",
    "2": "abc",
    "3": "abc",
    "4": 123,
    "5": "123",
    "6": "",
    "7": "abc"
} 

Karate Response:

{
    "colDefs": [{
        "entityAttributeId": "abc",
        "headerName": "xyz",
        "field": "2",
        "entityPath": "",
        "entityId": "mna"
    }, {
        "entityAttributeId": "abc",
        "headerName": "abc",
        "field": "3",
        "entityPath": "abc",
        "entityId": "abc"
}

Solution

  • Clearly your response is not valid JSON and in some proprietary format - and expecting Karate to magically convert it for you is expecting too much :)

    I suggest you write some Java code to do your custom validation. What is happening here is Karate tries its best - is able to get half the response parsed as JSON and gives up on the rest. You should actually appreciate this :)

    Since Karate also keeps a copy of the raw response as bytes (version 0.9.0 onwards), you can do this:

    * string temp = responseBytes
    

    Now please use some Java code or custom string parsing - and do whatever your requirement demands on temp which will be a Java String. I have to say that this looks like a VERY badly designed API.