TestRaptor
TestRaptor

Reputation: 1315

Cypress - How to use response body in another request header

I have a function that will return a token

var accessToken;
function TestToken(){
    return cy.request({
        method: 'POST',
        url: "https://site/token",
        headers: {
            'Content-Type': 'application/json',
        },
        body: {
            client_id: '1234',
            client_secret: '1234',
            audience: 'https://site/api/v1/',
            grant_type: 'credentials'
        }
    }).then(response => {
    return new Cypress.Promise((resolve, reject) => {
        const rbody = (response.body);
        var tokenPattern = "(?i)\"access_token\":\\s*\"([^\"]*)\"";
        const authToken = rbody.access_token;
        accessToken = authToken
        cy.log(accessToken);
        resolve(accessToken);
        return accessToken;
    })
});

I call that function in another cypress command, as I need to use the token in the authorization header

Cypress.Commands.add("ResetPwd", () => {
    const authToken = TestToken();
    cy.log(authToken);
    cy.request({
        method: 'POST',
        url: "https://site/api/v2/users/1234",
        headers: {
            'Content-Type': 'application/json',
            'authorization': 'Bearer '+authToken,
        },
        body: {
            password: 'Test4321',
            connection: 'DB',
        }
    });
});

When I execute the command, I don't see the token being used. Instead I see "authorization": "Bearer [object Object]" in the request.

In the TestToken funtion, I added cy.log(authToken);, to verify it was correctly grabbing the token. The cypress test failed saying

CypressError: cy.then() failed because you are mixing up async and sync code.

but I could still see the correct token in the console.

Here is the cypress test I am trying to run

describe('Token Test', function() {
    before(() => {
        cy.ResetPwd();
    })
    it('Go to website', function() {
        cy.visit('https://site/login')
    });
});

Upvotes: 4

Views: 10196

Answers (3)

schnumsel
schnumsel

Reputation: 35

I solved this, after lots of work using cy.task:

        cy.request({
            method: 'POST',
            url: '/where/you/retrieve/your/token',
            body: {username: user, password: password},
            failOnStatusCode: true
        }).then((response) => {
            cy.task('setToken', response.body);
        });

then:

cy.task('getToken').then((token) => {
    cy.request({
        method: 'GET',
        url: '/your/protected/endpoint/here',
        headers: {
           authorization: `Bearer ${token}`
        },
        failOnStatusCode: true
    }).then((response) => {
        expect(response.something).to.eq(something.else);
    }); 
});

Upvotes: 0

Dhananjai Pai
Dhananjai Pai

Reputation: 6015

I am assuming the TestToken() function is a promise and resolves asynchronously causing the authToken to be [ object Object ]

You could use async/await and the code should work fine.

Add async before the arrow function and use await const authToken = TestToken()

Upvotes: 0

Przemyslaw Jan Beigert
Przemyslaw Jan Beigert

Reputation: 2486

functions is synchronous so in moment of call it the result will be equal Promise, promise is object and when you try to stringify object (by + operator) you get [object Object].

After some time promise will be resolved and value in authToken variable will be correct.

To fix it is suggest use Cypress.Promise like in example id cypress docs: https://docs.cypress.io/api/utilities/promise.html#Basic-Promise

Upvotes: 1

Related Questions