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.
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.
Share Improve this question asked Jun 3, 2019 at 16:33 TestRaptorTestRaptor 1,3159 gold badges26 silver badges43 bronze badges 2 |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.
3 Answers
Reset to default 9Try 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");
});
});
Hitting login API every time a Test Run's cost resources at both(Server and Client)
here is optimized way:
Just store login/auth API Success response in Cypress Env and reuse it in command function
In cypress.json
{
"myenv": {
"authResponse": {
"apiToken": "jwt_token_received_from_server",
"refreshToken": "refresh_token_received_from_server"
}
}
}
In support/commands.js
Cypress.Commands.add('setSession', () => {
const accessToken = `${Cypress.env('myenv')['authResponse']['apiToken']}`
const refreshToken = `${Cypress.env('myenv')['authResponse']['refreshToken']}`
window.localStorage.setItem('accessToken', accessToken);
window.localStorage.setItem('refreshToken', responseToken);
})
});
Inside your test
beforeEach(() => {
cy.setSession();
})
it('Test Ui Components for Authorized User', () => {
})
I need to set local storage in order to bypass the login page process
. Do you also control the backend that sets this token? Is that only done in your integration tests? – msanford Commented Jun 3, 2019 at 16:39