chore: e2e testing

pull/13/head
moonrailgun 4 years ago
parent bfc413750e
commit 3daf76b2e3

@ -0,0 +1,7 @@
# 临时忽略, 这些是自动生成的代码
cypress/integration
cypress/fixtures
# 未启用的代码
cypress/screenshots
cypress/snapshots

@ -0,0 +1,6 @@
{
"component": {
"testFiles": "**/*.test.{js,ts,jsx,tsx}",
"componentFolder": "./cypress/components/"
}
}

@ -0,0 +1,36 @@
import React from 'react';
import { mount } from '@cypress/react';
import { Button } from 'antd';
import { TestWrapper } from './utils/TestWrapper';
describe('antd dark', () => {
it('antd button', () => {
mount(
<TestWrapper>
<Button data-testid="default"></Button>
<Button type="primary" data-testid="primary">
</Button>
<Button danger={true} type="primary" data-testid="primary-danger">
</Button>
</TestWrapper>
);
cy.get('[data-testid=default]')
.should('have.css', 'color', 'rgba(255, 255, 255, 0.65)')
.should('have.css', 'border-color', 'rgb(67, 67, 67)')
.should('have.css', 'background-color', 'rgba(0, 0, 0, 0)')
.matchImageSnapshot();
cy.get('[data-testid=primary]')
.should('have.css', 'color', 'rgb(255, 255, 255)')
.should('have.css', 'border-color', 'rgb(23, 125, 220)')
.should('have.css', 'background-color', 'rgb(23, 125, 220)');
cy.get('[data-testid=primary-danger]')
.should('have.css', 'color', 'rgb(255, 255, 255)')
.should('have.css', 'border-color', 'rgb(166, 29, 36)')
.should('have.css', 'background-color', 'rgb(166, 29, 36)');
});
});

@ -0,0 +1,21 @@
import React from 'react';
import '../../../../src/styles';
import clsx from 'clsx';
export const TestWrapper: React.FC<{
theme?: 'dark' | 'light';
}> = (props) => {
const { theme = 'dark' } = props;
return (
<div
className={clsx(theme, {
'bg-black': theme === 'dark',
})}
data-testid="test-wrapper"
>
{props.children}
</div>
);
};
TestWrapper.displayName = 'TestWrapper';

@ -0,0 +1,36 @@
/// <reference types="cypress" />
// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************
// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)
const injectDevServer = require('./load-webpack');
const path = require('path');
const {
addMatchImageSnapshotPlugin,
} = require('cypress-image-snapshot/plugin');
/**
* @type {Cypress.PluginConfig}
*/
// eslint-disable-next-line no-unused-vars
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
injectDevServer(on, config, {
webpackFilename: path.resolve(__dirname, '../../../webpack.config.ts'),
});
addMatchImageSnapshotPlugin(on, config);
return config;
};

@ -0,0 +1,39 @@
// @ts-check
const path = require('path');
const { startDevServer } = require('@cypress/webpack-dev-server');
const tryLoadWebpackConfig = require('./utils/tryLoadWebpackConfig');
/** @type {(config: Cypress.PluginConfigOptions, path: string) => string} */
function normalizeWebpackPath(config, webpackConfigPath) {
return path.isAbsolute(webpackConfigPath)
? webpackConfigPath
: path.resolve(config.projectRoot, webpackConfigPath);
}
/**
* Injects dev-server based on the webpack config file.
*
* **Important:** `webpackFilename` path is relative to the project root (cypress.json location)
* @type {(on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions, options: { webpackFilename: string }) => Cypress.PluginConfigOptions}
*/
function injectWebpackDevServer(on, config, { webpackFilename }) {
const webpackConfig = tryLoadWebpackConfig(
normalizeWebpackPath(config, webpackFilename)
);
if (!webpackConfig) {
throw new Error(
`Can not load webpack config from path ${webpackFilename}.`
);
}
on('dev-server:start', async (options) => {
return startDevServer({ options, webpackConfig });
});
config.env.reactDevtools = true;
return config;
}
module.exports = injectWebpackDevServer;

@ -0,0 +1,40 @@
// @ts-check
const debug = require('debug')('@cypress/react');
/** @type {(configPath: string) => null | import('webpack').Configuration } */
module.exports = function tryLoadWebpackConfig(webpackConfigPath) {
debug('trying to load webpack config from %s', webpackConfigPath);
// Do this as the first thing so that any code reading it knows the right env.
const envName = 'test';
// @ts-expect-error override env is possible
process.env.NODE_ENV = envName;
process.env.BABEL_ENV = envName;
try {
let webpackOptions = require(webpackConfigPath);
if (webpackOptions.default) {
// we probably loaded TS file
debug('loaded webpack options has .default - taking that as the config');
webpackOptions = webpackOptions.default;
}
if (typeof webpackOptions === 'function') {
debug('calling webpack function with environment "%s"', envName);
webpackOptions = webpackOptions('development');
}
debug('webpack options: %o', webpackOptions);
return webpackOptions;
} catch (err) {
debug('could not load react-scripts webpack');
debug('error %s', err.message);
debug(err);
console.error(err);
return null;
}
};

@ -0,0 +1,31 @@
// ***********************************************
// 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 { addMatchImageSnapshotCommand } from 'cypress-image-snapshot/command';
// TODO: 一个同样的组件视觉 在runner中两次测试不通过
// 不知道为什么可能是cypress runner的问题
addMatchImageSnapshotCommand();

@ -0,0 +1,20 @@
// ***********************************************************
// This example support/index.js 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')

@ -0,0 +1,21 @@
{
"name": "tailchat-e2e",
"version": "1.0.0",
"main": "index.js",
"author": "moonrailgun",
"license": "MIT",
"private": true,
"scripts": {
"cypress:open": "cypress open",
"cypress:run": "cypress run",
"cypress:open-ct": "cypress open-ct",
"cypress:run-ct": "cypress run-ct"
},
"devDependencies": {
"@cypress/react": "^5.9.4",
"@cypress/webpack-dev-server": "^1.4.0",
"@types/cypress-image-snapshot": "^3.1.6",
"cypress": "^8.3.0",
"cypress-image-snapshot": "^4.0.1"
}
}

File diff suppressed because it is too large Load Diff

@ -4,7 +4,7 @@ import {
DefaultFullModalInputEditorRender, DefaultFullModalInputEditorRender,
FullModalField, FullModalField,
} from '@/components/FullModal/Field'; } from '@/components/FullModal/Field';
import { getUserJWT, setUserJWT } from '@/utils/jwt-helper'; import { setUserJWT } from '@/utils/jwt-helper';
import { Button, Divider } from 'antd'; import { Button, Divider } from 'antd';
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import { useHistory } from 'react-router'; import { useHistory } from 'react-router';

@ -4,11 +4,7 @@ import React from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import { App } from './App'; import { App } from './App';
import { initPlugins } from './plugin/loader'; import { initPlugins } from './plugin/loader';
import './styles';
import 'antd/dist/antd.css';
import './styles/antd/index.less';
import 'tailwindcss/tailwind.css';
import './styles/global.less';
// 先加载插件再开启应用 // 先加载插件再开启应用
initPlugins().then(() => { initPlugins().then(() => {

@ -0,0 +1,4 @@
import 'antd/dist/antd.css';
import './antd/index.less';
import 'tailwindcss/tailwind.css';
import './global.less';

@ -31,7 +31,9 @@ declare module 'webpack' {
} }
} }
const isDev = process.env.NODE_ENV === 'development'; const NODE_ENV = process.env.NODE_ENV ?? 'production';
const isDev = NODE_ENV === 'development';
const mode = isDev ? 'development' : 'production'; const mode = isDev ? 'development' : 'production';
const config: Configuration = { const config: Configuration = {
@ -111,7 +113,7 @@ const config: Configuration = {
}, },
plugins: [ plugins: [
new DefinePlugin({ new DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV), 'process.env.NODE_ENV': JSON.stringify(NODE_ENV),
'process.env.SERVICE_URL': JSON.stringify(process.env.SERVICE_URL), 'process.env.SERVICE_URL': JSON.stringify(process.env.SERVICE_URL),
'process.env.VERSION': JSON.stringify( 'process.env.VERSION': JSON.stringify(
process.env.VERSION || packageJson.version process.env.VERSION || packageJson.version

Loading…
Cancel
Save