The suite waits for the editor now, and the count is 930 (#93)
1 parent
e6849977eb
commit
f05d610b86
2 files changed
+32
-4
No files matched your search
+29
-2
@@ -12,7 +12,7 @@ npm run check # typecheck + lint + format:check + tests, the gate CI runs
|
||||
# code is lost (tail's is reported), so a red run reads as green
|
||||
npm run build # writes dist/ and regenerates index.html
|
||||
./build.sh # the same under `set -o pipefail`, for callers that pipe the output
|
||||
node tools/seed-e2e.mjs && node tools/e2e.mjs # 910 editor checks, screenshots in /tmp/gm-e2e-*.png
|
||||
node tools/seed-e2e.mjs && node tools/e2e.mjs # 930 editor checks, screenshots in /tmp/gm-e2e-*.png
|
||||
GM_STEPS=20 node tools/e2e.mjs # or 1-12, or 6,20 — a subset while working on one step
|
||||
./e2e.sh start [GM_STEPS] # the same run detached, see below
|
||||
./e2e.sh status # live progress, or the last run's result
|
||||
@@ -69,6 +69,33 @@ scene state and share the CDP driver in `tools/lib/harness.mjs` — `press`, `un
|
||||
`object(id)`, `world()`, `mutate(js)` and friends, so a check reads like the interaction it
|
||||
exercises.
|
||||
|
||||
**The suite waits for the editor, not for the clock (#93).** Every action in the harness — `click`,
|
||||
`doubleClick`, `wheel`, `drag`, `press`, `typeText`, `select`, `mutate`, `undo`, `redo`, `showTab` —
|
||||
ends in `settle()`, which waits for two *drawn* frames (~32 ms) through `__gm.afterFrames()` rather
|
||||
than for a deadline somebody estimated. `afterFrames` wakes the loop itself, because an editor that
|
||||
draws nothing would never redeem a promise of a frame, and gives up after a timeout instead of
|
||||
hanging the run; `settle()` falls back to `sleep(150)` when the page has no such hook (an old
|
||||
build), since silently not waiting would turn every later check into a coin toss. What a frame
|
||||
cannot answer has its own condition: `waitUntil(expr)`, `play()`/`stop()` waiting on
|
||||
`__gm.state.mode`, and `saved()` for the autosave.
|
||||
|
||||
That replaced about 550 `sleep()` calls and took the suite from 564 s of step time (88% of it pure
|
||||
waiting) to 243 s (76%). Three kinds of wait were deliberately kept, and removing them breaks
|
||||
things:
|
||||
|
||||
- **Loading takes real time.** The 500/600 ms waits behind texture and font changes in
|
||||
`12-textures` and `15-aspect` are waiting for bytes, not for a picture. Two frames are no answer
|
||||
to that.
|
||||
- **Game time is not frame time.** `setTimeScale`, `shaderTime`, `particleTime`, the pause
|
||||
measurements in `18-pause`, and the live values on graph nodes in `18` — those are carried by a
|
||||
running graph, so the run must be given a tick, not a repaint.
|
||||
- **The scroll measurement in `11-menus`** times a real inertia, with its protocol in the comment.
|
||||
|
||||
One consequence of the new speed: a step can now finish before the autosave of the step before it
|
||||
has fired (it runs 1 s after the last model change and paints the status twice). `33-render-on-change`
|
||||
therefore waits for `__gm.state.saveStatus` to leave `dirty`/`saving` before it measures idleness —
|
||||
it must measure *that nothing happens any more*, not *that it waited long enough*.
|
||||
|
||||
A step that needs a tab opens it with `openTab(t, 'container')` from `tools/e2e/lib/scaffold.mjs`,
|
||||
not by clicking its name: since the tenth tab the row hides some of them at the test window's width,
|
||||
and the helper goes through the `»` menu when it has to. Clicking the label directly took the
|
||||
@@ -205,4 +232,4 @@ widths to find click points. The **render device is not in this repo** — `/dev
|
||||
and a 1 GB `/dev/shm` come from `container.options` in the runner's own `config.yaml`, which
|
||||
applies to every job on that runner. Without them chromium falls back to llvmpipe, which gets
|
||||
WebGL 1.0 only. Measured in the job container: `ANGLE (Intel, Vulkan 1.3.230, HD Graphics 630)`,
|
||||
WebGL 2.0, and the same 910 checks as here.
|
||||
WebGL 2.0, and the same 930 checks as here.
|
||||
+3
-2
@@ -32,16 +32,17 @@ fed to a colour port is broadcast to all three channels. A colour cannot be fed
|
||||
| **Texture size** | out `width`, `height` | The picture in pixels: of the frame, when the sprite wears one. |
|
||||
| **Time** | out `value` | Seconds since the editor started; see *Coordinates and time* below. |
|
||||
| **Output** | in `color`, `alpha` (number) | What the sprite is drawn with: the colour, clamped to 0-1, and the opacity, clamped too. Each input left unconnected stays the texture's. One per graph. Its *Edge* setting says how the picture continues past its border when sampled outside it: *Clamp* (the default) holds the border pixel, *Mirror* turns the picture back on itself, *Repeat* starts it over for tiles. |
|
||||
| **Property** | out `value` | Declares a number the sprite sets: `Name` is the row below the sprite's Shader dropdown and the uniform in the fragment; `Default`, `Min`, `Max` are the row's range. A name is one word (letters, digits, `_`), unique in the graph. |
|
||||
| **Property** | out `value` | Declares a number the sprite sets: `Name` is the row below the sprite's Shader dropdown and the uniform in the fragment; `Default`, `Min`, `Max` are the row's range. A name is one word (letters, digits, `_`), unique in the graph, and not one of the rows a sprite has anyway — `enabled`, `scale`, `rotation`, `mirrorX`, `mirrorY`, `width`, `height`, `color`, `texture`, `shader`. Both rows would sit on the same key and the uniform would read the sprite's width instead of the declared default, so the node says *"width" is a sprite property* and nothing compiles. |
|
||||
| **Color** | out `color` | A constant colour, picked in the inspector. |
|
||||
| **Number** | out `value` | A constant number, typed on the node. Handy where the same value feeds more than one input, or where an input has nothing to type on (Luminance, the Output's alpha). |
|
||||
| **Add**, **Subtract**, **Multiply**, **Divide** | in `a`, `b` (any) · out `result` | Arithmetic, per channel for colours. An unconnected input is the number typed on the node (0, or 1 for the second input of Multiply and Divide). |
|
||||
| **Add**, **Subtract**, **Multiply**, **Divide** | in `a`, `b` (any) · out `result` | Arithmetic, per channel for colours. An unconnected input is the number typed on the node (0, or 1 for the second input of Multiply and Divide). **Dividing by 0 gives 0**, the same answer the `Divide` of a behavior and of a particle graph give: `a / 0.0` is NaN in GLSL, and the Output's `clamp(NaN, 0, 1)` is undefined — the pixel would be whatever the driver does, different on Intel, on Nvidia and on a phone. |
|
||||
| **Mix** | in `a`, `b` (any), `t` (number) · out `result` | Blends from `a` to `b`: `t` = 0 is `a`, 1 is `b`, beyond that it extrapolates. |
|
||||
| **Luminance** | in `color` · out `value` | How bright a colour is (Rec. 709 weights), as one number. |
|
||||
| **Sin**, **Floor**, **Fract**, **Abs** | in `value` (any) · out `result` | The sine of a number in radians (one wave every 6.283); rounded down to a whole number; the part after the decimal point (2.75 becomes 0.75, a rising value becomes a sawtooth); the distance from 0 with the sign dropped (-0.3 becomes 0.3, a value crossing 0 becomes a V). Per channel for colours. |
|
||||
| **Step** | in `edge` (number), `value` (any) · out `result` | 0 while `value` is below `edge`, 1 from `edge` on: a hard cut. Per channel for colours. |
|
||||
| **Pow** | in `value` (any), `exponent` (number) · out `result` | `value` to the power of `exponent`: 2 squares it, 0.5 is the square root; an easing curve on `u`, a gamma on a colour. Below 0 the value counts as 0, because GLSL leaves `pow` undefined there (0 to a power of 0 or less is undefined too). Per channel for colours. |
|
||||
| **Sqrt** | in `value` (any) · out `result` | The square root: 0.25 becomes 0.5, 4 becomes 2. The same as `Pow` with exponent 0.5, in one node. Below 0 the value counts as 0, because GLSL leaves `sqrt` undefined there. Per channel for colours. |
|
||||
| **Clamp** | in `value` (any), `min`, `max` (number) · out `result` | Holds the value inside `min`..`max`, per channel for colours. The Output clamps the colour it is given anyway; this one holds a value *inside* the graph, before it is added to or multiplied. |
|
||||
|
||||
An input with nothing to type on it (the Output's two, Luminance's colour) that is left unconnected
|
||||
reads the texel: its colour for a colour port, its alpha for the Output's `alpha`. That is why the
|
||||
|
||||
Reference in new issue
Block a user