1

For my application I'm trying to login via the API and not the UI

I'm required to store the accessToken to navigate through the application

My current login method looks like this

 Cypress.Commands.add('login', (overrides = {}) => {
  Cypress.log({
    name: 'loginViaAuth0',
  });

  const options = {
    method: 'POST',
    url: Cypress.env('auth_url'),
      headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    body: {
      username: Cypress.env('auth_username'),
      password: Cypress.env('auth_password'),
    }
  }

  cy.request(options);
});

I need to store the accessToken to the resource file. I have tried various methods like on here but without success

Set local storage in Cypress

Thank you

Edit:

I have tried this but still no luck

 Cypress.Commands.add('login', (overrides = {}) => {
  cy.request({
    method: 'POST',
    url: Cypress.env('auth_url'),
    body: {
      user: {
        email: Cypress.env('auth_username'),
        password: Cypress.env('auth_password'),
      }
    }
  })
    .its('token')
    .then((token) => {
      window.localStorage.setItem('accessToken', token);
    });
});

Edit: this worked in the end for anybody interested

Cypress.Commands.add('login', (overrides = {}) => {
cy.request({ 
    method: 'POST', 
    url: Cypress.env('auth_url'), form: true, 
    body: { grant_type: 'client_credentials', scope: 'xero_all-apis' ,
           username: Cypress.env('auth_username'), 
           password: Cypress.env('auth_password'), } }) 
    .its('body') 
   .then(res => { 
     cy.setLocalStorage('accessToken',res.accessToken);
   }); 
});
Steven983
  • 43
  • 9
  • Hi. You just have to read the request response and save the token to `sessionsStorage`. BTW, I think is not the best way (in this case) to declare the payload as a `const`, then assign it to `cy.request`. Just set it directly to request body `cy.request({ ... }).its('body.token').then(token => { window.sessionsStorage.setItem('accessToken', token) })` – Alex Izbas Jan 05 '21 at 13:02
  • Cypress.Commands.add('login', (overrides = {}) => { cy.request({ method: 'POST', url: Cypress.env('auth_url'), body: { user: { email: Cypress.env('auth_username'), password: Cypress.env('auth_password'), } } }) .its('body.token') .then((token) => { window.localStorage.setItem('accessToken', token); }); }); like so? I'm getting – Steven983 Jan 05 '21 at 14:02
  • Timed out retrying: cy.its() errored because the property: token does not exist on your subject. cy.its() waited for the specified property token to exist, but it never did. If you do not expect the property token to exist, then add an assertion such as: cy.wrap({ foo: 'bar' }).its('quux').should('not.exist') – Steven983 Jan 05 '21 at 14:03
  • hey, it doesn't have to be `body.token`, it could be `body.access_token`. You have to find out from the response the right path/structure. Also, I do recommend storing your token in the `sessionStorage`, so you have it cleared when the session is done. – Alex Izbas Jan 06 '21 at 09:34
  • My answer match with this answer. So, please look at this https://stackoverflow.com/a/59016663/14910874 – Arek Khatry Jan 06 '21 at 12:24
  • @ArekKhatry Thank you, i have the accesstoken now in local storage but my last problem is that it is now 'undefined' – Steven983 Jan 06 '21 at 15:47

1 Answers1

0

@Steven983, Please try this

Cypress code Cypress.Commands.add('login', () => { 
cy.request({ 
    method: 'POST', 
    url: Cypress.env('auth_url'), form: true, 
    body: { grant_type: 'client_credentials', scope: 'xero_all-apis' }, 
    auth: { 
           username: Cypress.env('auth_username'), 
           password: Cypress.env('auth_password'), } }) 
    .its('body') 
   .then(res => { 
     cy.log(res.body.accessToken) //To verify token is shown in console
     cy.setLocalStorage('accessToken', res.body.accessToken); 
   }); 

});

  • it is returning the token but it is showing as undefined https://imgur.com/a/Zn866jG – Steven983 Jan 07 '21 at 09:16
  • It would be helpful if you can share the cypress code and the API response (can use postman) to understand json schema. Also, .its('body') .then(identity => { cy.log(identity.token) // Does this print the token in console ?? }); – Arek Khatry Jan 07 '21 at 10:08
  • API Response { "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6Im5hdGhhbi5oZXdpdHRAZWN1dGVzdGluZy5jb20iLCJyZWFsbSI6InVzZXIiLCJuYW1laWQiOiItMSIsIm5iZiI6MTYwOTk0NzgzNSwiZXhwIjoxNjEwMDM0MjM1LCJpYXQiOjE2MDk5NDc4MzV9.mtnnMYlV47rgvVyEhkfmKSE_eZFnjgIr-PXgvRJKTY4", "errorMsg": "", "isValid": true, "UserId": 1 } – Steven983 Jan 07 '21 at 11:01
  • Cypress code Cypress.Commands.add('login', () => { cy.request({ method: 'POST', url: Cypress.env('auth_url'), form: true, // sets to application/x-www-form-urlencoded body: { grant_type: 'client_credentials', scope: 'xero_all-apis' }, auth: { username: Cypress.env('auth_username'), password: Cypress.env('auth_password'), } }) .its('body') .then(res => { cy.setLocalStorage('accessToken', res.token); }); }); – Steven983 Jan 07 '21 at 11:01
  • @Steven983, I have edited my answer. Please look at that, it should work. – Arek Khatry Jan 07 '21 at 11:27
  • Thanks a lot for your help so far, appreciate it.. and do not blame you if you stop there ;) i have tried your edited answer and this happened. https://imgur.com/a/Zm0xxJ1 – Steven983 Jan 07 '21 at 12:40
  • Sad to hear that it didn't work. I will be happy if I can help you in any other way. I had written this blog related to API testing which might be helpful but not sure for this problem . https://ramesh-khatri.medium.com/api-automation-using-cypress-bc721e98ced5 – Arek Khatry Jan 08 '21 at 13:12
  • Thanks a lot for your help. i imagine the problem is related to the app and not the method of testing – Steven983 Jan 11 '21 at 09:35
  • 1
    I got it to work, i just had to include the username and pass in the body – Steven983 Jan 19 '21 at 09:57
  • Okay. That's Great. – Arek Khatry Jan 19 '21 at 11:06