0

Any idea why the 'token' set in localStorage is removed during cypress test run?

I have 'loadToken()' function written in commands.js file, while running the test i could see the token is being set, but as soon as cy.visit('/dashboard') is called, the token gets removed/disappeared and still displays the login page and doesnt allow to login. The same way was working with some other projects. note: When we actually hit the baseUrl [https://some-url.net] it actually add following extension to url '/auth/login'

Cypress.Commands.add('loadTokens', () => {
    return cy.fixture('tokenData.json').then(data => {
        const keys = Object.keys(data);
        keys.forEach(key => {
            window.localStorage.setItem(key, data[key]);
        });
    });
});

I am calling the loadTokens() and loginRequest() inside before each;

context('Login and Logout test',() => {
  before(()=>{
  cy.visit('/');
})

beforeEach(() => {
  cy.loadTokens();
  cy.loginRequest();
})

it.only('Check whether the login is possible',() => {
    cy.viewport(1600, 1000); 
    cy.get('#offCanvasLeft > ul > li > a > span').eq(1).invoke('text').then((text)=>{
        expect(text).to.equal("Dashboard");
    }) 
})

})

Cypress.Commands.add('loginRequest', () => {
  const accessToken = localStorage.getItem('tokens');
    var cookieValue = document.cookie.split(';');
    cy.request({
      method: 'GET',
      url: baseUrl+`/dashboard`,
      headers: {
        'content-type': 'text/html',
        'tokens': `${accessToken}`,
        'cookie': `${cookieValue}`
      }
    })
  })

//cypress.json file:

{
  "baseUrl": "https://some-url.net",
  "numTestsKeptInMemory": 3,
  "chromeWebSecurity": false
}

//Before the cypress test hit the cy.visit() command, I am able to see the tokens set. enter image description here

Maik Lowrey
  • 15,957
  • 6
  • 40
  • 79
soccerway
  • 10,371
  • 19
  • 67
  • 132
  • 2
    did you try to exchange position and put first `cy.visit('/dashboard')` and then `cy.loadTokens();`? – Evgenii Bazhanov Mar 27 '20 at 23:43
  • I have tried that, now I can see the token is displaying/holding in the localStorage(), but system is not login into the website. – soccerway Mar 28 '20 at 00:11
  • @EvgenyBazhanov ..Thank you Evgeny Bazhanov.. – soccerway Mar 28 '20 at 00:20
  • Does this answer your question? [Preserve cookies / localStorage session across tests in Cypress](https://stackoverflow.com/questions/50471047/preserve-cookies-localstorage-session-across-tests-in-cypress) – Barney Mar 28 '20 at 01:03
  • I have figured out a way already to get the token and that is saved into fixture folder and I am reading that token using `cy.loadTokens()` and setting to the localStorage()..all good till there...but some how website is not allowing to login. – soccerway Mar 28 '20 at 01:16
  • I have tried that now, getting 405 error method not allowed. I have tried as below: Cypress.Commands.add('loginRequest', () => { const accessToken = localStorage.getItem('tokens'); cy.request({ method: 'POST', url: baseUrl +'/dashboard', headers: { 'content-type': 'text/html', 'authorization': `bearer ${accessToken}` } }) }) – soccerway Mar 28 '20 at 03:55
  • tokens are loading first, I am calling that in the before() method. I have tried with cy.visit() and cy.request() but not looking good. Even changed from POST to GET – soccerway Mar 28 '20 at 04:23
  • Yes, one more thing I have noticed >> baseUrl is `https://some-url.net/auth/login`, when login to site, it displays as `https://some-url.net/dashboard`. So as per you suggested, I believe I can't give baseUrl+`/dashboard` which is giving 404 as the url returns is https://some-url.net/auth/login/dashboard- which is not valid. Also after login I checked the Request headers which has got `cookie: AWSALB=XrlekfVp4g2jrimfSdKu+FKJc0ePffiGiMi0JhA/CVFAjRHkSa/LtEeH5Mrz8d166..`, so does that mean we should get cookie instead of token ? – soccerway Mar 28 '20 at 04:52

1 Answers1

0

This Cypess example recipe shows a slightly different pattern for using tokens in local storage and cy.visit().

// but set the user before visiting the page
// so the app thinks it is already authenticated
beforeEach(function setUser () {
  cy.visit('/', {
    onBeforeLoad (win) {
      // and before the page finishes loading
      // set the user object in local storage
      win.localStorage.setItem('user', JSON.stringify(user))
    },
  })
  // the page should be opened and the user should be logged in
})

I presume the onBeforeLoad() callback is used to overcome the problem you are experiencing where cy.visit() clears down local storage.

So, your code would be something like this

beforeEach(function setTokensAndVisit () {
  cy.fixture('tokenData.json').then(tokenData => {
    cy.visit('/dashboard', {
      onBeforeLoad (win) {

        // Set cookie or load localStorage with tokenData here,
        // depending on how your app checks that user is authorized.

        // In a SPA app, this check is likely to done in the router

      },
    })
  })
})
Richard Matsen
  • 20,671
  • 3
  • 43
  • 77
  • It doesn;t work that way. Uncaught CypressError: Cypress detected that you returned a promise from a command while also invoking one or more cy commands in that promise. The command that returned the promise was: > cy.visit() The cy command you invoked inside the promise was: > cy.loadTokens() – soccerway Mar 28 '20 at 05:48
  • Anyway thank you very much and i will keep on trying and update – soccerway Mar 28 '20 at 05:48
  • Yeah I suspected that might be the case. Since you actually don't need to return anything from the callback, there will be a way to replicate what you command does without using cy commands. – Richard Matsen Mar 28 '20 at 05:52
  • Have you figured out the equivalent code for cookies? – Richard Matsen Mar 28 '20 at 05:52
  • Yes I have figured out, please check my question updated with latest test code. – soccerway Mar 28 '20 at 06:30
  • I have set a `debugger ` in the loginRequest() and could see the token and cookie values getting fetched, but it is not allowing to login. ( see the screenshot added above) – soccerway Mar 29 '20 at 02:00