TypeError: Cannot read property 'has' of undefined

I am executing a collection using Runner on Postman version 7.14.0. As part of the Tests Script, I am validating the response header contents using:

tests[“Content-Type is present”] = postman.getResponseHeader(“Content-Type”).has(“application/json; charset=utf-8”);
tests[“X-Content-Type-Options is present”] = postman.getResponseHeader(“X-Content-Type-Options”).has(“nosniff”);
tests[“X-Frame-Options is present”] = postman.getResponseHeader(“X-Frame-Options”).has(“SAMEORIGIN”);
tests[“X-XSS-Protection is present”] = postman.getResponseHeader(“X-XSS-Protection”).has(“1; mode=block”);

However, I keep running into the TypeError complaining that the property ‘has’ is undefined. I understand that this is part of the Sandbox API, but is it not supported when I execute it via Runner?

Hi @pshivashankar!

.has is a method associated with Postman variables (i.e. pm.environment.has('name')), it won’t work in your current implementation. Those assertions are also the old approach for writing tests in Postman.

I’d suggest writing your tests using the pm.test() method, and ChaiJS assertions like the following:

pm.test("content-type is application/json", function () {
    let responseHeadersJson = pm.response.json().headers;
    pm.expect(responseHeadersJson['content-type']).to.equal('application/json; charset=utf-8');
})

You can read more about writing tests in Postman on our Learning Center:

…and here’s more about ChaiJS assertions:

Hope that helps!

Hi @john-paul thanks for your response. I updated the test functions accordingly but I still get a “TypeError: Cannot read property ‘Content-Type’ of undefined”

@pshivashankar could you share your code here, as well as an example response your receive, so I can try to reproduce?

Hi @john-paul: Please find the sample response and the code below:

tests["Status code is 200"] = responseCode.code === 200;

if(responseCode.code === 200) {
    var result = JSON.parse(responseBody);
} else {
    console.log(responseHeaders);
    console.log(responseBody);
}

pm.test("Body matches string", function () {
    pm.expect(pm.response.text()).to.include("bctoken");
    pm.expect(pm.response.text()).to.include("bcaccesskey");
    pm.expect(pm.response.text()).to.include("bcentitykey");
});

pm.test("Set Globals", function () {
    var jsonData = pm.response.json();
    pm.environment.set("bctoken", jsonData["bctoken"]);
    pm.environment.set("bcaccesskey", jsonData["bcaccesskey"]);
    pm.environment.set("bcentitykey", jsonData["bcentitykey"]);
}); 

pm.test("Validate Data", function () {
    var jsonData = pm.response.json();
    pm.expect(jsonData["bcaccesskey"]).to.eql(pm.environment.get("bcaccesskey"));
    pm.expect(jsonData["bcentitykey"]).to.eql(pm.environment.get("bcentitykey"));
    pm.expect(jsonData["bctoken"]).to.eql(pm.environment.get("bctoken"));
});

pm.test("Content-Type is present", function() {
    let responseHeadersJson = pm.response.headers.all();
    pm.expect(responseHeadersJson['Content-Type'].to.equal('application/json; charset=utf-8'));
});

Also @john-paul here’s the result of the run:

As you may notice, after I changed the responseHeadersJson variable assignment with pm.response.headers.all(), the issue with ‘Content-Type’ got resolved but it is now throwing a different error indicating that it cannot read property ‘to’ of undefined.

@pshivashankar try this and let me know if it works:

pm.test("content-type is application/json", function () {
    let responseHeaders = pm.response.headers.all();
    let index = -1;
    for(var i = 0; i < responseHeaders.length-1; i++)
    {
        console.log(responseHeaders[i]);
        if(responseHeaders[i].key === 'Content-Type')
        {
            index = i;
            break;
        }
    }
    
    pm.expect(index).to.not.equal(-1);
    pm.expect(responseHeaders[index].value).to.equal('application/json; charset=utf-8');
});

pm.response.headers.all() returns an array of objects, so you’ll need to iterate through it by some means to find the correct index containing the content-type header. responseHeadersJson['Content-Type'] won’t work because of this.

1 Like

Hi @john-paul,

The new function didn’t work either. I am now getting an error - responseHeaders[index].value.to.equal is not a function. The code snippet is shown below along with the snapshot of the error:

pm.test("Content-Type is present", function() {
    let responseHeaders = pm.response.headers.all();
    let index = -1;
    for(var i = 0; i < responseHeaders.length-1; i++){
        console.log(responseHeaders[i]);
        if(responseHeaders[i].key === 'Content-Type'){
            index = i;
        }
        
    }
    pm.expect(index).to.not.equal(-1);
    pm.expect(responseHeaders[index].value.to.equal('application/json; charset=utf-8'));
}); 

image

Is there no way to extract each of the header if we don’t want it all together in an array format? The previous method of accessing each via pm.response.json().headers; resulted in the TypeError.

Looks like you’re missing a parenthesis after .value. This line should be:
pm.expect(responseHeaders[index].value).to.equal('application/json; charset=utf-8');

1 Like

Yep! That did it. However, is there a simpler method for implementing this? For checking 5-6 header values, this becomes unwieldy… a simpler method would be more preferable in my opinion. Please let me know.

Please Tell me about this Matter

In your case, jsonData doesn’t have the data property, so trying to access data’s own username property will cause an error, not simply fail the test. Add this before your other expect:
pm.expect(jsonData).to.have.property("data");