feat: cypress text (#317)

Signed-off-by: Gaius <gaius.qi@gmail.com>
Co-authored-by: Gaius <gaius.qi@gmail.com>
This commit is contained in:
Zhaoxinxin 2023-11-08 23:35:06 +08:00 committed by GitHub
parent cbfd04915a
commit 9dac701c8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 224 additions and 6 deletions

32
.github/workflows/e2e.yaml vendored Normal file
View File

@ -0,0 +1,32 @@
name: E2E Test
on: push
jobs:
cypress-run:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: '18.x'
- name: Install dependencies
run: yarn install --force
- name: Cypress run
uses: cypress-io/github-action@v6
with:
build: yarn build
start: yarn start
browser: chrome
wait-on: 'http://localhost:3000'
wait-on-timeout: 120
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v3
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

3
.gitignore vendored
View File

@ -46,3 +46,6 @@ tsconfig.tsbuildinfo
# mock
/mock
#nyc
/.nyc_output

View File

@ -6,11 +6,11 @@ coverage:
project:
default:
enabled: yes
target: 80%
target: 5%
patch:
default:
enabled: yes
target: 80%
target: 5%
comment:
layout: 'reach, diff, flags, files'
behavior: default

19
cypress.config.ts Normal file
View File

@ -0,0 +1,19 @@
import { defineConfig } from 'cypress';
export default defineConfig({
// setupNodeEvents can be defined in either
// the e2e or component configuration
e2e: {
setupNodeEvents(on, config) {
require('@cypress/code-coverage/task')(on, config);
// include any other plugin code...
// It's IMPORTANT to return the config object
// with any changed environment variables
return config;
},
baseUrl: 'http://localhost:3000',
},
defaultCommandTimeout: 15000,
responseTimeout: 60000,
});

97
cypress/e2e/signin.cy.ts Normal file
View File

@ -0,0 +1,97 @@
import signin from '../fixtures/api/signin.json';
import root from '../fixtures/api/role-root.json';
import user from '../fixtures/api/user.json';
import _ from 'lodash';
describe('Signin', () => {
beforeEach(() => {
cy.intercept('POST', '/api/v1/users/signin', (req) => {
const { name, password } = req.body;
if (name === 'root' && password === 'dragonfly') {
req.reply({
statusCode: 200,
body: signin,
});
} else {
req.reply({
statusCode: 401,
body: {
message: 'Unauthorized',
},
});
}
});
cy.intercept(
{
method: 'GET',
url: '/api/v1/users/1',
},
(req) => {
req.reply({
statusCode: 200,
body: user,
});
},
);
cy.intercept(
{
method: 'GET',
url: '/api/v1/users/1/roles',
},
(req) => {
req.reply({
statusCode: 200,
body: root,
});
},
);
cy.visit('/signin');
});
it('Signin failed', () => {
cy.get('#account').type('root');
cy.get('#password').type('rooot1');
cy.get('form').submit();
cy.get('.MuiAlert-message').should('be.visible').and('contain', 'Unauthorized');
cy.get('.MuiAlert-action > .MuiButtonBase-root').click();
cy.get('.MuiSnackbar-root > .MuiPaper-root').should('not.exist');
});
it('Signin suceesfully', () => {
cy.get('#account').type('root');
cy.get('#password').type(`dragonfly`);
cy.signin();
cy.get('form').submit();
cy.location('pathname').should('eq', '/clusters');
});
it('Switch to the signup page', () => {
cy.get('.MuiTypography-inherit > .MuiTypography-root').click();
cy.url().should('include', '/signup');
cy.get('.MuiTypography-inherit > .MuiTypography-root').click();
cy.url().should('include', '/signin');
});
it('Password hidden function', () => {
cy.get('#account').type('root');
cy.get('#password').type(`dragonfly`);
cy.get('.MuiInputBase-root > .MuiButtonBase-root').click();
cy.get('#password').should('have.value', 'dragonfly');
});
it('Validation error', () => {
const NameNotLongEnough = _.times(2, () => _.sample('abcdefghijklmnopqrstuvwxyz')).join('');
const nameLengthExceeds = _.times(11, () => _.sample('abcdefghijklmnopqrstuvwxyz')).join('');
const passwordLengthExceeds = _.times(17, () => _.sample('abcdefghijklmnopqrstuvwxyz')).join('');
cy.get('#account').type(NameNotLongEnough);
cy.get('#account-helper-text').should('be.visible').and('contain', 'Fill in the characters, the length is 3-10.');
cy.get('#account').type(nameLengthExceeds);
cy.get('#account-helper-text').should('be.visible').and('contain', 'Fill in the characters, the length is 3-10.');
cy.get('#password').type(passwordLengthExceeds);
cy.get('#password-helper-text')
.should('be.visible')
.and('contain', 'Fill in the characters, the maximum length is 16.');
});
});

View File

@ -0,0 +1,3 @@
[
"root"
]

View File

@ -0,0 +1,4 @@
{
"expire": "2023-11-04T10:57:15+09:00",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2OTkwNjY2MzUsImlkIjoxLCJvcmlnX2lhdCI6MTY5ODg5MzgzNX0.KH-3-Pu8BqVW1u5JDyiWooR1a_acyKFFE4BRbLB0bAg"
}

View File

@ -0,0 +1,14 @@
{
"id": 1,
"created_at": "2023-11-06T06:09:04Z",
"updated_at": "2023-11-06T06:09:04Z",
"is_del": 0,
"email": "lucy@example.com",
"name": "lucy",
"avatar": "https://example.com/avatar.png",
"phone": "1234567890",
"state": "enable",
"location": "Hangzhou",
"bio": "I am lucy",
"configs": null
}

View File

@ -0,0 +1,11 @@
declare namespace Cypress {
interface Chainable<Subject> {
signin(): void;
}
}
Cypress.Commands.add('signin', () => {
const jwtToken =
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2OTkwNzMzNDcsImlkIjoxLCJvcmlnX2lhdCI6MTY5ODkwMDU0N30.mplV3_e5ZLKo9Y4YkMpsc8_2GIMj4AgSsw9W-z_qDRM';
cy.setCookie('jwt', jwtToken);
});

21
cypress/support/e2e.ts Normal file
View File

@ -0,0 +1,21 @@
// ***********************************************************
// This example support/e2e.ts is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import './commands'
// Alternatively you can use CommonJS syntax:
// require('./commands')
import '@cypress/code-coverage/support'

View File

@ -10,11 +10,14 @@
],
"repository": "git@github.com:dragonflyoss/console.git",
"scripts": {
"start": "react-app-rewired start",
"start": "react-app-rewired -r @cypress/instrument-cra start",
"build": "BUILD_PATH='./dist' react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-scripts eject",
"lint": "react-scripts lint"
"lint": "react-scripts lint",
"cy:open": "npx cypress open",
"cy:run": "npx cypress run --browser chrome",
"coverage:verify": "npx nyc report --check-coverage true --lines 10"
},
"dependencies": {
"@emotion/react": "^11.11.1",
@ -58,8 +61,11 @@
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@commitlint/cli": "^18.2.0",
"@commitlint/config-conventional": "^18.0.0",
"@cypress/code-coverage": "^3.12.6",
"@cypress/instrument-cra": "^1.4.0",
"@web3-storage/parse-link-header": "^3.1.0",
"chart.js": "^4.4.0",
"cypress": "^13.3.3",
"eslint": "^8.0.0",
"eslint-config-prettier": "^9.0.0",
"eslint-config-react-app": "^7.0.1",

View File

@ -710,6 +710,7 @@ export default function NewCluster() {
size="small"
variant="outlined"
loadingPosition="end"
id="cancle"
sx={{
'&.MuiLoadingButton-root': {
color: 'var(--calcel-size-color)',

View File

@ -804,6 +804,7 @@ export default function ShowCluster() {
size="small"
variant="outlined"
loadingPosition="end"
id="cancelDeleteScheduler"
sx={{
'&.MuiLoadingButton-root': {
color: 'var(--calcel-size-color)',
@ -1082,6 +1083,7 @@ export default function ShowCluster() {
size="small"
variant="outlined"
loadingPosition="end"
id="cancelDeleteSeedPeer"
sx={{
'&.MuiLoadingButton-root': {
color: 'var(--calcel-size-color)',

View File

@ -6,6 +6,10 @@
"dom.iterable",
"esnext"
],
"types": [
"cypress",
"node"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
@ -16,11 +20,12 @@
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"isolatedModules": false,
"noEmit": true,
"jsx": "react-jsx"
},
"include": [
"src"
"src",
"**/*.ts"
]
}