For one of our applications, I need to set local storage in order to bypass the login page process.
I have the following function that will return the accessToken that I need to set. This function works when running in node.
async function getAccessToken(email, pwd) {
const form = {email: email, password: pwd};
let config = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
}
};
const accessToken = await axios.post(`${process.env.API_URL}/loginWithToken`, qs.stringify(form), config);
console.log(accessToken.data.accessToken);
return accessToken.data.accessToken
}
I'm trying to create a cypress command that will set local storage, then visit the application. When running, I get an error that I returned a promise from a command while also invoking one or more cy commands in that promise.
Cypress.Commands.add("logInAs", async(Useremail, Userpwd, TMURL) => {
var accessToken = cy.task('getAccessToken', {email: Useremail, pwd: Userpwd
}).then(Visit =>{
window.localStorage.setItem("accessToken", accessToken);
window.localStorage.setItem("refreshToken", accessToken);
cy.visit(`${process.env.TM_API_URL}/`+TMURL+``);
});
});
I've also tried the following cypress command
require('dotenv').config();
Cypress.Commands.add('logInAs3', (Useremail, Userpwd, TMURL) => {
cy.request({
method: 'POST',
url: `${process.env.API_URL}/loginWithToken`,
body: {
user: {
email: Useremail,
password: Userpwd,
}
}
})
.then((resp) => {
window.localStorage.setItem('accessToken', resp.body.data.data.accessToken);
window.localStorage.setItem('refreshToken', resp.body.data.data.accessToken);
cy.visit(`${process.env.TM_API_URL}/`+TMURL+``, {failOnStatusCode: false})
})
});
But I get the following error. The URL I need to post to in order to get the access token, is a different domain than the base url. So using the base in the post will not work for me.
cy.request() must be provided a fully qualified url - one that begins with 'http'. By default cy.request() will use either the current window's origin or the 'baseUrl' in cypress.json. Neither of those values were present.
Try this one:
In cypress.json
{
"env": {
"EXTERNAL_API": "https://jsonplaceholder.typicode.com/todos/1"
}
}
In support/commands.js
Cypress.Commands.add('logInAs3', (Useremail, Userpwd, TMURL) => {
cy.request({
method: 'POST',
url: `${Cypress.env('EXTERNAL_API')}/loginWithToken`,
body: {
user: {
email: Useremail,
password: Userpwd,
}
}
})
.its('body')
.then((body) => {
window.localStorage.setItem('accessToken', body.data.data.accessToken);
window.localStorage.setItem('refreshToken', body.data.data.accessToken);
})
});
Inside your test
beforeEach(() => {
cy.logInAs3()
})
it('check localStorage token', () => {
cy.visit()
expect(localStorage.getItem('accessToken')).not.null
expect(localStorage.getItem('refreshToken')).not.null
})
Based on the @Danny answer, you can use the cypress-localstorage-commands package to persist localStorage and reuse same user session for all tests in a block:
In cypress.json
{
"env": {
"EXTERNAL_API": "https://jsonplaceholder.typicode.com/"
}
}
In support/commands.js
import "cypress-localstorage-commands";
Cypress.Commands.add('logInAs', (UserEmail, UserPwd) => {
cy.request({
method: 'POST',
url: `${Cypress.env('EXTERNAL_API')}/loginWithToken`,
body: {
user: {
email: UserEmail,
password: UserPwd,
}
}
})
.its('body')
.then((body) => {
cy.setLocalStorage("accessToken", body.data.accessToken);
cy.setLocalStorage("refreshToken", body.data.refreshToken);
});
});
Inside your tests:
describe("when user FOO is logged in", ()=> {
before(() => {
cy.logInAs("[email protected]", "fooPassword");
cy.saveLocalStorage();
});
beforeEach(() => {
cy.restoreLocalStorage();
cy.visit("");
});
it('should exist accessToken in localStorage', () => {
cy.getLocalStorage("accessToken").should("exist");
});
it('should exist refreshToken in localStorage', () => {
cy.getLocalStorage("refreshToken").should("exist");
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With