Skip to content

A browser test proves an idle console stays quiet on a 50-worker fleet #918

Closed

Description

@V3RON

Part of #905.

Scope

A browser-lane test proves that an idle console tab on a 50-worker fleet stays at or under 40 requests a minute on every page, so a return to per-second polling fails CI.

In short

The test opens each of the seven pages against a gateway whose /v1/workers answer is stubbed with 50 workers and 500 devices and whose /v1/leases answer is stubbed with 300 leases. Once the page's first reads have answered, it counts the requests to /v1 over the next 60 s, the event stream not counted.

flowchart LR
  P[Playwright page] --> F["stubs: 50 workers, 500 devices, 300 leases"] --> D[real gateway daemon]
  P --> C["request counter (new)"]
Loading

If it goes wrong: the test is flaky on a slow CI machine, or passes while a page still polls fast.

Technical spec

Facts

# Fact Source
F1 long-lists.spec.ts stubs a route's answer on top of the daemon's own response with page.route + route.fulfill({ json, response }), keeping real headers; its answer helper is local to that file. e2e/console/long-lists.spec.ts:115-127
F2 startDaemon("gateway") starts a real gateway with HTTP on a free loopback port and no workers, so its own /v1/workers answer is empty. e2e/console/fixtures.ts:229-300, 426-484
F3 NAV lists the seven pages; openFromNav opens one; settled waits only for the page's slide and fade animations. e2e/console/fixtures.ts:748-781, 765-772
F4 The configured test timeout is 60 s per test. playwright.config.ts:13
F5 The console casts /v1/workers without validating it. ui/src/data/api.ts:147-151
F6 The idle ceiling and its window. #905 Shared values "Idle ceiling"
F7 The poll intervals live in ui/src/state/queries.ts after #914. #914 Modules touched

Modules touched

e2e/console/big-fleet.spec.ts (new: one test that visits the seven pages in turn, with test.setTimeout(10 * 60_000)), e2e/console/stub-answers.ts (new: answer moved out of long-lists.spec.ts, dropping If-None-Match before route.fetch() so a stub always edits a full answer, as #916 does for the other stubs), e2e/console/long-lists.spec.ts (imports it), a 50-worker builder typed as WorkerView from src/contract/worker-view.ts (F5). Searches: page.route( and function answer in e2e/console.

Contract and event changes

None.

Other code on the same state

None: the stubs and the counter live in the test's own page. Searches: page.on("request" in e2e/ (none to share).

Failure modes

Call Outcome What happens Limit, counted from
page load slow, or never quiet the 60 s window starts once no /v1 request other than the stream has been sent for 2 s, or 15 s after navigation, whichever comes first; so a page that polls every second fails on the count, not on a timeout 10 min for the test (F4 overridden)
stubbed read the daemon answers 304 cannot happen: the stub drops If-None-Match —

Rules in play

  • Testing rules: browser lane, no devices; stubs keep the daemon's real headers and a contract-typed body (F1, F5).

Tests

Seam: the console browser lane, modelled on e2e/console/long-lists.spec.ts.

  • An idle console on a big fleet stays quiet: for each of the seven pages (Overview, Inbox, Fleet, Leases, Queue, Activity, Usage), in the 60 s after its first reads → at most 40 requests to /v1 other than /v1/events/stream.

Done when

  • The console browser lane passes with big-fleet.spec.ts.
  • Setting the intervals in ui/src/state/queries.ts (F7) back to 1 s makes it fail (reviewer may check locally).

Out of scope

CPU or render-time budgets; event bursts (proven in #914's unit tests).

Depends on

Written by an agent.

Activity

  1. added
    task:draftScope written; technical spec or its spec check missing.
    on Oct 23, 2026
  2. changed the title [-]One shared recent-events list, bounded history, and a cheaper clock[/-] [+]A browser test proves an idle console stays quiet on a 50-worker fleet[/+] on Oct 23, 2026
  3. added
    task:readySpec checked. An agent may implement it once its Depends on allow.
    and removed
    task:draftScope written; technical spec or its spec check missing.
    on Oct 23, 2026
  4. self-assigned this
    on Oct 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

task:readySpec checked. An agent may implement it once its Depends on allow.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions