Can't set variable value to script in Postman - postman

There are two tests in the request, I want to use a different value of the variable in the second request, I set it using the command
pm.variables.set("confirm_emal", "vodani6277#ulforex.com");
Can't set variable value separately for second script
pm.test("Confirmed email", () =>{
//parse the response JSON and test three properties
const responseJson = pm.response.json();
pm.expect(responseJson.email).to.eql('gekisa9678#exoacre.com');
pm.expect(responseJson.auth_key).to.be.eql('557UmPdC2pGV_tA67bSjHGPbtbRz90Hk');
pm.expect(responseJson.first_name).to.eql('Vitalijj');
pm.expect(responseJson.last_name).to.eql('Agarev');
pm.expect(responseJson.birthday_date).to.eql(978307200);
pm.expect(responseJson.register_type).to.eql('email');
pm.expect(responseJson.email_confirmed).to.eql("true");
});
pm.test("unconfirmed email", () =>{
pm.variables.set("confirm_emal", "vodani6277#ulforex.com");
const responseJson = pm.response.json();
pm.expect(responseJson.email).to.eql('vodani6277#ulforex.com');
pm.expect(responseJson.register_type).to.eql('email');
pm.expect(responseJson.email_confirmed).to.eql(false);
});
I get an error that the expected value does not match the response from the server
AssertionError: expected 'vodani6277#ulforex.com' to deeply equal 'gekisa9678#exoacre.com'
What i am doing wrong?

Related

Postman test script - how to call an api twice to simulate 409 error

I am trying to run a few automated testing using the Postman tool. For regular scenarios, I understand how to write pre-test and test scripts. What I do not know (and trying to understand) is, how to write scripts for checking 409 error (let us call it duplicate resource check).
I want to run a create resource api like below, then run it again and ensure that the 2nd invocation really returns 409 error.
POST /myservice/books
Is there a way to run the same api twice and check the return value for 2nd invocation. If yes, how do I do that. One crude way of achieving this could be to create a dependency between two tests, where the first one creates a resource, and the second one uses the same payload once again to create the same resource. I am looking for a single test to do an end-to-end testing.
Postman doesn't really provide a standard way, but is still flexible. I realized that we have to write javascript code in the pre-request tab, to do our own http request (using sendRequest method) and store the resulting data into env vars for use by the main api call.
Here is a sample:
var phone = pm.variables.replaceIn("{{$randomPhoneNumber}}");
console.log("phone:", phone)
var baseURL = pm.variables.replaceIn("{{ROG_SERVER}}:{{ROG_PORT}}{{ROG_BASE_URL}}")
var usersURL = pm.variables.replaceIn("{{ROG_SERVICE}}/users")
var otpURL = `${baseURL}/${phone}/_otp_x`
// Payload for partner creation
const payload = {
"name": pm.variables.replaceIn("{{username}}"),
"phone":phone,
"password": pm.variables.replaceIn("{{$randomPassword}}"),
}
console.log("user payload:", payload)
function getOTP (a, callback) {
// Get an OTP
pm.sendRequest(otpURL, function(err, response) {
if (err) throw err
var jsonDaata = response.json()
pm.expect(jsonDaata).to.haveOwnProperty('otp')
pm.environment.set("otp", jsonDaata.otp)
pm.environment.set("phone", phone);
pm.environment.set("username", "{{$randomUserName}}")
if (callback) callback(jsonDaata.otp)
})
}
// Get an OTP
getOTP("a", otp => {
console.log("OTP received:", otp)
payload.partnerRef = pm.variables.replaceIn("{{$randomPassword}}")
payload.otp = otp
//create a partner user with the otp.
let reqOpts = {
url: usersURL,
method: 'POST',
headers: { 'Content-Type': 'application/json'},
body: JSON.stringify(payload)
}
pm.sendRequest(reqOpts, (err, response) => {
console.log("response?", response)
pm.expect(response).to.have.property('code', 201)
})
// Get a new OTP for the main request to be executed.
getOTP()
})
I did it in my test block. Create your normal request as you would send it, then in your tests, validate the original works, and then you can send the second command and validate the response.
You can also use the pre and post scripting to do something similar, or have one test after the other in the file (they run sequentially) to do the same testing.
For instance, I sent an API call here to create records. As I need the Key_ to delete them, I can make a call to GET /foo at my API
pm.test("Response should be 200", function () {
pm.response.to.be.ok;
pm.response.to.have.status(200);
});
pm.test("Parse Key_ values and send DELETE from original request response", function () {
var jsonData = JSON.parse(responseBody);
jsonData.forEach(function (TimeEntryRecord) {
console.log(TimeEntryRecord.Key_);
const DeleteURL = pm.variables.get('APIHost') + '/bar/' + TimeEntryRecord.Key_;
pm.sendRequest({
url: DeleteURL,
method: 'DELETE',
header: { 'Content-Type': 'application/json' },
body: { TimeEntryRecord }
}, function (err, res) {
console.log("Sent Delete: " + DeleteURL );
});
});
});

Postman & Newman - cookieJar.getAll() requires a callback function

I am trying to call a graphql and get the data from cookies, it runs well in postman app. However when I trying to run this postman collection on the command line with Newman
In terminal:
newman run postman_collection.json -e environment.json
then it gave me the error
[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block,
or by rejecting a promise which was not handled with .catch().
The promise rejected with the reason "TypeError: CookieJar.getAll() requires a callback function".]
{
code: 'ERR_UNHANDLED_REJECTION'
}
And the Test script code is like this
pm.test("Get a test data", function () {
const jsonData = pm.response.json();
pm.expect(jsonData.data.createTest.success).to.eql(true);
});
pm.test("Test data cookies set", async function () {
const cookieJar = pm.cookies.jar();
const url = pm.environment.get("service-url");
const cookies = await cookieJar.getAll(url);
const cookieNames = cookies.map(cookie => cookie.name);
pm.expect(cookieNames).to.include("test-token");
pm.expect(cookieNames).to.include("legacy-test-token");
});
So I assume the error is because getAll() requires a callback function, Do you know what I'm doing wrong? How can I improve it, Can you help me solve this? Many thanks
'it runs well in postman app' --> I doubt it. I tried and it always passed.
I added a callback, also changed a setting Whitelist Domain in Postman GUI.
pm.test("Test data cookies set", function () {
const cookieJar = pm.cookies.jar();
const url = pm.environment.get("service-url");
cookieJar.getAll(url, (error, cookies)=> {
if(error) console.log(error);
const cookieNames = cookies.map(cookie => cookie.name);
pm.expect(cookieNames).to.include("test-token");
pm.expect(cookieNames).to.include("legacy-test-token");
});
});

request.cookies is undefined when using Supertest

I'm passing my authentication token via an HTTP-Only cookie in my NestJS API.
As such, when writing some E2E tests for my Auth endpoints, I'm having an issue with cookies not being where I expect them.
Here's my pared-down test code:
describe('auth/logout', () => {
it('should log out a user', async (done) => {
// ... code to create user account
const loginResponse: Response = await request(app.getHttpServer())
.post('/auth/login')
.send({ username: newUser.email, password });
// get cookie manually from response.headers['set-cookie']
const cookie = getCookieFromHeaders(loginResponse);
// Log out the new user
const logoutResponse: Response = await request(app.getHttpServer())
.get('/auth/logout')
.set('Cookie', [cookie]);
});
});
In my JWT Strategy, I'm using a custom cookie parser. The problem I'm having is that request.cookies is always undefined when it gets to the parser. However, the cookie will be present in request.headers.
I'm following the manual cookie example from this Medium article: https://medium.com/#juha.a.hytonen/testing-authenticated-requests-with-supertest-325ccf47c2bb, and there don't appear to be any other methods available on the request object to set cookies.
If I test the same functionality from Postman, everything works as expected. What am I doing wrong?
I know this is an old thread but...
I also had req.cookies undefined, but for a different reason.
I'm testing my router independently, not the top level app. So I bootstrap the app in beforeEach and add the route to test.
I was getting req.cookies undefined because express 4 requires the cookieParser middleware to be present to parse the cookies from the headers.
E.g.
const express = require('express');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const request = require('supertest');
const {router} = require('./index');
describe('router', () => {
let app;
beforeAll(() => {
app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser());
app.use('/', router);
});
beforeEach(() => jest.clearAllMocks());
it('GET to /', async () => {
const jwt = 'qwerty-1234567890';
const resp = await request(app)
.get('/')
.set('Cookie', `jwt=${jwt};`)
.set('Content-Type', 'application/json')
.send({});
});
});
Testing this way allows me to unit test a router in isolation of the app. The req.cookies turn up as expected.
Late but I hope I can help you. The problem is in the initialization of the app object. Probably in your main.ts file you have some middlewares configured as they are: cors and queryParse. You must also put them in your tests when you create the app.
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
const app = moduleFixture.createNestApplication();
// Add cors
app.enableCors({
credentials: true,
origin: ['http://localhost:4200'],
});
// Add cookie parser
app.use(cookieParser());
await app.init();
As per the article you're following, the code at https://medium.com/#juha.a.hytonen/testing-authenticated-requests-with-supertest-325ccf47c2bb :
1) has the 'cookie' value in .set('cookie', cookie) in lowercase and in your code it's in Pascal case ==> Have you tried with lowercase in your code instead ?
2) the cookie value assigned to the 'cookie' header is not an array, whereas in your code you're assigning an array ==> Have you tried with a non array value ?
So to resume, can you try with the following code:
describe('auth/logout', () => {
it('should log out a user', async (done) => {
// ... code to create user account
const loginResponse: Response = await request(app.getHttpServer())
.post('/auth/login')
.send({ username: newUser.email, password });
// get cookie manually from response.headers['set-cookie']
const cookie = getCookieFromHeaders(loginResponse);
// Log out the new user
const logoutResponse: Response = await request(app.getHttpServer())
.get('/auth/logout')
.set('cookie', cookie) // <== here goes the diff
.expect(200, done);
});
});
Let us know if that helps :)

Postman Test with comparison to global variable

I want to orchestrate two requests in Postman. The first response will give me a variable. I save this id to a global variable id. In Postman this variable is usually accessible via {{id}}.
Then I send a second request with this id (like GET foo.bar/{{id}}). Now I want to check, if the id is in the result as well.
This is what I tried in the test code:
var jsonData = pm.response.json();
pm.expect(jsonData.id).to.eql({{id}});
where idis the variable from the first response (e.g. 72b302bf297a228a75730123efef7c41).
The response for the second request looks sth. like this:
{
"id": "72b302bf297a228a75730123efef7c41"
}
Here some examples which did not work either:
var jsonData = pm.response.json();
pm.expect(jsonData.id).to.eql("{{id}}");
var jsonData = pm.response.json();
var myId = {{id}};
pm.expect(jsonData.id).to.eql(myId);
My excpectation is, that the test will be positive and the `id from the request will be found in the response.
Do you have an idea how to solve this problem?
Thanks for the help.
The {{...}} syntax cannot be used like that, in the sandbox environment, you would need to access it this way.
pm.expect(jsonData.id).to.eql(pm.globals.get('id'))
The test syntax would be:
pm.test("IDs equal?", function () {
var jsonData = pm.response.json();
pm.expect(jsonData.id).to.eql(pm.globals.get('id'))
});

Invalid or unexpected token when referencing #odata.count

I am currently working with an Odata endpoint and am having an issue referencing JSON values with tags including #. The console shows “SyntaxError | Invalid or unexpected token”
JSON Response Body
pm.test("Your test name", function () {
var jsonData = pm.response.json();
pm.expect(jsonData.#odata.count).to.eql(73);
});
Can someone explain how I reference that value?
pm.test("Your test name", function() {
var jsonData = pm.response.json();
pm.expect(jsonData['#odata.count']).to.eql(73);
});