Home > OS >  Cypress adding token to all requests headers
Cypress adding token to all requests headers

Time:06-24

I'm testing a website that returns token in body from login request. Then all the requests made after we logged in use this token value in header.

I made a custom cypress command that logs in by sending a POST request, but i can't get how to make it push the token to all requests inside my app during test run.

This is a command:

Cypress.Commands.add('login', () => {
    cy.request({
        method: 'POST',
        url:'site/login',
        form: true,
        body:{
            "username":creds.login,
            "password":creds.password
        }
    }).then((resp) => {
        const token = resp.body.token
        cy.intercept('*', (req) => {
            req.headers['token'] = token
        })
    })
})

In the part after .then((resp) => {... i'm trying to intercept all requests and add token to their headers. I can see that requests are intercepted but i'm still logged out from my app.

Tried this solution, but also didn't work.

How can i get token from response body and add it to all requests in cypress?

CodePudding user response:

It depends if the requests are coming from the web page itself or if you are testing an API that needs the token.

cy.intercept() will not catch cy.request() calls made from the test, only calls made from the web page.

For API tests, you would need to set the token in cy.request() explicitly.

The other problem may be where the intercept is set up. It is probably better to store the token globally and set the intercept in the test or another beforeEach().

Here's a general pattern that may suit.

Cypress.Commands.add('login', () => {
  cy.request({
    method: 'POST',
    url:'site/login',
    form: true,
    body:{
      "username":creds.login,
      "password":creds.password
    }
  }).then((resp) => {
    const token = resp.body.token
    Cypress.env('token', token)     // save the token for use elsewhere
  })
})

beforeEach(() => {
  cy.login()
})

it('testing web page requests with token', () => {
  cy.intercept('*', (req) => {
    req.headers['token'] = Cypress.env('token')
    //or
    req.headers['authorization'] = Cypress.env('token')  // check you have the right header
  })
  cy.visit('/')
  ...
})

it('testing API with cy.request() and using token', () => {
  cy.request({
    method: 'GET',
    url:'site/api/...',
    headers: {
      token: Cypress.env('token')
    }
  }).then((resp) => {
    ...
  })
})

CodePudding user response:

Thank you, that worked perfectly for cy.request(), but still had issues with the requests coming from webpage.

I manage to deal with, it turns out that i not only needed to add token to headers, but also set it to localStorage alongside with another params that are setted after we press the login button in UI.

So it worked like this:

Cypress.Commands.add('login', () => {
    cy.request({
        method: 'POST',
        url:'/site/login',
        form: true,
        body:{
            "username":creds.login,
            "password":creds.password
        }
    }).then((resp) => {
        const token = resp.body.token
        Cypress.env('token', token)
        window.localStorage.setItem('item1', `{"a":"1", "b":"2", "token":${JSON.stringify(token)}}`)
        window.localStorage.setItem('item2', 'value2')
        window.localStorage.setItem('item3', 'value3')
    })
  • Related