Skip to content

Add a Stop test button to the station web UI - #1

Open
fcheein wants to merge 1 commit into
stagingfrom
feature/stop-test-button
Open

fcheein wants to merge 1 commit into
stagingfrom
feature/stop-test-button

Conversation

@fcheein

@fcheein fcheein commented Oct 9, 2026

Copy link
Copy Markdown

Description

Operators can stop a running test from the station web UI instead of pressing Ctrl+C in the terminal. The test ends ABORTED, and its teardown phases and output callbacks still run. That matters for us because the results upload and the hardware shutdown both run there.

  • Test.abort() (openhtf/core/test_descriptor.py): aborts the running test the same way SIGINT does. It calls executor.abort() and logs the same "Abort test executor." line, which stafltest.results_upload uses to upload ABORTED. Unlike a second SIGINT, a second call does nothing instead of force-stopping the process, so a double click can't skip teardown. It returns whether it started the abort. It's backed by a new TestExecutor.abort_requested and a read-only TestState.status.

  • Station server: POST /tests/<test_uid>/abort returns these codes:

    • 204 when it stops the test
    • 404 for an unknown or finished test
    • 409 if the test hasn't started yet, or is already stopping

    Unlike the other endpoints, it sends no CORS headers. It only accepts a JSON request whose Origin, if present, is this server. So another web page open on a machine on the network can't stop a test, and neither can the dashboard, which runs on a different port.

  • Web UI: a red Stop test button in the "Current test" header, shown while the test is running. It asks for confirmation, then shows a disabled "Stopping…". On an error other than 409 it re-enables and shows the error.

  • web_gui/dist is rebuilt with Node 16. The unchanged sources reproduce the old dist/ byte for byte, so the only difference is this change. The README fork notes now say how to rebuild it.

Motivation and Context

The only way to stop a test was Ctrl+C in the station's terminal. Operators work in the web UI, and a second Ctrl+C force-stops the process before the upload and hardware teardown run.

How Has This Been Tested?

  • test/core/test_descriptor_test.py, AbortTest:
    • abort gives ABORTED with teardown run
    • a second abort during teardown is a no-op
    • abort with no test running does nothing
  • test/output/servers/station_server_abort_test.py: status codes, the origin and content-type checks, and no CORS preflight. With the origin check removed, the cross-origin test fails.
  • Full suite: 521 passed (509 before, plus 12 new).
  • End to end: a StationServer serving this dist/, a real test with a long phase and a teardown, and headless Chromium clicking the button. The confirmation appeared, the button showed "Stopping…", the later phase was skipped, teardown ran, and the outcome was ABORTED.
  • Not yet tried on a station.

Affected components

openhtf.core (Test, TestExecutor, TestState), openhtf.output.servers.station_server, and the web GUI. After merge, the framework should pin the merge commit (per the fork notes) and the EOL should repin the framework.

🤖 Generated with Claude Code

Operators can stop a running test from the station page instead of
pressing Ctrl+C in the terminal. The test ends ABORTED and its teardown
phases and output callbacks still run.

- Test.abort(): aborts the running test the way SIGINT does (same
  executor.abort(), same "Abort test executor." log line), but a second
  call does nothing instead of forcibly stopping the process, so a
  double click can't skip teardown. Returns whether it started the abort.
  Backed by TestExecutor.abort_requested and a read-only
  TestState.status.
- Station server: POST /tests/<test_uid>/abort -> 204; 404 for an
  unknown or finished test, 409 if it hasn't started or is already
  stopping. Unlike the other endpoints it sends no CORS headers and only
  takes a JSON request whose Origin, if any, is this server, so another
  web page open on a machine on the network can't stop a test. The
  dashboard (a different port) can't either.
- Web UI: a red "Stop test" button in the Current test header while the
  test is running. It asks for confirmation, then shows "Stopping..."
  disabled; on an error other than 409 it re-enables and flashes the
  error.
- web_gui/dist rebuilt with Node 16 (unchanged sources reproduce the old
  dist byte for byte); README fork notes say how.

Tests: test_descriptor_test.AbortTest (ABORTED with teardown run, second
abort is a no-op during teardown, no running test), and
test/output/servers/station_server_abort_test.py (status codes, origin
and content-type checks, no CORS preflight). Full suite: 521 passed.
Also checked end to end: a StationServer serving this dist, a real test,
and headless Chromium clicking the button -> confirmation, "Stopping...",
later phase skipped, teardown ran, outcome ABORTED.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coveralls

Copy link
Copy Markdown

Coverage Report for CI Build 38000336077

Coverage increased (+2.6%) to 64.052%

Details

  • Coverage increased (+2.6%) from the base build.
  • Patch coverage: 1 uncovered change across 1 file (42 of 43 lines covered, 97.67%).
  • No coverage regressions found.

Uncovered Changes

File Changed Covered %
openhtf/core/test_state.py 3 2 66.67%
Total (4 files) 43 42 97.67%

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 7533
Covered Lines: 4825
Line Coverage: 64.05%
Coverage Strength: 3.2 hits per line

💛 - Coveralls

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants