cocos2d-cli 1.6.4 → 1.6.5
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/cocos2d-cli.js +152 -152
- package/data/script_map.json +25 -25
- package/package.json +33 -33
- package/src/commands/add-component.js +112 -112
- package/src/commands/add.js +177 -177
- package/src/commands/build.js +78 -78
- package/src/commands/create-scene.js +181 -181
- package/src/commands/get.js +108 -108
- package/src/commands/prefab-create.js +110 -110
- package/src/commands/remove-component.js +110 -110
- package/src/commands/remove.js +99 -99
- package/src/commands/screenshot.js +108 -108
- package/src/commands/set-component.js +119 -119
- package/src/commands/set.js +107 -107
- package/src/commands/tree.js +28 -28
- package/src/lib/cc/CCButton.js +122 -122
- package/src/lib/cc/CCCamera.js +93 -93
- package/src/lib/cc/CCCanvas.js +54 -54
- package/src/lib/cc/CCColor.js +32 -32
- package/src/lib/cc/CCComponent.js +60 -60
- package/src/lib/cc/CCLabel.js +146 -146
- package/src/lib/cc/CCNode.js +255 -255
- package/src/lib/cc/CCObject.js +23 -23
- package/src/lib/cc/CCPrefab.js +242 -242
- package/src/lib/cc/CCRect.js +32 -32
- package/src/lib/cc/CCRichText.js +44 -44
- package/src/lib/cc/CCScene.js +42 -42
- package/src/lib/cc/CCSceneAsset.js +302 -302
- package/src/lib/cc/CCSize.js +26 -26
- package/src/lib/cc/CCSprite.js +94 -94
- package/src/lib/cc/CCTrs.js +74 -74
- package/src/lib/cc/CCVec2.js +26 -26
- package/src/lib/cc/CCVec3.js +29 -29
- package/src/lib/cc/CCWidget.js +98 -98
- package/src/lib/cc/index.js +42 -42
- package/src/lib/fire-utils.js +373 -373
- package/src/lib/json-parser.js +185 -185
- package/src/lib/node-utils.js +395 -395
- package/src/lib/screenshot/index.html +29 -29
- package/src/lib/screenshot-core.js +285 -286
- package/src/lib/templates.js +49 -49
- package/src/lib/utils.js +202 -202
|
@@ -1,286 +1,285 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Screenshot Core Module
|
|
3
|
-
* 渲染 JSON 数据并使用 Playwright 截图
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
const { chromium } = require('playwright');
|
|
7
|
-
const fs = require('fs').promises;
|
|
8
|
-
const path = require('path');
|
|
9
|
-
const http = require('http');
|
|
10
|
-
const url = require('url');
|
|
11
|
-
const os = require('os');
|
|
12
|
-
|
|
13
|
-
// 默认配置
|
|
14
|
-
const DEFAULT_CONFIG = {
|
|
15
|
-
jsonPath: null,
|
|
16
|
-
outputDir: process.cwd(),
|
|
17
|
-
viewport: { width: 750, height: 1334 },
|
|
18
|
-
fullPage: true,
|
|
19
|
-
debugBounds: false,
|
|
20
|
-
timeout: 30000,
|
|
21
|
-
waitTime: 1000
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
// 获取内置资源目录
|
|
25
|
-
function getAssetsDir() {
|
|
26
|
-
return path.join(__dirname, 'screenshot');
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// 创建临时工作目录
|
|
30
|
-
async function createTempWorkDir() {
|
|
31
|
-
const tempBase = os.tmpdir();
|
|
32
|
-
const timestamp = Date.now();
|
|
33
|
-
const tempDir = path.join(tempBase, `cocos2d-screenshot-${timestamp}`);
|
|
34
|
-
await fs.mkdir(tempDir, { recursive: true });
|
|
35
|
-
return tempDir;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// 复制内置资源到临时目录
|
|
39
|
-
async function copyBuiltInAssets(tempDir, logs) {
|
|
40
|
-
const assetsDir = getAssetsDir();
|
|
41
|
-
const assets = ['index.html', 'favicon.ico'];
|
|
42
|
-
|
|
43
|
-
for (const asset of assets) {
|
|
44
|
-
const src = path.join(assetsDir, asset);
|
|
45
|
-
const dest = path.join(tempDir, asset);
|
|
46
|
-
try {
|
|
47
|
-
await fs.copyFile(src, dest);
|
|
48
|
-
} catch (err) {
|
|
49
|
-
logs.push({
|
|
50
|
-
timestamp: new Date().toISOString(),
|
|
51
|
-
type: 'warning',
|
|
52
|
-
text: `Could not copy ${asset}: ${err.message}`
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// 静态文件服务器
|
|
59
|
-
async function startServer(staticDir, logs) {
|
|
60
|
-
return new Promise((resolve, reject) => {
|
|
61
|
-
const server = http.createServer(async (req, res) => {
|
|
62
|
-
try {
|
|
63
|
-
const parsedUrl = url.parse(req.url);
|
|
64
|
-
let filePath = path.join(staticDir, parsedUrl.pathname);
|
|
65
|
-
|
|
66
|
-
if (parsedUrl.pathname === '/') {
|
|
67
|
-
filePath = path.join(staticDir, 'index.html');
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const data = await fs.readFile(filePath);
|
|
71
|
-
|
|
72
|
-
const ext = path.extname(filePath).toLowerCase();
|
|
73
|
-
const contentTypes = {
|
|
74
|
-
'.html': 'text/html',
|
|
75
|
-
'.htm': 'text/html',
|
|
76
|
-
'.json': 'application/json',
|
|
77
|
-
'.js': 'application/javascript',
|
|
78
|
-
'.mjs': 'application/javascript',
|
|
79
|
-
'.css': 'text/css',
|
|
80
|
-
'.png': 'image/png',
|
|
81
|
-
'.jpg': 'image/jpeg',
|
|
82
|
-
'.jpeg': 'image/jpeg',
|
|
83
|
-
'.gif': 'image/gif',
|
|
84
|
-
'.svg': 'image/svg+xml',
|
|
85
|
-
'.ico': 'image/x-icon',
|
|
86
|
-
'.txt': 'text/plain',
|
|
87
|
-
'.xml': 'application/xml'
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
res.writeHead(200, {
|
|
91
|
-
'Content-Type': contentTypes[ext] || 'application/octet-stream',
|
|
92
|
-
'Access-Control-Allow-Origin': '*'
|
|
93
|
-
});
|
|
94
|
-
res.end(data);
|
|
95
|
-
|
|
96
|
-
} catch (err) {
|
|
97
|
-
if (err.code === 'ENOENT') {
|
|
98
|
-
res.writeHead(404);
|
|
99
|
-
res.end();
|
|
100
|
-
} else {
|
|
101
|
-
logs.push({
|
|
102
|
-
timestamp: new Date().toISOString(),
|
|
103
|
-
type: 'server-error',
|
|
104
|
-
text: `${req.url}: ${err.message}`
|
|
105
|
-
});
|
|
106
|
-
res.writeHead(500);
|
|
107
|
-
res.end();
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
server.listen(0, '127.0.0.1', () => resolve(server));
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// 递归删除目录
|
|
117
|
-
async function removeDir(dirPath, logs) {
|
|
118
|
-
try {
|
|
119
|
-
await fs.rm(dirPath, { recursive: true, force: true });
|
|
120
|
-
} catch (err) {
|
|
121
|
-
if (logs) {
|
|
122
|
-
logs.push({
|
|
123
|
-
timestamp: new Date().toISOString(),
|
|
124
|
-
type: 'warning',
|
|
125
|
-
text: `Could not remove temp dir: ${err.message}`
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* 截图核心函数
|
|
133
|
-
* @param {Object} userConfig - 配置选项
|
|
134
|
-
* @param {string} userConfig.jsonPath - JSON 文件路径
|
|
135
|
-
* @param {string} userConfig.outputDir - 输出目录
|
|
136
|
-
* @param {Object} userConfig.viewport - 视口大小 {width, height}
|
|
137
|
-
* @param {boolean} userConfig.fullPage - 是否全页截图
|
|
138
|
-
* @param {number} userConfig.timeout - 超时时间(毫秒)
|
|
139
|
-
* @param {number} userConfig.waitTime - 等待时间(毫秒)
|
|
140
|
-
* @returns {Promise<{screenshotPath: string, logs: Array}>}
|
|
141
|
-
*/
|
|
142
|
-
async function takeScreenshot(userConfig = {}) {
|
|
143
|
-
const config = { ...DEFAULT_CONFIG, ...userConfig };
|
|
144
|
-
|
|
145
|
-
if (!config.jsonPath) {
|
|
146
|
-
throw new Error('JSON file path is required');
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
let server = null;
|
|
150
|
-
let browser = null;
|
|
151
|
-
let tempDir = null;
|
|
152
|
-
const logs = [];
|
|
153
|
-
let screenshotPath = null;
|
|
154
|
-
let logDir = null;
|
|
155
|
-
|
|
156
|
-
const addLog = (type, text, extra = {}) => {
|
|
157
|
-
logs.push({
|
|
158
|
-
timestamp: new Date().toISOString(),
|
|
159
|
-
type,
|
|
160
|
-
text,
|
|
161
|
-
...extra
|
|
162
|
-
});
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
try {
|
|
166
|
-
const timestamp = Date.now();
|
|
167
|
-
|
|
168
|
-
// 检查 JSON 文件是否存在
|
|
169
|
-
try {
|
|
170
|
-
await fs.access(config.jsonPath);
|
|
171
|
-
} catch (error) {
|
|
172
|
-
throw new Error(`JSON file not found: ${config.jsonPath}`);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// 确保输出目录存在
|
|
176
|
-
await fs.mkdir(config.outputDir, { recursive: true });
|
|
177
|
-
|
|
178
|
-
// 创建临时工作目录
|
|
179
|
-
tempDir = await createTempWorkDir();
|
|
180
|
-
addLog('info', `Temp dir: ${tempDir}`);
|
|
181
|
-
|
|
182
|
-
// 复制内置资源到临时目录
|
|
183
|
-
await copyBuiltInAssets(tempDir, logs);
|
|
184
|
-
|
|
185
|
-
// 复制用户的 JSON 文件到临时目录
|
|
186
|
-
const destJsonPath = path.join(tempDir, 'data.json');
|
|
187
|
-
await fs.copyFile(config.jsonPath, destJsonPath);
|
|
188
|
-
addLog('info', `JSON: ${config.jsonPath}`);
|
|
189
|
-
|
|
190
|
-
// 截图输出路径
|
|
191
|
-
screenshotPath = path.join(config.outputDir, `screenshot-${timestamp}.png`);
|
|
192
|
-
|
|
193
|
-
// 启动HTTP服务器
|
|
194
|
-
addLog('info', 'Starting Server');
|
|
195
|
-
server = await startServer(tempDir, logs);
|
|
196
|
-
const serverUrl = `http://127.0.0.1:${server.address().port}`;
|
|
197
|
-
addLog('info', `Server: ${serverUrl}`);
|
|
198
|
-
|
|
199
|
-
// 启动浏览器
|
|
200
|
-
addLog('info', 'Launching Browser');
|
|
201
|
-
browser = await chromium.launch({
|
|
202
|
-
headless: true
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
const
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
});
|
|
249
|
-
addLog('info',
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
await fs.
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
error
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
if (
|
|
281
|
-
if (
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
module.exports = { takeScreenshot };
|
|
1
|
+
/**
|
|
2
|
+
* Screenshot Core Module
|
|
3
|
+
* 渲染 JSON 数据并使用 Playwright 截图
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { chromium } = require('playwright');
|
|
7
|
+
const fs = require('fs').promises;
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const http = require('http');
|
|
10
|
+
const url = require('url');
|
|
11
|
+
const os = require('os');
|
|
12
|
+
|
|
13
|
+
// 默认配置
|
|
14
|
+
const DEFAULT_CONFIG = {
|
|
15
|
+
jsonPath: null,
|
|
16
|
+
outputDir: process.cwd(),
|
|
17
|
+
viewport: { width: 750, height: 1334 },
|
|
18
|
+
fullPage: true,
|
|
19
|
+
debugBounds: false,
|
|
20
|
+
timeout: 30000,
|
|
21
|
+
waitTime: 1000
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// 获取内置资源目录
|
|
25
|
+
function getAssetsDir() {
|
|
26
|
+
return path.join(__dirname, 'screenshot');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// 创建临时工作目录
|
|
30
|
+
async function createTempWorkDir() {
|
|
31
|
+
const tempBase = os.tmpdir();
|
|
32
|
+
const timestamp = Date.now();
|
|
33
|
+
const tempDir = path.join(tempBase, `cocos2d-screenshot-${timestamp}`);
|
|
34
|
+
await fs.mkdir(tempDir, { recursive: true });
|
|
35
|
+
return tempDir;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// 复制内置资源到临时目录
|
|
39
|
+
async function copyBuiltInAssets(tempDir, logs) {
|
|
40
|
+
const assetsDir = getAssetsDir();
|
|
41
|
+
const assets = ['index.html', 'favicon.ico'];
|
|
42
|
+
|
|
43
|
+
for (const asset of assets) {
|
|
44
|
+
const src = path.join(assetsDir, asset);
|
|
45
|
+
const dest = path.join(tempDir, asset);
|
|
46
|
+
try {
|
|
47
|
+
await fs.copyFile(src, dest);
|
|
48
|
+
} catch (err) {
|
|
49
|
+
logs.push({
|
|
50
|
+
timestamp: new Date().toISOString(),
|
|
51
|
+
type: 'warning',
|
|
52
|
+
text: `Could not copy ${asset}: ${err.message}`
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// 静态文件服务器
|
|
59
|
+
async function startServer(staticDir, logs) {
|
|
60
|
+
return new Promise((resolve, reject) => {
|
|
61
|
+
const server = http.createServer(async (req, res) => {
|
|
62
|
+
try {
|
|
63
|
+
const parsedUrl = url.parse(req.url);
|
|
64
|
+
let filePath = path.join(staticDir, parsedUrl.pathname);
|
|
65
|
+
|
|
66
|
+
if (parsedUrl.pathname === '/') {
|
|
67
|
+
filePath = path.join(staticDir, 'index.html');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const data = await fs.readFile(filePath);
|
|
71
|
+
|
|
72
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
73
|
+
const contentTypes = {
|
|
74
|
+
'.html': 'text/html',
|
|
75
|
+
'.htm': 'text/html',
|
|
76
|
+
'.json': 'application/json',
|
|
77
|
+
'.js': 'application/javascript',
|
|
78
|
+
'.mjs': 'application/javascript',
|
|
79
|
+
'.css': 'text/css',
|
|
80
|
+
'.png': 'image/png',
|
|
81
|
+
'.jpg': 'image/jpeg',
|
|
82
|
+
'.jpeg': 'image/jpeg',
|
|
83
|
+
'.gif': 'image/gif',
|
|
84
|
+
'.svg': 'image/svg+xml',
|
|
85
|
+
'.ico': 'image/x-icon',
|
|
86
|
+
'.txt': 'text/plain',
|
|
87
|
+
'.xml': 'application/xml'
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
res.writeHead(200, {
|
|
91
|
+
'Content-Type': contentTypes[ext] || 'application/octet-stream',
|
|
92
|
+
'Access-Control-Allow-Origin': '*'
|
|
93
|
+
});
|
|
94
|
+
res.end(data);
|
|
95
|
+
|
|
96
|
+
} catch (err) {
|
|
97
|
+
if (err.code === 'ENOENT') {
|
|
98
|
+
res.writeHead(404);
|
|
99
|
+
res.end();
|
|
100
|
+
} else {
|
|
101
|
+
logs.push({
|
|
102
|
+
timestamp: new Date().toISOString(),
|
|
103
|
+
type: 'server-error',
|
|
104
|
+
text: `${req.url}: ${err.message}`
|
|
105
|
+
});
|
|
106
|
+
res.writeHead(500);
|
|
107
|
+
res.end();
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
server.listen(0, '127.0.0.1', () => resolve(server));
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// 递归删除目录
|
|
117
|
+
async function removeDir(dirPath, logs) {
|
|
118
|
+
try {
|
|
119
|
+
await fs.rm(dirPath, { recursive: true, force: true });
|
|
120
|
+
} catch (err) {
|
|
121
|
+
if (logs) {
|
|
122
|
+
logs.push({
|
|
123
|
+
timestamp: new Date().toISOString(),
|
|
124
|
+
type: 'warning',
|
|
125
|
+
text: `Could not remove temp dir: ${err.message}`
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* 截图核心函数
|
|
133
|
+
* @param {Object} userConfig - 配置选项
|
|
134
|
+
* @param {string} userConfig.jsonPath - JSON 文件路径
|
|
135
|
+
* @param {string} userConfig.outputDir - 输出目录
|
|
136
|
+
* @param {Object} userConfig.viewport - 视口大小 {width, height}
|
|
137
|
+
* @param {boolean} userConfig.fullPage - 是否全页截图
|
|
138
|
+
* @param {number} userConfig.timeout - 超时时间(毫秒)
|
|
139
|
+
* @param {number} userConfig.waitTime - 等待时间(毫秒)
|
|
140
|
+
* @returns {Promise<{screenshotPath: string, logs: Array}>}
|
|
141
|
+
*/
|
|
142
|
+
async function takeScreenshot(userConfig = {}) {
|
|
143
|
+
const config = { ...DEFAULT_CONFIG, ...userConfig };
|
|
144
|
+
|
|
145
|
+
if (!config.jsonPath) {
|
|
146
|
+
throw new Error('JSON file path is required');
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
let server = null;
|
|
150
|
+
let browser = null;
|
|
151
|
+
let tempDir = null;
|
|
152
|
+
const logs = [];
|
|
153
|
+
let screenshotPath = null;
|
|
154
|
+
let logDir = null;
|
|
155
|
+
|
|
156
|
+
const addLog = (type, text, extra = {}) => {
|
|
157
|
+
logs.push({
|
|
158
|
+
timestamp: new Date().toISOString(),
|
|
159
|
+
type,
|
|
160
|
+
text,
|
|
161
|
+
...extra
|
|
162
|
+
});
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
try {
|
|
166
|
+
const timestamp = Date.now();
|
|
167
|
+
|
|
168
|
+
// 检查 JSON 文件是否存在
|
|
169
|
+
try {
|
|
170
|
+
await fs.access(config.jsonPath);
|
|
171
|
+
} catch (error) {
|
|
172
|
+
throw new Error(`JSON file not found: ${config.jsonPath}`);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// 确保输出目录存在
|
|
176
|
+
await fs.mkdir(config.outputDir, { recursive: true });
|
|
177
|
+
|
|
178
|
+
// 创建临时工作目录
|
|
179
|
+
tempDir = await createTempWorkDir();
|
|
180
|
+
addLog('info', `Temp dir: ${tempDir}`);
|
|
181
|
+
|
|
182
|
+
// 复制内置资源到临时目录
|
|
183
|
+
await copyBuiltInAssets(tempDir, logs);
|
|
184
|
+
|
|
185
|
+
// 复制用户的 JSON 文件到临时目录
|
|
186
|
+
const destJsonPath = path.join(tempDir, 'data.json');
|
|
187
|
+
await fs.copyFile(config.jsonPath, destJsonPath);
|
|
188
|
+
addLog('info', `JSON: ${config.jsonPath}`);
|
|
189
|
+
|
|
190
|
+
// 截图输出路径
|
|
191
|
+
screenshotPath = path.join(config.outputDir, `screenshot-${timestamp}.png`);
|
|
192
|
+
|
|
193
|
+
// 启动HTTP服务器
|
|
194
|
+
addLog('info', 'Starting Server');
|
|
195
|
+
server = await startServer(tempDir, logs);
|
|
196
|
+
const serverUrl = `http://127.0.0.1:${server.address().port}`;
|
|
197
|
+
addLog('info', `Server: ${serverUrl}`);
|
|
198
|
+
|
|
199
|
+
// 启动浏览器
|
|
200
|
+
addLog('info', 'Launching Browser');
|
|
201
|
+
browser = await chromium.launch({
|
|
202
|
+
headless: true
|
|
203
|
+
});
|
|
204
|
+
addLog('info', 'Browser launched');
|
|
205
|
+
|
|
206
|
+
const page = await browser.newPage({
|
|
207
|
+
viewport: config.viewport
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
// 监听浏览器控制台日志
|
|
211
|
+
page.on('console', msg => {
|
|
212
|
+
const text = msg.text();
|
|
213
|
+
addLog(msg.type(), text);
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
page.on('pageerror', error => {
|
|
217
|
+
addLog('pageerror', error.message);
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
page.on('requestfailed', request => {
|
|
221
|
+
const failure = request.failure();
|
|
222
|
+
const errorText = failure ? failure.errorText : 'Unknown error';
|
|
223
|
+
addLog('requestfailed', request.url(), { error: errorText });
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
// 加载页面
|
|
227
|
+
addLog('info', 'Loading Page');
|
|
228
|
+
const pageUrl = config.debugBounds
|
|
229
|
+
? `${serverUrl}/index.html?debugBounds=true`
|
|
230
|
+
: `${serverUrl}/index.html`;
|
|
231
|
+
await page.goto(pageUrl, {
|
|
232
|
+
waitUntil: 'networkidle',
|
|
233
|
+
timeout: config.timeout
|
|
234
|
+
});
|
|
235
|
+
addLog('info', 'Page loaded');
|
|
236
|
+
|
|
237
|
+
// 等待渲染
|
|
238
|
+
addLog('info', 'Waiting for Render');
|
|
239
|
+
await page.waitForTimeout(config.waitTime);
|
|
240
|
+
addLog('info', 'Wait complete');
|
|
241
|
+
|
|
242
|
+
// 截图
|
|
243
|
+
addLog('info', 'Taking Screenshot');
|
|
244
|
+
await page.screenshot({
|
|
245
|
+
path: screenshotPath,
|
|
246
|
+
fullPage: config.fullPage
|
|
247
|
+
});
|
|
248
|
+
addLog('info', `Screenshot saved: ${screenshotPath}`);
|
|
249
|
+
addLog('info', 'Done');
|
|
250
|
+
|
|
251
|
+
return { screenshotPath, logs };
|
|
252
|
+
|
|
253
|
+
} catch (error) {
|
|
254
|
+
addLog('error', error.message);
|
|
255
|
+
try {
|
|
256
|
+
logDir = path.join(config.outputDir, `screenshot-logs-${Date.now()}`);
|
|
257
|
+
await fs.mkdir(logDir, { recursive: true });
|
|
258
|
+
await fs.writeFile(
|
|
259
|
+
path.join(logDir, 'logs.json'),
|
|
260
|
+
JSON.stringify({
|
|
261
|
+
error: error.message,
|
|
262
|
+
jsonPath: config.jsonPath,
|
|
263
|
+
outputDir: config.outputDir,
|
|
264
|
+
viewport: config.viewport,
|
|
265
|
+
fullPage: config.fullPage,
|
|
266
|
+
debugBounds: config.debugBounds,
|
|
267
|
+
timeout: config.timeout,
|
|
268
|
+
waitTime: config.waitTime,
|
|
269
|
+
screenshotPath,
|
|
270
|
+
logs
|
|
271
|
+
}, null, 2),
|
|
272
|
+
'utf8'
|
|
273
|
+
);
|
|
274
|
+
} catch (_) {}
|
|
275
|
+
error.logDir = logDir;
|
|
276
|
+
throw error;
|
|
277
|
+
} finally {
|
|
278
|
+
// 清理资源
|
|
279
|
+
if (browser) await browser.close().catch(() => {});
|
|
280
|
+
if (server) server.close();
|
|
281
|
+
if (tempDir) await removeDir(tempDir, logs);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
module.exports = { takeScreenshot };
|
package/src/lib/templates.js
CHANGED
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 模板模块
|
|
3
|
-
* 提供预制体和场景的创建方法
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
const { CCNode, CCScene, CCSceneAsset, CCPrefab, CCPrefabInfo } = require('./cc');
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* 创建预制体
|
|
10
|
-
* @param {string} name - 预制体名称
|
|
11
|
-
* @returns {CCPrefab}
|
|
12
|
-
*/
|
|
13
|
-
function createPrefab(name = 'Node') {
|
|
14
|
-
const prefab = new CCPrefab();
|
|
15
|
-
const node = new CCNode(name);
|
|
16
|
-
const info = new CCPrefabInfo();
|
|
17
|
-
|
|
18
|
-
prefab._root = node;
|
|
19
|
-
node._prefab = info;
|
|
20
|
-
|
|
21
|
-
return prefab;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* 创建场景
|
|
26
|
-
* @param {string} name - 场景名称
|
|
27
|
-
* @returns {CCSceneAsset}
|
|
28
|
-
*/
|
|
29
|
-
function createScene(name = 'NewScene') {
|
|
30
|
-
const asset = new CCSceneAsset();
|
|
31
|
-
const scene = new CCScene(name);
|
|
32
|
-
|
|
33
|
-
asset._scene = scene;
|
|
34
|
-
scene._parent = null;
|
|
35
|
-
scene._children = [];
|
|
36
|
-
|
|
37
|
-
return asset;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
module.exports = {
|
|
41
|
-
createPrefab,
|
|
42
|
-
createScene,
|
|
43
|
-
// 导出类供其他模块使用
|
|
44
|
-
CCNode,
|
|
45
|
-
CCScene,
|
|
46
|
-
CCSceneAsset,
|
|
47
|
-
CCPrefab,
|
|
48
|
-
CCPrefabInfo
|
|
49
|
-
};
|
|
1
|
+
/**
|
|
2
|
+
* 模板模块
|
|
3
|
+
* 提供预制体和场景的创建方法
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { CCNode, CCScene, CCSceneAsset, CCPrefab, CCPrefabInfo } = require('./cc');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* 创建预制体
|
|
10
|
+
* @param {string} name - 预制体名称
|
|
11
|
+
* @returns {CCPrefab}
|
|
12
|
+
*/
|
|
13
|
+
function createPrefab(name = 'Node') {
|
|
14
|
+
const prefab = new CCPrefab();
|
|
15
|
+
const node = new CCNode(name);
|
|
16
|
+
const info = new CCPrefabInfo();
|
|
17
|
+
|
|
18
|
+
prefab._root = node;
|
|
19
|
+
node._prefab = info;
|
|
20
|
+
|
|
21
|
+
return prefab;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* 创建场景
|
|
26
|
+
* @param {string} name - 场景名称
|
|
27
|
+
* @returns {CCSceneAsset}
|
|
28
|
+
*/
|
|
29
|
+
function createScene(name = 'NewScene') {
|
|
30
|
+
const asset = new CCSceneAsset();
|
|
31
|
+
const scene = new CCScene(name);
|
|
32
|
+
|
|
33
|
+
asset._scene = scene;
|
|
34
|
+
scene._parent = null;
|
|
35
|
+
scene._children = [];
|
|
36
|
+
|
|
37
|
+
return asset;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
module.exports = {
|
|
41
|
+
createPrefab,
|
|
42
|
+
createScene,
|
|
43
|
+
// 导出类供其他模块使用
|
|
44
|
+
CCNode,
|
|
45
|
+
CCScene,
|
|
46
|
+
CCSceneAsset,
|
|
47
|
+
CCPrefab,
|
|
48
|
+
CCPrefabInfo
|
|
49
|
+
};
|