@nocobase/cli 0.15.0-alpha.2 → 0.15.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/index.js +21 -2
- package/package.json +4 -4
- package/src/commands/e2e.js +199 -0
- package/src/commands/index.js +1 -0
package/bin/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const dotenv = require('dotenv');
|
|
4
4
|
const { resolve } = require('path');
|
|
5
|
-
const
|
|
5
|
+
const fs = require('fs');
|
|
6
6
|
const chalk = require('chalk');
|
|
7
7
|
const { genTsConfigPaths } = require('../src/util');
|
|
8
8
|
|
|
@@ -25,11 +25,26 @@ const env = {
|
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
if (!process.env.APP_ENV_PATH && process.argv[2] && process.argv[2] === 'test') {
|
|
28
|
-
if (existsSync(resolve(process.cwd(), '.env.test'))) {
|
|
28
|
+
if (fs.existsSync(resolve(process.cwd(), '.env.test'))) {
|
|
29
29
|
process.env.APP_ENV_PATH = '.env.test';
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
if (process.argv[2] === 'e2e') {
|
|
34
|
+
// 用于存放 playwright 自动生成的相关的文件
|
|
35
|
+
if (!fs.existsSync('playwright')) {
|
|
36
|
+
fs.mkdirSync('playwright');
|
|
37
|
+
}
|
|
38
|
+
if (!fs.existsSync('.env.e2e') && fs.existsSync('.env.e2e.example')) {
|
|
39
|
+
const env = fs.readFileSync('.env.e2e.example');
|
|
40
|
+
fs.writeFileSync('.env.e2e', env);
|
|
41
|
+
}
|
|
42
|
+
if (!fs.existsSync('.env.e2e')) {
|
|
43
|
+
throw new Error('Please create .env.e2e file first!');
|
|
44
|
+
}
|
|
45
|
+
process.env.APP_ENV_PATH = '.env.e2e';
|
|
46
|
+
}
|
|
47
|
+
|
|
33
48
|
genTsConfigPaths();
|
|
34
49
|
|
|
35
50
|
dotenv.config({
|
|
@@ -42,6 +57,10 @@ for (const key in env) {
|
|
|
42
57
|
}
|
|
43
58
|
}
|
|
44
59
|
|
|
60
|
+
if (process.argv[2] === 'e2e' && !process.env.APP_BASE_URL) {
|
|
61
|
+
process.env.APP_BASE_URL = `http://127.0.0.1:${process.env.APP_PORT}`;
|
|
62
|
+
}
|
|
63
|
+
|
|
45
64
|
if (require('semver').satisfies(process.version, '<16')) {
|
|
46
65
|
console.error(chalk.red('[nocobase cli]: Node.js version must be >= 16'));
|
|
47
66
|
process.exit(1);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/cli",
|
|
3
|
-
"version": "0.15.0-alpha.
|
|
3
|
+
"version": "0.15.0-alpha.4",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"nocobase": "./bin/index.js"
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@nocobase/app": "0.15.0-alpha.
|
|
11
|
+
"@nocobase/app": "0.15.0-alpha.4",
|
|
12
12
|
"@types/fs-extra": "^11.0.1",
|
|
13
13
|
"@umijs/utils": "3.5.20",
|
|
14
14
|
"chalk": "^4.1.1",
|
|
@@ -23,12 +23,12 @@
|
|
|
23
23
|
"tsx": "^3.12.7"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@nocobase/devtools": "0.15.0-alpha.
|
|
26
|
+
"@nocobase/devtools": "0.15.0-alpha.4"
|
|
27
27
|
},
|
|
28
28
|
"repository": {
|
|
29
29
|
"type": "git",
|
|
30
30
|
"url": "git+https://github.com/nocobase/nocobase.git",
|
|
31
31
|
"directory": "packages/core/cli"
|
|
32
32
|
},
|
|
33
|
-
"gitHead": "
|
|
33
|
+
"gitHead": "380045c660ea0432f3e8fd7cf01c3cfe7275db34"
|
|
34
34
|
}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
const { Command } = require('commander');
|
|
2
|
+
const { run, isPortReachable } = require('../util');
|
|
3
|
+
const { execSync } = require('node:child_process');
|
|
4
|
+
const axios = require('axios');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 检查服务是否启动成功
|
|
8
|
+
*/
|
|
9
|
+
const checkServer = async (duration = 1000, max = 60 * 10) => {
|
|
10
|
+
return new Promise((resolve, reject) => {
|
|
11
|
+
let count = 0;
|
|
12
|
+
const timer = setInterval(async () => {
|
|
13
|
+
if (count++ > max) {
|
|
14
|
+
clearInterval(timer);
|
|
15
|
+
return reject(new Error('Server start timeout.'));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// if (!(await checkPort(PORT))) {
|
|
19
|
+
// return;
|
|
20
|
+
// }
|
|
21
|
+
|
|
22
|
+
const url = `${process.env.APP_BASE_URL}/api/__health_check`;
|
|
23
|
+
// console.log('url', url);
|
|
24
|
+
|
|
25
|
+
axios
|
|
26
|
+
.get(url)
|
|
27
|
+
.then((response) => {
|
|
28
|
+
if (response.status === 200) {
|
|
29
|
+
clearInterval(timer);
|
|
30
|
+
resolve(true);
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
.catch((error) => {
|
|
34
|
+
console.error('Request error:', error.message);
|
|
35
|
+
});
|
|
36
|
+
}, duration);
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* 检查 UI 是否启动成功
|
|
42
|
+
* @param duration
|
|
43
|
+
*/
|
|
44
|
+
const checkUI = async (duration = 1000, max = 60 * 10) => {
|
|
45
|
+
return new Promise((resolve, reject) => {
|
|
46
|
+
let count = 0;
|
|
47
|
+
const timer = setInterval(async () => {
|
|
48
|
+
if (count++ > max) {
|
|
49
|
+
clearInterval(timer);
|
|
50
|
+
return reject(new Error('UI start timeout.'));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
axios
|
|
54
|
+
.get(`${process.env.APP_BASE_URL}/__umi/api/bundle-status`)
|
|
55
|
+
.then((response) => {
|
|
56
|
+
if (response.data === 'ok') {
|
|
57
|
+
clearInterval(timer);
|
|
58
|
+
resolve(true);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (response.data.bundleStatus.done) {
|
|
62
|
+
clearInterval(timer);
|
|
63
|
+
resolve(true);
|
|
64
|
+
}
|
|
65
|
+
})
|
|
66
|
+
.catch((error) => {
|
|
67
|
+
console.error('Request error:', error.message);
|
|
68
|
+
});
|
|
69
|
+
}, duration);
|
|
70
|
+
});
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
async function appReady() {
|
|
74
|
+
console.log('check server...');
|
|
75
|
+
await checkServer();
|
|
76
|
+
console.log('server is ready, check UI...');
|
|
77
|
+
await checkUI();
|
|
78
|
+
console.log('UI is ready.');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async function runApp(options = {}) {
|
|
82
|
+
console.log('installing...');
|
|
83
|
+
await run('nocobase', ['install', '-f']);
|
|
84
|
+
if (await isPortReachable(process.env.APP_PORT)) {
|
|
85
|
+
console.log('app started');
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
console.log('starting...');
|
|
89
|
+
run('nocobase', [process.env.APP_ENV === 'production' ? 'start' : 'dev'], options);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const commonConfig = {
|
|
93
|
+
stdio: 'inherit',
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const runCodegenSync = () => {
|
|
97
|
+
try {
|
|
98
|
+
execSync(
|
|
99
|
+
`npx playwright codegen --load-storage=playwright/.auth/codegen.auth.json ${process.env.APP_BASE_URL} --save-storage=playwright/.auth/codegen.auth.json`,
|
|
100
|
+
commonConfig,
|
|
101
|
+
);
|
|
102
|
+
} catch (err) {
|
|
103
|
+
if (err.message.includes('auth.json')) {
|
|
104
|
+
execSync(
|
|
105
|
+
`npx playwright codegen ${process.env.APP_BASE_URL} --save-storage=playwright/.auth/codegen.auth.json`,
|
|
106
|
+
commonConfig,
|
|
107
|
+
);
|
|
108
|
+
} else {
|
|
109
|
+
console.error(err);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const filterArgv = () => {
|
|
115
|
+
const arr = process.argv.slice(4);
|
|
116
|
+
const argv = [];
|
|
117
|
+
for (let index = 0; index < arr.length; index++) {
|
|
118
|
+
const element = arr[index];
|
|
119
|
+
if (element === '--url') {
|
|
120
|
+
index++;
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
if (element.startsWith('--url=')) {
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
if (element === '--skip-reporter') {
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
argv.push(element);
|
|
130
|
+
}
|
|
131
|
+
return argv;
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
*
|
|
136
|
+
* @param {Command} cli
|
|
137
|
+
*/
|
|
138
|
+
module.exports = (cli) => {
|
|
139
|
+
const e2e = cli.command('e2e').hook('preAction', () => {
|
|
140
|
+
if (process.env.APP_BASE_URL) {
|
|
141
|
+
process.env.APP_BASE_URL = process.env.APP_BASE_URL.replace('localhost', '127.0.0.1');
|
|
142
|
+
console.log('APP_BASE_URL:', process.env.APP_BASE_URL);
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
e2e
|
|
146
|
+
.command('test')
|
|
147
|
+
.allowUnknownOption()
|
|
148
|
+
.option('--url [url]')
|
|
149
|
+
.option('--skip-reporter')
|
|
150
|
+
.action(async (options) => {
|
|
151
|
+
if (options.skipReporter) {
|
|
152
|
+
process.env.PLAYWRIGHT_SKIP_REPORTER = true;
|
|
153
|
+
}
|
|
154
|
+
if (options.url) {
|
|
155
|
+
process.env.APP_BASE_URL = options.url.replace('localhost', '127.0.0.1');
|
|
156
|
+
} else {
|
|
157
|
+
await runApp({
|
|
158
|
+
stdio: 'ignore',
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
await appReady();
|
|
162
|
+
await run('npx', ['playwright', 'test', ...filterArgv()]);
|
|
163
|
+
process.exit();
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
e2e
|
|
167
|
+
.command('codegen')
|
|
168
|
+
.allowUnknownOption()
|
|
169
|
+
.option('--url [url]')
|
|
170
|
+
.action(async (options) => {
|
|
171
|
+
if (options.url) {
|
|
172
|
+
process.env.APP_BASE_URL = options.url.replace('localhost', '127.0.0.1');
|
|
173
|
+
} else {
|
|
174
|
+
await runApp({
|
|
175
|
+
stdio: 'ignore',
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
await appReady();
|
|
179
|
+
runCodegenSync();
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
e2e
|
|
183
|
+
.command('start-app')
|
|
184
|
+
.option('--production')
|
|
185
|
+
.option('--port [port]')
|
|
186
|
+
.action(async (options) => {
|
|
187
|
+
if (options.production) {
|
|
188
|
+
process.env.APP_ENV = 'production';
|
|
189
|
+
}
|
|
190
|
+
if (options.port) {
|
|
191
|
+
process.env.APP_PORT = options.port;
|
|
192
|
+
}
|
|
193
|
+
runApp();
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
e2e.command('reinstall-app').action(async (options) => {
|
|
197
|
+
await run('nocobase', ['install', '-f'], options);
|
|
198
|
+
});
|
|
199
|
+
};
|