mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-05 13:39:24 +08:00
254 lines
6.3 KiB
JavaScript
254 lines
6.3 KiB
JavaScript
const { Command } = require('commander');
|
|
const { run, isPortReachable } = require('../util');
|
|
const { execSync } = require('node:child_process');
|
|
const axios = require('axios');
|
|
const { pTest } = require('./p-test');
|
|
const os = require('os');
|
|
const treeKill = require('tree-kill');
|
|
|
|
/**
|
|
* 检查服务是否启动成功
|
|
*/
|
|
const checkServer = async (duration = 1000, max = 60 * 10) => {
|
|
return new Promise((resolve, reject) => {
|
|
let count = 0;
|
|
const timer = setInterval(async () => {
|
|
if (count++ > max) {
|
|
clearInterval(timer);
|
|
return reject(new Error('Server start timeout.'));
|
|
}
|
|
|
|
// if (!(await checkPort(PORT))) {
|
|
// return;
|
|
// }
|
|
|
|
const url = `${process.env.APP_BASE_URL}/api/__health_check`;
|
|
// console.log('url', url);
|
|
|
|
axios
|
|
.get(url)
|
|
.then((response) => {
|
|
if (response.status === 200) {
|
|
clearInterval(timer);
|
|
resolve(true);
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
console.error('Request error:', error?.response?.data?.error);
|
|
});
|
|
}, duration);
|
|
});
|
|
};
|
|
|
|
/**
|
|
* 检查 UI 是否启动成功
|
|
* @param duration
|
|
*/
|
|
const checkUI = async (duration = 1000, max = 60 * 10) => {
|
|
return new Promise((resolve, reject) => {
|
|
let count = 0;
|
|
const timer = setInterval(async () => {
|
|
if (count++ > max) {
|
|
clearInterval(timer);
|
|
return reject(new Error('UI start timeout.'));
|
|
}
|
|
|
|
axios
|
|
.get(`${process.env.APP_BASE_URL}/__umi/api/bundle-status`)
|
|
.then((response) => {
|
|
if (response.data === 'ok') {
|
|
clearInterval(timer);
|
|
resolve(true);
|
|
return;
|
|
}
|
|
if (response.data.bundleStatus.done) {
|
|
clearInterval(timer);
|
|
resolve(true);
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
console.error('Request error:', error.message);
|
|
});
|
|
}, duration);
|
|
});
|
|
};
|
|
|
|
async function appReady() {
|
|
console.log('check server...');
|
|
await checkServer();
|
|
console.log('server is ready, check UI...');
|
|
await checkUI();
|
|
console.log('UI is ready.');
|
|
}
|
|
|
|
async function runApp(options = {}) {
|
|
console.log('installing...');
|
|
await run('nocobase', ['install', '-f']);
|
|
if (await isPortReachable(process.env.APP_PORT)) {
|
|
console.log('app started');
|
|
return;
|
|
}
|
|
console.log('starting...');
|
|
run('nocobase', [process.env.APP_ENV === 'production' ? 'start' : 'dev'], options);
|
|
}
|
|
|
|
process.on('SIGINT', async () => {
|
|
treeKill(process.pid, (error) => {
|
|
if (error) {
|
|
console.error(error);
|
|
} else {
|
|
console.log('所有子进程已被杀掉,应用程序即将退出');
|
|
}
|
|
process.exit();
|
|
});
|
|
});
|
|
|
|
const commonConfig = {
|
|
stdio: 'inherit',
|
|
};
|
|
|
|
const runCodegenSync = () => {
|
|
try {
|
|
execSync(
|
|
`npx playwright codegen --load-storage=storage/playwright/.auth/codegen.auth.json ${process.env.APP_BASE_URL} --save-storage=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=storage/playwright/.auth/codegen.auth.json`,
|
|
commonConfig,
|
|
);
|
|
} else {
|
|
console.error(err);
|
|
}
|
|
}
|
|
};
|
|
|
|
const filterArgv = () => {
|
|
const arr = process.argv.slice(4);
|
|
const argv = [];
|
|
for (let index = 0; index < arr.length; index++) {
|
|
const element = arr[index];
|
|
if (element === '--url') {
|
|
index++;
|
|
continue;
|
|
}
|
|
if (element.startsWith('--url=')) {
|
|
continue;
|
|
}
|
|
if (element === '--skip-reporter') {
|
|
continue;
|
|
}
|
|
if (element === '--build') {
|
|
continue;
|
|
}
|
|
if (element === '--production') {
|
|
continue;
|
|
}
|
|
argv.push(element);
|
|
}
|
|
return argv;
|
|
};
|
|
|
|
/**
|
|
*
|
|
* @param {Command} cli
|
|
*/
|
|
module.exports = (cli) => {
|
|
const e2e = cli.command('e2e').hook('preAction', () => {
|
|
if (process.env.APP_BASE_URL) {
|
|
process.env.APP_BASE_URL = process.env.APP_BASE_URL.replace('localhost', '127.0.0.1');
|
|
console.log('APP_BASE_URL:', process.env.APP_BASE_URL);
|
|
}
|
|
});
|
|
|
|
e2e
|
|
.command('test')
|
|
.allowUnknownOption()
|
|
.option('--url [url]')
|
|
.option('--skip-reporter')
|
|
.option('--build')
|
|
.option('--production')
|
|
.action(async (options) => {
|
|
process.env.__E2E__ = true;
|
|
if (options.production) {
|
|
process.env.APP_ENV = 'production';
|
|
}
|
|
if (options.build) {
|
|
process.env.APP_ENV = 'production';
|
|
await run('yarn', ['build']);
|
|
}
|
|
if (options.skipReporter) {
|
|
process.env.PLAYWRIGHT_SKIP_REPORTER = true;
|
|
}
|
|
if (options.url) {
|
|
process.env.APP_BASE_URL = options.url.replace('localhost', '127.0.0.1');
|
|
} else {
|
|
await runApp({
|
|
stdio: 'ignore',
|
|
});
|
|
}
|
|
await appReady();
|
|
await run('npx', ['playwright', 'test', ...filterArgv()]);
|
|
process.exit();
|
|
});
|
|
|
|
e2e
|
|
.command('codegen')
|
|
.allowUnknownOption()
|
|
.option('--url [url]')
|
|
.action(async (options) => {
|
|
if (options.url) {
|
|
process.env.APP_BASE_URL = options.url.replace('localhost', '127.0.0.1');
|
|
} else {
|
|
await runApp({
|
|
stdio: 'ignore',
|
|
});
|
|
}
|
|
await appReady();
|
|
runCodegenSync();
|
|
});
|
|
|
|
e2e
|
|
.command('start-app')
|
|
.option('--production')
|
|
.option('--build')
|
|
.option('--port [port]')
|
|
.action(async (options) => {
|
|
process.env.__E2E__ = true;
|
|
if (options.build) {
|
|
await run('yarn', ['build']);
|
|
}
|
|
if (options.production) {
|
|
process.env.APP_ENV = 'production';
|
|
}
|
|
if (options.port) {
|
|
process.env.APP_PORT = options.port;
|
|
}
|
|
runApp();
|
|
});
|
|
|
|
e2e.command('reinstall-app').action(async (options) => {
|
|
await run('nocobase', ['install', '-f'], options);
|
|
});
|
|
|
|
e2e.command('install-deps').action(async () => {
|
|
await run('npx', ['playwright', 'install', '--with-deps']);
|
|
});
|
|
|
|
e2e
|
|
.command('p-test')
|
|
.option('--stop-on-error')
|
|
.option('--build')
|
|
.option('--concurrency [concurrency]', '', os.cpus().length)
|
|
.action(async (options) => {
|
|
process.env.__E2E__ = true;
|
|
if (options.build) {
|
|
process.env.APP_ENV = 'production';
|
|
await run('yarn', ['build']);
|
|
}
|
|
await pTest({ ...options, concurrency: 1 * options.concurrency });
|
|
});
|
|
};
|