@solidxai/core 0.1.10-beta.0 → 0.1.10-beta.10
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/dist/commands/run-tests.command.d.ts +2 -0
- package/dist/commands/run-tests.command.d.ts.map +1 -1
- package/dist/commands/run-tests.command.js +49 -17
- package/dist/commands/run-tests.command.js.map +1 -1
- package/dist/controllers/action-metadata.controller.js +1 -1
- package/dist/controllers/action-metadata.controller.js.map +1 -1
- package/dist/controllers/facebook-authentication.controller.js +1 -1
- package/dist/controllers/facebook-authentication.controller.js.map +1 -1
- package/dist/controllers/google-authentication.controller.js +1 -1
- package/dist/controllers/google-authentication.controller.js.map +1 -1
- package/dist/controllers/menu-item-metadata.controller.js +1 -1
- package/dist/controllers/menu-item-metadata.controller.js.map +1 -1
- package/dist/controllers/microsoft-authentication.controller.js +1 -1
- package/dist/controllers/microsoft-authentication.controller.js.map +1 -1
- package/dist/controllers/mq-message-queue.controller.js +1 -1
- package/dist/controllers/mq-message-queue.controller.js.map +1 -1
- package/dist/controllers/mq-message.controller.js +1 -1
- package/dist/controllers/mq-message.controller.js.map +1 -1
- package/dist/controllers/user.controller.d.ts.map +1 -1
- package/dist/controllers/user.controller.js.map +1 -1
- package/dist/controllers/view-metadata.controller.js +1 -1
- package/dist/controllers/view-metadata.controller.js.map +1 -1
- package/dist/dtos/update-user.dto.d.ts +1 -0
- package/dist/dtos/update-user.dto.d.ts.map +1 -1
- package/dist/dtos/update-user.dto.js +7 -1
- package/dist/dtos/update-user.dto.js.map +1 -1
- package/dist/entities/chatter-message-details.entity.d.ts.map +1 -1
- package/dist/entities/chatter-message-details.entity.js +0 -1
- package/dist/entities/chatter-message-details.entity.js.map +1 -1
- package/dist/entities/user.entity.js +1 -0
- package/dist/entities/user.entity.js.map +1 -1
- package/dist/helpers/bootstrap.helper.d.ts.map +1 -1
- package/dist/helpers/bootstrap.helper.js +2 -0
- package/dist/helpers/bootstrap.helper.js.map +1 -1
- package/dist/helpers/field-crud-managers/BigIntFieldCrudManager.js.map +1 -1
- package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.js.map +1 -1
- package/dist/helpers/module-metadata-helper.service.js.map +1 -1
- package/dist/jobs/database/chatter-queue-subscriber-database.service.d.ts.map +1 -1
- package/dist/jobs/database/chatter-queue-subscriber-database.service.js +3 -3
- package/dist/jobs/database/chatter-queue-subscriber-database.service.js.map +1 -1
- package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.js.map +1 -1
- package/dist/jobs/rabbitmq/chatter-queue-subscriber.service.d.ts.map +1 -1
- package/dist/jobs/rabbitmq/chatter-queue-subscriber.service.js +3 -3
- package/dist/jobs/rabbitmq/chatter-queue-subscriber.service.js.map +1 -1
- package/dist/jobs/redis/chatter-queue-subscriber-redis.service.d.ts.map +1 -1
- package/dist/jobs/redis/chatter-queue-subscriber-redis.service.js +3 -3
- package/dist/jobs/redis/chatter-queue-subscriber-redis.service.js.map +1 -1
- package/dist/repository/security-rule.repository.js.map +1 -1
- package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
- package/dist/seeders/module-test-data.service.d.ts +7 -0
- package/dist/seeders/module-test-data.service.d.ts.map +1 -1
- package/dist/seeders/module-test-data.service.js +94 -18
- package/dist/seeders/module-test-data.service.js.map +1 -1
- package/dist/seeders/permission-metadata-seeder.service.js.map +1 -1
- package/dist/seeders/seed-data/solid-core-metadata.json +34 -2
- package/dist/services/authentication.service.d.ts.map +1 -1
- package/dist/services/authentication.service.js +5 -5
- package/dist/services/authentication.service.js.map +1 -1
- package/dist/services/chatter-message.service.d.ts +6 -3
- package/dist/services/chatter-message.service.d.ts.map +1 -1
- package/dist/services/chatter-message.service.js +23 -35
- package/dist/services/chatter-message.service.js.map +1 -1
- package/dist/services/crud.service.js.map +1 -1
- package/dist/services/csv.service.js.map +1 -1
- package/dist/services/dashboard.service.js.map +1 -1
- package/dist/services/database/database-bootstrap.service.js.map +1 -1
- package/dist/services/excel.service.js.map +1 -1
- package/dist/services/export-transaction.service.js.map +1 -1
- package/dist/services/field-metadata.service.js +2 -2
- package/dist/services/field-metadata.service.js.map +1 -1
- package/dist/services/fixtures.service.js.map +1 -1
- package/dist/services/import-transaction.service.js.map +1 -1
- package/dist/services/list-of-values.service.js.map +1 -1
- package/dist/services/model-metadata.service.d.ts.map +1 -1
- package/dist/services/model-metadata.service.js +3 -13
- package/dist/services/model-metadata.service.js.map +1 -1
- package/dist/services/module-metadata.service.js.map +1 -1
- package/dist/services/queues/database-publisher.service.js +3 -3
- package/dist/services/queues/database-publisher.service.js.map +1 -1
- package/dist/services/queues/database-subscriber.service.js +3 -3
- package/dist/services/queues/database-subscriber.service.js.map +1 -1
- package/dist/services/queues/rabbitmq-publisher.service.js +3 -3
- package/dist/services/queues/rabbitmq-publisher.service.js.map +1 -1
- package/dist/services/queues/rabbitmq-subscriber.service.js +4 -4
- package/dist/services/queues/rabbitmq-subscriber.service.js.map +1 -1
- package/dist/services/queues/redis-publisher.service.d.ts.map +1 -1
- package/dist/services/queues/redis-publisher.service.js +4 -1
- package/dist/services/queues/redis-publisher.service.js.map +1 -1
- package/dist/services/queues/redis-subscriber.service.d.ts.map +1 -1
- package/dist/services/queues/redis-subscriber.service.js +4 -1
- package/dist/services/queues/redis-subscriber.service.js.map +1 -1
- package/dist/services/role-metadata.service.js.map +1 -1
- package/dist/services/scheduled-jobs/scheduler.service.js.map +1 -1
- package/dist/services/settings/default-settings-provider.service.d.ts +58 -8
- package/dist/services/settings/default-settings-provider.service.d.ts.map +1 -1
- package/dist/services/settings/default-settings-provider.service.js +21 -4
- package/dist/services/settings/default-settings-provider.service.js.map +1 -1
- package/dist/services/sms/TwilioSMSService.js.map +1 -1
- package/dist/services/solid-introspect.service.js.map +1 -1
- package/dist/services/user-activity-history.service.js.map +1 -1
- package/dist/services/view-metadata.service.d.ts.map +1 -1
- package/dist/services/view-metadata.service.js +17 -2
- package/dist/services/view-metadata.service.js.map +1 -1
- package/dist/solid-core.module.d.ts +1 -0
- package/dist/solid-core.module.d.ts.map +1 -1
- package/dist/solid-core.module.js +1 -0
- package/dist/solid-core.module.js.map +1 -1
- package/dist/subscribers/computed-entity-field.subscriber.js.map +1 -1
- package/dist/subscribers/security-rule.subscriber.d.ts.map +1 -1
- package/dist/subscribers/security-rule.subscriber.js.map +1 -1
- package/dist/subscribers/view-metadata.subscriber.js.map +1 -1
- package/dist/testing/core/testing-engine.js.map +1 -1
- package/dist/testing/reporter/console-reporter.d.ts +10 -0
- package/dist/testing/reporter/console-reporter.d.ts.map +1 -1
- package/dist/testing/reporter/console-reporter.js +21 -0
- package/dist/testing/reporter/console-reporter.js.map +1 -1
- package/dist/testing/reporter/reporter.types.d.ts +7 -0
- package/dist/testing/reporter/reporter.types.d.ts.map +1 -1
- package/dist/testing/reporter/reporter.types.js.map +1 -1
- package/dist/testing/reporter/webhook-reporter.d.ts +54 -0
- package/dist/testing/reporter/webhook-reporter.d.ts.map +1 -0
- package/dist/testing/reporter/webhook-reporter.js +74 -0
- package/dist/testing/reporter/webhook-reporter.js.map +1 -0
- package/dist/testing/runner/run-from-metadata.d.ts.map +1 -1
- package/dist/testing/runner/run-from-metadata.js +20 -1
- package/dist/testing/runner/run-from-metadata.js.map +1 -1
- package/package.json +5 -1
- package/src/commands/run-tests.command.ts +45 -17
- package/src/controllers/action-metadata.controller.ts +1 -1
- package/src/controllers/facebook-authentication.controller.ts +1 -1
- package/src/controllers/google-authentication.controller.ts +1 -1
- package/src/controllers/menu-item-metadata.controller.ts +1 -1
- package/src/controllers/microsoft-authentication.controller.ts +1 -1
- package/src/controllers/mq-message-queue.controller.ts +1 -1
- package/src/controllers/mq-message.controller.ts +1 -1
- package/src/controllers/user.controller.ts +16 -16
- package/src/controllers/view-metadata.controller.ts +1 -1
- package/src/dtos/update-user.dto.ts +4 -0
- package/src/entities/chatter-message-details.entity.ts +1 -2
- package/src/entities/user.entity.ts +1 -1
- package/src/helpers/bootstrap.helper.ts +3 -0
- package/src/helpers/field-crud-managers/BigIntFieldCrudManager.ts +1 -1
- package/src/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.ts +1 -1
- package/src/helpers/module-metadata-helper.service.ts +1 -1
- package/src/jobs/database/chatter-queue-subscriber-database.service.ts +4 -2
- package/src/jobs/database/trigger-mcp-client-subscriber-database.service.ts +1 -1
- package/src/jobs/rabbitmq/chatter-queue-subscriber.service.ts +4 -2
- package/src/jobs/redis/chatter-queue-subscriber-redis.service.ts +10 -3
- package/src/repository/security-rule.repository.ts +1 -1
- package/src/seeders/module-metadata-seeder.service.ts +4 -4
- package/src/seeders/module-test-data.service.ts +107 -15
- package/src/seeders/permission-metadata-seeder.service.ts +1 -1
- package/src/seeders/seed-data/solid-core-metadata.json +34 -2
- package/src/services/authentication.service.ts +19 -31
- package/src/services/chatter-message.service.ts +28 -38
- package/src/services/crud.service.ts +3 -3
- package/src/services/csv.service.ts +1 -1
- package/src/services/dashboard.service.ts +1 -1
- package/src/services/database/database-bootstrap.service.ts +1 -1
- package/src/services/excel.service.ts +1 -1
- package/src/services/export-transaction.service.ts +2 -2
- package/src/services/field-metadata.service.ts +3 -3
- package/src/services/fixtures.service.ts +2 -2
- package/src/services/import-transaction.service.ts +2 -2
- package/src/services/list-of-values.service.ts +1 -1
- package/src/services/model-metadata.service.ts +22 -21
- package/src/services/module-metadata.service.ts +7 -7
- package/src/services/queues/database-publisher.service.ts +4 -4
- package/src/services/queues/database-subscriber.service.ts +7 -7
- package/src/services/queues/rabbitmq-publisher.service.ts +7 -7
- package/src/services/queues/rabbitmq-subscriber.service.ts +13 -13
- package/src/services/queues/redis-publisher.service.ts +7 -4
- package/src/services/queues/redis-subscriber.service.ts +9 -6
- package/src/services/role-metadata.service.ts +1 -1
- package/src/services/scheduled-jobs/scheduler.service.ts +5 -5
- package/src/services/settings/default-settings-provider.service.ts +21 -4
- package/src/services/sms/TwilioSMSService.ts +2 -2
- package/src/services/solid-introspect.service.ts +2 -2
- package/src/services/user-activity-history.service.ts +1 -1
- package/src/services/view-metadata.service.ts +25 -8
- package/src/solid-core.module.ts +1 -0
- package/src/subscribers/computed-entity-field.subscriber.ts +1 -1
- package/src/subscribers/security-rule.subscriber.ts +8 -8
- package/src/subscribers/view-metadata.subscriber.ts +1 -1
- package/src/testing/core/testing-engine.ts +2 -2
- package/src/testing/reporter/console-reporter.ts +27 -0
- package/src/testing/reporter/reporter.types.ts +7 -0
- package/src/testing/reporter/webhook-reporter.ts +116 -0
- package/src/testing/runner/run-from-metadata.ts +19 -1
|
@@ -43,7 +43,7 @@ export class ViewMetadataSubsciber implements EntitySubscriberInterface<ViewMeta
|
|
|
43
43
|
const filePath = await this.moduleMetadataHelperService.getModuleMetadataFilePath(viewMetadata.model.module.name);
|
|
44
44
|
try {
|
|
45
45
|
await fs.access(filePath);
|
|
46
|
-
} catch (error) {
|
|
46
|
+
} catch (error: any) {
|
|
47
47
|
this.logger.error(`File not found at path: ${filePath}`);
|
|
48
48
|
return;
|
|
49
49
|
}
|
|
@@ -57,7 +57,7 @@ export class TestingEngine {
|
|
|
57
57
|
} else {
|
|
58
58
|
await execute();
|
|
59
59
|
}
|
|
60
|
-
} catch (err) {
|
|
60
|
+
} catch (err: any) {
|
|
61
61
|
scenarioError = err;
|
|
62
62
|
} finally {
|
|
63
63
|
const durationMs = Date.now() - scenarioStart;
|
|
@@ -108,7 +108,7 @@ export class TestingEngine {
|
|
|
108
108
|
// console.log(`Step ${resolvedStep.name} attempting to saveAs ${resolvedStep.saveAs}`, JSON.stringify(result));
|
|
109
109
|
ctx.resources.set(resolvedStep.saveAs, result);
|
|
110
110
|
}
|
|
111
|
-
} catch (err) {
|
|
111
|
+
} catch (err: any) {
|
|
112
112
|
stepError = err;
|
|
113
113
|
throw err;
|
|
114
114
|
} finally {
|
|
@@ -146,6 +146,10 @@ function formatStepLabel(step: OpStep): string {
|
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
export class ConsoleReporter implements Reporter {
|
|
149
|
+
private totalScenarios = 0;
|
|
150
|
+
private passedScenarios = 0;
|
|
151
|
+
private failedScenarios = 0;
|
|
152
|
+
|
|
149
153
|
onScenarioStart(scenario: { id: string; name?: string }): void {
|
|
150
154
|
const label = scenario.name ? `${scenario.id} (${scenario.name})` : scenario.id;
|
|
151
155
|
console.log(`\n▶ Scenario: ${label}`);
|
|
@@ -157,6 +161,12 @@ export class ConsoleReporter implements Reporter {
|
|
|
157
161
|
): void {
|
|
158
162
|
const label = scenario.name ? `${scenario.id} (${scenario.name})` : scenario.id;
|
|
159
163
|
const status = result.ok ? "✔" : "✖";
|
|
164
|
+
this.totalScenarios += 1;
|
|
165
|
+
if (result.ok) {
|
|
166
|
+
this.passedScenarios += 1;
|
|
167
|
+
} else {
|
|
168
|
+
this.failedScenarios += 1;
|
|
169
|
+
}
|
|
160
170
|
console.log(`${status} Scenario: ${label} (${result.durationMs}ms)`);
|
|
161
171
|
}
|
|
162
172
|
|
|
@@ -226,4 +236,21 @@ export class ConsoleReporter implements Reporter {
|
|
|
226
236
|
if (!dataText.length) return;
|
|
227
237
|
console.log(indentLines(dataText, `${STEP_INDENT}${INDENT}${INDENT}`));
|
|
228
238
|
}
|
|
239
|
+
|
|
240
|
+
onRunEnd(args: {
|
|
241
|
+
ok: boolean;
|
|
242
|
+
total: number;
|
|
243
|
+
passed: number;
|
|
244
|
+
failed: number;
|
|
245
|
+
durationMs: number;
|
|
246
|
+
}): void {
|
|
247
|
+
const durationSeconds = (args.durationMs / 1000).toFixed(2);
|
|
248
|
+
const finalStatus = args.ok ? "PASSED" : "FAILED";
|
|
249
|
+
|
|
250
|
+
console.log("\n════════ Test Run Summary ════════");
|
|
251
|
+
console.log(`Result: Test run ${finalStatus}`);
|
|
252
|
+
console.log(`Cases: total=${args.total}, passed=${args.passed}, failed=${args.failed}`);
|
|
253
|
+
console.log(`Duration: ${durationSeconds}s`);
|
|
254
|
+
console.log("══════════════════════════════════");
|
|
255
|
+
}
|
|
229
256
|
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { ConsoleReporter } from "./console-reporter";
|
|
2
|
+
import type { OpStep, ScenarioSpec } from "../contracts/testing-metadata.types";
|
|
3
|
+
import type { StepPhase } from "../contracts/runtime-context.types";
|
|
4
|
+
|
|
5
|
+
interface TestStepResult {
|
|
6
|
+
phase: string;
|
|
7
|
+
operation: string;
|
|
8
|
+
name?: string;
|
|
9
|
+
ok: boolean;
|
|
10
|
+
durationMs: number;
|
|
11
|
+
error?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface TestScenarioResult {
|
|
15
|
+
id: string;
|
|
16
|
+
name?: string;
|
|
17
|
+
ok: boolean;
|
|
18
|
+
durationMs: number;
|
|
19
|
+
error?: string;
|
|
20
|
+
steps: TestStepResult[];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface TestRunPayload {
|
|
24
|
+
runName: string;
|
|
25
|
+
startedAt: string;
|
|
26
|
+
completedAt: string;
|
|
27
|
+
durationMs: number;
|
|
28
|
+
exitCode: number;
|
|
29
|
+
total: number;
|
|
30
|
+
passed: number;
|
|
31
|
+
failed: number;
|
|
32
|
+
scenarios: TestScenarioResult[];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function formatError(err: unknown): string {
|
|
36
|
+
if (!err) return "";
|
|
37
|
+
if (err instanceof Error) return err.stack || err.message;
|
|
38
|
+
return String(err);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export class WebhookReporter extends ConsoleReporter {
|
|
42
|
+
private readonly startedAt = new Date();
|
|
43
|
+
private readonly accumulated: TestScenarioResult[] = [];
|
|
44
|
+
private currentSteps: TestStepResult[] = [];
|
|
45
|
+
|
|
46
|
+
constructor(
|
|
47
|
+
private readonly webhookUrl: string,
|
|
48
|
+
private readonly runName: string,
|
|
49
|
+
) {
|
|
50
|
+
super();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
override onStepEnd(args: {
|
|
54
|
+
scenarioId: string;
|
|
55
|
+
phase: StepPhase;
|
|
56
|
+
step: OpStep;
|
|
57
|
+
ok: boolean;
|
|
58
|
+
error?: unknown;
|
|
59
|
+
durationMs: number;
|
|
60
|
+
}): void {
|
|
61
|
+
super.onStepEnd(args);
|
|
62
|
+
this.currentSteps.push({
|
|
63
|
+
phase: String(args.phase),
|
|
64
|
+
operation: args.step.op,
|
|
65
|
+
name: args.step.name,
|
|
66
|
+
ok: args.ok,
|
|
67
|
+
durationMs: args.durationMs,
|
|
68
|
+
error: args.error ? formatError(args.error) : undefined,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
override onScenarioEnd(
|
|
73
|
+
scenario: ScenarioSpec,
|
|
74
|
+
result: { ok: boolean; error?: unknown; durationMs: number },
|
|
75
|
+
): void {
|
|
76
|
+
super.onScenarioEnd(scenario, result);
|
|
77
|
+
this.accumulated.push({
|
|
78
|
+
id: scenario.id,
|
|
79
|
+
name: scenario.name,
|
|
80
|
+
ok: result.ok,
|
|
81
|
+
durationMs: result.durationMs,
|
|
82
|
+
error: result.error ? formatError(result.error) : undefined,
|
|
83
|
+
steps: [...this.currentSteps],
|
|
84
|
+
});
|
|
85
|
+
this.currentSteps = [];
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async flush(exitCode: number): Promise<void> {
|
|
89
|
+
const completedAt = new Date();
|
|
90
|
+
const payload: TestRunPayload = {
|
|
91
|
+
runName: this.runName,
|
|
92
|
+
startedAt: this.startedAt.toISOString(),
|
|
93
|
+
completedAt: completedAt.toISOString(),
|
|
94
|
+
durationMs: completedAt.getTime() - this.startedAt.getTime(),
|
|
95
|
+
exitCode,
|
|
96
|
+
total: this.accumulated.length,
|
|
97
|
+
passed: this.accumulated.filter((s) => s.ok).length,
|
|
98
|
+
failed: this.accumulated.filter((s) => !s.ok).length,
|
|
99
|
+
scenarios: this.accumulated,
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
const response = await fetch(this.webhookUrl, {
|
|
104
|
+
method: "POST",
|
|
105
|
+
headers: { "Content-Type": "application/json" },
|
|
106
|
+
body: JSON.stringify(payload),
|
|
107
|
+
signal: AbortSignal.timeout(10_000),
|
|
108
|
+
});
|
|
109
|
+
if (!response.ok) {
|
|
110
|
+
console.warn(`[WebhookReporter] Webhook returned ${response.status}`);
|
|
111
|
+
}
|
|
112
|
+
} catch (err: any) {
|
|
113
|
+
console.warn(`[WebhookReporter] Failed to deliver test results: ${err}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -44,6 +44,7 @@ export type RunnerOptions = {
|
|
|
44
44
|
};
|
|
45
45
|
|
|
46
46
|
export async function runFromMetadata(opts: RunnerOptions): Promise<void> {
|
|
47
|
+
const startedAt = Date.now();
|
|
47
48
|
const registry = new StepRegistry();
|
|
48
49
|
registerApiSteps(registry);
|
|
49
50
|
registerUiSteps(registry);
|
|
@@ -71,15 +72,32 @@ export async function runFromMetadata(opts: RunnerOptions): Promise<void> {
|
|
|
71
72
|
const ui = new PlaywrightAdapter(opts.ui);
|
|
72
73
|
const ctxBase = { resources, reporter, api, ui, specRegistry, testData, options: opts.options };
|
|
73
74
|
const uiStarted = { value: false };
|
|
75
|
+
let passed = 0;
|
|
76
|
+
let failed = 0;
|
|
77
|
+
let runError: unknown;
|
|
74
78
|
|
|
75
79
|
try {
|
|
76
80
|
for (const scenario of scenarios) {
|
|
77
81
|
if (scenarioNeedsUi(scenario)) {
|
|
78
82
|
await ensureUiStarted(ctxBase, uiStarted);
|
|
79
83
|
}
|
|
80
|
-
|
|
84
|
+
try {
|
|
85
|
+
await engine.runScenario(scenario, ctxBase);
|
|
86
|
+
passed += 1;
|
|
87
|
+
} catch (error) {
|
|
88
|
+
failed += 1;
|
|
89
|
+
runError = error;
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
81
92
|
}
|
|
82
93
|
} finally {
|
|
94
|
+
reporter.onRunEnd?.({
|
|
95
|
+
ok: !runError,
|
|
96
|
+
total: scenarios.length,
|
|
97
|
+
passed,
|
|
98
|
+
failed,
|
|
99
|
+
durationMs: Date.now() - startedAt,
|
|
100
|
+
});
|
|
83
101
|
if (uiStarted.value) {
|
|
84
102
|
await ui.stop();
|
|
85
103
|
}
|