diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ef81918..ee8f741 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -68,12 +68,12 @@ jobs: run: npm install -g @native-sdk/cli@0.4.1 - name: Build headless app (automation enabled) run: native build -Dplatform=linux -Dautomation=true - - name: Drive the app headless and assert the widget tree + - name: Drive the GUI headless and assert the widget tree run: ./scripts/smoke.sh - - name: Upload rendered screenshot + - name: Upload rendered screenshots if: always() uses: actions/upload-artifact@v4 with: - name: smoke-screenshot - path: .zig-cache/native-sdk-automation/screenshot-main-canvas.png + name: gui-screenshots + path: .zig-cache/native-sdk-automation/screenshot-*.png if-no-files-found: ignore diff --git a/CURRENT_STATE.md b/CURRENT_STATE.md index 0846865..aabd4f3 100644 --- a/CURRENT_STATE.md +++ b/CURRENT_STATE.md @@ -19,10 +19,12 @@ criticals raise OS notifications live (#60, ADR-0011) — all **in-runner** **S6 — public release & launch (0.5.0): in progress.** Packaging is wired (#70) — `native package` builds a macOS `.app` (ad-hoc `.dmg`) and a Linux `.tar.gz`, and a tag-triggered [release workflow](.github/workflows/release.yml) -publishes both to a GitHub release (see [RELEASING.md](RELEASING.md)). Remaining: -GUI test suite (#71), the frozen conformance contract (#72), release-ready docs -(#73), and the v0.5.0 cut (#74). The menu-bar monitor and notarization are -post-0.5; see [ROADMAP.md](ROADMAP.md). +publishes both to a GitHub release (see [RELEASING.md](RELEASING.md)). The +automation smoke now **drives** the GUI (#71) — clicking the replay transport, +a filter facet, and the Live tab, asserting the semantics tree after each and +screenshotting the inspector + live surfaces. Remaining: the frozen conformance +contract (#72), release-ready docs (#73), and the v0.5.0 cut (#74). The menu-bar +monitor and notarization are post-0.5; see [ROADMAP.md](ROADMAP.md). ## What's done @@ -185,7 +187,7 @@ live inspector surface with notifications (#54–#60) — is landed. | Area | Status | | --- | --- | -| `repo` (tooling, CI) | ✅ S0 CI; 🔨 S6 packaging + release workflow (#70) | +| `repo` (tooling, CI) | ✅ S0 CI + S6 packaging/release (#70) + driven GUI suite (#71) | | `docs` (docs, ADRs) | ✅ done for S0 | | `ocpp` (engine) | ✅ S2 + ingestion (#29) + reports (#41) + anonymize (#42) + diff (#43) + replay core (#44); O(n) detection pending (#36) | | `ui` (native views) | ✅ S3 inspector (#27–#32) + replay transport (#44) + live-capture view (#59) + live notifications (#60) | diff --git a/scripts/smoke.sh b/scripts/smoke.sh index ef49400..ae4bf74 100755 --- a/scripts/smoke.sh +++ b/scripts/smoke.sh @@ -1,17 +1,19 @@ #!/usr/bin/env bash # -# Automation smoke test: launch the app, wait for its embedded automation -# server, assert the widget tree actually rendered, and capture a -# deterministic screenshot artifact. Portable — uses a virtual framebuffer -# (Xvfb) when available (CI), otherwise runs the window directly (local -# macOS). The app must be built with -Dautomation=true. +# Automation-driven GUI test: launch the app, wait for its embedded automation +# server, then DRIVE the headline flows through the automation protocol — +# clicking real widgets and asserting the rendered semantics tree after each +# step — and capture deterministic screenshots as artifacts. Portable: uses a +# virtual framebuffer (Xvfb) when available (CI), otherwise runs the window +# directly (local macOS). The app must be built with -Dautomation=true. # set -euo pipefail BIN=zig-out/bin/studio AUTO_DIR=.zig-cache/native-sdk-automation -# Launch with the vendored sample as a command-line trace argument, so the smoke -# test exercises the real CLI load path and lands on the loaded overview. +CANVAS=main-canvas +# Launch with the vendored sample as a command-line trace argument, so the test +# exercises the real CLI load path and lands on the loaded overview. SAMPLE=src/ocpp/testdata/normal-session.json if [ ! -x "$BIN" ]; then @@ -44,14 +46,42 @@ launch & APP_PID=$! trap 'kill "$APP_PID" >/dev/null 2>&1 || true' EXIT +# The numeric widget id for the widget whose accessibility name equals $1. Each +# snapshot line is `widget @w/# role= name="