Skip to content

Add browser end-to-end test for multiple sync sources #77

Add browser end-to-end test for multiple sync sources

Add browser end-to-end test for multiple sync sources #77

Workflow file for this run

name: Code tests & eval
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
jobs:
check:
name: Type check
runs-on: ubuntu-22.04
steps:
- name: Checkout source
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with: { persist-credentials: false }
- name: Setup environment
uses: ./.github/actions/common-setup
- name: svelte-check
run: pnpm check
test:
name: Unit tests
runs-on: ubuntu-22.04
steps:
- name: Checkout source
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with: { persist-credentials: false }
- name: Setup environment
uses: ./.github/actions/common-setup
- name: vitest
run: pnpm test
build:
name: Production build
runs-on: ubuntu-22.04
steps:
- name: Checkout source
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with: { persist-credentials: false }
- name: Setup environment
uses: ./.github/actions/common-setup
- name: Build production bundle
run: pnpm build
- name: Upload dist artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: dist-${{ github.sha }}
path: dist/
retention-days: 7
smoke:
name: Smoke (real sync-server)
runs-on: ubuntu-22.04
timeout-minutes: 10
# Pin sync-server by digest so this test can never silently shift if `latest`
# is republished. Refresh intentionally when targeting a different release.
services:
sync-server:
image: ghcr.io/d4rken-org/octi-server@sha256:3829efba5ca5a4d407a0d0a048b8d0c20264ad2f9e389aa087c857ea0d0bddaa
ports:
- 18080:8080
env:
OCTI_CORS_ALLOWED_ORIGINS: 'http://127.0.0.1:5173,http://localhost:5173'
sync-server-b:
image: ghcr.io/d4rken-org/octi-server@sha256:3829efba5ca5a4d407a0d0a048b8d0c20264ad2f9e389aa087c857ea0d0bddaa
ports:
- 18081:8080
env:
OCTI_CORS_ALLOWED_ORIGINS: 'http://127.0.0.1:5173,http://localhost:5173'
steps:
- name: Checkout source
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with: { persist-credentials: false }
- name: Setup environment
uses: ./.github/actions/common-setup
- name: Wait for sync-servers
run: |
set -euo pipefail
for port in 18080 18081; do
for attempt in $(seq 1 30); do
if curl -sf "http://127.0.0.1:${port}/v1/status" > /dev/null; then
echo "sync-server on ${port} up after ${attempt}s"
continue 2
fi
sleep 1
done
echo "sync-server on ${port} did not respond within 30s" >&2
docker logs ${{ job.services.sync-server.id }} || true
docker logs ${{ job.services['sync-server-b'].id }} || true
exit 1
done
- name: Run smoke suite
env:
SMOKE_SERVER_URL: http://127.0.0.1:18080
SMOKE_SERVER_B_URL: http://127.0.0.1:18081
run: pnpm test:smoke
- name: Dump sync-server logs on failure
if: failure()
run: |
docker logs ${{ job.services.sync-server.id }} || true
docker logs ${{ job.services['sync-server-b'].id }} || true
release-tooling:
name: Release tooling
runs-on: ubuntu-22.04
steps:
- name: Checkout source
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with: { persist-credentials: false }
- name: Install bats + shellcheck
run: |
sudo apt-get update
sudo apt-get install -y bats shellcheck
- name: Shellcheck bump.sh
run: shellcheck tools/release/bump.sh
- name: Run bump.sh unit tests
run: bats tools/release/bump.bats
- name: Verify package.json + bump.sh are consistent
run: tools/release/bump.sh --mode=check
e2e-smoke:
name: E2E smoke
runs-on: ubuntu-22.04
timeout-minutes: 20
# Mirrors the release-tag.yml e2e job at lower cost: bootstrap a fake phone
# peer, build the SPA, drive it through Playwright with no screenshots.
# Catches selector/bootstrap drift on every PR/main push so a release tag
# never surfaces these surprises for the first time. A second sync-server
# backs the multi-connector spec (link the SPA to two servers via the UI).
services:
sync-server:
image: ghcr.io/d4rken-org/octi-server@sha256:3829efba5ca5a4d407a0d0a048b8d0c20264ad2f9e389aa087c857ea0d0bddaa
ports:
- 18080:8080
env:
OCTI_CORS_ALLOWED_ORIGINS: 'http://127.0.0.1:4173,http://localhost:4173'
sync-server-b:
image: ghcr.io/d4rken-org/octi-server@sha256:3829efba5ca5a4d407a0d0a048b8d0c20264ad2f9e389aa087c857ea0d0bddaa
ports:
- 18081:8080
env:
OCTI_CORS_ALLOWED_ORIGINS: 'http://127.0.0.1:4173,http://localhost:4173'
steps:
- name: Checkout source
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with: { persist-credentials: false }
- name: Setup environment
uses: ./.github/actions/common-setup
- name: Wait for sync-servers
run: |
set -euo pipefail
for port in 18080 18081; do
for attempt in $(seq 1 30); do
if curl -sf "http://127.0.0.1:${port}/v1/status" > /dev/null; then
echo "sync-server on ${port} up after ${attempt}s"
continue 2
fi
sleep 1
done
echo "sync-server on ${port} did not respond within 30s" >&2
docker logs ${{ job.services.sync-server.id }} || true
docker logs ${{ job.services['sync-server-b'].id }} || true
exit 1
done
# Three bootstrap files with independent one-time-use share codes:
# bootstrap-peer.json (server A) — the single-connector smoke spec
# peer-a.json (server A), peer-b.json (server B) — the multi-connector spec
# Separate files so the two specs never redeem the same code.
- name: Bootstrap fake phone peer (smoke, server A)
env:
SYNC_SERVER_URL: http://127.0.0.1:18080
OUTPUT_PATH: bootstrap-peer.json
run: pnpm bootstrap-peer
- name: Bootstrap fake phone peer (multi, server A)
env:
SYNC_SERVER_URL: http://127.0.0.1:18080
OUTPUT_PATH: peer-a.json
run: pnpm bootstrap-peer
- name: Bootstrap fake phone peer (multi, server B)
env:
SYNC_SERVER_URL: http://127.0.0.1:18081
OUTPUT_PATH: peer-b.json
run: pnpm bootstrap-peer
- name: Install Playwright browsers
run: pnpm exec playwright install --with-deps chromium
- name: Build SPA (stable channel for smoke)
env:
VITE_CHANNEL: stable
VITE_COMMIT_SHA: ${{ github.sha }}
run: pnpm build
- name: Run E2E smoke
env:
BOOTSTRAP_PEER_FILE: bootstrap-peer.json
run: pnpm e2e:smoke
- name: Run E2E multi-connector
env:
BOOTSTRAP_PEER_A_FILE: peer-a.json
BOOTSTRAP_PEER_B_FILE: peer-b.json
run: pnpm e2e:multi
- name: Dump sync-server logs on failure
if: failure()
run: |
docker logs ${{ job.services.sync-server.id }} || true
docker logs ${{ job.services['sync-server-b'].id }} || true
- name: Upload Playwright trace on failure
if: failure()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: playwright-trace-${{ github.run_id }}
path: |
test-results/
playwright-report/
if-no-files-found: ignore