Reputation: 1086
I have a Rest API which generates a token. This session token is used across multiple REST API's as an authorization Bearer token. I used this as reference: https://github.com/cypress-io/cypress-example-recipes/blob/master/examples/logging-in__jwt/cypress/integration/spec.js
However, in that example, the function to generate token is embedded in the test. I tried to create a custom command for which should store locally but it is not being picked up by the test. Note that no return value is included in the custom command.
My code below under support/commands.js:
let identity
Cypress.Commands.add('postToken', () => {
cy.request({
method: 'POST',
url: Cypress.env('api_identity_url'), //get from cypress.env.json
form: true, //sets to application/x-www-form-urlencoded
body: {
grant_type: 'client_credentials',
scope: 'xero_all-apis'
},
auth: {
username: Cypress.env('api_identity_username'),
password: Cypress.env('api_identity_password')
}
})
.its('body')
.then((response) => {
identity = response
window.localStorage.setItem('identity', JSON.stringify(identity))
cy.log(identity.access_token)
})
})
My test:
context('Check token details', () => {
it('Check token', () => {
cy.postToken()
const bToken = window.localStorage.getItem('identity')
cy.log(bToken)
})
})
When I run the test, the log shows null
value for 'identity'. However, it shows the current value in the custom command where I placed cy.log(identity.access_token)
I tried using cy.writeFile but I don't think this is a clean method. There must be some way data can be passed between functions, and different classes.
Sample JSON format:
{
"token": "<this is the value I would like to use for other API's authorisation bearer token>",
"expires_in": 1200,
"token_type": "Bearer"
}
Upvotes: 13
Views: 24702
Reputation: 11
I used this code in commmand.js
var headers_login = new Headers()
headers_login.append('Content-Type', 'application/json')
Cypress.Commands.add('get_token', (username, password)=>{
var token = ""
cy.request({
method: 'POST',
url: Cypress.env("api") + "users/getToken",
failOnStatusCode: false,
json: true,
form: true,
body: {username: username, password: password},
headers: headers_login
}).then((json) => {
//cy.setLocalStorage('token', json.body.response.data.token)
token = json.body.response.data.token
return token;
}) })
After in your test add this code
describe('test', ()=>{
before(()=>{
cy.get_token('username', 'password').then(youToken => {
cy.visit('/', {
onBeforeLoad: function (window) {
window.localStorage.setItem('token', youToken);
}
})
})
cy.close_welcome()
})
it('test 001', ()=>{
// contain test
})})
afterEach(()=>{cy.clearLocalStorage('token')})
Upvotes: 0
Reputation: 125
Thank you Javier for showing me the cypress-localstorage-commands
package. I started using it. Until that I used to get the login token like this.
describe('Record audit', () => {
let token = null;
before(() => {
cy.login().then((responseToken) => { // or postToken() in your case
token = responseToken;
});
});
it('I can use the token here', () => {
cy.log(token);
});
});
The only difference is that my login
command returns the token. It should look like this in your code
// commands.js
.then((response) => {
identity = response
window.localStorage.setItem('identity', JSON.stringify(identity))
cy.log(identity.access_token)
return identity.access_token
})
Upvotes: 0
Reputation: 1415
You can use the cypress-localstorage-commands package to persist localStorage between tests.
In support/commands.js
:
import "cypress-localstorage-commands";
Cypress.Commands.add('postToken', () => {
cy.request({
method: 'POST',
url: Cypress.env('api_identity_url'), //get from cypress.env.json
form: true, //sets to application/x-www-form-urlencoded
body: {
grant_type: 'client_credentials',
scope: 'xero_all-apis'
},
auth: {
username: Cypress.env('api_identity_username'),
password: Cypress.env('api_identity_password')
}
})
.its('body')
.then(identity => {
cy.setLocalStorage("identity_token", identity.token);
});
});
Inside your tests:
describe("postToken", ()=> {
before(() => {
cy.postToken();
cy.saveLocalStorage();
});
beforeEach(() => {
cy.restoreLocalStorage();
});
it("should exist identity in localStorage", () => {
cy.getLocalStorage("identity_token").should("exist");
cy.getLocalStorage("identity_token").then(token => {
console.log("Identity token", token);
});
});
it("should still exist identity in localStorage", () => {
cy.getLocalStorage("identity_token").should("exist");
cy.getLocalStorage("identity_token").then(token => {
console.log("Identity token", token);
});
});
});
Upvotes: 15