webui: add "6. Scenario" page — run scriptable test scenarios from removable media through the normal task queue
Exposes the scenario engine (platform.System.RunScenario, added earlier) in the web UI instead of only the `bee run` CLI: a new nav item lists every scenarios/*.json found on mounted removable media (GET /api/scenario/list) and runs one with a click (POST /api/scenario/run), enqueued as a normal Task with target "scenario" — progress/logs live in Tasks like any other SAT pack, no separate live-output UI needed. - app.go: satRunner gains RunScenario, exportManager gains ListScenarioFilesOnRemovableMedia/ReadScenarioFromRemovableMedia — both already implemented on platform.System, just newly exposed through App. - webui/tasks.go: taskParams.ScenarioName; runTask's "scenario" case reads the file from removable media, parses it, and runs it. - webui/page_scenario.go: the page itself. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
20cd317c87
commit
bcf02e0515
@@ -46,6 +46,55 @@ func TestHandleAPISATRunDecodesBodyWithoutContentLength(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleAPIScenarioRunRequiresName(t *testing.T) {
|
||||
h := &handler{opts: HandlerOptions{App: &app.App{}}}
|
||||
req := httptest.NewRequest("POST", "/api/scenario/run", strings.NewReader(`{}`))
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
h.handleAPIScenarioRun(rec, req)
|
||||
|
||||
if rec.Code != 400 {
|
||||
t.Fatalf("status=%d want 400, body=%s", rec.Code, rec.Body.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleAPIScenarioRunEnqueuesTask(t *testing.T) {
|
||||
globalQueue.mu.Lock()
|
||||
originalTasks := globalQueue.tasks
|
||||
globalQueue.tasks = nil
|
||||
globalQueue.mu.Unlock()
|
||||
t.Cleanup(func() {
|
||||
globalQueue.mu.Lock()
|
||||
globalQueue.tasks = originalTasks
|
||||
globalQueue.mu.Unlock()
|
||||
})
|
||||
|
||||
h := &handler{opts: HandlerOptions{App: &app.App{}}}
|
||||
req := httptest.NewRequest("POST", "/api/scenario/run", strings.NewReader(`{"name":"power-watch"}`))
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
h.handleAPIScenarioRun(rec, req)
|
||||
|
||||
if rec.Code != 200 {
|
||||
t.Fatalf("status=%d body=%s", rec.Code, rec.Body.String())
|
||||
}
|
||||
globalQueue.mu.Lock()
|
||||
defer globalQueue.mu.Unlock()
|
||||
if len(globalQueue.tasks) != 1 {
|
||||
t.Fatalf("tasks=%d want 1", len(globalQueue.tasks))
|
||||
}
|
||||
task := globalQueue.tasks[0]
|
||||
if task.Target != "scenario" {
|
||||
t.Fatalf("target=%q want scenario", task.Target)
|
||||
}
|
||||
if task.params.ScenarioName != "power-watch" {
|
||||
t.Fatalf("scenario name=%q want power-watch", task.params.ScenarioName)
|
||||
}
|
||||
if task.Priority != taskPriorityBurn {
|
||||
t.Fatalf("priority=%d want %d", task.Priority, taskPriorityBurn)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleAPIBlackboxStatusReturnsDisabledWhenStateMissing(t *testing.T) {
|
||||
h := &handler{opts: HandlerOptions{ExportDir: t.TempDir()}}
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
Reference in New Issue
Block a user