bun-ui-tests 1.0.5 → 1.0.7
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 +101 -57
- package/package.json +1 -1
- package/ui-runner.ts +18 -7
package/cli.ts
CHANGED
|
@@ -5,22 +5,47 @@ import { readFile, access } from "node:fs/promises";
|
|
|
5
5
|
import { join, dirname, resolve } from "node:path";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
|
|
8
|
-
//
|
|
8
|
+
// Função robusta para determinar o diretório raiz do pacote
|
|
9
9
|
function getPackageRoot() {
|
|
10
|
-
// 1.
|
|
11
|
-
|
|
10
|
+
// 1. Tentar import.meta.dir (Bun específico)
|
|
11
|
+
if (import.meta.dir) {
|
|
12
|
+
return import.meta.dir;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// 2. Tentar via import.meta.url
|
|
16
|
+
try {
|
|
17
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
18
|
+
return dirname(__filename);
|
|
19
|
+
} catch (e) {}
|
|
20
|
+
|
|
21
|
+
// 3. Tentar process.argv[1] (caminho do script)
|
|
12
22
|
try {
|
|
13
23
|
const argvPath = process.argv[1];
|
|
14
|
-
if (argvPath
|
|
15
|
-
|
|
24
|
+
if (argvPath) {
|
|
25
|
+
// Se é um arquivo .ts, usa o diretório dele
|
|
26
|
+
if (argvPath.endsWith('.ts')) {
|
|
27
|
+
return dirname(argvPath);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Se é um executável, procura node_modules ou cache
|
|
31
|
+
// bunx instala em: ~/.bun/install/cache/bun-ui-tests@version/
|
|
32
|
+
const parts = argvPath.split('/');
|
|
33
|
+
const cacheIndex = parts.findIndex(p => p === 'cache' || p === '.bun' || p === 'node_modules');
|
|
34
|
+
if (cacheIndex !== -1 && cacheIndex + 1 < parts.length) {
|
|
35
|
+
// Pega até o nome do pacote (ex: bun-ui-tests@1.0.5)
|
|
36
|
+
const packagePath = parts.slice(0, cacheIndex + 2).join('/');
|
|
37
|
+
return packagePath;
|
|
38
|
+
}
|
|
16
39
|
}
|
|
17
|
-
} catch (e) {
|
|
40
|
+
} catch (e) {
|
|
41
|
+
console.error('Error resolving from argv[1]:', e);
|
|
42
|
+
}
|
|
18
43
|
|
|
19
|
-
//
|
|
20
|
-
return
|
|
44
|
+
// 4. Fallback: usar diretório atual
|
|
45
|
+
return process.cwd();
|
|
21
46
|
}
|
|
22
47
|
|
|
23
|
-
|
|
48
|
+
let packageRoot = getPackageRoot();
|
|
24
49
|
|
|
25
50
|
const COMMANDS = {
|
|
26
51
|
run: "Run the test UI (production mode)",
|
|
@@ -28,12 +53,42 @@ const COMMANDS = {
|
|
|
28
53
|
help: "Show this help message"
|
|
29
54
|
};
|
|
30
55
|
|
|
56
|
+
async function findVerifiedRoot(): Promise<string> {
|
|
57
|
+
const possibleRoots = [
|
|
58
|
+
packageRoot,
|
|
59
|
+
process.cwd(),
|
|
60
|
+
dirname(fileURLToPath(import.meta.url)),
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
for (const root of possibleRoots) {
|
|
64
|
+
if (!root) continue;
|
|
65
|
+
const runnerPath = join(root, "ui-runner.ts");
|
|
66
|
+
const distPath = join(root, "app", "dist", "index.html");
|
|
67
|
+
|
|
68
|
+
if (await Bun.file(runnerPath).exists() && await Bun.file(distPath).exists()) {
|
|
69
|
+
return root;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Se não achou, tenta procurar subindo diretórios (útil se estiver em node_modules/.bin)
|
|
74
|
+
try {
|
|
75
|
+
let current = packageRoot;
|
|
76
|
+
for (let i = 0; i < 3; i++) {
|
|
77
|
+
const runnerPath = join(current, "ui-runner.ts");
|
|
78
|
+
if (await Bun.file(runnerPath).exists()) return current;
|
|
79
|
+
current = dirname(current);
|
|
80
|
+
}
|
|
81
|
+
} catch (e) {}
|
|
82
|
+
|
|
83
|
+
return packageRoot;
|
|
84
|
+
}
|
|
85
|
+
|
|
31
86
|
async function showHelp() {
|
|
32
87
|
console.log(`
|
|
33
88
|
🧪 Bun Test UI - A beautiful UI for running Bun tests
|
|
34
89
|
|
|
35
90
|
Usage:
|
|
36
|
-
|
|
91
|
+
bunx bun-ui-tests <command>
|
|
37
92
|
|
|
38
93
|
Commands:
|
|
39
94
|
run Start the test UI (production mode)
|
|
@@ -41,62 +96,54 @@ Commands:
|
|
|
41
96
|
help Show this help message
|
|
42
97
|
|
|
43
98
|
Examples:
|
|
44
|
-
|
|
45
|
-
|
|
99
|
+
bunx bun-ui-tests run # Run in production mode
|
|
100
|
+
bunx bun-ui-tests dev # Run in development mode (for testing)
|
|
46
101
|
`);
|
|
47
102
|
}
|
|
48
103
|
|
|
49
|
-
async function
|
|
50
|
-
|
|
104
|
+
async function checkBuildExists(root: string): Promise<boolean> {
|
|
105
|
+
const distPath = join(root, "app", "dist", "index.html");
|
|
51
106
|
|
|
52
|
-
|
|
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}`);
|
|
53
111
|
|
|
54
|
-
return new Promise<void>((resolve, reject) => {
|
|
55
|
-
const proc = spawn("bun", ["run", "build"], {
|
|
56
|
-
cwd: appDir,
|
|
57
|
-
stdio: "inherit",
|
|
58
|
-
shell: true
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
proc.on("close", (code) => {
|
|
62
|
-
if (code === 0) {
|
|
63
|
-
console.log("\n✅ Frontend built successfully!");
|
|
64
|
-
resolve();
|
|
65
|
-
} else {
|
|
66
|
-
reject(new Error(`Frontend build failed with code ${code}`));
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
proc.on("error", (err) => {
|
|
71
|
-
reject(err);
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
async function checkBuildExists(): Promise<boolean> {
|
|
77
|
-
const distPath = join(__dirname, "app", "dist", "index.html");
|
|
78
|
-
console.error(`Debug: process.argv[1] is ${process.argv[1]}`);
|
|
79
|
-
console.error(`Debug: Resolved __dirname is ${__dirname}`);
|
|
80
112
|
try {
|
|
81
113
|
const exists = await Bun.file(distPath).exists();
|
|
82
114
|
if (!exists) {
|
|
83
|
-
console.
|
|
115
|
+
console.log(` - File exists: NO ❌`);
|
|
116
|
+
} else {
|
|
117
|
+
console.log(` - File exists: YES ✓`);
|
|
84
118
|
}
|
|
85
119
|
return exists;
|
|
86
120
|
} catch (err) {
|
|
87
|
-
console.error(
|
|
121
|
+
console.error(`❌ Error checking path:`, err);
|
|
88
122
|
return false;
|
|
89
123
|
}
|
|
90
124
|
}
|
|
91
125
|
|
|
92
126
|
async function runTestUI() {
|
|
127
|
+
// Encontra o root real onde estão os arquivos
|
|
128
|
+
packageRoot = await findVerifiedRoot();
|
|
129
|
+
|
|
93
130
|
// Verifica se o build do frontend existe
|
|
94
|
-
const buildExists = await checkBuildExists();
|
|
131
|
+
const buildExists = await checkBuildExists(packageRoot);
|
|
95
132
|
|
|
96
133
|
if (!buildExists) {
|
|
97
|
-
console.log("⚠️ Frontend assets not found.\n");
|
|
98
|
-
console.log("
|
|
99
|
-
console.log("
|
|
134
|
+
console.log("\n⚠️ Frontend assets not found.\n");
|
|
135
|
+
console.log("This usually means one of:");
|
|
136
|
+
console.log(" 1. The package wasn't built before publishing (contact maintainer)");
|
|
137
|
+
console.log(" 2. You're running from source (run: bun run build first)");
|
|
138
|
+
console.log(" 3. Installation issue (try: npm cache clean --force)\n");
|
|
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");
|
|
146
|
+
|
|
100
147
|
process.exit(1);
|
|
101
148
|
}
|
|
102
149
|
|
|
@@ -106,11 +153,10 @@ async function runTestUI() {
|
|
|
106
153
|
console.log("Press Ctrl+C to stop\n");
|
|
107
154
|
|
|
108
155
|
// Roda o script do backend diretamente com Bun
|
|
109
|
-
|
|
110
|
-
const runnerScript = join(__dirname, "ui-runner.ts");
|
|
156
|
+
const runnerScript = join(packageRoot, "ui-runner.ts");
|
|
111
157
|
|
|
112
158
|
const proc = spawn("bun", ["run", runnerScript], {
|
|
113
|
-
cwd: process.cwd(),
|
|
159
|
+
cwd: process.cwd(),
|
|
114
160
|
stdio: "inherit",
|
|
115
161
|
shell: false,
|
|
116
162
|
env: { ...process.env, NODE_ENV: "production" }
|
|
@@ -137,13 +183,15 @@ async function runTestUI() {
|
|
|
137
183
|
}
|
|
138
184
|
|
|
139
185
|
async function runDevMode() {
|
|
186
|
+
// Encontra o root real onde estão os arquivos
|
|
187
|
+
packageRoot = await findVerifiedRoot();
|
|
188
|
+
|
|
140
189
|
console.log("🚀 Starting Bun Test UI (Development Mode)...\n");
|
|
141
190
|
console.log("📡 WebSocket server: ws://localhost:5060");
|
|
142
191
|
console.log("🌐 Frontend: http://localhost:5050 (with hot reload)\n");
|
|
143
192
|
console.log("Press Ctrl+C to stop\n");
|
|
144
193
|
|
|
145
|
-
|
|
146
|
-
const backendPath = join(__dirname, "ui-runner.ts");
|
|
194
|
+
const backendPath = join(packageRoot, "ui-runner.ts");
|
|
147
195
|
const backendProc = spawn("bun", ["run", backendPath], {
|
|
148
196
|
cwd: process.cwd(),
|
|
149
197
|
stdio: "inherit",
|
|
@@ -151,18 +199,15 @@ async function runDevMode() {
|
|
|
151
199
|
env: { ...process.env, BUN_TEST_UI_DEV: "true" }
|
|
152
200
|
});
|
|
153
201
|
|
|
154
|
-
// Aguarda um pouco para o backend iniciar
|
|
155
202
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
156
203
|
|
|
157
|
-
|
|
158
|
-
const appDir = join(__dirname, "app");
|
|
204
|
+
const appDir = join(packageRoot, "app");
|
|
159
205
|
const frontendProc = spawn("bun", ["run", "dev"], {
|
|
160
206
|
cwd: appDir,
|
|
161
207
|
stdio: "inherit",
|
|
162
208
|
shell: true
|
|
163
209
|
});
|
|
164
210
|
|
|
165
|
-
// Handle Ctrl+C
|
|
166
211
|
process.on("SIGINT", () => {
|
|
167
212
|
console.log("\n\n👋 Stopping Bun Test UI...");
|
|
168
213
|
backendProc.kill("SIGINT");
|
|
@@ -170,7 +215,6 @@ async function runDevMode() {
|
|
|
170
215
|
process.exit(0);
|
|
171
216
|
});
|
|
172
217
|
|
|
173
|
-
// Se um processo terminar, termina o outro também
|
|
174
218
|
backendProc.on("close", (code) => {
|
|
175
219
|
console.log("\n❌ Backend stopped");
|
|
176
220
|
frontendProc.kill("SIGINT");
|
package/package.json
CHANGED
package/ui-runner.ts
CHANGED
|
@@ -14,24 +14,35 @@
|
|
|
14
14
|
import { spawn } from "node:child_process";
|
|
15
15
|
import { readdir, readFile, stat } from "node:fs/promises";
|
|
16
16
|
import { join, relative, dirname } from "node:path";
|
|
17
|
+
import { fileURLToPath } from "node:url";
|
|
17
18
|
|
|
18
19
|
// Determina o diretório do executável ou script
|
|
19
20
|
const getBaseDir = () => {
|
|
20
|
-
//
|
|
21
|
-
if (import.meta.
|
|
22
|
-
return
|
|
21
|
+
// 1. Tentar import.meta.dir (Bun específico)
|
|
22
|
+
if (import.meta.dir) {
|
|
23
|
+
return import.meta.dir;
|
|
23
24
|
}
|
|
25
|
+
|
|
26
|
+
// 2. Tentar via import.meta.url
|
|
27
|
+
try {
|
|
28
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
29
|
+
return dirname(__filename);
|
|
30
|
+
} catch (e) {}
|
|
24
31
|
|
|
25
|
-
// Try process.argv[1] to find real path
|
|
32
|
+
// 3. Try process.argv[1] to find real path
|
|
26
33
|
try {
|
|
27
34
|
const argvPath = process.argv[1];
|
|
28
|
-
if (argvPath
|
|
35
|
+
if (argvPath) {
|
|
36
|
+
// Se rodando como executável compilado, pega o diretório onde o CLI foi instalado
|
|
37
|
+
if (import.meta.path && !import.meta.path.endsWith('.ts')) {
|
|
38
|
+
return dirname(process.execPath);
|
|
39
|
+
}
|
|
29
40
|
return dirname(argvPath);
|
|
30
41
|
}
|
|
31
42
|
} catch (e) {}
|
|
32
43
|
|
|
33
|
-
// Se
|
|
34
|
-
return
|
|
44
|
+
// Se tudo falhar
|
|
45
|
+
return process.cwd();
|
|
35
46
|
};
|
|
36
47
|
|
|
37
48
|
const baseDir = getBaseDir();
|