Files
2026-06-18 02:34:20 +00:00

10 KiB

UniDesk E2E Reference

UniDesk delivery is not complete until the public production frontend, public dev frontend proxy when deployed, public provider ingress, internal core API, PostgreSQL database, local provider-gateway self-connection, and frontend Playwright flow pass the relevant end-to-end checks. The canonical automated command is bun scripts/cli.ts e2e run; set UNIDESK_E2E_FRONTEND=dev to target the public dev frontend proxy and UNIDESK_E2E_AUTH_USERNAME / UNIDESK_E2E_AUTH_PASSWORD when that environment uses credentials different from root config.json.

Required Preconditions

  • config.json network.publicHost must be the externally reachable host name or IP of the main server, not 127.0.0.1, when validating browser access from outside the server.
  • The Docker stack must be running through bun scripts/cli.ts server start, and bun scripts/cli.ts server status must report healthy frontend, provider ingress, internal core, database, and provider-gateway containers.
  • Browser runner dependencies, Playwright execution shape, screenshots, focused frontend checks and layout assertions are owned by $unidesk-webdev; this file only records delivery gate scope.

Automated E2E Scope

bun scripts/cli.ts e2e run validates the public production frontend, optional public dev frontend proxy, public provider ingress, internal core API, PostgreSQL database, provider-gateway self-connection and registered user service paths derived from config.json. The CLI response is intentionally bounded: it prints check names/statuses, screenshot path, counts, failed checks and resultPath; full diagnostics stay under .state/e2e/.

Selective Execution Rule

Run E2E in two stages. First run the smallest real selection that covers the change, then run the full public bun scripts/cli.ts e2e run before claiming delivery. Selection uses --only <pattern[,pattern...]> and --skip <pattern[,pattern...]>; patterns may be full check names, prefixes or wildcards. Frontend selection and layout acceptance details are in $unidesk-webdev.

Typical targeted commands:

  • bun scripts/cli.ts e2e run --only frontend:pipeline-step-timeline-visible
  • bun scripts/cli.ts e2e run --only frontend:pipeline
  • bun scripts/cli.ts e2e run --only frontend --skip frontend:todo-note-integrated-visible,frontend:findjob-integrated-visible
  • bun scripts/cli.ts e2e run --only network,provider-ingress

Stable non-frontend E2E groups:

  • Public exposure: only production frontend, dev frontend proxy and provider ingress are unrestricted public entries; private service ports must remain private or source-restricted.
  • Core API and database: internal overview/performance endpoints, PostgreSQL readiness and named volume persistence must pass.
  • Provider self-connection and remote control: main-server provider-gateway must be online, versioned, always-enabled, host SSH capable and able to plan provider.upgrade without recreating itself.
  • User services: registered services must be visible through the real UniDesk proxy path, with health and representative API checks for Todo Note, OA Event Flow, k3s Control, Code Queue, File Browser, FindJob, Pipeline, MET Nonlinear and ClaudeQQ.
  • Pipeline/OA event flow and Code Queue liveness selections remain first-class E2E checks; their current exact check names live in the CLI output and source tests, not in this long-term reference.
  • Frontend Playwright and dense layout assertions are governed by $unidesk-webdev.

Frontend JSON Rule

The frontend must render JSON data into React controls by default. Raw JSON is allowed only after an explicit 查看原始JSON user action, and E2E must fail if the initial page exposes raw JSON text or a raw JSON block.

Remote update records in the frontend are covered by the same rule: provider.upgrade task history must be rendered as rows/cards with status, mode, task id, source, duration, policy, outcome summary, and updated time. The page must not expose upgrade plan/result JSON as a log block unless the operator clicks 查看原始JSON.

Provider operation availability is also covered by the structured rendering rule. host.ssh availability must be displayed as badges or equivalent controls derived from capabilities and hostSsh* labels, and remote update availability must be displayed from provider.upgrade capability plus the always-enabled policy; these fields must not require opening raw Provider JSON.

User service pages are covered by the same rule. Todo Note must show lists, task tree, filters, reminder input, movement controls, undo/redo and metrics as controls; OA Event Flow must show health, live tag stream state, event table, tag filter presets and Trace stats table as controls; Code Queue must show queue cards, execution liveness diagnostics, live transcript, model/cwd/max attempt inputs, judge decision, attempt table, append prompt, interrupt and retry controls; File Browser must show D518 as the default target, D601 as an alternate target, a screenshot export action, and an embedded upstream WebUI frame served through /api/microservices/<id>/proxy/ with compact file rows that do not let material-icon fallback text cover file metadata; FindJob must show metrics, jobs and drafts as cards/tables; Pipeline must show component classes, React Flow graph nodes/edges, run cards, Gantt execution lines and OpenCode Trace timelines as controls; MET Nonlinear must show queue rows, GPU/image cards, a real path tree for the project library, structured project/job detail panels, project config preview, data/ training state, model parameter count, metrics, progress bars, ETA, epoch/h speed and history diagnostics as controls; ClaudeQQ must show NapCat HTTP/WS/login badges, QR/login panel, event cache, subscriptions and message push controls; the full user-service config, summary, snapshot, jobs preview, drafts, OA events and run JSON can only appear after an explicit 查看原始JSON click.

Public Boundary Rule

The production frontend URL, dev frontend proxy URL and provider ingress URL are the only unrestricted public network interfaces. backend-core REST API remains Docker-internal only; PostgreSQL and OA Event Flow may expose restricted host mappings solely for controlled Code Queue nodes, and E2E must prove those mappings are unreachable to generic clients or protected by explicit source rules.

Database Persistence Rule

The PostgreSQL data volume is the named Docker volume unidesk_pgdata_10gb. CLI server control commands must never use docker compose down -v, docker volume rm, or any equivalent data-volume removal. To validate persistence, insert a marker row into unidesk_e2e_markers, run bun scripts/cli.ts server start or a full stop/start cycle, and verify the marker row still exists.

User Service Restart-Recovery Rule

Any new user service, service migration, or change to a service's Compose/docker run/k8s configuration must prove it can recover after container restart and Docker daemon restart. The delivery evidence must include the service's config.json id/provider/container or Kubernetes Service mapping, restart policy or Deployment replica policy, private port or ClusterIP Service, persistent mounts or PostgreSQL tables, health readiness fields, and at least one post-restart bun scripts/cli.ts microservice health <id> plus a representative microservice proxy check through the real UniDesk path. k3sctl-managed services must prove the proxy path through k3sctl-adapter and Kubernetes API service proxy, not the provider-gateway direct business path.

D601 services have an extra gate because Windows, WSL, Docker Desktop and native k3s are separate supervisors: record the Windows scheduled task or equivalent keepalive, run docker inspect to confirm Docker-managed services such as met-nonlinear-ts have non-empty restart policies and host bind mounts for durable state, and run kubectl -n unidesk get deploy,pod,svc,endpoints claudeqq -o wide for k3s-managed ClaudeQQ. Then verify MET Nonlinear queue/image health and ClaudeQQ logged-in NapCat HTTP/WebSocket state through the real UniDesk proxy after the restart. A service that only becomes running but loses login, queue, token, subscription, data directory or pending work is not restart-recovery complete.

Delivery Gate

Before claiming delivery, run these checks and keep their JSON output or screenshot path available for review:

  1. bun scripts/cli.ts check
  2. bun scripts/cli.ts server start, then bun scripts/cli.ts job status latest until succeeded
  3. bun scripts/cli.ts server status
  4. bun scripts/cli.ts e2e run and inspect failedChecks or the emitted resultPath if any check fails
  5. a database persistence marker check across at least one CLI-controlled restart

Provider Upgrade Gate

When delivery explicitly includes upgrading or rebuilding a compute-node provider-gateway such as D601 or D518, the automated E2E plan check is not sufficient. The operator must first bootstrap any legacy provider only from a node-local terminal, node-owned web terminal, systemd, scheduled task, or detached shell if it cannot yet schedule upgrades; SSH passthrough carried by the same provider-gateway must not be used for synchronous self-rebuilds. Then run provider.upgrade with mode: "schedule" against that Provider ID, confirm the task succeeds, confirm the sleep-and-validate candidate gateway reconnects in the public frontend, confirm docker inspect reports final restart policy always and PID mode host, record whether systemd/PM2/Windows scheduled task/Docker Desktop autostart is the daemon-level supervisor, and finally verify any required host.ssh capability with trans <PROVIDER_ID> hostname. This schedule check is a node-upgrade gate, not a replacement for the standard public frontend Playwright E2E gate.

External compute nodes should run that schedule check through the remote main-server passthrough form: bun scripts/cli.ts --main-server-ip 74.48.78.17 debug dispatch <PROVIDER_ID> provider.upgrade --mode schedule --wait-ms 15000. The default remote transport logs in to the public frontend and does not require a main server SSH key; this proves the node can validate itself without direct access to backend-core REST or PostgreSQL.