20 Commits

Author SHA1 Message Date
Adam Shiervani 5427b80248 test(e2e): preserve remote agent diagnostics (#1457)
* test(e2e): lower s3 wake version gate

* test(e2e): preserve device logs across restarts

Capture failing device logs before later restarts can truncate last.log, and keep a rotated copy available during global teardown.
2026-05-19 10:34:32 +02:00
Adam Shiervani df5dbea431 fix(keyboard): keep modifiers out of auto-release (#1438)
* fix(keyboard): keep modifiers out of auto-release
Prevent per-key auto-release from dropping held modifiers during jitter while keeping explicit cleanup paths covered by E2E tests.

* fix(keyboard): keep modifiers out of auto-release
Prevent per-key auto-release from dropping held modifiers during jitter while keeping explicit cleanup paths covered by E2E tests.

* chore(keyboard): trim autorelease comments

Keep comments focused on keyboard behavior and remove branch-specific narrative from the tests.

* fix(keyboard): reset keepalive timing on key state changes

Reset session keepalive timing on every keyboard state change so stale gaps do not poison later holds under modifiers.
2026-05-01 14:48:25 +02:00
Adam Shiervani 1c478b1264 fix(test): harden remote agent serial console checks
Improve the remote-agent e2e helpers to escape SSH commands, time out stuck SSH calls, and retry transient failures. Replace fixed ttyACM sleeps with polling so serial console tests wait for the actual remote host state.
2026-04-07 14:09:01 +02:00
Adam Shiervani 49f30d9dde test(e2e): add S3 suspend/wake tests via USB remote wakeup (#1392)
Add two e2e tests that verify JetKVM can wake a host from S3 sleep
using HID input (keyboard and mouse). Tests trigger suspend via
`echo mem > /sys/power/state`, wait for the host to become
unreachable, then send HID reports and verify recovery.

Both tests skip gracefully when system firmware is below 0.2.8
(missing wakeup_on_write kernel support) or when the remote host
doesn't support S3 deep sleep.

Also adds a `semverGte` helper for version comparisons.
2026-04-02 15:01:14 +02:00
Adam Shiervani 785c9c1b7c fix(test): fix e2e flakiness from RPC timeouts and stale session dialogs (#1376)
setEDID blocks ~7.5s for HDMI renegotiation, which could exceed the
hardcoded 10s RPC timeout. Add configurable timeout to sendJsonRpc and
use 20s for all setEDID calls. Also handle the "Use Here" session dialog
after page reload in beforeAll, and wait for video stream before LED tests.
2026-03-29 23:25:45 +02:00
Adam Shiervani a5bb97eb7b test(ota): add e2e test for upgrading to a signed release (#1373)
Validates that the locally-built binary can accept a GPG-signed OTA
update. Deploys the dev build, then serves the latest production binary
and its real signature via a mock update server. Runs in the regular
test_e2e lane — no signing key required.
2026-03-29 20:36:54 +02:00
Adam Shiervani 76e748a820 fix: USB HID startup recovery, unreliable channel fallback, and e2e test stability (#1364)
* fix: USB HID startup recovery and e2e test stability

- fix(usb): always rebind UDC on Init() to guarantee clean HID
  function driver state. After factory reset + reboot, the configfs
  entries may exist from the previous boot but the kernel's internal
  HID function attachment is broken (/dev/hidg0 returns ENXIO).
  The changeset resolver skipped the bind because the UDC file
  content matched — but content match != working. Rebinding on
  every startup is cheap (brief USB re-enumeration) and guarantees
  a clean state.

- fix(ui): fall back to reliable HID channel when unreliable WebRTC
  data channel is not yet established. Prevents silent mouse event
  drops during the brief window after page reload.

- fix(e2e): suppress SSH known-hosts warnings with LogLevel=ERROR,
  replace zsh-incompatible glob patterns with find(1), fix nested
  SSH quoting, increase USB rebind timeouts, add keyboard warmup
  after EDID changes, reorder tests for stability.

* test: remove Polish diacritics, WoL broadcast, and factory reset UI tests

* fix(test): assert keyboard recovery after EDID restore instead of silently passing

The retry loop captured no result and had no assertion, so a timeout
would let the test pass without verifying HID actually recovered.
2026-03-28 13:40:04 +01:00
Adam Shiervani 711158ab18 fix: modifier key auto-release and keyboard reset on disconnect (#641) (#1339)
* fix: modifier key auto-release and keyboard reset on disconnect (#641)

- Fix performAutoRelease() to check state.Modifier bitmask for modifier
  keys (0xE0-0xE7) instead of only checking state.Keys array, which never
  contained modifiers
- Release all keys (send all-keys-up HID report) when WebRTC session
  disconnects to prevent stuck keys
- Add keyboard state reset in onLastSessionDisconnected() as safety net

* test(e2e): add modifier auto-release and disconnect key-release tests

- Add test verifying modifier keys (Ctrl, Shift, Alt) auto-release after
  timeout using direct JSON-RPC to bypass browser keepalive
- Add test verifying all held keys are released when WebRTC session
  disconnects, checking both host-side events and device-side state
- Add getKeysDownState helper to e2e helpers
2026-03-27 22:38:12 +01:00
Adam Shiervani 71db3b91ab fix: add settling delay when waking HDMI capture chip from sleep (#519) (#1356)
* fix: add settling delay in VideoStart() when waking from sleep mode (#519)

* test: improve e2e test reliability and reduce flakiness

- Replace fire-sleep-assert with polling in wheel scroll tests
- Add retry loops for macro test and RPC setup after USB re-enumeration
- Add waitForRpcReady helper to handle session dialogs and stale pages
- Remove flaky paste modal UI test (redundant with keyboard scan tests)
- Preserve SSH keys and dev mode across config resets in setup/teardown
- Add saveSSHDevState/restoreSSHDevState helpers

* fix: trim sysfs whitespace in getSleepMode() so sleep detection works

Linux sysfs attributes include a trailing newline, so comparing raw
content with "1" always returned false. Use strings.TrimSpace to match
the convention used elsewhere in the codebase.
2026-03-27 15:30:29 +01:00
Adam Shiervani c176ee20f9 fix: prevent cursor jumping to top-left on window blur (#392) (#1359)
* fix: prevent cursor jumping to top-left on window blur (#392)

On window blur/visibilitychange, resetMousePosition was sending
sendAbsMouseMovement(0, 0, 0), which moved the target cursor to the
top-left corner. This could trigger hot-corner actions on the target.

Track the last sent absolute position in a ref and use it in
resetMousePosition to only release mouse buttons (buttons=0) without
changing the cursor position.

* fix(e2e): add SSH retry logic and keepalives for high-latency links

Consolidate SSH options into a shared SSH_OPTS constant with increased
ConnectTimeout (10→30s), ServerAliveInterval, and ServerAliveCountMax.
Add retry logic (3 attempts with backoff) to sshExec for transient
connection errors (reset, refused, timed out, no route).

* fix(e2e): reset device config in global teardown

Always reset the device config and restart the app after a test run so
the device is left in a clean state regardless of pass/fail.
2026-03-27 13:41:27 +01:00
Adam Shiervani eee6d728cd feat(e2e): add OTA upgrade-from-stable test (#1324)
Add a new E2E test that downloads the latest stable production binary
from api.jetkvm.com, deploys it to the device, then OTA-upgrades to
the locally-built binary with a config reset. This catches cross-version
upgrade regressions (config migrations, schema changes) that the
existing mock-only OTA tests cannot detect.
2026-03-24 16:02:02 +01:00
Adam Shiervani 15dc380062 fix: auto-recover USB gadget when host power-cycles (#1297)
* fix: auto-recover USB gadget when host reconnects (#128)

When the USB host reboots or disconnects, the UDC state becomes
"not attached" and never recovers. Add automatic recovery that detects
this state and rebinds the USB gadget, with rate limiting to avoid
thrashing. Also refactor keyboard HID file handling to support
force-reopen after rebind.

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

* refactor: move USB recovery logic to internal/usbgadget package

Extract ShouldAttemptUSBRecovery and its retry interval constant into
the internal/usbgadget package so the logic is testable without
importing the top-level kvm package. Reset the recovery timer in
updateUsbRelatedConfig to prevent auto-recovery from interfering
during the host's USB re-enumeration window after a deliberate
config change.

Made-with: Cursor

* feat(e2e): add JSON-RPC data channel support to test hooks

Expose the WebRTC RPC data channel through test hooks and add a
sendJsonRpc helper that sends a JSON-RPC request over the channel
and resolves via callback with timeout handling. This enables e2e
tests to invoke backend RPC methods directly.

Made-with: Cursor

* refactor(e2e): restructure tests with remote-agent suite

Move device-level e2e tests (config-reset, EDID, HTTPS, HDMI sleep,
LED, mouse, USB attach timing, USB device) into a consolidated
remote-agent suite that runs through a Go-based agent binary. Add a
separate Playwright project for remote-agent tests.

- Remove standalone spec files now covered by ra-all.spec.ts
- Rename login-rate-limit to zz-login-rate-limit so it runs last
  (avoids needing a post-test reboot to clear rate-limit state)
- Reorder welcome-password tests so validation runs first, reusing
  the onboarding state and saving an SSH reset cycle

Made-with: Cursor

* refactor(e2e): clean up test helpers and reduce duplication

Consolidate all test helpers into a single helpers.ts file, removing
the separate ota-helpers.ts. This gives every test file a single import
source and eliminates duplicated code across the test suite.

Key changes:
- Merge ota-helpers.ts into helpers.ts (mock server, binary deployment,
  device config, env var validation, triggerUpdate, withTempSignature)
- Remove duplicated rpc/restartAppViaSSH/waitForDeviceReady functions
  from ra-all.spec.ts in favour of shared imports
- Extract loginAndOpenSettings helper in settings-local-auth tests
- Extract getOTAEnvVars, toPreReleaseVersion, triggerUpdate, and
  withTempSignature to reduce boilerplate across OTA tests
- Remove unused verifyMouseWorks function and dead variables
- Strip redundant JSDoc that just restated type signatures
- Remove duplicated per-project use config from playwright.config.ts
  (already inherited from top-level)
- Convert dynamic imports in sshExec to top-level imports

Made-with: Cursor

* refactor(e2e): move binary deployment into Playwright globalSetup

Replace the shell-script deployment logic with Playwright's
globalSetup/globalTeardown hooks. When BASELINE_BINARY_PATH is set,
globalSetup deploys the binary, resets device config, reboots, and
captures pre-test logs. globalTeardown captures post-test logs.

This keeps the deployment lifecycle inside Playwright where it belongs,
and reduces test_core_e2e.sh to a thin wrapper that sets env vars.

Made-with: Cursor

* fix: retry HID file reopen after USB gadget rebind

After rebinding the DWC3 USB controller, the kernel needs a moment to
create the /dev/hidg* device nodes. The previous code attempted to
reopen the keyboard HID file immediately after rebind, which raced
with the kernel and failed with "no such device or address".

Add a retry loop (up to 10 attempts, 200ms apart) to wait for the
device nodes to appear before reopening the keyboard HID file.

Made-with: Cursor

* fix: harden USB gadget recovery after UDC unbind

Reset stale HID gadget handles after rebind, suppress transient HID-open errors during detach windows, and fall back to full gadget reconfiguration when simple UDC rebind does not restore keyboard HID promptly. Strengthen the remote-agent USB recovery E2E to verify both keyboard and mouse input recover after unbind with retry tolerance for host-side input node churn.

Made-with: Cursor

* refactor: simplify USB HID error handling and reduce hot-path overhead

- Use errors.Is with syscall.Errno instead of string matching in
  IsHIDTemporarilyUnavailableError (robust, zero-alloc)
- Cache USB state in usbReadyForHidReports instead of reading sysfs
  on every HID report
- Extract rpcHidReport wrapper to deduplicate 5 rpc*Report functions
- Fix openWithTimeout goroutine/fd leak on timeout
- Add USBStateNotAttached/USBStateUnknown constants, replace literals
- Deduplicate discoverJetKVMDevices by delegating to listInputDevices

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

* feat: run remote-agent e2e tests when JETKVM_REMOTE_HOST is provided

Made-with: Cursor

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 12:54:20 +01:00
Adam Shiervani 11b99d59fd Signed Releases (#1188)
* Implement GPG signature verification for OTA updates

- Added GPG signature verification to the OTA update process, ensuring that updates requiring signatures cannot be applied without them.
- Introduced a new GPGVerifier struct to handle fetching and verifying signatures.
- Updated the updateApp and updateSystem methods to check for signature URLs and download signatures as needed.
- Enhanced error handling for missing signatures and verification failures.
- Removed the old release.sh script as its functionality has been integrated into the Makefile for better release management.

* Add tests for GPG signature verification in OTA updates

* Refactor error message for missing GPG signature URL in OTA updates

* Refactor OTA update process to improve signature handling

- Introduced a new method for downloading component signatures, ensuring that updates requiring signatures cannot proceed without them.
- Updated the Makefile to allow E2E tests to optionally include OTA tests based on the SKIP_OTA_E2E variable.
- Enhanced the test_local_update.sh script to support signature file verification and inclusion during tests.
- Improved error handling for missing signature URLs and added context cancellation checks in GPG key fetching.

* Refactor GPG key caching to validate keyring before storing

* Update Makefile to enhance E2E test process with optional OTA signature verification

* Comment out non-working keyservers and update root key fingerprint

* Add Ubunutu keyserver

* Update root key fingerprint for GPG signature verification in OTA updates

* Add signed OTA E2E test and full E2E test suite to Makefile

- Introduced `test_e2e_signed` target for testing signed OTA updates with GPG signature verification.
- Added `test_e2e_full` target to run both regular and signed OTA tests, requiring a signing key fingerprint.
- Enhanced error handling for missing parameters in both test targets.

* Update IP address extraction in test_local_update.sh to exclude all localhost addresses

* Add GPG public key fetching tests with caching and error handling

* Enhance build and testing scripts for signed OTA updates

* Add fingerprint extraction and validation for GPG keys

* Simplify bypass mechanism of OTA signature checks

* Refactor E2E testing and release workflows

* Enhance OTA testing framework and scripts

* Improve local network IP detection in OTA helpers by implementing route-based detection as a primary method, falling back to interface scanning if necessary.

* Add support for unsigned OTA version testing

- Introduced a new script to test unsigned OTA updates with specific version checks.
- Updated Makefile to include the new test script for unsigned OTA.
- Enhanced existing E2E tests to validate version differences and ensure proper OTA behavior.
- Improved error handling for required environment variables in the testing framework.

* Update Makefile to include core E2E tests and enhance dev release validation

- Added `test_core_e2e.sh` script execution to both production and development release workflows.
- Improved user confirmation prompt before proceeding with the dev release.
- Added completion messages to indicate successful test execution and readiness for release.

* Enhance Makefile and testing scripts for improved OTA validation

- Added a new script execution for testing unsigned OTA updates in the Makefile.
- Updated E2E test configurations to exclude specific OTA tests and improve retry logic for video stream dimension retrieval.
- Refactored mouse round-trip tests to remove unnecessary settle time parameters.

* Final release confirmation of prod releases

* Cleanup OTA code: eliminate redundant parsing, TOCTOU, and duplication

- Remove double parseAndValidateKeyring call by threading validated
  keyring through fetchFromSingleKeyserver → fetchFromKeyservers →
  updateMemoryCache
- Extract getKeyring() helper to deduplicate VerifySignature and
  VerifySignatureFromFile preamble
- Replace os.Stat+os.Remove TOCTOU pattern with direct os.Remove
  ignoring os.ErrNotExist in downloadFile
- Remove unnecessary fs.existsSync in mock server handler; check
  signaturePath variable directly

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

* E2E: fix flaky tests, add unsigned OTA to dev test lane

- Fix mouse roundtrip flakiness by increasing MOUSE_SETTLE_MS (50→150ms)
- Export sshExec from helpers for ota-helpers.ts
- Reduce overly conservative delays (polling, animations, reconnects)
- Add waitForVideoDimensions helper with proper polling
- Improve ensureLocalAuthMode to try known passwords before SSH reset
- Add unsigned specific-version OTA test to `make test_e2e` target
- Build baseline + dev binary with pinned VERSION_DEV to avoid timestamp drift

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

* Remove stale dev_release checklist item from PR templates

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 18:26:23 +01:00
Adam Shiervani 13c5e55962 Rate limit login access (#1185)
* Set minimum chars and ratelimit on pw

* Implement onboarding flow for USB device tests by adding helper functions to handle welcome state and login. Enhance test setup to ensure device is ready before running tests.

* Refactor password handling by removing rate limiting checks from update and delete password functions. Update UI error handling to remove rate limit messages. Clean up related test cases for rate limiting.

* Refactor welcome flow and password handling in tests. Consolidate password setup functions and enhance local authentication mode checks. Update test cases to streamline onboarding and password management processes.

* Update log file paths in DEVELOPMENT.md

* Add password validation messages for multiple languages

- Added error message for passwords that are too short (minimum 8 characters).
- Included rate limiting error message for too many failed attempts.
- Updated localization files for Danish, German, Spanish, French, Italian, Japanese, Norwegian, Portuguese, Swedish, and both Simplified and Traditional Chinese.

* Update noder version in DEVELOPMENT.md

* Fix typo in log file path in DEVELOPMENT.md

* Refactor device onboarding and authentication flow in tests

- Renamed `ensureWelcomeState` to `resetDeviceToWelcome` for clarity.
- Consolidated password handling in welcome flow tests, replacing deprecated functions.
- Updated test setup to ensure device is in noPassword mode before running tests.
- Removed unused functions and cleaned up related test cases for better maintainability.

* Refactor mouse round-trip tests to streamline cursor movement verification
2026-02-08 10:19:28 +01:00
Adam Shiervani 4011536cc3 improve mouse bidirectional check (#1197) 2026-02-07 21:50:40 +01:00
Adam Shiervani 13dd58a204 Improve tests (#1134) 2026-01-06 13:04:52 +01:00
Adam Shiervani d1cecfe73a Add OTA Update E2E Tests (#1106)
* Implement local update testing framework with Makefile integration and E2E tests

- Added `scripts/test_local_update.sh` for orchestrating local OTA update tests.
- Modified `Makefile` to include a new `test_e2e` target that builds the binary and calls the new script.
- Created `ui/e2e/local-update-flow.spec.ts` for end-to-end testing of the update process.
- Enhanced UI components with `data-testid` attributes for better testability.
- Introduced `getCurrentVersion()` helper function to retrieve the app version from the `/metrics` endpoint.
- Ensured cleanup processes are robust, even on failure or interruption.

* Update Makefile and E2E test scripts for improved OTA testing and version management

- Bump version from 0.5.1 to 0.5.2 in the Makefile.
- Modify `test_e2e` target to use DEVICE_IP from environment or prompt for input.
- Replace `test_release_on_device.sh` with `test_local_update.sh` for consistency in testing.
- Enhance `test_local_update.sh` to include stable version retrieval from GitHub and improve logging.
- Remove deprecated `local-update-flow.spec.ts` and streamline E2E tests for better coverage.
- Refactor helper functions for clarity and maintainability in test scripts.

* Refactor E2E test scripts and Makefile for improved clarity and functionality

- Update `Makefile` to streamline the `test_e2e` target by removing unnecessary dependencies and simplifying the Playwright installation command.
- Enhance `scripts/test_local_update.sh` by cleaning up logging, removing redundant output, and improving the structure for better readability.
- Update E2E test scripts to remove excessive console logging, ensuring a cleaner output during test execution.
- Refactor test steps for better organization and clarity, particularly in the OTA update flow tests.
- Adjust Playwright configuration to enable step printing for better visibility during test runs.

* Fix linting errors
2025-12-29 13:21:34 +01:00
Adam Shiervani 8769ac0dcd feat(e2e): add integration tests for config reset, HDMI sleep, and HTTPS mode (#1079) 2025-12-18 12:35:49 +01:00
Adam Shiervani ba60d0ad33 Improve E2E tests (#1063) 2025-12-15 10:57:21 +01:00
Adam Shiervani 428191b1d2 feat: basic automated e2e test (#1050) 2025-12-10 10:39:24 +01:00