@scenetest/dashboard 0.11.0 → 0.12.0
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/README.md +87 -35
- package/dist/app.d.ts +10 -7
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +12 -130
- package/dist/app.js.map +1 -1
- package/dist/collections/index.d.ts +19 -0
- package/dist/collections/index.d.ts.map +1 -0
- package/dist/collections/index.js +18 -0
- package/dist/collections/index.js.map +1 -0
- package/dist/collections/options.d.ts +29 -0
- package/dist/collections/options.d.ts.map +1 -0
- package/dist/collections/options.js +68 -0
- package/dist/collections/options.js.map +1 -0
- package/dist/collections/projections.d.ts +117 -0
- package/dist/collections/projections.d.ts.map +1 -0
- package/dist/collections/projections.js +228 -0
- package/dist/collections/projections.js.map +1 -0
- package/dist/collections/source.d.ts +32 -0
- package/dist/collections/source.d.ts.map +1 -0
- package/dist/collections/source.js +84 -0
- package/dist/collections/source.js.map +1 -0
- package/dist/collections/types.d.ts +87 -0
- package/dist/collections/types.d.ts.map +1 -0
- package/dist/collections/types.js +2 -0
- package/dist/collections/types.js.map +1 -0
- package/dist/dashboard.d.ts +20 -0
- package/dist/dashboard.d.ts.map +1 -0
- package/dist/dashboard.js +114 -0
- package/dist/dashboard.js.map +1 -0
- package/dist/dev-transport.d.ts +3 -3
- package/dist/dev-transport.d.ts.map +1 -1
- package/dist/dev-transport.js +3 -7
- package/dist/dev-transport.js.map +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/runner.d.ts +8 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +249 -0
- package/dist/runner.js.map +1 -0
- package/dist/select-helpers.d.ts +50 -0
- package/dist/select-helpers.d.ts.map +1 -0
- package/dist/select-helpers.js +48 -0
- package/dist/select-helpers.js.map +1 -0
- package/dist/select-runner.d.ts +55 -0
- package/dist/select-runner.d.ts.map +1 -0
- package/dist/select-runner.js +108 -0
- package/dist/select-runner.js.map +1 -0
- package/dist/select-waterfall.d.ts +12 -0
- package/dist/select-waterfall.d.ts.map +1 -0
- package/dist/select-waterfall.js +79 -0
- package/dist/select-waterfall.js.map +1 -0
- package/dist/style.css +878 -0
- package/dist/types.d.ts +6 -20
- package/dist/types.d.ts.map +1 -1
- package/dist/use-live-query.d.ts +28 -0
- package/dist/use-live-query.d.ts.map +1 -0
- package/dist/use-live-query.js +25 -0
- package/dist/use-live-query.js.map +1 -0
- package/dist/use-run-slice.d.ts +25 -0
- package/dist/use-run-slice.d.ts.map +1 -0
- package/dist/use-run-slice.js +48 -0
- package/dist/use-run-slice.js.map +1 -0
- package/package.json +10 -5
- package/dist/mount.d.ts +0 -14
- package/dist/mount.d.ts.map +0 -1
- package/dist/mount.js +0 -50
- package/dist/mount.js.map +0 -1
- package/dist/store.d.ts +0 -19
- package/dist/store.d.ts.map +0 -1
- package/dist/store.js +0 -164
- package/dist/store.js.map +0 -1
- package/dist/styles.d.ts +0 -10
- package/dist/styles.d.ts.map +0 -1
- package/dist/styles.js +0 -152
- package/dist/styles.js.map +0 -1
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { attributeToScene } from './collections/projections.js';
|
|
2
|
+
/**
|
|
3
|
+
* The latest run's id — the newest `run:start` (max `startTime`). Falls back to
|
|
4
|
+
* the most-recent scene's `runId` only when no run row exists yet (a window that
|
|
5
|
+
* doesn't occur in practice, since `run:start` precedes the first scene).
|
|
6
|
+
*/
|
|
7
|
+
export function latestRunId(runs, scenes = []) {
|
|
8
|
+
const run = runs.reduce((m, r) => (!m || r.startTime > m.startTime ? r : m), undefined);
|
|
9
|
+
if (run)
|
|
10
|
+
return run.id;
|
|
11
|
+
if (scenes.length === 0)
|
|
12
|
+
return undefined;
|
|
13
|
+
return scenes.reduce((m, s) => (s.startTime > m.startTime ? s : m)).runId;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Bucket assertion/action rows by the scene they attribute to, in **one pass**
|
|
17
|
+
* over the rows. Both selectors then read each scene's rows by id instead of
|
|
18
|
+
* re-filtering the whole list per scene through `attributeToScene` (which itself
|
|
19
|
+
* scans the scenes) — turning the O(scenes² × rows) per-scene filter into one
|
|
20
|
+
* O(rows × scenes) pass. Rows that attribute to no scene are dropped.
|
|
21
|
+
*/
|
|
22
|
+
export function groupByScene(rows, scenes) {
|
|
23
|
+
const byScene = new Map();
|
|
24
|
+
for (const row of rows) {
|
|
25
|
+
const id = attributeToScene(row, scenes);
|
|
26
|
+
if (id === null)
|
|
27
|
+
continue;
|
|
28
|
+
const bucket = byScene.get(id);
|
|
29
|
+
if (bucket)
|
|
30
|
+
bucket.push(row);
|
|
31
|
+
else
|
|
32
|
+
byScene.set(id, [row]);
|
|
33
|
+
}
|
|
34
|
+
return byScene;
|
|
35
|
+
}
|
|
36
|
+
export function latestRunSlice(scenes, assertions, actions, runs) {
|
|
37
|
+
const byStart = [...scenes].sort((a, b) => a.startTime - b.startTime);
|
|
38
|
+
const runId = latestRunId(runs, scenes);
|
|
39
|
+
const run = runs.find((r) => r.id === runId);
|
|
40
|
+
return {
|
|
41
|
+
runId,
|
|
42
|
+
run,
|
|
43
|
+
scenes: runId ? byStart.filter((s) => s.runId === runId) : byStart,
|
|
44
|
+
assertions: runId ? assertions.filter((a) => a.runId === runId) : assertions,
|
|
45
|
+
actions: runId ? actions.filter((a) => a.runId === runId) : actions,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=select-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-helpers.js","sourceRoot":"","sources":["../src/select-helpers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AAgC/D;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,IAAc,EAAE,SAAqB,EAAE;IACjE,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAqB,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAA;IAC3G,IAAI,GAAG;QAAE,OAAO,GAAG,CAAC,EAAE,CAAA;IACtB,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAA;IACzC,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;AAC3E,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAC1B,IAAS,EACT,MAAkB;IAElB,MAAM,OAAO,GAAG,IAAI,GAAG,EAAe,CAAA;IACtC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,EAAE,GAAG,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;QACxC,IAAI,EAAE,KAAK,IAAI;YAAE,SAAQ;QACzB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QAC9B,IAAI,MAAM;YAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;;YACvB,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;IAC7B,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,MAAkB,EAClB,UAA6B,EAC7B,OAAuB,EACvB,IAAc;IAEd,MAAM,OAAO,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,CAAA;IACrE,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;IACvC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,CAAA;IAC5C,OAAO;QACL,KAAK;QACL,GAAG;QACH,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO;QAClE,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU;QAC5E,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO;KACpE,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { TeamMeta } from '@scenetest/protocol';
|
|
2
|
+
import { type RunSlice } from './select-helpers.js';
|
|
3
|
+
/**
|
|
4
|
+
* The Runner view's read model — pure selectors over the latest-run `RunSlice`.
|
|
5
|
+
* `selectSnapshot` is the live path; `mapReportToSnapshot` adapts past-run CLI
|
|
6
|
+
* JSON reports into the same shape so live and past runs render identically.
|
|
7
|
+
*/
|
|
8
|
+
export interface RunnerAssertion {
|
|
9
|
+
result: boolean;
|
|
10
|
+
description: string;
|
|
11
|
+
actor: string | null;
|
|
12
|
+
timestamp: number;
|
|
13
|
+
}
|
|
14
|
+
export interface RunnerTimelineEntry {
|
|
15
|
+
actor: string;
|
|
16
|
+
action: string;
|
|
17
|
+
target?: string;
|
|
18
|
+
duration: number | null;
|
|
19
|
+
error: string | null;
|
|
20
|
+
}
|
|
21
|
+
/** One scene with its attributed assertions + timeline — the unit the view renders. */
|
|
22
|
+
export interface RunnerScene {
|
|
23
|
+
id: string;
|
|
24
|
+
name: string;
|
|
25
|
+
file: string;
|
|
26
|
+
line?: number;
|
|
27
|
+
status: string;
|
|
28
|
+
duration: number | null;
|
|
29
|
+
error: string | null;
|
|
30
|
+
team: TeamMeta;
|
|
31
|
+
teamIndex: number;
|
|
32
|
+
actors: string[];
|
|
33
|
+
assertions: RunnerAssertion[];
|
|
34
|
+
timeline: RunnerTimelineEntry[];
|
|
35
|
+
}
|
|
36
|
+
export interface RunnerSummary {
|
|
37
|
+
scenes: number;
|
|
38
|
+
completed: number;
|
|
39
|
+
failed: number;
|
|
40
|
+
assertions: {
|
|
41
|
+
total: number;
|
|
42
|
+
passed: number;
|
|
43
|
+
failed: number;
|
|
44
|
+
};
|
|
45
|
+
warnings: number;
|
|
46
|
+
}
|
|
47
|
+
export interface RunnerSnapshot {
|
|
48
|
+
scenes: RunnerScene[];
|
|
49
|
+
summary: RunnerSummary;
|
|
50
|
+
}
|
|
51
|
+
export declare const EMPTY_SNAPSHOT: RunnerSnapshot;
|
|
52
|
+
/** Build the live snapshot from the latest-run slice: attribute assertions/actions to scenes and roll up the summary. */
|
|
53
|
+
export declare function selectSnapshot(slice: RunSlice): RunnerSnapshot;
|
|
54
|
+
export declare function mapReportToSnapshot(report: unknown): RunnerSnapshot;
|
|
55
|
+
//# sourceMappingURL=select-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-runner.d.ts","sourceRoot":"","sources":["../src/select-runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAgB,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAEjE;;;;GAIG;AAEH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,OAAO,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CACrB;AAED,uFAAuF;AACvF,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,IAAI,EAAE,QAAQ,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,UAAU,EAAE,eAAe,EAAE,CAAA;IAC7B,QAAQ,EAAE,mBAAmB,EAAE,CAAA;CAChC;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;IAC7D,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,WAAW,EAAE,CAAA;IACrB,OAAO,EAAE,aAAa,CAAA;CACvB;AAED,eAAO,MAAM,cAAc,EAAE,cAG5B,CAAA;AAUD,yHAAyH;AACzH,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,GAAG,cAAc,CA8C9D;AAcD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,GAAG,cAAc,CA+CnE"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { groupByScene } from './select-helpers.js';
|
|
2
|
+
export const EMPTY_SNAPSHOT = {
|
|
3
|
+
scenes: [],
|
|
4
|
+
summary: { scenes: 0, completed: 0, failed: 0, assertions: { total: 0, passed: 0, failed: 0 }, warnings: 0 },
|
|
5
|
+
};
|
|
6
|
+
function isCompleted(status) {
|
|
7
|
+
return status === 'completed';
|
|
8
|
+
}
|
|
9
|
+
function isFailure(status) {
|
|
10
|
+
return status !== 'completed' && status !== 'running';
|
|
11
|
+
}
|
|
12
|
+
/** Build the live snapshot from the latest-run slice: attribute assertions/actions to scenes and roll up the summary. */
|
|
13
|
+
export function selectSnapshot(slice) {
|
|
14
|
+
const { run: latestRun, scenes: runScenes, assertions: runAssertions, actions: runActions } = slice;
|
|
15
|
+
const assertionsByScene = groupByScene(runAssertions, runScenes);
|
|
16
|
+
const actionsByScene = groupByScene(runActions, runScenes);
|
|
17
|
+
const view = runScenes.map((s) => ({
|
|
18
|
+
id: s.id,
|
|
19
|
+
name: s.name,
|
|
20
|
+
file: s.file,
|
|
21
|
+
status: s.status,
|
|
22
|
+
duration: s.duration,
|
|
23
|
+
error: s.error,
|
|
24
|
+
team: s.team,
|
|
25
|
+
teamIndex: s.teamIndex,
|
|
26
|
+
actors: s.actors,
|
|
27
|
+
assertions: (assertionsByScene.get(s.id) ?? []).map((a) => ({
|
|
28
|
+
result: a.result,
|
|
29
|
+
description: a.description,
|
|
30
|
+
actor: a.actor,
|
|
31
|
+
timestamp: a.timestamp,
|
|
32
|
+
})),
|
|
33
|
+
timeline: (actionsByScene.get(s.id) ?? [])
|
|
34
|
+
.slice()
|
|
35
|
+
.sort((a, b) => a.startTime - b.startTime)
|
|
36
|
+
.map((ac) => ({
|
|
37
|
+
actor: ac.actor,
|
|
38
|
+
action: ac.status === 'running' ? ac.action + ' (in flight)' : ac.action,
|
|
39
|
+
target: ac.target ?? undefined,
|
|
40
|
+
duration: ac.duration,
|
|
41
|
+
error: ac.error,
|
|
42
|
+
})),
|
|
43
|
+
}));
|
|
44
|
+
const summary = {
|
|
45
|
+
scenes: Math.max(latestRun?.sceneCount ?? 0, view.length),
|
|
46
|
+
completed: latestRun?.completed ?? view.filter((s) => isCompleted(s.status)).length,
|
|
47
|
+
failed: latestRun?.failed ?? view.filter((s) => isFailure(s.status)).length,
|
|
48
|
+
assertions: {
|
|
49
|
+
total: runAssertions.length,
|
|
50
|
+
passed: runAssertions.filter((a) => a.result).length,
|
|
51
|
+
failed: runAssertions.filter((a) => !a.result).length,
|
|
52
|
+
},
|
|
53
|
+
warnings: 0,
|
|
54
|
+
};
|
|
55
|
+
return { scenes: view, summary };
|
|
56
|
+
}
|
|
57
|
+
const isObj = (v) => typeof v === 'object' && v !== null;
|
|
58
|
+
const asStr = (v, d = '') => (typeof v === 'string' ? v : d);
|
|
59
|
+
const asNum = (v) => (typeof v === 'number' ? v : null);
|
|
60
|
+
export function mapReportToSnapshot(report) {
|
|
61
|
+
if (!isObj(report))
|
|
62
|
+
return EMPTY_SNAPSHOT;
|
|
63
|
+
const rawScenes = Array.isArray(report.scenes) ? report.scenes : [];
|
|
64
|
+
const scenes = rawScenes.filter(isObj).map((s, i) => {
|
|
65
|
+
const team = isObj(s.team) ? s.team : {};
|
|
66
|
+
const teamIndex = asNum(s.teamIndex) ?? 0;
|
|
67
|
+
return {
|
|
68
|
+
id: `${asStr(s.name, 'scene')}:${teamIndex}:${i}`,
|
|
69
|
+
name: asStr(s.name, '(unnamed)'),
|
|
70
|
+
file: asStr(s.file),
|
|
71
|
+
line: asNum(s.line) ?? undefined,
|
|
72
|
+
status: asStr(s.status, 'completed'),
|
|
73
|
+
duration: asNum(s.duration),
|
|
74
|
+
error: typeof s.error === 'string' ? s.error : null,
|
|
75
|
+
team,
|
|
76
|
+
teamIndex,
|
|
77
|
+
actors: Array.isArray(s.actors) ? s.actors.filter((a) => typeof a === 'string') : [],
|
|
78
|
+
assertions: (Array.isArray(s.assertions) ? s.assertions : []).filter(isObj).map((a) => ({
|
|
79
|
+
result: a.result === true,
|
|
80
|
+
description: asStr(a.description),
|
|
81
|
+
actor: typeof a.actor === 'string' ? a.actor : null,
|
|
82
|
+
timestamp: asNum(a.timestamp) ?? 0,
|
|
83
|
+
})),
|
|
84
|
+
timeline: (Array.isArray(s.timeline) ? s.timeline : []).filter(isObj).map((t) => ({
|
|
85
|
+
actor: asStr(t.actor),
|
|
86
|
+
action: asStr(t.action),
|
|
87
|
+
target: typeof t.target === 'string' ? t.target : undefined,
|
|
88
|
+
duration: asNum(t.duration),
|
|
89
|
+
error: typeof t.error === 'string' ? t.error : null,
|
|
90
|
+
})),
|
|
91
|
+
};
|
|
92
|
+
});
|
|
93
|
+
const rs = isObj(report.summary) ? report.summary : {};
|
|
94
|
+
const ra = isObj(rs.assertions) ? rs.assertions : {};
|
|
95
|
+
const summary = {
|
|
96
|
+
scenes: asNum(rs.scenes) ?? scenes.length,
|
|
97
|
+
completed: asNum(rs.completed) ?? scenes.filter((s) => isCompleted(s.status)).length,
|
|
98
|
+
failed: asNum(rs.failed) ?? scenes.filter((s) => isFailure(s.status)).length,
|
|
99
|
+
assertions: {
|
|
100
|
+
total: asNum(ra.total) ?? 0,
|
|
101
|
+
passed: asNum(ra.passed) ?? 0,
|
|
102
|
+
failed: asNum(ra.failed) ?? 0,
|
|
103
|
+
},
|
|
104
|
+
warnings: asNum(rs.warnings) ?? 0,
|
|
105
|
+
};
|
|
106
|
+
return { scenes, summary };
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=select-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-runner.js","sourceRoot":"","sources":["../src/select-runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { DashboardState } from './types.js';
|
|
2
|
+
import { type RunSlice } from './select-helpers.js';
|
|
3
|
+
/**
|
|
4
|
+
* Project the latest-run slice into the Waterfall's shape: actions become
|
|
5
|
+
* per-actor lanes, assertions are attributed to their scene, and the run rollup
|
|
6
|
+
* drives the counts. Returns the view data only — `connection` is the host's to
|
|
7
|
+
* supply (`WaterfallHost` spreads it in), since a pure projection can't know it.
|
|
8
|
+
*/
|
|
9
|
+
export declare function selectWaterfall(slice: RunSlice): Omit<DashboardState, 'connection'>;
|
|
10
|
+
/** Number of scenes that have finished (not currently running). */
|
|
11
|
+
export declare function completedSceneCount(state: DashboardState): number;
|
|
12
|
+
//# sourceMappingURL=select-waterfall.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-waterfall.d.ts","sourceRoot":"","sources":["../src/select-waterfall.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAc,cAAc,EAAe,MAAM,YAAY,CAAA;AACzE,OAAO,EAAgB,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAQjE;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,CA+DnF;AAED,mEAAmE;AACnE,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAEjE"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { groupByScene } from './select-helpers.js';
|
|
2
|
+
function laneStatus(a) {
|
|
3
|
+
if (a.status === 'running')
|
|
4
|
+
return 'running';
|
|
5
|
+
if (a.status === 'error')
|
|
6
|
+
return 'error';
|
|
7
|
+
return a.duration != null && a.duration > 500 ? 'slow' : 'success';
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Project the latest-run slice into the Waterfall's shape: actions become
|
|
11
|
+
* per-actor lanes, assertions are attributed to their scene, and the run rollup
|
|
12
|
+
* drives the counts. Returns the view data only — `connection` is the host's to
|
|
13
|
+
* supply (`WaterfallHost` spreads it in), since a pure projection can't know it.
|
|
14
|
+
*/
|
|
15
|
+
export function selectWaterfall(slice) {
|
|
16
|
+
const actionsByScene = groupByScene(slice.actions, slice.scenes);
|
|
17
|
+
const assertionsByScene = groupByScene(slice.assertions, slice.scenes);
|
|
18
|
+
const viewScenes = slice.scenes.map((s) => {
|
|
19
|
+
const lanes = s.actors.map((actor) => ({ actor, items: [] }));
|
|
20
|
+
const laneFor = (actor) => {
|
|
21
|
+
let lane = lanes.find((l) => l.actor === actor);
|
|
22
|
+
if (!lane) {
|
|
23
|
+
lane = { actor, items: [] };
|
|
24
|
+
lanes.push(lane);
|
|
25
|
+
}
|
|
26
|
+
return lane;
|
|
27
|
+
};
|
|
28
|
+
for (const a of (actionsByScene.get(s.id) ?? []).slice().sort((x, y) => x.startTime - y.startTime)) {
|
|
29
|
+
laneFor(a.actor).items.push({
|
|
30
|
+
action: a.action,
|
|
31
|
+
target: a.target ?? undefined,
|
|
32
|
+
startTime: a.startTime,
|
|
33
|
+
endTime: a.endTime,
|
|
34
|
+
duration: a.duration,
|
|
35
|
+
error: a.error,
|
|
36
|
+
status: laneStatus(a),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
name: s.name,
|
|
41
|
+
file: s.file,
|
|
42
|
+
actors: s.actors.slice(),
|
|
43
|
+
lanes,
|
|
44
|
+
assertions: (assertionsByScene.get(s.id) ?? []).map((a) => ({
|
|
45
|
+
actor: a.actor ?? undefined,
|
|
46
|
+
description: a.description,
|
|
47
|
+
result: a.result,
|
|
48
|
+
timestamp: a.timestamp,
|
|
49
|
+
})),
|
|
50
|
+
startTime: s.startTime,
|
|
51
|
+
endTime: s.endTime,
|
|
52
|
+
status: s.status,
|
|
53
|
+
duration: s.duration ?? undefined,
|
|
54
|
+
error: s.error ?? undefined,
|
|
55
|
+
team: s.team,
|
|
56
|
+
teamIndex: s.teamIndex,
|
|
57
|
+
};
|
|
58
|
+
});
|
|
59
|
+
const teams = [...new Set(slice.scenes.map((s) => s.team?.name).filter((n) => !!n))];
|
|
60
|
+
const completed = slice.run?.completed ?? viewScenes.filter((s) => s.status === 'completed').length;
|
|
61
|
+
const failed = slice.run?.failed ?? viewScenes.filter((s) => s.status !== 'completed' && s.status !== 'running').length;
|
|
62
|
+
const running = slice.run ? slice.run.status === 'running' : viewScenes.some((s) => s.status === 'running');
|
|
63
|
+
return {
|
|
64
|
+
scenes: viewScenes,
|
|
65
|
+
currentSceneIndex: null,
|
|
66
|
+
runStartTime: slice.run?.startTime ?? slice.scenes[0]?.startTime ?? null,
|
|
67
|
+
passCount: completed,
|
|
68
|
+
failCount: failed,
|
|
69
|
+
sceneCount: Math.max(slice.run?.sceneCount ?? 0, viewScenes.length),
|
|
70
|
+
teams,
|
|
71
|
+
running,
|
|
72
|
+
endDurationMs: slice.run?.duration ?? null,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/** Number of scenes that have finished (not currently running). */
|
|
76
|
+
export function completedSceneCount(state) {
|
|
77
|
+
return state.scenes.filter((s) => s.status !== 'running').length;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=select-waterfall.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-waterfall.js","sourceRoot":"","sources":["../src/select-waterfall.ts"],"names":[],"mappings":"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"}
|