Color the dot beside each host name by its latest latency (closes #207)
check / check (push) Canceled after 0s

updateHostRow gives the dot the color of the row's latest figure from
CONFIG.latencyColors, gray when the check failed or no result has come
yet. Pausing still sets it gray. The dot carries a status-dot class and
data-host, as the figure and status line do, so both functions find it
the same way.

Model: opus-5-5
This commit was merged in pull request #218.
This commit is contained in:
clawbot committed 2026-11-11 21:56:03 +01:00
1 parent 93bbd80d57
commit 0a714bc57f
3 files changed
+55 -20

No files matched your search

+40 -3
View File
@@ -28,8 +28,8 @@ import {
// a host's row that tick or greyOutUI draws into is a plain object, made
// the first time a test looks it up and kept in elements under its
// selector until the next test starts. As on a page, writing its text
// replaces its markup; the status dot greyOutUI looks for in it is not
// there. Drawing a sparkline does nothing; it looks for the pixel ratio on
// replaces its markup; setting a style keeps it in the element's style
// object. Drawing a sparkline does nothing; it looks for the pixel ratio on
// window and finds none. The commit the page's footer names, which
// vite.config.js fills in when it builds the page, is blank. In each test,
// console.error and console.info print nothing and keep what they are
@@ -63,7 +63,7 @@ globalThis.document = {
querySelector: (selector) =>
(elements[selector] ??= {
getContext: () => canvasContext,
querySelector: () => null,
style: {},
set textContent(text) {
this.innerHTML = text;
},
@@ -83,6 +83,12 @@ function statusText(state, host) {
return elements[`.status-text[data-host="${index}"]`]?.innerHTML;
}
// The color last given to the dot beside host's name.
function statusDot(state, host) {
const index = state.allHosts.indexOf(host);
return elements[`.status-dot[data-host="${index}"]`]?.style.backgroundColor;
}
// What this test wrote to the browser console with console[method].
function consoleLines(method) {
return console[method].mock.calls.map((call) => call.arguments[0]);
@@ -683,6 +689,37 @@ test("a check that timed out or found its target unreachable has a grey figure a
assert.equal(latencyHex(null), "#6b7280");
});
test("a check that answers after 488ms turns the dot beside its target's name orange", async (t) => {
const { state, target } = stateWithOneTarget();
mockTargets(t, () => 488);
const round = tick(state, new AbortController().signal);
t.mock.timers.tick(488);
assert.notEqual(await settled(round), "still waiting");
assert.equal(statusDot(state, target), "#f97316");
});
test("a check that fails after one that answered turns the dot beside its target's name gray", async (t) => {
const { state, target } = stateWithOneTarget();
target.pushSample(Date.now(), { latency: 8, error: null });
mockTargets(t, () => 23, target.url);
const round = tick(state, new AbortController().signal);
t.mock.timers.tick(23);
assert.notEqual(await settled(round), "still waiting");
assert.equal(statusDot(state, target), "#6b7280");
});
test("pausing turns the dot beside a target's name gray", async (t) => {
const { state, target } = stateWithOneTarget();
mockTargets(t, () => 8);
const round = tick(state, new AbortController().signal);
t.mock.timers.tick(8);
assert.notEqual(await settled(round), "still waiting");
assert.equal(statusDot(state, target), "#22c55e");
state.paused = true;
greyOutUI(state);
assert.equal(statusDot(state, target), "#6b7280");
});
// buildUI draws the page into #app, here a plain object. Each entry in the
// footer's color legend is a colored dot and the latencies it stands for,
// with < and > written as &lt; and &gt;. A latency takes the color of the