Postman pm.response.to.have.header not working as expected - automated-tests

Using Postman version v6.1.3 See
https://www.getpostman.com/docs/v6/postman/scripts/test_examples
PART 1
Postman's test examples include this test to see if a header is present:
pm.test("Content-Type is present", function () {
pm.response.to.have.header("Content-Type");
});
My response headers contain this:
Content-Type →application/json
I expect the test above to PASS, but it FAILS. Why?
It says:
FAIL Content-Type is present | AssertionError: expected response to not have header with key 'Content-Type'
Further, since the above test FAILS, then I would expect this negative test to succeed, but it FAILS too:
pm.test("Content-Type is present", function () {
pm.response.to.have.header("Content-Type");
});
It says:
FAIL Content-Type is present | AssertionError: expected response to not have header with key 'Content-Type'
Note that this is the EXACT SAME error message as above. They both say "expected response to not have" which seems wrong to me.
PART 2
Just to make the whole experience more confusing, testing for the key and value string works. Am I misunderstanding of "have.header"?
pm.test("Content-Type is present", function () {
pm.response.to.have.header("Content-Type →application/json");
});
It returns:
PASS Content-Type is present
And yet again, the negative test for this ALSO PASSSES!
pm.test("Content-Type is present", function () {
pm.response.to.not.have.header("Content-Type →application/json");
});
It returns:
PASS Content-Type is present
PART 3
Help?!

My problem seems to be related to this bug:
https://github.com/postmanlabs/postman-app-support/issues/3690
"pm.response.to.not.be causes later assertions to work backwards."

You probably got this working by now but anyways here is what worked for me:
pm.test("Content Type is present", function () {
pm.expect(pm.response).to.have.header("Content-Type");
})

Related

Show test body, test steps for passing tests in Cypress

When tests pass in Cypress it doesn't show the steps but if fails it shows all the steps and what step caused test to fail.
I want to see passing tests body/steps too.
Below image shows a passing test and a failing test. Failing test is much more informative. I want passing test to be like that too. How can I achieve this?
it('should select shipment method and type "test" into additional
notes', function () {
cy.intercept('GET',
'**/GetDetailWithAvailableCampaign*').as('basketDetails')
cy.on('uncaught:exception', (err, runnable) => { // If CheckoutJS throws an error, it will be caught here
cy.get('[data-cy="information::forward"]').click()
cy.url().should('include', '/basket/checkout/payment')
cy.get('[data-cy="shipping::shipment_type"]').first().click()
cy.get('[data-cy="shipping::shipment_type"]').should('be.checked')
cy.get('[data-cy="misc::additional_message_checkbox"]').check({force: true}).should('be.checked')
cy.get('[data-cy="misc::additional_message_textarea"]').should('be.visible').clear().type('Test')
// there is no shipping::forward
// cy.get('[data-cy="shipping::forward"]').click()
cy.get('[data-cy="information::forward"]').click()
})
})
it('should focus iframe and put a credit card', function () {
cy.wait(4000)
cy.url().should('include', '/basket/checkout/shipping')
const iframeSelector = 'iframe[data-cy="payment::iframe"]'
getIframeBody(iframeSelector).find('.btn-card-visa').click()
cy.wait(2000)
getIframeBody(iframeSelector).find('input#CardNumber').clear().type(Cypress.env('credit_card').number)
getIframeBody(iframeSelector).find('input#Expiry').clear().type(Cypress.env('credit_card').expiry)
getIframeBody(iframeSelector).find('input#HolderName').clear().type(Cypress.env('credit_card').holder_name)
getIframeBody(iframeSelector).find('input#VerificationCode').clear().type(Cypress.env('credit_card').cvv)
getIframeBody(iframeSelector).find('.btn-next').click()
}
By default, clicking on a test's name in the runner will expand and show all steps executed. In your case, it is doing this. But the issue you are running into is most likely that the uncaught:exception event you are waiting for in the first test is not occurring, and therefore no steps are executed. If you remove the cy.on('uncaught:exception'), you'll see the steps are executed.

Mirage Passthrough returns Response Object instead of JSON data returned from network call

I am getting an error:
Mirage: Your Ember app tried to GET 'http://localhost:3006/data.json',
but there was no route defined to handle this request.
Define a route that matches this path in your mirage/config.js file.
Did you forget to add your namespace?
So following the documentation of mirage i added this:
this.passthrough('http://localhost:3006/data.json');
Even though after adding passthrough, I am getting such Response instead of JSON Object returned from the network api call.
The Actual Request i am making is:
fetch(`${host}/data.json`)
.then(res => res.json())
.then(data => {
// my operation on data
});
The response i am getting is:
{bodyUsed: true
headers: Headers {map: {…}}
ok: true
status: 200
statusText: "OK"
type: "default"
url: "http://localhost:3006/data.json"
_bodyInit: null
_bodyText: ""}
But I am expecting:
{
"files":
{
"x": "any",
"a": "any",
"b": "any",
"c": "any"
}
}
I kept a debugger in Pretender.js which is sending the FakeRequest and there in its object, I see that FakeRequest has responseType="" and response as null. And somehow my responseText has value but that is not considered and response value is considered and receiving null.
Also there is a logic which is return saying
"response" in xhr ? xhr.response : xhr.responseText
In this case i have response property but its value is null. Hence according to the above condition it is returning xhr.response which is null
Thanks in Advance.

httpClient.get call is returning 404 Not Found Error

I attempt to get a list of products from localhost:4200 using the following code...
In one file:
constructor(private http: HttpClient) {}
getProducts(query: string): Observable<Product[]> { return this.http.get<Product[]>('/api/product'); }
In another file I call the above getProducts(), like this:
this.products$ = this.productService.getProducts( "" );
The error is this:
status 404, statusText: "Not Found", url: "localhost:4200/api/product".
I don't know how to query the structure of a localhost site, so I am rather stuck as to how to understand and fix this "Not Found" problem.
Also, there was also a similar error just before this one:
zone-evergreen.js:2952 GET http://localhost:4200/api/product 404 (Not Found)
Can you help me out?

Function not found error: Name: [get]. in firestore security rules simulation

match /UserProfile {
match /{uId}{
allow get: if isUserLoggedIn() && !isUserBlocked(uId);
}
when i try to get data from UserProfile/{uId} using the above security rules it throws the following error in the firestore and in code it says insufficient permissions:
Error running simulation — Error: simulator.rules line [199], column [28]. Function not found error: Name: [get].
now the definition of above two function are here
function isUserLoggedIn(){
return request.auth != null;
}
function isUserBlocked(uId){
return (('blocked' in get(/databases/$(database)/documents/UserSettings/$(uId)).data) && (request.auth.uid in get(/databases/$(database)/documents/UserSettings/$(uId)).data.blocked));
}
the first function runs very well
but the second one doesn't
it throws that error
and as of my knowledge the function is alright
please help i have wasted a whole lot of time on this piddly problem
what i have tried
i read in one of the threads that it is a temporary problem
but it is not like that. its been more than 48 hours now
somewhere it was also mentioned that this is a bug only in simulator but the code will run smoothly and even this is not the case. in code the error is insufficient permissions as expected by me
i have read the docs properly so my code is alright have tested the get method in other rules and there it is working fine
thats it please help
Update: The errors are a bug in the rules simulator, see Doug's comment below.
I tried out your rules and they worked as expected in the simulator.
Rules:
match /UserProfile {
function isUserLoggedIn(){
return request.auth != null;
}
function isUserBlocked(uId){
return (('blocked' in get(/databases/$(database)/documents/UserSettings/$(uId)).data) && (request.auth.uid in get(/databases/$(database)/documents/UserSettings/$(uId)).data.blocked));
}
match /{uId}{
allow get: if isUserLoggedIn() && !isUserBlocked(uId);
}
}
Test query in simulator:
get /UserProfile/foo
Authenticated: Yes
Firebase UID: bar
The request succeeds or fails based on the UserSettings/foo document in the database:
Denies request:
/UserSettings/foo
{
content: "my content"
blocked: { bar: true }
}
Allows request:
/UserSettings/foo
{
content: "my content"
blocked: { otheruser: true }
}
I think that errors can pop up when the data doesn't exist or isn't in the expected format.
For example, if I delete the /UserSettings/foo document I also receive:
Error: simulator.rules line [58], column [28]. Function not found error: Name: [get].
I also get this error if the blocked field is anything other than a map (because in is a function for maps):
Error: simulator.rules line [58], column [95]. Function not found error: Name: [in].
You can probably clean up these errors by using exists and checking the type of blocked but either way, your rules should still deny the request as expected.

Async Tests - Mocha and Chai - Ensure the done() callback is being called

I'm trying test my container component methods. My container had a async method that load all proposals and set in the state. Example.:
loadProposal(proposalId) {
return axios
.get("http://localhost:9292/api/proposal_drafts/1.json")
.then(response => {
this.setState({
proposal: Immutable.fromJS(response.data)
})
})
}
So, to test this method i get the component instance and call the method (the api url is mocked).
it("sets proposal in the state", (done) => {
const wrapper = shallow(<Container/>)
loadProposalRequest(1)
wrapper.instance().loadProposal(1).then(() => {
chai.expect(wrapper.state().proposal).to.be(Map)
done()
})
})
But i get this error from console:
Error: timeout of 2000ms exceeded. Ensure the done() callback is being
called in this test.
Ops: If i put a console.log(wrapper.state()) inside then() . The log shows my state correctly.
If chai.expect() throws an error (which I think is what's happening), two things will happen:
done won't get called, because of the thrown error;
the error won't get caught, because there's not additional error handling.
You should use Mocha's promise support instead to remove both issues:
it("sets proposal in the state", () => {
const wrapper = shallow(<Container/>)
loadProposalRequest(1)
return wrapper.instance().loadProposal(1).then(() => {
chai.expect(wrapper.state().proposal).to.be(Map)
})
})
You can also use chai-as-promised
you can write code that expresses what you really mean:
return doSomethingAsync().should.eventually.equal("foo");
or if you have a case where return is not preferable (e.g. style considerations) or not possible (e.g. the testing framework doesn't allow returning promises to signal asynchronous test completion), then you can use the following workaround (where done() is supplied by the test framework):
doSomethingAsync().should.eventually.equal("foo").notify(done);

Resources