plum-e2e 2.4.6 → 2.4.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/backend/prisma/migrations/20260622000000_report_test_run/migration.sql +5 -0
- package/backend/prisma/schema.prisma +3 -0
- package/backend/services/reportService.js +5 -2
- package/bin/plum.js +58 -0
- package/frontend/src/lib/components/layout/RunnerPanel.svelte +2 -2
- package/frontend/src/routes/reports/+page.svelte +4 -3
- package/package.json +1 -1
|
@@ -64,6 +64,8 @@ model Report {
|
|
|
64
64
|
runner Runner? @relation(fields: [runnerId], references: [id], onDelete: SetNull)
|
|
65
65
|
cronJobId Int?
|
|
66
66
|
cronJob CronJob? @relation(fields: [cronJobId], references: [id], onDelete: SetNull)
|
|
67
|
+
testRunId String?
|
|
68
|
+
testRun TestRun? @relation(fields: [testRunId], references: [id], onDelete: SetNull)
|
|
67
69
|
content Json
|
|
68
70
|
createdAt DateTime @default(now())
|
|
69
71
|
testHistory TestCaseHistory[]
|
|
@@ -162,6 +164,7 @@ model TestRun {
|
|
|
162
164
|
updatedAt DateTime @updatedAt
|
|
163
165
|
entries TestRunEntry[]
|
|
164
166
|
history TestCaseHistory[]
|
|
167
|
+
reports Report[]
|
|
165
168
|
}
|
|
166
169
|
|
|
167
170
|
model TestRunEntry {
|
|
@@ -239,7 +239,8 @@ const getAllReports = () =>
|
|
|
239
239
|
runners: true,
|
|
240
240
|
browser: true,
|
|
241
241
|
runnerName: true,
|
|
242
|
-
createdAt: true
|
|
242
|
+
createdAt: true,
|
|
243
|
+
testRun: { select: { id: true, title: true } }
|
|
243
244
|
}
|
|
244
245
|
});
|
|
245
246
|
|
|
@@ -263,7 +264,8 @@ const getReportDetail = async (id) => {
|
|
|
263
264
|
browser: true,
|
|
264
265
|
runnerName: true,
|
|
265
266
|
createdAt: true,
|
|
266
|
-
content: true
|
|
267
|
+
content: true,
|
|
268
|
+
testRun: { select: { id: true, title: true } }
|
|
267
269
|
}
|
|
268
270
|
});
|
|
269
271
|
if (!report) return null;
|
|
@@ -315,6 +317,7 @@ const saveReport = async ({
|
|
|
315
317
|
runnerName: runnerName ?? null,
|
|
316
318
|
runnerId: runnerId ?? null,
|
|
317
319
|
cronJobId,
|
|
320
|
+
testRunId: testRunId ?? null,
|
|
318
321
|
content: { features }
|
|
319
322
|
}
|
|
320
323
|
});
|
package/bin/plum.js
CHANGED
|
@@ -323,6 +323,44 @@ async function serverStart() {
|
|
|
323
323
|
clack.outro(pc.green('Plum is running. Use "plum server stop" to shut down.'));
|
|
324
324
|
}
|
|
325
325
|
|
|
326
|
+
async function serverRestart() {
|
|
327
|
+
clack.intro(pc.bgMagenta(pc.white(' 🟣 Plum — Restart ')));
|
|
328
|
+
const { loadServerConfig } = serverConfigLib();
|
|
329
|
+
const cfg = loadServerConfig(process.cwd());
|
|
330
|
+
applyServerConfig(cfg);
|
|
331
|
+
clack.log.info(`UI: ${pc.cyan(`http://localhost:${cfg.frontendPort}`)}`);
|
|
332
|
+
|
|
333
|
+
execSync('docker compose up --build -d', { cwd: plumRoot, stdio: 'inherit' });
|
|
334
|
+
|
|
335
|
+
const apiBase = `http://localhost:${cfg.backendPort}`;
|
|
336
|
+
const s = clack.spinner();
|
|
337
|
+
s.start('Waiting for server to be ready…');
|
|
338
|
+
let ready = false;
|
|
339
|
+
for (let i = 0; i < 40; i++) {
|
|
340
|
+
await new Promise((r) => setTimeout(r, 1500));
|
|
341
|
+
try {
|
|
342
|
+
const res = await fetch(`${apiBase}/auth/needs-setup`);
|
|
343
|
+
if (res.ok) {
|
|
344
|
+
ready = true;
|
|
345
|
+
break;
|
|
346
|
+
}
|
|
347
|
+
} catch {}
|
|
348
|
+
}
|
|
349
|
+
s.stop(ready ? pc.green('✓ Server is ready') : pc.yellow('Server may still be starting'));
|
|
350
|
+
clack.log.info(`UI: ${pc.cyan(`http://localhost:${cfg.frontendPort}`)}`);
|
|
351
|
+
clack.log.info(`API: ${pc.cyan(`http://localhost:${cfg.backendPort}`)}`);
|
|
352
|
+
clack.outro(pc.green('Plum restarted.'));
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
async function serverUpdate() {
|
|
356
|
+
clack.intro(pc.bgMagenta(pc.white(' 🟣 Plum — Update ')));
|
|
357
|
+
clack.log.step('Fetching latest Plum version…');
|
|
358
|
+
execSync('npm install -g plum-e2e@latest', { stdio: 'inherit' });
|
|
359
|
+
clack.log.success('Plum CLI updated.');
|
|
360
|
+
clack.log.step('Rebuilding server with new version…');
|
|
361
|
+
await serverRestart();
|
|
362
|
+
}
|
|
363
|
+
|
|
326
364
|
async function serverReconfig() {
|
|
327
365
|
clack.intro(pc.bgMagenta(pc.white(' 🟣 Plum — Reconfigure Server ')));
|
|
328
366
|
const cfg = await configureServer({ force: true });
|
|
@@ -759,6 +797,14 @@ switch (command) {
|
|
|
759
797
|
await serverReconfig();
|
|
760
798
|
break;
|
|
761
799
|
}
|
|
800
|
+
if (subcommand === 'restart') {
|
|
801
|
+
await serverRestart();
|
|
802
|
+
break;
|
|
803
|
+
}
|
|
804
|
+
if (subcommand === 'update') {
|
|
805
|
+
await serverUpdate();
|
|
806
|
+
break;
|
|
807
|
+
}
|
|
762
808
|
// fall through to start for 'plum server start' or 'plum server'
|
|
763
809
|
// intentional fall-through
|
|
764
810
|
|
|
@@ -766,6 +812,14 @@ switch (command) {
|
|
|
766
812
|
await serverStart();
|
|
767
813
|
break;
|
|
768
814
|
|
|
815
|
+
case 'restart':
|
|
816
|
+
await serverRestart();
|
|
817
|
+
break;
|
|
818
|
+
|
|
819
|
+
case 'update':
|
|
820
|
+
await serverUpdate();
|
|
821
|
+
break;
|
|
822
|
+
|
|
769
823
|
case 'run-test': {
|
|
770
824
|
console.log('--------------------------------------\n');
|
|
771
825
|
console.log('🚀 Running tests locally...');
|
|
@@ -957,7 +1011,11 @@ switch (command) {
|
|
|
957
1011
|
console.log(' --backend-port <n> Host port for the backend/API (default: 3001)');
|
|
958
1012
|
console.log(' --frontend-port <n> Host port for the UI (default: 5173)');
|
|
959
1013
|
console.log(' server reconfig Re-enter server settings without starting');
|
|
1014
|
+
console.log(
|
|
1015
|
+
' server restart Rebuild and restart the server (no prompts; alias: plum restart)'
|
|
1016
|
+
);
|
|
960
1017
|
console.log(' server stop Stop the server (alias: plum stop)');
|
|
1018
|
+
console.log(' update Update Plum to the latest version and restart the server');
|
|
961
1019
|
console.log(' node start Start a runner node (interactive), then open runner menu');
|
|
962
1020
|
console.log(' --primary <url> Primary Plum server to auto-register with');
|
|
963
1021
|
console.log(' --url <url> Address the primary calls back (default: <lan-ip>:<port>;');
|
|
@@ -332,8 +332,8 @@
|
|
|
332
332
|
<span class="status-dot" class:pulse={state.running} style="background:{statusColor}"
|
|
333
333
|
></span>
|
|
334
334
|
<span class="status-word" style="color:{statusColor}">{statusLabel}</span>
|
|
335
|
-
{#if state.lastRunId}
|
|
336
|
-
<span class="run-tag">{state.
|
|
335
|
+
{#if state.lastRunId || state.currentRun?.runTitle}
|
|
336
|
+
<span class="run-tag">{state.currentRun?.runTitle || state.lastRunId}</span>
|
|
337
337
|
{/if}
|
|
338
338
|
</div>
|
|
339
339
|
{#if state.testCompleted && state.latestReportId}
|
|
@@ -228,9 +228,10 @@
|
|
|
228
228
|
{report.status === 'PASS' ? '✓' : '✗'}
|
|
229
229
|
</span>
|
|
230
230
|
<div class="item-meta">
|
|
231
|
-
<span class="item-tags"
|
|
232
|
-
|
|
233
|
-
|
|
231
|
+
<span class="item-tags">
|
|
232
|
+
{report.testRun?.title ??
|
|
233
|
+
(isScheduled(report.triggerType) ? report.triggerType : report.tags)}
|
|
234
|
+
</span>
|
|
234
235
|
<div class="item-badges">
|
|
235
236
|
<Badge variant={triggerVariant(report.triggerType)}>
|
|
236
237
|
{triggerLabel(report.triggerType)}
|