E2e test fw lite#1866
Conversation
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
UI unit Tests 1 files 59 suites 28s ⏱️ Results for commit 8c9969c. ♻️ This comment has been updated with latest results. |
|
The latest updates on your projects. Learn more about Argos notifications ↗︎
|
3a3f357 to
f79a76d
Compare
| name: E2E Tests | ||
| needs: [frontend] | ||
| runs-on: ubuntu-latest | ||
| env: | ||
| FW_LITE_BINARY_PATH: ${{ github.workspace }}/backend/FwLite/artifacts/publish/FwLiteWeb/release_linux-x64/FwLiteWeb | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| submodules: true | ||
| - uses: actions/download-artifact@v4 | ||
| with: | ||
| name: fw-lite-viewer-js | ||
| path: ${{ env.VIEWER_BUILD_OUTPUT_DIR }} | ||
| - uses: actions/setup-dotnet@v4 | ||
| with: | ||
| dotnet-version: '9.x' | ||
| - name: Publish FwLiteWeb (linux-x64) | ||
| working-directory: backend/FwLite/FwLiteWeb | ||
| run: dotnet publish -r linux-x64 --artifacts-path ../artifacts -p:PublishSingleFile=true | ||
|
|
||
| - name: set execute permissions | ||
| shell: bash | ||
| run: chmod +x ${{ env.FW_LITE_BINARY_PATH }} | ||
|
|
||
| - name: Install Task | ||
| uses: arduino/setup-task@b91d5d2c96a56797b48ac1e0e89220bf64044611 #v2 | ||
| with: | ||
| repo-token: ${{ secrets.GITHUB_TOKEN }} | ||
| - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0 | ||
| with: | ||
| package_json_file: 'frontend/package.json' | ||
| - uses: actions/setup-node@v4 | ||
| with: | ||
| node-version-file: './frontend/package.json' | ||
| cache: 'pnpm' | ||
| cache-dependency-path: './frontend/pnpm-lock.yaml' | ||
| - name: Install frontend deps | ||
| working-directory: frontend | ||
| run: pnpm install | ||
| - name: Test FwLite launcher | ||
| working-directory: frontend/viewer | ||
| run: task e2e-test-helper-unit-tests | ||
|
|
||
| - uses: ./.github/actions/setup-k8s | ||
| with: | ||
| lexbox-api-tag: develop | ||
| ingress-controller-port: '6579' # http; only used by the action's own curl-verify step | ||
| repo-token: ${{ secrets.GITHUB_TOKEN }} | ||
|
|
||
| # MSAL refuses any non-https authority. ingress-nginx serves a snake-oil | ||
| # cert that FwLite trusts via --environment Development and playwright via | ||
| # ignoreHTTPSErrors. | ||
| - name: Forward ingress HTTPS port | ||
| shell: bash | ||
| run: | | ||
| kubectl port-forward service/ingress-nginx-controller 6580:443 -n languagedepot >/tmp/https-port-forward.log 2>&1 & | ||
| # Wait for the port-forward to actually be listening | ||
| for i in $(seq 1 30); do | ||
| if curl -sk https://localhost:6580 >/dev/null 2>&1; then | ||
| echo "✅ HTTPS port-forward ready on :6580" | ||
| exit 0 | ||
| fi | ||
| sleep 1 | ||
| done | ||
| echo "❌ HTTPS port-forward did not become ready" | ||
| cat /tmp/https-port-forward.log | ||
| exit 1 | ||
|
|
||
| - name: Cache Playwright browsers | ||
| uses: actions/cache@v4 | ||
| id: playwright-cache | ||
| with: | ||
| path: ~/.cache/ms-playwright | ||
| key: ${{ runner.os }}-playwright-${{ hashFiles('frontend/pnpm-lock.yaml') }} | ||
| - name: Install Playwright browsers | ||
| if: steps.playwright-cache.outputs.cache-hit != 'true' | ||
| working-directory: frontend/viewer | ||
| run: pnpm exec playwright install --with-deps | ||
|
|
||
| - name: Run E2E tests | ||
| working-directory: frontend/viewer | ||
| env: | ||
| TEST_SERVER_PROTOCOL: https | ||
| TEST_SERVER_PORT: 6580 | ||
| run: task test:e2e | ||
|
|
||
| - name: Upload Playwright results/traces (on failure) | ||
| if: failure() | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: fw-lite-e2e-test-results | ||
| if-no-files-found: ignore | ||
| path: frontend/viewer/tests/e2e/test-results/ | ||
|
|
||
| - name: Capture k8s pod logs (on failure) | ||
| if: failure() | ||
| shell: bash | ||
| run: | | ||
| mkdir -p k8s-logs | ||
| for app in lexbox ui hg db fw-headless; do | ||
| kubectl describe pods -l "app=${app}" -n languagedepot > k8s-logs/describe-${app}.txt 2>&1 || true | ||
| kubectl logs -l "app=${app}" -n languagedepot --prefix --all-containers --tail=-1 > k8s-logs/logs-${app}.txt 2>&1 || true | ||
| done | ||
| kubectl logs -l 'app.kubernetes.io/name=ingress-nginx' -n languagedepot --prefix --all-containers --tail=-1 > k8s-logs/logs-ingress.txt 2>&1 || true | ||
|
|
||
| - name: Upload k8s logs (on failure) | ||
| if: failure() | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: fw-lite-e2e-k8s-logs | ||
| if-no-files-found: ignore | ||
| path: k8s-logs/*.txt |
Spins up a real `FwLiteWeb` binary against a kind-cluster lexbox in CI and
drives it from a Playwright-controlled Chromium. Two scenarios so far: a
smoke test (login + see server projects) and a full project-download test
(triggers an initial CRDT sync via the lexbox API, then downloads sena-3
through the FwLite UI). Both run end-to-end against a fresh kind cluster.
Test infrastructure
- New `frontend/viewer/tests/e2e/` directory with playwright.config.ts,
fixtures, helpers, and the integration test file.
- Existing snapshot tests moved to `tests/snapshots/`; package.json scripts
split into `test:snapshots` and `test:e2e`.
- New vitest `integration` project for `tests/integration/fw-lite-launcher.test.ts`
(node env, hard-fails when the binary is missing). `pnpm test` excludes
it via `--project=!integration` so unrelated jobs don't need the binary.
- Vitest `browser` project restored (was dropped accidentally during
earlier cleanup) so existing `*.browser.test.ts` files keep running.
Workflow (`.github/workflows/fw-lite.yaml`)
- New `e2e-test` job depending only on `frontend` (fast-lane — parallel
with `build-and-test`). Does its own `dotnet publish -r linux-x64` so
it doesn't wait for `publish-linux`.
- Spins up lexbox via `setup-k8s`, then port-forwards ingress-nginx :443
to localhost:6580 (MSAL.NET refuses non-HTTPS authorities; the snake-oil
cert is trusted via `--environment Development` and playwright's
`ignoreHTTPSErrors: true`).
- On failure, uploads playwright traces/screenshots/videos AND a dump of
k8s pod logs (`kubectl describe`/`logs` for lexbox/ui/hg/db/fw-headless/
ingress-nginx) — pattern lifted from `integration-test-gha.yaml`.
- Caches `~/.cache/ms-playwright` keyed on pnpm-lock hash across the three
jobs that run `playwright install --with-deps` (frontend,
frontend-component-unit-tests, e2e-test).
- Adds `permissions:` blocks to satisfy least-privilege guidelines.
Backend (FwLite)
- `FwLiteWeb`: `/health` endpoint (used by the launcher's readiness probe),
`DELETE /api/crdt/{code}` for per-test cleanup, stdin-triggered shutdown
(Windows can't SIGTERM child processes; launcher writes "shutdown\n").
- `AuthRoutes`: redirect-after-login fallback to `/` when the referer is
the auth endpoint itself.
- `HomeView.svelte` / `Server.svelte`: stable anchor IDs (`#local-projects`,
`id={server?.id}`) for Playwright selectors.
Deployment
- `deployment/gha/lexbox.patch.yaml`: trust-all `KnownNetworks` override so
lexbox honors `X-Forwarded-Proto: https` from the kind ingress controller
(without this, lexbox emits HTTP URLs in `/.well-known/openid-configuration`
even though the request came in over HTTPS, breaking the OAuth redirect).
Iteration history is preserved in branch `e2e-test-fw-lite-backup-pre-squash`.
- Poll for entry rows in ProjectPage.waitFor: the table shell renders before all entries hydrate, so a one-shot count was racing. - afterEach: navigate back to home before logout. The download test ends on the project page, where serverSection isn't visible. - fw-lite workflow: cancel-in-progress concurrency group so iterating on a PR doesn't stack up Windows + e2e lanes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The shadcnMode-removal commit (3c30769) dropped the `<script module>` block, which also held `import {onMount} from 'svelte'`. The regular script still calls `onMount(() => onloaded(true))`, so without the import the page crashed on mount, `onloaded` never fired, ProjectLoader never resolved, and all 21 UI tests timed out waiting for the Filter textbox. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Extract serverUrl(server) helper; drop duplicated URL building - Inline single-use logoutFromServer wrapper - Extract launchConfig() helper in launcher tests - Name launcher constants (DEFAULT_LAUNCH_TIMEOUT_MS, READY_STDOUT_MARKERS) - Fix latent hang in FwLiteLauncher.spawnProcess: clean early exits (code=0 before the listening marker) now reject instead of hanging - Tighten JSDoc, keeping the substantive why Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Resolves: #1511
Kevin: I started working on this with Kiro, but then ditched it as it was going in the wrong direction and creating a bunch of fluff