@unotest/viewer 0.24.0 → 0.26.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/CHANGELOG.md +178 -0
- package/dist/server/main.d.ts +16 -0
- package/dist/server/main.js +1 -1
- package/dist/server/session.js +1 -1
- package/dist/web/assets/{DslEditor-N4UwO68S.js → DslEditor-wifnRBrr.js} +2 -2
- package/dist/web/assets/index-BLJmmyy1.css +32 -0
- package/dist/web/assets/index-NnxVWV8z.js +55 -0
- package/dist/web/index.html +2 -2
- package/package.json +6 -5
- package/dist/web/assets/index-6gexjEOk.css +0 -32
- package/dist/web/assets/index-Dp8GG7NG.js +0 -55
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,183 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.26.0] - 2026-08-30
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 3eede7c: The viewer can now be hosted: it shows which test bundle an environment
|
|
8
|
+
is running, and lets you switch it.
|
|
9
|
+
|
|
10
|
+
This is the other half of `bundle push`. Nothing changes for a local
|
|
11
|
+
viewer — everything here appears only when something is hosting it.
|
|
12
|
+
|
|
13
|
+
- **The artifact root and the project root are now genuinely separate.**
|
|
14
|
+
The viewer already took `UNOTEST_ARTIFACTS_ROOT` for the run queue;
|
|
15
|
+
run discovery, the run index, snapshots, log capture and the viewer's
|
|
16
|
+
own lock file now honour it too. Locally the two are the same directory
|
|
17
|
+
and nothing moves. Where they differ — sources in a disposable copy of a
|
|
18
|
+
bundle, history in the environment beside it — the history is no longer
|
|
19
|
+
read out of (or written into) the sources.
|
|
20
|
+
- **Bundle badge in the status bar.** `main@1a2b3c4`, or `wip` for a
|
|
21
|
+
bundle packed from an uncommitted tree, with the author, the pinned
|
|
22
|
+
`@unotest/web` and who switched the environment last. Clicking it lists
|
|
23
|
+
the bundles pushed to this environment and switches to one — that runs
|
|
24
|
+
as a maintenance ticket on the host, so it waits for the environment to
|
|
25
|
+
be free instead of pulling the code out from under a running suite.
|
|
26
|
+
- **Runs remember their bundle.** `manifest.json` and `GET /api/runs`
|
|
27
|
+
carry `bundleId` (from `UNOTEST_BUNDLE_ID`, set by the host); the runs
|
|
28
|
+
list marks the ones that ran on another bundle, so "was this red run
|
|
29
|
+
even the code I am looking at?" has an answer.
|
|
30
|
+
- **The contract is a file, not a mode.** `@unotest/protocol` gains
|
|
31
|
+
`WorkspaceFile` — the host writes `unotest/.workspace.json` beside the
|
|
32
|
+
artifacts and the viewer reads it, the same way the guard's session
|
|
33
|
+
header narrows the UI. No file, no bundle UI; the viewer never learns
|
|
34
|
+
what a box is. Values of environment variables and secrets never appear
|
|
35
|
+
in it — only their names.
|
|
36
|
+
- **Queue tickets can name a bundle.** `QueueTicket.source.bundleId` is
|
|
37
|
+
recorded when a run is queued, so a run executes the code it was
|
|
38
|
+
ordered with even if the environment moved on while it waited.
|
|
39
|
+
|
|
40
|
+
- dbfa36f: Your CI can now ask a box to run the suite it just pushed, and a box can
|
|
41
|
+
report the result back to GitHub.
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
npx @unotest/web bundle push --run --env test --collection smoke
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`--run` sends the second half of the CI recipe: upload the bundle, then
|
|
48
|
+
order a run of it. Two requests rather than one flag on the upload,
|
|
49
|
+
because a bundle is _content_ — pushing an identical tree twice is normal
|
|
50
|
+
and answers `exists` — while "run it" is an event. The same split is what
|
|
51
|
+
lets a deploy script run a bundle somebody pushed hours ago.
|
|
52
|
+
|
|
53
|
+
- **The box answers as soon as the runs are queued** (202) with their run
|
|
54
|
+
ids. A suite takes minutes to hours; an HTTP request held open for that
|
|
55
|
+
long is a timeout in somebody's proxy, not a result. The ids are real
|
|
56
|
+
from the moment you get them, so a CI log can print a link into the
|
|
57
|
+
viewer straight away.
|
|
58
|
+
- **`--env <name>` is required with `--run`.** Which environments a box
|
|
59
|
+
has is the operator's decision, and guessing one would be guessing
|
|
60
|
+
which system gets tested.
|
|
61
|
+
- **Without `--collection`, the box runs what that environment normally
|
|
62
|
+
runs** — the collections its `schedules` name. Naming them explicitly is
|
|
63
|
+
the deploy-check case; leaving it out is the "same as every night" case.
|
|
64
|
+
- **`--pr <number>` coalesces.** A newer push of the same pull request
|
|
65
|
+
withdraws its older runs that are still _waiting_; a run that already
|
|
66
|
+
started is never killed. Three pushes in five minutes cost one suite.
|
|
67
|
+
`--json` reports how many were withdrawn, so "my run vanished" has an
|
|
68
|
+
answer in the log of the run that replaced it.
|
|
69
|
+
- **Refusals are typed and say what to do**: no such environment, an
|
|
70
|
+
environment belonging to another project, a bundle the box no longer
|
|
71
|
+
holds, nothing to run.
|
|
72
|
+
|
|
73
|
+
On a hosted viewer, the queue panel now names the change each machine
|
|
74
|
+
ticket belongs to (`PR #412@1a2b3c4`) instead of a row of identical "ci"
|
|
75
|
+
entries, and the history gained a **this bundle only** filter for the
|
|
76
|
+
moment you are judging the bundle in front of you rather than the last
|
|
77
|
+
month of runs.
|
|
78
|
+
|
|
79
|
+
Nothing changes for a local `npx @unotest/web viewer`: there are no
|
|
80
|
+
bundles there, so neither the badge nor the filter appears.
|
|
81
|
+
|
|
82
|
+
- c43aa00: Runs of one project now take turns instead of colliding.
|
|
83
|
+
|
|
84
|
+
Until now nothing coordinated them: the viewer refused a second run with
|
|
85
|
+
HTTP 409, and that was the whole defence — a `npx @unotest/web e2e` in a
|
|
86
|
+
terminal, an agent's `run_test` and a scheduled suite would all start on
|
|
87
|
+
top of each other, driving the same browser and the same seeded database
|
|
88
|
+
at the same time. The 409 protected the UI, not the machine.
|
|
89
|
+
|
|
90
|
+
- **A filesystem queue**, in `unotest/.queue<target>[.<env>]/` beside the
|
|
91
|
+
runs root it belongs to. A run writes a ticket, waits until it is at
|
|
92
|
+
the head, takes a slot, runs, and gives the slot back. There is no
|
|
93
|
+
daemon: whoever holds the slot executes the run itself, so nothing new
|
|
94
|
+
has to be installed, started or kept alive. Only `open("wx")`, rename,
|
|
95
|
+
unlink and mtime — no `flock`, which lies on network and container
|
|
96
|
+
filesystems. A crashed producer is reaped by whoever comes next.
|
|
97
|
+
- **Every producer is in it**: the CLI (`e2e`, `collection`, `author`),
|
|
98
|
+
the viewer's Run button, and the MCP `run_test` (which spawns the CLI).
|
|
99
|
+
A collection is ONE run — its `workers` still run in parallel inside
|
|
100
|
+
it, because a child process carries its parent's lease and skips the
|
|
101
|
+
queue.
|
|
102
|
+
- **The viewer shows the queue**: the Active panel lists what is waiting,
|
|
103
|
+
including tickets a terminal or an agent wrote, with a button to take
|
|
104
|
+
any of them back out. `GET /api/queue`, `DELETE /api/queue/:ticket`,
|
|
105
|
+
and a `queue:changed` websocket message.
|
|
106
|
+
- **Config**: `queue.concurrency` (default 1) and `queue.enabled`
|
|
107
|
+
(default true) in `unotest.config`. Both the CLI and the viewer read
|
|
108
|
+
the same file, so they cannot disagree about how many slots exist.
|
|
109
|
+
- **Escape hatches**: `UNOTEST_NO_QUEUE=1` runs without queueing;
|
|
110
|
+
Ctrl-C while waiting gives up your place in line and runs nothing.
|
|
111
|
+
- **For boxes**: `UNOTEST_QUEUE_GLOBAL_DIR` + `UNOTEST_QUEUE_GLOBAL_SLOTS`
|
|
112
|
+
add a host-wide budget several environments share (a collection weighs
|
|
113
|
+
its worker count), and `UNOTEST_ARTIFACTS_ROOT` puts `.runs` / `.queue`
|
|
114
|
+
somewhere other than the directory the tests live in — so the history
|
|
115
|
+
outlives a throwaway copy of the tests.
|
|
116
|
+
|
|
117
|
+
### Migration notes
|
|
118
|
+
|
|
119
|
+
**`POST /api/run` no longer answers 409.** Ordering a run while another
|
|
120
|
+
one is active used to fail with `ActiveRunConflictError` (HTTP 409); it
|
|
121
|
+
now succeeds and the run waits. The response changed shape with it:
|
|
122
|
+
|
|
123
|
+
```diff
|
|
124
|
+
- { runId, kind, ref, pid, startedAt }
|
|
125
|
+
+ { runId, kind, ref, status: "queued" | "running", ticket, acceptedAt }
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
`runId` is still final and immediately usable — open the tab on it as
|
|
129
|
+
before — but the run may not have started yet, and `pid` is not known at
|
|
130
|
+
that point. `POST /api/runs/:runId/abort` covers both states: it
|
|
131
|
+
withdraws a waiting ticket or SIGTERMs a running child.
|
|
132
|
+
|
|
133
|
+
Anything that treated 409 as "busy, try later" should now simply order
|
|
134
|
+
the run. Anything that relied on "only one run can exist" should read
|
|
135
|
+
`GET /api/queue`. To keep the old immediate-start behaviour (without the
|
|
136
|
+
protection), set `queue.enabled: false`.
|
|
137
|
+
|
|
138
|
+
### Patch Changes
|
|
139
|
+
|
|
140
|
+
- Updated dependencies [3eede7c]
|
|
141
|
+
- Updated dependencies [6d1c612]
|
|
142
|
+
- Updated dependencies [dbfa36f]
|
|
143
|
+
- Updated dependencies [c43aa00]
|
|
144
|
+
- Updated dependencies [8ec4177]
|
|
145
|
+
- @unotest/protocol@0.26.0
|
|
146
|
+
- @unotest/core@0.26.0
|
|
147
|
+
- @unotest/dsl@0.26.0
|
|
148
|
+
|
|
149
|
+
## [0.25.0] - 2026-08-29
|
|
150
|
+
|
|
151
|
+
### Minor Changes
|
|
152
|
+
|
|
153
|
+
- adb9d72: Viewer: a pinned Home tab, a multi-row tab strip, and live tiles on the
|
|
154
|
+
overview field.
|
|
155
|
+
|
|
156
|
+
- **Home tab.** The project-health overview used to render only when no
|
|
157
|
+
tab was open, so it disappeared exactly while you were working. It is
|
|
158
|
+
now a pinned first tab: always present, never closable, and what
|
|
159
|
+
"Close All" leaves you on.
|
|
160
|
+
- **Multi-row tabs.** The strip wraps instead of scrolling sideways —
|
|
161
|
+
every open tab is visible at once, up to three rows, then it scrolls.
|
|
162
|
+
Tabs are pills now: the active one is filled like a selected tree row,
|
|
163
|
+
inactive ones are plain text until hovered. Middle-click closes a tab,
|
|
164
|
+
the `⋮` button opens the same actions as a right-click, and the strip
|
|
165
|
+
is a proper `tablist` for screen readers.
|
|
166
|
+
- **Live tiles.** A scenario that is running right now breathes on the
|
|
167
|
+
overview field — the tile fades in and out under a warm ring (a still
|
|
168
|
+
ring when paused, since nothing is moving). Status colour, tile order
|
|
169
|
+
and the counters/filters stay exactly as they were until the run
|
|
170
|
+
finishes.
|
|
171
|
+
|
|
172
|
+
`@unotest/protocol` gains the `overview` tab kind in the `TabKind` union.
|
|
173
|
+
|
|
174
|
+
### Patch Changes
|
|
175
|
+
|
|
176
|
+
- Updated dependencies [70f2e11]
|
|
177
|
+
- Updated dependencies [adb9d72]
|
|
178
|
+
- @unotest/protocol@0.25.0
|
|
179
|
+
- @unotest/dsl@0.25.0
|
|
180
|
+
|
|
3
181
|
## [0.24.0] - 2026-08-26
|
|
4
182
|
|
|
5
183
|
### Patch Changes
|
package/dist/server/main.d.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { IRunnerAdapter, IDslLanguageService, IProcessLauncher } from '@unotest/protocol';
|
|
2
2
|
|
|
3
|
+
interface ViewerQueueConfig {
|
|
4
|
+
/** With queueing off, the viewer starts every run immediately — and
|
|
5
|
+
* so does every terminal. Nothing serialises them. */
|
|
6
|
+
readonly enabled: boolean;
|
|
7
|
+
/** Runs allowed in flight for one environment. */
|
|
8
|
+
readonly concurrency: number;
|
|
9
|
+
}
|
|
10
|
+
|
|
3
11
|
interface RunnerEntry {
|
|
4
12
|
/** Short target id derived from the runner package name —
|
|
5
13
|
* `web`/`mobile`/`unity`. Drives the UI switcher and per-target tree
|
|
@@ -38,6 +46,14 @@ interface StartViewerOptions {
|
|
|
38
46
|
* injects its bundled `node` + runner bin so terminal commands resolve
|
|
39
47
|
* without a system install). */
|
|
40
48
|
terminalPathPrefix?: readonly string[];
|
|
49
|
+
/** Run-queue policy, read from the project's `unotest.config` by the
|
|
50
|
+
* launcher. Omitted (the standalone bin) = the shipped default: queue
|
|
51
|
+
* on, one run at a time. Both the viewer and the CLI must see the SAME
|
|
52
|
+
* numbers — they share one queue directory. */
|
|
53
|
+
queue?: ViewerQueueConfig;
|
|
54
|
+
/** Absolute artifact root when it is not the project root
|
|
55
|
+
* (`UNOTEST_ARTIFACTS_ROOT`); see `ViewerConfig.artifactsRoot`. */
|
|
56
|
+
artifactsRoot?: string;
|
|
41
57
|
}
|
|
42
58
|
interface ViewerHandle {
|
|
43
59
|
url: string;
|