bun-ui-tests 1.0.7 → 1.0.8
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/cli.ts +40 -58
- package/package.json +1 -1
- package/ui-runner.ts +23 -79
package/cli.ts
CHANGED
|
@@ -45,7 +45,18 @@ function getPackageRoot() {
|
|
|
45
45
|
return process.cwd();
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
const packageRoot = getPackageRoot();
|
|
49
|
+
|
|
50
|
+
// Cores ANSI suaves
|
|
51
|
+
const colors = {
|
|
52
|
+
reset: "\x1b[0m",
|
|
53
|
+
red: "\x1b[31m",
|
|
54
|
+
green: "\x1b[32m",
|
|
55
|
+
yellow: "\x1b[33m",
|
|
56
|
+
blue: "\x1b[34m",
|
|
57
|
+
cyan: "\x1b[36m",
|
|
58
|
+
gray: "\x1b[90m"
|
|
59
|
+
};
|
|
49
60
|
|
|
50
61
|
const COMMANDS = {
|
|
51
62
|
run: "Run the test UI (production mode)",
|
|
@@ -55,7 +66,7 @@ const COMMANDS = {
|
|
|
55
66
|
|
|
56
67
|
async function findVerifiedRoot(): Promise<string> {
|
|
57
68
|
const possibleRoots = [
|
|
58
|
-
|
|
69
|
+
getPackageRoot(),
|
|
59
70
|
process.cwd(),
|
|
60
71
|
dirname(fileURLToPath(import.meta.url)),
|
|
61
72
|
];
|
|
@@ -70,9 +81,9 @@ async function findVerifiedRoot(): Promise<string> {
|
|
|
70
81
|
}
|
|
71
82
|
}
|
|
72
83
|
|
|
73
|
-
// Se não achou, tenta procurar subindo diretórios
|
|
84
|
+
// Se não achou, tenta procurar subindo diretórios
|
|
74
85
|
try {
|
|
75
|
-
let current =
|
|
86
|
+
let current = getPackageRoot();
|
|
76
87
|
for (let i = 0; i < 3; i++) {
|
|
77
88
|
const runnerPath = join(current, "ui-runner.ts");
|
|
78
89
|
if (await Bun.file(runnerPath).exists()) return current;
|
|
@@ -80,12 +91,12 @@ async function findVerifiedRoot(): Promise<string> {
|
|
|
80
91
|
}
|
|
81
92
|
} catch (e) {}
|
|
82
93
|
|
|
83
|
-
return
|
|
94
|
+
return getPackageRoot();
|
|
84
95
|
}
|
|
85
96
|
|
|
86
97
|
async function showHelp() {
|
|
87
98
|
console.log(`
|
|
88
|
-
|
|
99
|
+
${colors.cyan}Bun Test UI${colors.reset} - A beautiful UI for running Bun tests
|
|
89
100
|
|
|
90
101
|
Usage:
|
|
91
102
|
bunx bun-ui-tests <command>
|
|
@@ -104,56 +115,32 @@ Examples:
|
|
|
104
115
|
async function checkBuildExists(root: string): Promise<boolean> {
|
|
105
116
|
const distPath = join(root, "app", "dist", "index.html");
|
|
106
117
|
|
|
107
|
-
console.log(`🔍 Debug Info:`);
|
|
108
|
-
console.log(` - process.argv[1]: ${process.argv[1]}`);
|
|
109
|
-
console.log(` - Resolved packageRoot: ${root}`);
|
|
110
|
-
console.log(` - Looking for: ${distPath}`);
|
|
111
|
-
|
|
112
118
|
try {
|
|
113
|
-
|
|
114
|
-
if (!exists) {
|
|
115
|
-
console.log(` - File exists: NO ❌`);
|
|
116
|
-
} else {
|
|
117
|
-
console.log(` - File exists: YES ✓`);
|
|
118
|
-
}
|
|
119
|
-
return exists;
|
|
119
|
+
return await Bun.file(distPath).exists();
|
|
120
120
|
} catch (err) {
|
|
121
|
-
console.error(`❌ Error checking path:`, err);
|
|
122
121
|
return false;
|
|
123
122
|
}
|
|
124
123
|
}
|
|
125
124
|
|
|
126
125
|
async function runTestUI() {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
// Verifica se o build do frontend existe
|
|
131
|
-
const buildExists = await checkBuildExists(packageRoot);
|
|
126
|
+
const root = await findVerifiedRoot();
|
|
127
|
+
const buildExists = await checkBuildExists(root);
|
|
132
128
|
|
|
133
129
|
if (!buildExists) {
|
|
134
|
-
console.log(
|
|
130
|
+
console.log(`\n${colors.yellow}!${colors.reset} Frontend assets not found.\n`);
|
|
135
131
|
console.log("This usually means one of:");
|
|
136
|
-
console.log(" 1. The package wasn't built before publishing
|
|
132
|
+
console.log(" 1. The package wasn't built before publishing");
|
|
137
133
|
console.log(" 2. You're running from source (run: bun run build first)");
|
|
138
|
-
console.log(" 3. Installation issue
|
|
139
|
-
|
|
140
|
-
console.log("💡 Temporary workaround:");
|
|
141
|
-
console.log(" git clone https://github.com/KillDarkness/Bun-UI-Test.git");
|
|
142
|
-
console.log(" cd Bun-UI-Test");
|
|
143
|
-
console.log(" bun install");
|
|
144
|
-
console.log(" cd app && bun install && bun run build && cd ..");
|
|
145
|
-
console.log(" bun run ui-runner.ts\n");
|
|
134
|
+
console.log(" 3. Installation issue\n");
|
|
146
135
|
|
|
147
136
|
process.exit(1);
|
|
148
137
|
}
|
|
149
138
|
|
|
150
|
-
console.log(
|
|
151
|
-
console.log(
|
|
152
|
-
console.log(
|
|
153
|
-
console.log("Press Ctrl+C to stop\n");
|
|
139
|
+
console.log(`${colors.green}›${colors.reset} Starting Bun Test UI...`);
|
|
140
|
+
console.log(`${colors.gray}→ WebSocket: ws://localhost:5050/ws`);
|
|
141
|
+
console.log(`→ Frontend: http://localhost:5050${colors.reset}\n`);
|
|
154
142
|
|
|
155
|
-
|
|
156
|
-
const runnerScript = join(packageRoot, "ui-runner.ts");
|
|
143
|
+
const runnerScript = join(root, "ui-runner.ts");
|
|
157
144
|
|
|
158
145
|
const proc = spawn("bun", ["run", runnerScript], {
|
|
159
146
|
cwd: process.cwd(),
|
|
@@ -164,34 +151,31 @@ async function runTestUI() {
|
|
|
164
151
|
|
|
165
152
|
proc.on("close", (code) => {
|
|
166
153
|
if (code !== 0) {
|
|
167
|
-
console.error(`\n
|
|
154
|
+
console.error(`\n${colors.red}✗${colors.reset} Process exited with code ${code}`);
|
|
168
155
|
process.exit(code || 1);
|
|
169
156
|
}
|
|
170
157
|
});
|
|
171
158
|
|
|
172
159
|
proc.on("error", (err) => {
|
|
173
|
-
console.error(
|
|
160
|
+
console.error(`${colors.red}✗${colors.reset} Error starting test UI:`, err);
|
|
174
161
|
process.exit(1);
|
|
175
162
|
});
|
|
176
163
|
|
|
177
|
-
// Handle Ctrl+C
|
|
178
164
|
process.on("SIGINT", () => {
|
|
179
|
-
console.log(
|
|
165
|
+
console.log(`\n\n${colors.gray}Stopping Bun Test UI...${colors.reset}`);
|
|
180
166
|
proc.kill("SIGINT");
|
|
181
167
|
process.exit(0);
|
|
182
168
|
});
|
|
183
169
|
}
|
|
184
170
|
|
|
185
171
|
async function runDevMode() {
|
|
186
|
-
|
|
187
|
-
packageRoot = await findVerifiedRoot();
|
|
172
|
+
const root = await findVerifiedRoot();
|
|
188
173
|
|
|
189
|
-
console.log(
|
|
190
|
-
console.log(
|
|
191
|
-
console.log(
|
|
192
|
-
console.log("Press Ctrl+C to stop\n");
|
|
174
|
+
console.log(`${colors.cyan}›${colors.reset} Starting Bun Test UI (Dev Mode)...`);
|
|
175
|
+
console.log(`${colors.gray}→ WebSocket: ws://localhost:5060`);
|
|
176
|
+
console.log(`→ Frontend: http://localhost:5050${colors.reset}\n`);
|
|
193
177
|
|
|
194
|
-
const backendPath = join(
|
|
178
|
+
const backendPath = join(root, "ui-runner.ts");
|
|
195
179
|
const backendProc = spawn("bun", ["run", backendPath], {
|
|
196
180
|
cwd: process.cwd(),
|
|
197
181
|
stdio: "inherit",
|
|
@@ -201,7 +185,7 @@ async function runDevMode() {
|
|
|
201
185
|
|
|
202
186
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
203
187
|
|
|
204
|
-
const appDir = join(
|
|
188
|
+
const appDir = join(root, "app");
|
|
205
189
|
const frontendProc = spawn("bun", ["run", "dev"], {
|
|
206
190
|
cwd: appDir,
|
|
207
191
|
stdio: "inherit",
|
|
@@ -209,20 +193,18 @@ async function runDevMode() {
|
|
|
209
193
|
});
|
|
210
194
|
|
|
211
195
|
process.on("SIGINT", () => {
|
|
212
|
-
console.log(
|
|
196
|
+
console.log(`\n\n${colors.gray}Stopping Bun Test UI...${colors.reset}`);
|
|
213
197
|
backendProc.kill("SIGINT");
|
|
214
198
|
frontendProc.kill("SIGINT");
|
|
215
199
|
process.exit(0);
|
|
216
200
|
});
|
|
217
201
|
|
|
218
202
|
backendProc.on("close", (code) => {
|
|
219
|
-
console.log("\n❌ Backend stopped");
|
|
220
203
|
frontendProc.kill("SIGINT");
|
|
221
204
|
process.exit(code || 1);
|
|
222
205
|
});
|
|
223
206
|
|
|
224
207
|
frontendProc.on("close", (code) => {
|
|
225
|
-
console.log("\n❌ Frontend stopped");
|
|
226
208
|
backendProc.kill("SIGINT");
|
|
227
209
|
process.exit(code || 1);
|
|
228
210
|
});
|
|
@@ -235,7 +217,7 @@ switch (command) {
|
|
|
235
217
|
case "run":
|
|
236
218
|
runTestUI()
|
|
237
219
|
.catch((err) => {
|
|
238
|
-
console.error(
|
|
220
|
+
console.error(`${colors.red}✗${colors.reset} Failed to start:`, err);
|
|
239
221
|
process.exit(1);
|
|
240
222
|
});
|
|
241
223
|
break;
|
|
@@ -243,7 +225,7 @@ switch (command) {
|
|
|
243
225
|
case "dev":
|
|
244
226
|
runDevMode()
|
|
245
227
|
.catch((err) => {
|
|
246
|
-
console.error(
|
|
228
|
+
console.error(`${colors.red}✗${colors.reset} Failed to start dev mode:`, err);
|
|
247
229
|
process.exit(1);
|
|
248
230
|
});
|
|
249
231
|
break;
|
|
@@ -255,7 +237,7 @@ switch (command) {
|
|
|
255
237
|
break;
|
|
256
238
|
|
|
257
239
|
default:
|
|
258
|
-
console.error(
|
|
240
|
+
console.error(`${colors.red}✗${colors.reset} Unknown command: ${command}\n`);
|
|
259
241
|
showHelp();
|
|
260
242
|
process.exit(1);
|
|
261
243
|
}
|
package/package.json
CHANGED
package/ui-runner.ts
CHANGED
|
@@ -45,22 +45,29 @@ const getBaseDir = () => {
|
|
|
45
45
|
return process.cwd();
|
|
46
46
|
};
|
|
47
47
|
|
|
48
|
+
const colors = {
|
|
49
|
+
reset: "\x1b[0m",
|
|
50
|
+
red: "\x1b[31m",
|
|
51
|
+
green: "\x1b[32m",
|
|
52
|
+
yellow: "\x1b[33m",
|
|
53
|
+
blue: "\x1b[34m",
|
|
54
|
+
cyan: "\x1b[36m",
|
|
55
|
+
gray: "\x1b[90m"
|
|
56
|
+
};
|
|
57
|
+
|
|
48
58
|
const baseDir = getBaseDir();
|
|
49
59
|
const distPath = join(baseDir, "app", "dist");
|
|
50
|
-
console.log(`Debug: ui-runner argv[1] is ${process.argv[1]}`);
|
|
51
|
-
console.log(`Debug: distPath is ${distPath}`);
|
|
52
60
|
const isDevMode = process.env.BUN_TEST_UI_DEV === "true";
|
|
53
61
|
|
|
54
62
|
// WebSocket Handler (lógica compartilhada)
|
|
55
63
|
const websocketHandler = {
|
|
56
64
|
async open(ws: any) {
|
|
57
|
-
console.log(
|
|
65
|
+
console.log(`${colors.green}✓${colors.reset} UI connected`);
|
|
58
66
|
|
|
59
67
|
// Escaneia arquivos de teste
|
|
60
68
|
const testFiles = await scanTestFiles();
|
|
61
69
|
|
|
62
70
|
// Escaneia todos os testes de cada arquivo
|
|
63
|
-
console.log("📖 Reading test files to extract test names...");
|
|
64
71
|
const testsMap = await scanAllTests();
|
|
65
72
|
|
|
66
73
|
// Envia evento de conexão com lista de arquivos e testes
|
|
@@ -73,65 +80,48 @@ const websocketHandler = {
|
|
|
73
80
|
}
|
|
74
81
|
}));
|
|
75
82
|
|
|
76
|
-
console.log(
|
|
83
|
+
console.log(`${colors.gray}› Found ${testFiles.length} test files with ${Object.values(testsMap).flat().length} tests total${colors.reset}`);
|
|
77
84
|
},
|
|
78
85
|
message(ws: any, message: any) {
|
|
79
86
|
try {
|
|
80
87
|
const data = JSON.parse(message.toString());
|
|
81
|
-
console.log('📨 [WEBSOCKET] Mensagem recebida:', data.type, data.payload);
|
|
82
88
|
|
|
83
89
|
// Processa comandos da UI
|
|
84
90
|
if (data.type === "run:request") {
|
|
85
91
|
const file = data.payload?.file;
|
|
86
92
|
const testName = data.payload?.testName;
|
|
87
93
|
|
|
88
|
-
console.log('▶️ [RUN REQUEST] file:', file, 'testName:', testName);
|
|
89
|
-
|
|
90
94
|
if (testName) {
|
|
91
|
-
console.log(
|
|
95
|
+
console.log(`${colors.cyan}▶${colors.reset} Running test: ${colors.gray}${testName}${colors.reset} in ${file}`);
|
|
92
96
|
} else if (file) {
|
|
93
|
-
console.log(
|
|
97
|
+
console.log(`${colors.cyan}▶${colors.reset} Running file: ${file}`);
|
|
94
98
|
} else {
|
|
95
|
-
console.log(
|
|
99
|
+
console.log(`${colors.cyan}▶${colors.reset} Running all tests`);
|
|
96
100
|
}
|
|
97
101
|
|
|
98
102
|
runTests(ws, file, testName);
|
|
99
|
-
} else {
|
|
100
|
-
console.log('⚠️ [WEBSOCKET] Tipo desconhecido:', data.type);
|
|
101
103
|
}
|
|
102
104
|
} catch (err) {
|
|
103
105
|
console.error("Error processing message:", err);
|
|
104
106
|
}
|
|
105
107
|
},
|
|
106
108
|
close(ws: any) {
|
|
107
|
-
console.log(
|
|
109
|
+
console.log(`${colors.red}✗${colors.reset} UI disconnected`);
|
|
108
110
|
},
|
|
109
111
|
};
|
|
110
112
|
|
|
111
113
|
if (isDevMode) {
|
|
112
114
|
// === MODO DESENVOLVIMENTO ===
|
|
113
|
-
// Frontend roda via Vite na porta 5050
|
|
114
|
-
// Backend roda separadamente na porta 5060 (apenas WS)
|
|
115
|
-
|
|
116
115
|
Bun.serve({
|
|
117
116
|
port: 5060,
|
|
118
117
|
fetch(req, server) {
|
|
119
|
-
|
|
120
|
-
if (server.upgrade(req)) {
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
118
|
+
if (server.upgrade(req)) return;
|
|
123
119
|
return new Response("Bun Test UI Backend (Dev Mode)", { status: 200 });
|
|
124
120
|
},
|
|
125
121
|
websocket: websocketHandler
|
|
126
122
|
});
|
|
127
|
-
|
|
128
|
-
console.log("📡 WebSocket server running on ws://localhost:5060");
|
|
129
|
-
|
|
130
123
|
} else {
|
|
131
124
|
// === MODO PRODUÇÃO ===
|
|
132
|
-
// Servidor ÚNICO na porta 5050
|
|
133
|
-
// Serve arquivos estáticos do frontend E WebSocket no mesmo endpoint
|
|
134
|
-
|
|
135
125
|
const PORT = 5050;
|
|
136
126
|
|
|
137
127
|
Bun.serve({
|
|
@@ -141,24 +131,18 @@ if (isDevMode) {
|
|
|
141
131
|
|
|
142
132
|
// 1. WebSocket Upgrade (/ws)
|
|
143
133
|
if (url.pathname === "/ws") {
|
|
144
|
-
if (server.upgrade(req))
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
134
|
+
if (server.upgrade(req)) return;
|
|
147
135
|
return new Response("WebSocket upgrade failed", { status: 400 });
|
|
148
136
|
}
|
|
149
137
|
|
|
150
138
|
// 2. Arquivos Estáticos (Frontend)
|
|
151
139
|
const file = Bun.file(join(distPath, url.pathname === "/" ? "/index.html" : url.pathname));
|
|
152
|
-
if (await file.exists())
|
|
153
|
-
return new Response(file);
|
|
154
|
-
}
|
|
140
|
+
if (await file.exists()) return new Response(file);
|
|
155
141
|
|
|
156
142
|
// SPA fallback
|
|
157
143
|
if (!url.pathname.includes(".")) {
|
|
158
144
|
const indexFile = Bun.file(join(distPath, "index.html"));
|
|
159
|
-
if (await indexFile.exists())
|
|
160
|
-
return new Response(indexFile);
|
|
161
|
-
}
|
|
145
|
+
if (await indexFile.exists()) return new Response(indexFile);
|
|
162
146
|
}
|
|
163
147
|
|
|
164
148
|
return new Response("Frontend build not found.", { status: 404 });
|
|
@@ -166,8 +150,7 @@ if (isDevMode) {
|
|
|
166
150
|
websocket: websocketHandler
|
|
167
151
|
});
|
|
168
152
|
|
|
169
|
-
console.log(
|
|
170
|
-
console.log(`📡 WebSocket endpoint available at ws://localhost:${PORT}/ws`);
|
|
153
|
+
console.log(`${colors.green}✓${colors.reset} Server running on http://localhost:${PORT}`);
|
|
171
154
|
}
|
|
172
155
|
|
|
173
156
|
|
|
@@ -292,17 +275,11 @@ function runTests(ws: any, file?: string, testName?: string) {
|
|
|
292
275
|
args.push(file);
|
|
293
276
|
}
|
|
294
277
|
|
|
295
|
-
// Bun suporta --test-name-pattern para filtrar testes
|
|
296
|
-
// Escapa caracteres especiais de regex e usa o nome exato
|
|
297
278
|
if (testName) {
|
|
298
|
-
// Escapa caracteres especiais de regex
|
|
299
279
|
const escapedName = testName.replace(/[.*+?^${}()|[\\]/g, '\\$&');
|
|
300
280
|
args.push("--test-name-pattern", escapedName);
|
|
301
281
|
}
|
|
302
282
|
|
|
303
|
-
console.log('🚀 [RUN] Comando:', `bun ${args.join(" ")}`);
|
|
304
|
-
console.log(`Starting bun test ${args.slice(1).join(" ") || "(all)"}...`);
|
|
305
|
-
|
|
306
283
|
// Emite evento de início
|
|
307
284
|
ws.send(JSON.stringify({
|
|
308
285
|
type: "run:start",
|
|
@@ -313,11 +290,9 @@ function runTests(ws: any, file?: string, testName?: string) {
|
|
|
313
290
|
}
|
|
314
291
|
}));
|
|
315
292
|
|
|
316
|
-
// Spawna o processo bun test
|
|
317
|
-
// IMPORTANTE: Não usamos nenhuma API interna do bun:test
|
|
318
293
|
const bunTest = spawn("bun", args, {
|
|
319
294
|
cwd: process.cwd(),
|
|
320
|
-
env: { ...process.env, FORCE_COLOR: "0" },
|
|
295
|
+
env: { ...process.env, FORCE_COLOR: "0" },
|
|
321
296
|
});
|
|
322
297
|
|
|
323
298
|
let currentTestFile = "";
|
|
@@ -359,11 +334,6 @@ function runTests(ws: any, file?: string, testName?: string) {
|
|
|
359
334
|
// Função para enviar bloco de erro
|
|
360
335
|
const flushErrorBlock = () => {
|
|
361
336
|
if (errorBlock.length > 0) {
|
|
362
|
-
console.log('📦 [ERROR BLOCK] Enviando bloco com', errorBlock.length, 'linhas:');
|
|
363
|
-
console.log('---START---');
|
|
364
|
-
console.log(errorBlock.join('\n'));
|
|
365
|
-
console.log('---END---');
|
|
366
|
-
|
|
367
337
|
ws.send(JSON.stringify({
|
|
368
338
|
type: "log",
|
|
369
339
|
payload: { message: errorBlock.join('\n'), stream: "stdout" }
|
|
@@ -376,11 +346,6 @@ function runTests(ws: any, file?: string, testName?: string) {
|
|
|
376
346
|
// Função para enviar bloco de resumo
|
|
377
347
|
const flushSummaryBlock = () => {
|
|
378
348
|
if (summaryBlock.length > 0) {
|
|
379
|
-
console.log('📊 [SUMMARY BLOCK] Enviando bloco com', summaryBlock.length, 'linhas:');
|
|
380
|
-
console.log('---START---');
|
|
381
|
-
console.log(summaryBlock.join('\n'));
|
|
382
|
-
console.log('---END---');
|
|
383
|
-
|
|
384
349
|
ws.send(JSON.stringify({
|
|
385
350
|
type: "log",
|
|
386
351
|
payload: { message: summaryBlock.join('\n'), stream: "stdout" }
|
|
@@ -395,52 +360,36 @@ function runTests(ws: any, file?: string, testName?: string) {
|
|
|
395
360
|
const text = data.toString();
|
|
396
361
|
buffer += text;
|
|
397
362
|
|
|
398
|
-
// Processa linhas completas
|
|
399
363
|
const lines = buffer.split("\n");
|
|
400
|
-
buffer = lines.pop() || "";
|
|
364
|
+
buffer = lines.pop() || "";
|
|
401
365
|
|
|
402
366
|
for (const line of lines) {
|
|
403
367
|
currentTestFile = processLine(line, ws, currentTestFile);
|
|
404
|
-
|
|
405
|
-
// Linhas vazias podem fazer parte de blocos
|
|
406
368
|
const trimmed = line.trim();
|
|
407
369
|
|
|
408
|
-
// Verifica se é linha de erro
|
|
409
370
|
if (isErrorLine(line)) {
|
|
410
|
-
console.log('🔴 [ERROR LINE] Detectado:', line.substring(0, 50));
|
|
411
|
-
// Se estava no resumo, envia o resumo primeiro
|
|
412
371
|
flushSummaryBlock();
|
|
413
|
-
|
|
414
372
|
inErrorBlock = true;
|
|
415
373
|
errorBlock.push(line);
|
|
416
374
|
continue;
|
|
417
375
|
}
|
|
418
376
|
|
|
419
|
-
// Linha vazia dentro de bloco de erro - mantém no bloco
|
|
420
377
|
if (inErrorBlock && !trimmed) {
|
|
421
|
-
console.log('🔴 [ERROR EMPTY] Linha vazia no bloco de erro');
|
|
422
378
|
errorBlock.push(line);
|
|
423
379
|
continue;
|
|
424
380
|
}
|
|
425
381
|
|
|
426
|
-
// Verifica se é linha de resumo
|
|
427
382
|
if (isSummaryLine(line)) {
|
|
428
|
-
console.log('📊 [SUMMARY LINE] Detectado:', line.substring(0, 50));
|
|
429
|
-
// Se estava no erro, envia o erro primeiro
|
|
430
383
|
flushErrorBlock();
|
|
431
|
-
|
|
432
384
|
inSummaryBlock = true;
|
|
433
385
|
summaryBlock.push(line);
|
|
434
386
|
continue;
|
|
435
387
|
}
|
|
436
388
|
|
|
437
|
-
// Linha normal - envia blocos pendentes e depois a linha
|
|
438
389
|
flushErrorBlock();
|
|
439
390
|
flushSummaryBlock();
|
|
440
391
|
|
|
441
|
-
// Envia linhas normais separadamente (se não vazia)
|
|
442
392
|
if (trimmed) {
|
|
443
|
-
console.log('📝 [NORMAL LINE] Enviando:', line.substring(0, 50));
|
|
444
393
|
ws.send(JSON.stringify({
|
|
445
394
|
type: "log",
|
|
446
395
|
payload: { message: line, stream: "stdout" }
|
|
@@ -463,11 +412,8 @@ function runTests(ws: any, file?: string, testName?: string) {
|
|
|
463
412
|
});
|
|
464
413
|
|
|
465
414
|
bunTest.on("close", (code) => {
|
|
466
|
-
console.log(`bun test exited with code ${code}`);
|
|
467
|
-
|
|
468
415
|
// Processa buffer pendente antes de finalizar
|
|
469
416
|
if (buffer.trim()) {
|
|
470
|
-
console.log('⚠️ [CLOSE] Buffer pendente:', buffer.substring(0, 100));
|
|
471
417
|
const lines = buffer.split("\n");
|
|
472
418
|
for (const line of lines) {
|
|
473
419
|
if (line.trim()) {
|
|
@@ -500,8 +446,6 @@ function runTests(ws: any, file?: string, testName?: string) {
|
|
|
500
446
|
flushErrorBlock();
|
|
501
447
|
flushSummaryBlock();
|
|
502
448
|
|
|
503
|
-
console.log('✅ [CLOSE] Processo finalizado, todos os logs enviados');
|
|
504
|
-
|
|
505
449
|
ws.send(JSON.stringify({
|
|
506
450
|
type: "run:complete",
|
|
507
451
|
payload: {
|