Files
ui/_docs/02_document/tests/performance-tests.md
Oleksandr Bezdieniezhnykh 510df68bcf [AZ-447] autodev Steps 1-4 baseline: docs, tests, refactor specs
Captures the full output of autodev existing-code Phase A through
Step 4 (Code Testability Revision) for the Azaion UI workspace:

- Step 1 Document: _docs/02_document/ (FINAL_report, architecture,
  glossary, components/, modules/, diagrams/, system-flows,
  module-layout) plus _docs/00_problem/ + _docs/01_solution/ +
  _docs/legacy/ + _docs/how_to_test + README.
- Step 2 Architecture Baseline: architecture_compliance_baseline.md.
- Step 3 Test Spec: _docs/02_document/tests/ (environment,
  test-data, blackbox/performance/resilience/security/
  resource-limit tests, traceability-matrix), enum_spec_snapshot,
  expected_results/results_report.md (98 rows), plus the
  run-tests.sh + run-performance-tests.sh runners.
- Step 4 Code Testability Revision: 01-testability-refactoring/
  run dir (list-of-changes C01-C07, deferred_to_refactor,
  analysis/research_findings + refactoring_roadmap) and the 7
  child task specs AZ-448..AZ-454 under _docs/02_tasks/todo/
  plus _dependencies_table.md.
- _docs/_autodev_state.md pins the cursor at Step 4 / refactor
  Phase 4 entry so /autodev resumes cleanly.

Epic AZ-447 (UI testability gates) tracks the 7 child tasks that
will land in subsequent commits.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 00:38:49 +03:00

8.0 KiB

Performance Tests

The Azaion UI is a thin SPA; the dominant performance concerns are bundle size, auth-refresh transparency, SSE responsiveness, and UI reflection of server-confirmed state changes. Server-side throughput is OUT of scope here — this file covers the UI's observable timing only.

NFT-PERF-01: Initial JS bundle ≤ 2 MB gzipped

Summary: The sum of gzipped initial-route JS chunks in dist/ stays within the architecture's stated budget. Traces to: AC-11, O13 Metric: gzipped byte total of initial JS entries. Profile: static

Preconditions:

  • bun run build has produced dist/.

Steps:

Step Consumer Action Measurement
1 Run vite build (or read the build manifest if already built) dist/ produced
2 Walk Vite's manifest.json to enumerate entry chunks (non-async) list of initial chunks
3 Gzip-size each chunk (Node zlib.gzipSync(content, {level:9}) or equivalent) per-chunk size
4 Sum sizes total bytes

Pass criteria: total ≤ 2 097 152 bytes (2 MB). Documentary today — no CI gate (AC-11 status: "target, not currently enforced"). Test exists so the gate flips to blocking the day CI wires it up. Duration: ≤ 60 s. Expected result source: results_report.md row 40.


NFT-PERF-02: Auth refresh — exactly one network round trip per cycle

Summary: A single 401-triggered refresh round consists of exactly one POST /api/admin/auth/refresh plus one retry of the original request. Traces to: AC-01, AC-23 Metric: count of /api/admin/auth/refresh requests per refresh event. Profile: fast

Preconditions:

  • Authenticated session.

Steps:

Step Consumer Action Measurement
1 Issue an authenticated request that returns 401 once, then 200 on retry network log captured
2 Count refresh requests fired in the cycle exactly 1

Pass criteria: refresh count == 1 per cycle (results_report.md row 12 — exact). Duration: ≤ 5 s. Expected result source: results_report.md row 12.


NFT-PERF-03: SSE bearer-rotation reconnect ≤ 5 s

Summary: When the bearer rotates while N SSE streams are open, all streams close and reopen with the new token within 5 s. Traces to: AC-24 Metric: per-EventSource time from close() observed to next OPEN readyState (after reconnect with new token). Profile: fast — quarantined until SSE refresh-reconnect is implemented (Step 8 hardening)

Preconditions:

  • Two EventSources open (live-GPS + annotation-status).

Steps:

Step Consumer Action Measurement
1 Trigger a refresh that rotates the bearer new bearer in memory
2 For each EventSource: time from old close to new OPEN dt_i (ms)
3 Inspect new URLs for new token in query string new ?token= value

Pass criteria: max(dt_i) ≤ 5 000 ms; both streams close+open exactly once (results_report.md row 13). Duration: ≤ 30 s. Expected result source: results_report.md row 13.


NFT-PERF-04: Live-GPS SSE opens within 5 s of flight select

Summary: After clicking a flight in the Header, the live-GPS EventSource reaches OPEN quickly. Traces to: AC-08 Metric: time from select-flight click to EventSource readyState === 1 (OPEN). Profile: e2e (suite live-gps simulator emits events at 1 Hz)

Preconditions:

  • Authenticated; flight selectable.

Steps:

Step Consumer Action Measurement
1 Click a flight one EventSource constructed to `^/api/flights/[0-9]+/live-gps(?
2 Wait for OPEN dt (ms)

Pass criteria: dt ≤ 5 000 ms (results_report.md row 34). Duration: ≤ 10 s. Expected result source: results_report.md row 34.


NFT-PERF-05: Live-GPS SSE closes within 1 s of deselect

Summary: Deselecting the flight tears down the live-GPS stream promptly. Traces to: AC-08 Metric: time from deselect to CLOSED. Profile: e2e

Preconditions:

  • Continuation of NFT-PERF-04.

Steps:

Step Consumer Action Measurement
1 Deselect the flight EventSource closes
2 Wait for CLOSED dt (ms)

Pass criteria: dt ≤ 1 000 ms and no remaining open live-GPS sources (results_report.md row 35). Duration: ≤ 5 s. Expected result source: results_report.md row 35.


NFT-PERF-06: Annotation-status SSE unsubscribes within 1 s on page unmount

Summary: Navigating away from /annotations closes the status-events SSE within 1 s. Traces to: AC-09 Metric: time from unmount to CLOSED. Profile: fast

Steps:

Step Consumer Action Measurement
1 Mount /annotations then unmount EventSource transitions
2 Measure dt ms

Pass criteria: dt ≤ 1 000 ms (results_report.md row 25). Duration: ≤ 5 s. Expected result source: results_report.md row 25.


NFT-PERF-07: Bulk-validate UI reflects new status within 2 s

Summary: After a successful bulk-validate, every selected row shows Validated quickly. Traces to: AC-07 Metric: time from server 200 to last DOM row update. Profile: fast

Steps:

Step Consumer Action Measurement
1 Select N items, click Validate request issued
2 Stub responds 200 UI updates begin
3 Wait for all N rows to show Validated dt (ms)

Pass criteria: dt ≤ 2 000 ms (results_report.md row 37). Duration: ≤ 5 s. Expected result source: results_report.md row 37.


NFT-PERF-08: Panel-width persistence debounce ≤ 1 s after resize-end

Summary: A drag-end on a resizable panel triggers a single PUT within 1 s (debounced). Traces to: AC-21 Metric: time from mouseup (drag-end) to outbound PUT; PUT count per drag. Profile: fast — quarantined until Step 4 writer is added

Steps:

Step Consumer Action Measurement
1 Drag and release a divider event captured
2 Wait for PUT or 1 s timeout dt (ms); count

Pass criteria: exactly 1 PUT within ≤ 1 000 ms; URL = /api/annotations/settings/user; body contains panelWidths (results_report.md row 64). Duration: ≤ 5 s. Expected result source: results_report.md row 64.


NFT-PERF-09: Settings save error surfaces within 2 s

Summary: A 500 on settings save produces an error toast and resets the saving flag within 2 s. Traces to: AC-27 Metric: time from server 500 to error visibility + state reset. Profile: fast — quarantined until Step 4 try/finally fix

Steps:

Step Consumer Action Measurement
1 Trigger save, stub responds 500 after T ms failure delivered
2 Wait for error toast and saving === false dt (ms)

Pass criteria: dt ≤ 2 000 ms (results_report.md row 68). Duration: ≤ 5 s. Expected result source: results_report.md row 68.


NFT-PERF-10: First Contentful Paint on /flights ≤ 3 s on mid-range edge hardware

Summary: A warm-cache load of the default authenticated route renders the main pane within 3 s. Traces to: AC-11 (target), H2 (edge deploys) Metric: performance.getEntriesByName('first-contentful-paint')[0].startTime. Profile: e2e — documentary (no enforcement today; no AC binds a hard FCP budget)

Preconditions:

  • Warm browser cache (second visit).
  • Edge-profile container: 2 vCPU, 4 GB RAM (the hardware-assessment phase confirms the figure).

Steps:

Step Consumer Action Measurement
1 Navigate to /flights post-login navigation completes
2 Read FCP entry ms

Pass criteria: FCP ≤ 3 000 ms (row 98 — threshold_max). Duration: ≤ 30 s. Expected result source: results_report.md row 98.