test: optimize command (#3030)
* test: optimize command * chore: add force options * chore: kill child process
This commit is contained in:
parent
4d4b73767f
commit
887ddf0ed1
@ -12,11 +12,13 @@ VERDACCIO_PORT=10104
|
||||
# !!! It is recommended to use nginx to proxy static files. For example https://github.com/nocobase/nocobase/blob/main/docker/nocobase/nocobase.conf
|
||||
APP_ENV=development
|
||||
APP_PORT=20000
|
||||
APP_BASE_URL=http://localhost:20000
|
||||
APP_KEY=test-key-e2e
|
||||
SOCKET_PATH=storage/gateway-e2e.sock
|
||||
__E2E__=true
|
||||
|
||||
# 指定运行测试的服务地址;当 APP_BASE_URL 不为空时,将不会在本地启动测试服务
|
||||
# APP_BASE_URL=http://localhost:20000
|
||||
|
||||
# 启用 mock-collections 插件
|
||||
APPEND_PRESET_BUILT_IN_PLUGINS=mock-collections
|
||||
|
||||
|
@ -114,6 +114,9 @@ interface CreatePageOptions {
|
||||
pageSchema?: any;
|
||||
}
|
||||
|
||||
const PORT = process.env.APP_PORT || 20000;
|
||||
const APP_BASE_URL = process.env.APP_BASE_URL || `http://localhost:${PORT}`;
|
||||
|
||||
class NocoPage {
|
||||
private url: string;
|
||||
private uid: string;
|
||||
@ -213,7 +216,7 @@ export const test = Object.assign(_test, {
|
||||
|
||||
const getStorageItem = (key: string, storageState: any) => {
|
||||
return storageState.origins
|
||||
.find((item) => item.origin === process.env.APP_BASE_URL)
|
||||
.find((item) => item.origin === APP_BASE_URL)
|
||||
?.localStorage.find((item) => item.name === key)?.value;
|
||||
};
|
||||
|
||||
@ -470,8 +473,8 @@ function getHeaders(storageState: any) {
|
||||
const headers: any = {};
|
||||
const token = getStorageItem('NOCOBASE_TOKEN', storageState);
|
||||
const auth = getStorageItem('NOCOBASE_AUTH', storageState);
|
||||
const subAppName = new URL(process.env.APP_BASE_URL).pathname.match(/^\/apps\/([^/]*)\/*/)?.[1];
|
||||
const hostName = new URL(process.env.APP_BASE_URL).host;
|
||||
const subAppName = new URL(APP_BASE_URL).pathname.match(/^\/apps\/([^/]*)\/*/)?.[1];
|
||||
const hostName = new URL(APP_BASE_URL).host;
|
||||
const locale = getStorageItem('NOCOBASE_LOCALE', storageState);
|
||||
const timezone = '+08:00';
|
||||
const withAclMeta = 'true';
|
||||
|
@ -28,7 +28,7 @@ export default defineConfig({
|
||||
|
||||
use: {
|
||||
// Base URL to use in actions like `await page.goto('/')`.
|
||||
baseURL: process.env.APP_BASE_URL,
|
||||
baseURL: process.env.APP_BASE_URL || `http://localhost:${process.env.APP_PORT || 20000}`,
|
||||
|
||||
// Collect trace when retrying the failed test.
|
||||
trace: 'on-first-retry',
|
||||
|
@ -5,9 +5,7 @@ import path from 'path';
|
||||
const adminFile = 'playwright/.auth/admin.json';
|
||||
|
||||
// 加载变量
|
||||
if (!process.env.APP_BASE_URL) {
|
||||
dotenv.config({ path: path.resolve(process.cwd(), '.env.e2e') });
|
||||
}
|
||||
dotenv.config({ path: path.resolve(process.cwd(), '.env.e2e') });
|
||||
|
||||
// 保存登录状态,避免每次都要登录
|
||||
setup('admin', async ({ page }) => {
|
||||
|
@ -1,16 +1,16 @@
|
||||
import { execSync } from 'node:child_process';
|
||||
import { commonConfig, runNocoBase } from './utils';
|
||||
import { APP_BASE_URL, commonConfig, runNocoBase } from './utils';
|
||||
|
||||
const runCodegenSync = () => {
|
||||
try {
|
||||
execSync(
|
||||
`npx playwright codegen --load-storage=playwright/.auth/codegen.auth.json ${process.env.APP_BASE_URL} --save-storage=playwright/.auth/codegen.auth.json`,
|
||||
`npx playwright codegen --load-storage=playwright/.auth/codegen.auth.json ${APP_BASE_URL} --save-storage=playwright/.auth/codegen.auth.json`,
|
||||
commonConfig,
|
||||
);
|
||||
} catch (err) {
|
||||
if (err.message.includes('auth.json')) {
|
||||
execSync(
|
||||
`npx playwright codegen ${process.env.APP_BASE_URL} --save-storage=playwright/.auth/codegen.auth.json`,
|
||||
`npx playwright codegen ${APP_BASE_URL} --save-storage=playwright/.auth/codegen.auth.json`,
|
||||
commonConfig,
|
||||
);
|
||||
} else {
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { runNocoBase } from './utils';
|
||||
|
||||
runNocoBase();
|
||||
runNocoBase({
|
||||
force: true,
|
||||
});
|
||||
|
@ -1,15 +1,23 @@
|
||||
import { runCommand, runNocoBase } from './utils';
|
||||
|
||||
const abortController = new AbortController();
|
||||
|
||||
process.on('SIGINT', () => {
|
||||
abortController.abort();
|
||||
process.exit();
|
||||
});
|
||||
|
||||
const run = async () => {
|
||||
const { kill, awaitForNocoBase } = await runNocoBase({
|
||||
const { awaitForNocoBase } = await runNocoBase({
|
||||
stdio: 'ignore', // 不输出服务的日志,避免干扰测试的日志
|
||||
signal: abortController.signal,
|
||||
});
|
||||
|
||||
await awaitForNocoBase();
|
||||
|
||||
console.log('Start running tests...');
|
||||
await runCommand('npx', ['playwright', 'test', ...process.argv.slice(2)]);
|
||||
kill?.('SIGKILL');
|
||||
abortController.abort();
|
||||
};
|
||||
|
||||
run();
|
||||
|
@ -2,19 +2,23 @@ import axios from 'axios';
|
||||
import dotenv from 'dotenv';
|
||||
import type { CommonOptions } from 'execa';
|
||||
import execa from 'execa';
|
||||
import _ from 'lodash';
|
||||
import net from 'net';
|
||||
import fs from 'node:fs';
|
||||
import path from 'path';
|
||||
|
||||
const PORT = process.env.APP_PORT || 20000;
|
||||
export const APP_BASE_URL = process.env.APP_BASE_URL || `http://localhost:${PORT}`;
|
||||
|
||||
export const commonConfig: any = {
|
||||
stdio: 'inherit',
|
||||
};
|
||||
|
||||
export const runCommand = (command, argv, options = {}) => {
|
||||
export const runCommand = (command, argv, options: any = {}) => {
|
||||
return execa(command, argv, {
|
||||
shell: true,
|
||||
stdio: 'inherit',
|
||||
...options,
|
||||
..._.omit(options, 'force'),
|
||||
env: {
|
||||
...process.env,
|
||||
},
|
||||
@ -53,12 +57,12 @@ const checkServer = async (duration = 1000, max = 60 * 10) => {
|
||||
return reject(new Error('Server start timeout.'));
|
||||
}
|
||||
|
||||
if (!(await checkPort(process.env.APP_PORT))) {
|
||||
if (!(await checkPort(PORT))) {
|
||||
return;
|
||||
}
|
||||
|
||||
axios
|
||||
.get(`${process.env.APP_BASE_URL}/api/__health_check`)
|
||||
.get(`${APP_BASE_URL}/api/__health_check`)
|
||||
.then((response) => {
|
||||
if (response.status === 200) {
|
||||
clearInterval(timer);
|
||||
@ -86,7 +90,7 @@ const checkUI = async (duration = 1000, max = 60 * 10) => {
|
||||
}
|
||||
|
||||
axios
|
||||
.get(`${process.env.APP_BASE_URL}/__umi/api/bundle-status`)
|
||||
.get(`${APP_BASE_URL}/__umi/api/bundle-status`)
|
||||
.then((response) => {
|
||||
if (response.data.bundleStatus.done) {
|
||||
clearInterval(timer);
|
||||
@ -100,7 +104,15 @@ const checkUI = async (duration = 1000, max = 60 * 10) => {
|
||||
});
|
||||
};
|
||||
|
||||
export const runNocoBase = async (options?: CommonOptions<any>) => {
|
||||
export const runNocoBase = async (
|
||||
options?: CommonOptions<any> & {
|
||||
/**
|
||||
* 是否强制启动服务
|
||||
*/
|
||||
force?: boolean;
|
||||
signal?: AbortSignal;
|
||||
},
|
||||
) => {
|
||||
// 用于存放 playwright 自动生成的相关的文件
|
||||
if (!fs.existsSync('playwright')) {
|
||||
fs.mkdirSync('playwright');
|
||||
@ -117,6 +129,11 @@ export const runNocoBase = async (options?: CommonOptions<any>) => {
|
||||
|
||||
dotenv.config({ path: path.resolve(process.cwd(), '.env.e2e') });
|
||||
|
||||
if (process.env.APP_BASE_URL && !options?.force) {
|
||||
console.log('APP_BASE_URL is setting, skip starting server.');
|
||||
return { awaitForNocoBase: () => {} };
|
||||
}
|
||||
|
||||
const awaitForNocoBase = async () => {
|
||||
if (process.env.CI) {
|
||||
console.log('check server...');
|
||||
@ -133,28 +150,22 @@ export const runNocoBase = async (options?: CommonOptions<any>) => {
|
||||
if (process.env.CI) {
|
||||
console.log('yarn nocobase install');
|
||||
await runCommand('yarn', ['nocobase', 'install'], options);
|
||||
console.log(`yarn start -d -p ${process.env.APP_PORT}`);
|
||||
await runCommand('yarn', ['start', '-d', `-p ${process.env.APP_PORT}`], options);
|
||||
console.log(`yarn start -d -p ${PORT}`);
|
||||
await runCommand('yarn', ['start', '-d', `-p ${PORT}`], options);
|
||||
return { awaitForNocoBase };
|
||||
}
|
||||
|
||||
if (!process.env.APP_BASE_URL.includes('localhost')) {
|
||||
return {
|
||||
awaitForNocoBase: async () => {},
|
||||
};
|
||||
}
|
||||
|
||||
// 加上 -f 会清空数据库
|
||||
console.log('yarn nocobase install -f');
|
||||
await runCommand('yarn', ['nocobase', 'install', '-f'], options);
|
||||
|
||||
if (await checkPort(process.env.APP_PORT)) {
|
||||
if (await checkPort(PORT)) {
|
||||
console.log('Server is running, skip starting server.');
|
||||
return { awaitForNocoBase };
|
||||
}
|
||||
|
||||
console.log('starting server...');
|
||||
const { cancel, kill } = runCommand('yarn', ['dev', `-p ${process.env.APP_PORT}`, ...process.argv.slice(2)], options);
|
||||
const { cancel, kill } = runCommand('yarn', ['dev', `-p ${PORT}`, ...process.argv.slice(2)], options);
|
||||
|
||||
return { cancel, kill, awaitForNocoBase };
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user