对于我们的一个应用程序,我需要设置本地存储以绕过登录页面过程。
我有以下函数,该函数将返回需要设置的accessToken。在节点中运行时,此功能有效。
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
}
我正在尝试创建一个cypress命令来设置本地存储,然后访问该应用程序。运行时,出现错误,我从命令中返回了一个承诺,同时又在该承诺中调用了一个或多个cy命令。
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+``);
});
});
我还尝试了以下cypress命令
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})
})
});
但是出现以下错误。我需要发布到该URL以获得访问令牌的URL是与基本URL不同的域。因此,在帖子中使用基础不适用于我。
必须为cy.request()提供一个完全合格的url-开头的URL 与“ http”。默认情况下,cy.request()将使用当前 窗口的来源或cypress.json中的“ baseUrl”。那些都不 值存在。
答案 0 :(得分:1)
尝试这个:
在cypress.json
{
"env": {
"EXTERNAL_API": "https://jsonplaceholder.typicode.com/todos/1"
}
}
在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);
})
});
测试内部
beforeEach(() => {
cy.logInAs3()
})
it('check localStorage token', () => {
cy.visit()
expect(localStorage.getItem('accessToken')).not.null
expect(localStorage.getItem('refreshToken')).not.null
})
答案 1 :(得分:0)
基于@Danny的答案,您可以使用cypress-localstorage-commands包来持久存储localStorage并在一个块中的所有测试中重用同一用户会话:
在cypress.json
{
"env": {
"EXTERNAL_API": "https://jsonplaceholder.typicode.com/"
}
}
在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);
});
});
测试内部:
describe("when user FOO is logged in", ()=> {
before(() => {
cy.logInAs("foo@foo.com", "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");
});
});
答案 2 :(得分:0)
每次在服务器和客户端进行一次测试运行的成本资源时,都会命中登录API
这是优化方式:
只需在Cypress Env中存储登录/身份验证API成功响应并重复使用 在命令功能中
在cypress.json
{
"myenv": {
"authResponse": {
"apiToken": "jwt_token_received_from_server",
"refreshToken": "refresh_token_received_from_server"
}
}
}
在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);
})
});
测试内部
beforeEach(() => {
cy.setSession();
})
it('Test Ui Components for Authorized User', () => {
})