比如:
FROM cypress/browsers:node16.14.0-slim-chrome99-ff97
浏览器镜像参考: cypress-docker-images/browsers at master · cypress-io/cypress-docker-images
yarn add --dev cypress eslint eslint-plugin-cypress
参考: GitHub - cypress-io/eslint-plugin-cypress: An ESLint plugin for projects that use Cypress
参考: IDE Integration | Cypress Documentation
安装好依赖后执行
npx cypress open
运行会初始化配置。
参考: Configuration | Cypress Documentation
示例项目: cypress-io / cypress-example-docker-gitlab
修改 cypress.json
:
{
"baseUrl": "http://localhost:4100",
"env": {
"apiUrl": "http://localhost:3000",
"user": {
"email": "tester@test.com",
"password": "password1234",
"username": "testuser"
},
"codeCoverage": {
"url": "http://localhost:3000/__coverage__"
}
},
"viewportHeight": 1000,
"viewportWidth": 1000,
"video": true,
"projectId": "bh5j1d",
"nodeVersion": "system"
}
可以在 plugins/index.js
中注入,如:
// 也可以在这里注入 dotenv
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
/* eslint-disable no-param-reassign */
config.env.authing_username = process.env.AUTHING_USERNAME;
config.env.authing_password = process.env.AUTHING_PASSWORD;
config.env.authing_userpool_id = process.env.AUTHING_USERPOOL;
return config;
};
注意一下,需要用根用户池登录,且最好关闭 MFA (没有接口支持)。产品环境用户池 ID 为 59f86b4832eb28071bdd9214
。
// Cpress 是测试脚本中全局注入的
const apiUrl = Cypress.env('apiUrl')
如获取登录 token。登录方式自行封装,这里以邮箱登录为例:
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
import JSEncrypt from 'jsencrypt';
function encrypt(text, key) {
const jsencrypt = new JSEncrypt();
jsencrypt.setPublicKey(key); // 设置公钥
const encrypted = jsencrypt.encrypt(text);
return encrypted;
}
Cypress.Commands.add(
'login',
(
userPoolId = Cypress.env('authing_userpool_id'),
email = Cypress.env('authing_username'),
password = Cypress.env('authing_password')
) => {
cy.loginByEmail(userPoolId, email, password).then((token) => {
localStorage.setItem('token', token);
cy.getCookie('authing_session')
.should('exist')
.then((c) => {
cy.setCookie('authing_session', c.value);
});
});
}
);
Cypress.Commands.add(
'loginByEmail',
(
userPoolId = Cypress.env('authing_userpool_id'),
email = Cypress.env('authing_username'),
password = Cypress.env('authing_password')
) =>
cy.getPublicKey().then((publicKey) =>
cy
.request({
method: 'POST',
url: '/api/v2/login/login-by-email',
headers: {
'x-authing-userpool-id': userPoolId
},
body: {
input: {
email,
password: encrypt(password, publicKey)
}
}
})
.its('body.data.token')
.should('exist')
)
);
Cypress.Commands.add('getPublicKey', () =>
cy
.request({
method: 'GET',
url: 'https://core.authing.cn/api/v2/.well-known'
})
.its('body.data.publicKey')
.should('exist')
);
参考文档:
// enables intelligent code completion for Cypress commands
// https://on.cypress.io/intelligent-code-completion
///
context('Console Sample', () => {
beforeEach(() => {
// https://on.cypress.io/visit
cy.login();
});
it('With Login', () => {
cy.visit('/console/61e4da8864ed00680e252e99/application/self-built-apps');
cy.get('.app').contains('创建自建应用');
});
// more examples
//
// https://github.com/cypress-io/cypress-example-todomvc
// https://github.com/cypress-io/cypress-example-kitchensink
// https://on.cypress.io/writing-your-first-test
});