Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
28cc2cc
feat(e2e): overhaul E2E test suite with comprehensive flow coverage
CodeGhost21 Apr 9, 2026
fad483b
feat(e2e): overhaul E2E test suite with comprehensive flow coverage
CodeGhost21 Apr 9, 2026
04d1a43
fix(e2e): remove unused imports to pass lint
CodeGhost21 Apr 9, 2026
f084773
style: apply prettier formatting
CodeGhost21 Apr 9, 2026
98a49ee
Merge branch 'main' into e2e-flow
senamakel Apr 9, 2026
c233dc4
feat(e2e): split rewards/settings specs, fix Mac2 navigation and bill…
CodeGhost21 Apr 9, 2026
d153488
fix(e2e): harden assertions, fix Mac2 navigation, update Skills page …
CodeGhost21 Apr 9, 2026
507f9ed
chore(e2e): remove chat-skills-integrations from flow runner
CodeGhost21 Apr 9, 2026
0b6dd77
fix(e2e): add skillId to built-in card CTA buttons, fix E2E selectors
CodeGhost21 Apr 10, 2026
d3e3cbd
chore(e2e): harden E2E scripts, specs, CI workflow, and subconscious …
CodeGhost21 Apr 10, 2026
4c34f1d
fix(e2e): remove unused imports and variables flagged by lint
CodeGhost21 Apr 10, 2026
3a7a443
style(e2e): apply Prettier formatting to E2E helpers and specs
CodeGhost21 Apr 10, 2026
5ecba20
fix(ci): run full E2E spec list on all platforms, fix Linux RPC bridge
CodeGhost21 Apr 10, 2026
d8dc62a
Merge branch 'main' into e2e-flow
CodeGhost21 Apr 10, 2026
44303ae
Merge remote-tracking branch 'origin/main' into e2e-flow
CodeGhost21 Apr 10, 2026
99ed414
chore(e2e): scroll-aware assertions and spec tweaks across flow tests
CodeGhost21 Apr 10, 2026
3238133
ci(e2e): don't let one broken spec block the whole macOS job
CodeGhost21 Apr 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
215 changes: 153 additions & 62 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ on:
options:
- 'false'
- 'true'
run_windows_e2e:
description: 'Run Windows E2E tests (tauri-driver)'
required: false
default: 'false'
type: choice
options:
- 'false'
- 'true'

permissions:
contents: read
Expand Down Expand Up @@ -191,66 +199,149 @@ jobs:
mkdir -p ~/.local/share/applications
export RUST_BACKTRACE=1
cd app
# Core specs — must pass on Linux CI
FAILED=0
for spec in \
test/e2e/specs/login-flow.spec.ts \
test/e2e/specs/smoke.spec.ts \
test/e2e/specs/navigation.spec.ts \
test/e2e/specs/telegram-flow.spec.ts; do
SPEC_NAME=$(basename "$spec" .spec.ts)
echo "=== Running $SPEC_NAME ==="
bash scripts/e2e-run-spec.sh "$spec" "$SPEC_NAME" || {
echo "FAILED: $SPEC_NAME"
cat /tmp/tauri-driver-e2e-${SPEC_NAME}.log 2>/dev/null || true
FAILED=1
}
done
# Extended specs (auth, billing, gmail, notion, payments) are skipped
# on Linux CI — webkit2gtk text matching differences cause Settings
# page navigation timeouts. Full suite runs on macOS locally.
if [ "$FAILED" -eq 1 ]; then
echo "Core E2E specs failed"
exit 1
bash scripts/e2e-run-all-flows.sh

e2e-macos:
name: E2E (macOS / Appium)
if: >-
github.event_name == 'pull_request' ||
github.event_name == 'push' ||
(github.event_name == 'workflow_dispatch' && github.event.inputs.run_macos_e2e == 'true')
runs-on: macos-latest
timeout-minutes: 90
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 1
submodules: recursive

- name: Setup Node.js 24.x
uses: actions/setup-node@v4
with:
node-version: 24.x
cache: "yarn"

- name: Install Rust (rust-toolchain.toml)
uses: dtolnay/rust-toolchain@1.93.0

- name: Cargo.lock fingerprint (deps only)
id: cargo-lock-fingerprint
shell: bash
run: |
echo "hash=$(tail -n +8 Cargo.lock | openssl dgst -sha256 | awk '{print $2}')" >> "$GITHUB_OUTPUT"

- name: Cache Cargo registry and build
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-e2e-cargo-${{ steps.cargo-lock-fingerprint.outputs.hash }}
restore-keys: |
${{ runner.os }}-e2e-cargo-

- name: Install dependencies
run: yarn install --frozen-lockfile

- name: Ensure .env exists for E2E build
run: |
touch .env
touch app/.env

- name: Install Appium and mac2 driver
run: |
npm install -g appium
appium driver install mac2

- name: Build E2E app bundle
run: yarn workspace openhuman-app test:e2e:build

- name: Run E2E specs
run: |
cd app
bash scripts/e2e-run-all-flows.sh

e2e-windows:
name: E2E (Windows / tauri-driver)
if: >-
github.event_name == 'pull_request' ||
github.event_name == 'push' ||
(github.event_name == 'workflow_dispatch' && github.event.inputs.run_windows_e2e == 'true')
runs-on: windows-latest
timeout-minutes: 90
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 1
submodules: recursive

- name: Setup Node.js 24.x
uses: actions/setup-node@v4
with:
node-version: 24.x
cache: "yarn"

- name: Install Rust (rust-toolchain.toml)
uses: dtolnay/rust-toolchain@1.93.0
with:
targets: x86_64-pc-windows-msvc

- name: Cargo.lock fingerprint (deps only)
id: cargo-lock-fingerprint
shell: bash
run: |
echo "hash=$(tail -n +8 Cargo.lock | openssl dgst -sha256 | awk '{print $2}')" >> "$GITHUB_OUTPUT"

- name: Cache Cargo registry and build
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-e2e-cargo-${{ steps.cargo-lock-fingerprint.outputs.hash }}
restore-keys: |
${{ runner.os }}-e2e-cargo-

- name: Install tauri-driver
run: cargo install tauri-driver --version 2.0.5

- name: Install JS dependencies
run: yarn install --frozen-lockfile

- name: Ensure .env exists for E2E build
run: |
echo.> .env
echo.> app\.env
shell: cmd

- name: Build E2E app
run: yarn workspace openhuman-app test:e2e:build
shell: bash

- name: Stage sidecar next to app binary
shell: bash
run: |
# Copy the sidecar so the app can find it at runtime
SIDECAR_SRC="$(ls app/src-tauri/binaries/openhuman-core-*.exe 2>/dev/null | head -1)"
if [ -z "$SIDECAR_SRC" ]; then
echo "WARNING: No Windows sidecar found in binaries/, attempting to stage from target/"
SIDECAR_SRC="$(ls target/debug/openhuman-core.exe 2>/dev/null | head -1)"
fi
echo "Core E2E specs passed"

# e2e-macos:
# name: E2E (macOS / Appium)
# if: github.event_name == 'workflow_dispatch' && github.event.inputs.run_macos_e2e == 'true'
# runs-on: macos-latest
# timeout-minutes: 90
# steps:
# - name: Checkout code
# uses: actions/checkout@v4
# with:
# fetch-depth: 1
# submodules: recursive

# - name: Setup Node.js 24.x
# uses: actions/setup-node@v4
# with:
# node-version: 24.x
# cache: "yarn"

# - name: Install Rust (rust-toolchain.toml)
# uses: dtolnay/rust-toolchain@1.93.0

# - name: Install dependencies
# run: yarn install --frozen-lockfile

# - name: Ensure .env exists for E2E build
# run: |
# touch .env
# touch app/.env

# - name: Install Appium and mac2 driver
# run: |
# npm install -g appium
# appium driver install mac2

# - name: Build E2E app bundle
# run: yarn workspace openhuman-app test:e2e:build

# - name: Run all E2E flows
# run: yarn workspace openhuman-app test:e2e:all:flows
if [ -n "$SIDECAR_SRC" ]; then
cp "$SIDECAR_SRC" app/src-tauri/target/debug/openhuman-core-x86_64-pc-windows-msvc.exe
echo "Sidecar staged:"
ls -la app/src-tauri/target/debug/openhuman-core-*.exe app/src-tauri/target/debug/OpenHuman.exe
else
echo "WARNING: No sidecar binary found — tests that require core RPC will fail"
fi

- name: Run E2E tests
shell: bash
run: |
export RUST_BACKTRACE=1
cd app
bash scripts/e2e-run-all-flows.sh
2 changes: 1 addition & 1 deletion app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"test:e2e:auth": "bash ./scripts/e2e-auth.sh",
"test:e2e:service-connectivity": "OPENHUMAN_SERVICE_MOCK=1 bash ./scripts/e2e-run-spec.sh test/e2e/specs/service-connectivity-flow.spec.ts service-connectivity",
"test:e2e:skills-registry": "bash ./scripts/e2e-run-spec.sh test/e2e/specs/skills-registry.spec.ts skills-registry",
"test:e2e:skill-execution": "bash ./scripts/e2e-run-spec.sh test/e2e/specs/skill-execution-flow.spec.ts skill-execution",
"test:e2e:text-autocomplete": "bash ./scripts/e2e-run-spec.sh test/e2e/specs/text-autocomplete-flow.spec.ts text-autocomplete",
"test:e2e": "yarn test:e2e:build && yarn test:e2e:login && yarn test:e2e:auth",
"test:e2e:all:flows": "bash ./scripts/e2e-run-all-flows.sh",
"test:e2e:all": "yarn test:e2e:build && yarn test:e2e:all:flows",
Expand Down
2 changes: 1 addition & 1 deletion app/scripts/e2e-auth.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env bash
# Run E2E auth & access control tests only. See app/scripts/e2e-run-spec.sh.
set -euo pipefail
exec "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/e2e-run-spec.sh" "test/e2e/specs/auth-access-control.spec.ts" "auth"
exec "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/e2e-run-spec.sh" "test/e2e/specs/auth-session-management.spec.ts" "auth"
31 changes: 20 additions & 11 deletions app/scripts/e2e-build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
#
# Build the app for E2E tests with the mock server URL baked in.
#
# - macOS: builds a .app bundle (Appium Mac2)
# - Linux: builds a debug binary (tauri-driver)
# - macOS: builds a .app bundle (Appium Mac2)
# - Linux: builds a debug binary (tauri-driver)
# - Windows: builds a debug binary (tauri-driver)
#
# Cargo incremental builds are used by default for faster iteration.
#
Expand Down Expand Up @@ -45,14 +46,22 @@ TAURI_CONFIG_OVERRIDE='{"bundle":{"createUpdaterArtifacts":false}}'
case "${CI:-}" in 1) export CI=true ;; 0) export CI=false ;; esac

OS="$(uname)"
if [ "$OS" = "Linux" ]; then
# Linux: build debug binary only (no bundle needed for tauri-driver)
echo "Building for Linux (debug binary, no bundle)..."
npx tauri build -c "$TAURI_CONFIG_OVERRIDE" --debug --no-bundle
else
# macOS: build .app bundle for Appium Mac2
echo "Building for macOS (.app bundle)..."
npx tauri build -c "$TAURI_CONFIG_OVERRIDE" --bundles app --debug
fi
case "$OS" in
Linux)
# Linux: build debug binary only (no bundle needed for tauri-driver)
echo "Building for Linux (debug binary, no bundle)..."
npx tauri build -c "$TAURI_CONFIG_OVERRIDE" --debug --no-bundle
;;
MINGW*|MSYS*|CYGWIN*|Windows_NT)
# Windows: build debug binary only (tauri-driver, like Linux)
echo "Building for Windows (debug binary, no bundle)..."
npx tauri build -c "$TAURI_CONFIG_OVERRIDE" --debug --no-bundle
;;
*)
# macOS: build .app bundle for Appium Mac2
echo "Building for macOS (.app bundle)..."
npx tauri build -c "$TAURI_CONFIG_OVERRIDE" --bundles app --debug
;;
esac

echo "E2E build complete."
4 changes: 0 additions & 4 deletions app/scripts/e2e-crypto-payment.sh

This file was deleted.

4 changes: 0 additions & 4 deletions app/scripts/e2e-payment.sh

This file was deleted.

7 changes: 4 additions & 3 deletions app/scripts/e2e-resolve-node-appium.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ if [ "${NODE_MAJOR:-0}" -lt 24 ]; then
exit 1
fi

APPIUM_BIN="$(command -v appium 2>/dev/null || true)"
if [ -z "${APPIUM_BIN:-}" ] || [ ! -x "$APPIUM_BIN" ]; then
APPIUM_BIN="$(dirname "$NODE24")/appium"
# Prefer the appium binary that lives next to the resolved Node 24 binary.
APPIUM_BIN="$(dirname "$NODE24")/appium"
if [ ! -x "$APPIUM_BIN" ]; then
APPIUM_BIN="$(command -v appium 2>/dev/null || true)"
fi
if [ ! -x "$APPIUM_BIN" ]; then
echo "ERROR: appium not found. Install with: npm install -g appium" >&2
Expand Down
61 changes: 48 additions & 13 deletions app/scripts/e2e-run-all-flows.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,65 @@
# Run all E2E WDIO specs sequentially (Appium restarted per spec).
# Requires a prior E2E app build: yarn test:e2e:build
#
set -euo pipefail
# Failure policy: specs are independent, so one failing spec must NOT abort
# subsequent specs. We collect every failure and exit non-zero at the end
# with a summary, so CI sees the full picture instead of bailing on spec #1.
#
set -uo pipefail

APP_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$APP_DIR"

FAILED_SPECS=()
PASSED_SPECS=()

run() {
"$APP_DIR/scripts/e2e-run-spec.sh" "$1" "$2"
local spec="$1"
local label="$2"
echo ""
echo "============================================================"
echo "[e2e-run-all-flows] START $label ($spec)"
echo "============================================================"
if "$APP_DIR/scripts/e2e-run-spec.sh" "$spec" "$label"; then
echo "[e2e-run-all-flows] PASS $label"
PASSED_SPECS+=("$label")
else
local rc=$?
echo "[e2e-run-all-flows] FAIL $label (exit=$rc)"
FAILED_SPECS+=("$label")
fi
}

run "test/e2e/specs/macos-distribution.spec.ts" "macos-distribution"
run "test/e2e/specs/auth-session-management.spec.ts" "auth"
run "test/e2e/specs/permissions-system-access.spec.ts" "permissions-system-access"
# run "test/e2e/specs/local-model-runtime.spec.ts" "local-model"
run "test/e2e/specs/system-resource-access.spec.ts" "system-resource-access"
# run "test/e2e/specs/service-connectivity-flow.spec.ts" "service-connectivity"
run "test/e2e/specs/memory-system.spec.ts" "memory-system"
run "test/e2e/specs/automation-scheduling.spec.ts" "automation-scheduling"
run "test/e2e/specs/chat-interface-flow.spec.ts" "chat-interface"
run "test/e2e/specs/login-flow.spec.ts" "login"
run "test/e2e/specs/auth-access-control.spec.ts" "auth"
run "test/e2e/specs/telegram-flow.spec.ts" "telegram"
run "test/e2e/specs/discord-flow.spec.ts" "discord"
run "test/e2e/specs/gmail-flow.spec.ts" "gmail"
run "test/e2e/specs/notion-flow.spec.ts" "notion"
run "test/e2e/specs/card-payment-flow.spec.ts" "card-payment"
run "test/e2e/specs/crypto-payment-flow.spec.ts" "crypto-payment"
run "test/e2e/specs/conversations-web-channel-flow.spec.ts" "conversations"
run "test/e2e/specs/local-model-runtime.spec.ts" "local-model"
run "test/e2e/specs/screen-intelligence.spec.ts" "screen-intelligence"
OPENHUMAN_SERVICE_MOCK=1 run "test/e2e/specs/service-connectivity-flow.spec.ts" "service-connectivity"
run "test/e2e/specs/skills-registry.spec.ts" "skills-registry"
run "test/e2e/specs/skill-execution-flow.spec.ts" "skill-execution"
run "test/e2e/specs/navigation.spec.ts" "navigation"
run "test/e2e/specs/smoke.spec.ts" "smoke"
run "test/e2e/specs/tauri-commands.spec.ts" "tauri-commands"
run "test/e2e/specs/voice-mode.spec.ts" "voice-mode"
run "test/e2e/specs/text-autocomplete-flow.spec.ts" "text-autocomplete"
run "test/e2e/specs/rewards-flow.spec.ts" "rewards-flow"
run "test/e2e/specs/settings-flow.spec.ts" "settings-flow"
Comment on lines +35 to +53
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Don't drop the service-connectivity flow from the all-flows runner.

app/test/e2e/specs/service-connectivity-flow.spec.ts still owns the OPENHUMAN_SERVICE_MOCK=1 install/start/stop/restart coverage, and app/scripts/e2e-run-spec.sh still has dedicated state-file setup for that mode. Removing it here turns that path into dead coverage for the main E2E entrypoint.

↩️ Suggested addition
 run "test/e2e/specs/notion-flow.spec.ts" "notion"
 run "test/e2e/specs/screen-intelligence.spec.ts" "screen-intelligence"
+OPENHUMAN_SERVICE_MOCK=1 run "test/e2e/specs/service-connectivity-flow.spec.ts" "service-connectivity"
 run "test/e2e/specs/voice-mode.spec.ts" "voice-mode"
 run "test/e2e/specs/text-autocomplete-flow.spec.ts" "text-autocomplete"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
run "test/e2e/specs/macos-distribution.spec.ts" "macos-distribution"
run "test/e2e/specs/auth-session-management.spec.ts" "auth"
run "test/e2e/specs/permissions-system-access.spec.ts" "permissions-system-access"
run "test/e2e/specs/local-model-runtime.spec.ts" "local-model"
run "test/e2e/specs/system-resource-access.spec.ts" "system-resource-access"
run "test/e2e/specs/memory-system.spec.ts" "memory-system"
run "test/e2e/specs/automation-scheduling.spec.ts" "automation-scheduling"
run "test/e2e/specs/chat-interface-flow.spec.ts" "chat-interface"
run "test/e2e/specs/login-flow.spec.ts" "login"
run "test/e2e/specs/auth-access-control.spec.ts" "auth"
run "test/e2e/specs/telegram-flow.spec.ts" "telegram"
run "test/e2e/specs/discord-flow.spec.ts" "discord"
run "test/e2e/specs/gmail-flow.spec.ts" "gmail"
run "test/e2e/specs/notion-flow.spec.ts" "notion"
run "test/e2e/specs/card-payment-flow.spec.ts" "card-payment"
run "test/e2e/specs/crypto-payment-flow.spec.ts" "crypto-payment"
run "test/e2e/specs/conversations-web-channel-flow.spec.ts" "conversations"
run "test/e2e/specs/local-model-runtime.spec.ts" "local-model"
run "test/e2e/specs/screen-intelligence.spec.ts" "screen-intelligence"
OPENHUMAN_SERVICE_MOCK=1 run "test/e2e/specs/service-connectivity-flow.spec.ts" "service-connectivity"
run "test/e2e/specs/skills-registry.spec.ts" "skills-registry"
run "test/e2e/specs/skill-execution-flow.spec.ts" "skill-execution"
run "test/e2e/specs/navigation.spec.ts" "navigation"
run "test/e2e/specs/smoke.spec.ts" "smoke"
run "test/e2e/specs/tauri-commands.spec.ts" "tauri-commands"
run "test/e2e/specs/voice-mode.spec.ts" "voice-mode"
run "test/e2e/specs/text-autocomplete-flow.spec.ts" "text-autocomplete"
run "test/e2e/specs/rewards-flow.spec.ts" "rewards-flow"
run "test/e2e/specs/settings-flow.spec.ts" "settings-flow"
run "test/e2e/specs/macos-distribution.spec.ts" "macos-distribution"
run "test/e2e/specs/auth-session-management.spec.ts" "auth"
run "test/e2e/specs/permissions-system-access.spec.ts" "permissions-system-access"
run "test/e2e/specs/local-model-runtime.spec.ts" "local-model"
run "test/e2e/specs/system-resource-access.spec.ts" "system-resource-access"
run "test/e2e/specs/memory-system.spec.ts" "memory-system"
run "test/e2e/specs/automation-scheduling.spec.ts" "automation-scheduling"
run "test/e2e/specs/chat-interface-flow.spec.ts" "chat-interface"
run "test/e2e/specs/login-flow.spec.ts" "login"
run "test/e2e/specs/telegram-flow.spec.ts" "telegram"
run "test/e2e/specs/discord-flow.spec.ts" "discord"
run "test/e2e/specs/gmail-flow.spec.ts" "gmail"
run "test/e2e/specs/notion-flow.spec.ts" "notion"
run "test/e2e/specs/screen-intelligence.spec.ts" "screen-intelligence"
OPENHUMAN_SERVICE_MOCK=1 run "test/e2e/specs/service-connectivity-flow.spec.ts" "service-connectivity"
run "test/e2e/specs/voice-mode.spec.ts" "voice-mode"
run "test/e2e/specs/text-autocomplete-flow.spec.ts" "text-autocomplete"
run "test/e2e/specs/rewards-flow.spec.ts" "rewards-flow"
run "test/e2e/specs/settings-flow.spec.ts" "settings-flow"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/scripts/e2e-run-all-flows.sh` around lines 15 - 32, The all-flows runner
removed the service-connectivity flow and must re-add its run entry; insert a
line invoking the service-connectivity spec using the same pattern as the
others, e.g. run "test/e2e/specs/service-connectivity-flow.spec.ts"
"service-connectivity", so the OPENHUMAN_SERVICE_MOCK install/start/stop/restart
coverage and state-file handling in e2e-run-spec.sh remain exercised.


echo ""
echo "============================================================"
echo "[e2e-run-all-flows] SUMMARY"
echo "============================================================"
echo " Passed (${#PASSED_SPECS[@]}): ${PASSED_SPECS[*]:-<none>}"
echo " Failed (${#FAILED_SPECS[@]}): ${FAILED_SPECS[*]:-<none>}"

if [ "${#FAILED_SPECS[@]}" -gt 0 ]; then
echo "[e2e-run-all-flows] One or more specs failed — exiting non-zero."
exit 1
fi

echo "All E2E flows completed."
Loading
Loading