Skip to content

Add Kind for CI E2E testing, improve local test workflow#20

Merged
oldsj merged 27 commits into
mainfrom
test-env
Jan 5, 2026
Merged

Add Kind for CI E2E testing, improve local test workflow#20
oldsj merged 27 commits into
mainfrom
test-env

Conversation

@oldsj

@oldsj oldsj commented Jan 3, 2026

Copy link
Copy Markdown
Owner

Summary

Add Kind (Kubernetes in Docker) for CI E2E testing and improve local test workflow. This enables testing actual K8s job spawning in CI while keeping fast Docker Compose tests for local development.

CI E2E Testing (Kind)

  • Add GitHub Actions workflow with Kind cluster for E2E tests
  • Matrix builds for parallel Docker image creation
  • Comprehensive caching (pnpm, Playwright browsers, Docker layers)
  • Fix API_URL default (8081 → 8000) to match Kind port mapping

Fast Local Testing (Docker Compose)

  • Add make test with mock Claude and hot reload for rapid iteration
  • Backend restarts automatically on file changes via watchexec
  • Frontend uses Vite dev server with HMR

Local Kind Testing (optional)

  • Add make test-e2e for testing K8s job spawning locally
  • Test scripts use --context flag to avoid changing shell's kubectl context
  • Kind management scripts (create, load images, secrets, deploy, reset)

Kustomize Restructure

  • Move prod-specific resources (HTTPRoute, CloudNativePG) to prod overlay
  • Fix deprecation warnings (use patches instead of patchesJson6902)
  • Test overlay uses simple Postgres StatefulSet

Test Reliability

  • Remove flaky waitForTimeout() calls - use specific conditions
  • Fix mobile tab navigation tests with proper selectors
  • Add retries in CI for transient failures

Test plan

  • make test runs locally with Docker Compose
  • make test-e2e runs locally with Kind cluster
  • CI workflow passes

🤖 Generated with Claude Code

oldsj and others added 17 commits January 3, 2026 11:14
- Add single `make test-e2e` command that auto-creates Kind cluster
- Build images using Docker cache from dev/deploy builds
- Test scripts use --context flag to avoid changing shell's kubectl context
- Restructure Kustomize overlays: move prod-specific resources (HTTPRoute, CloudNativePG) to prod overlay
- Fix Kustomize deprecation warnings (use `patches` instead of `patchesJson6902`)
- Add GitHub Actions workflow for E2E tests with Kind
- Create Kind management scripts (create, load images, secrets, deploy, reset)
- Update CLAUDE.md with simplified E2E testing workflow

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The .python-version file is gitignored and not needed since the
base image already specifies python3.13-bookworm-slim.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Caching improvements:
- pnpm store: Cache npm packages between runs
- Playwright browsers: Cache chromium binary
- Docker layers: Use GitHub Actions cache for all images

Docker buildx with GHA cache backend provides:
- Persistent layer caching across runs
- mode=max caches all intermediate layers
- Separate scopes for backend/frontend/agent

Expected speedup: 5-10x faster builds after first run.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Replace hardcoded http://localhost:3031 with baseURL-relative
paths (/) so tests respect PLAYWRIGHT_BASE_URL env var.

This fixes CI where tests run on port 3000 instead of 3031.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Changes:
- Separate build job with matrix strategy (true parallelism)
- Each image builds on its own runner concurrently
- Images saved as artifacts and transferred to test job
- Free up disk space before loading images
- Load images one at a time to minimize disk usage

Benefits:
- Faster builds (true parallel, not just backgrounded)
- Better visibility in GitHub UI (separate jobs)
- Isolated build failures
- Optimized disk space usage

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The frontend Dockerfile requires pnpm-lock.yaml for deterministic
dependency installation, but it was gitignored.

Lockfiles should always be committed to ensure:
- Reproducible builds across environments
- Consistent dependency versions in CI/CD
- Protection against registry issues

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add explicit permissions block (contents: read, actions: read)
- Fix Playwright cache key to use root pnpm-lock.yaml
- Add restore-keys for better cache hit rates
- Upgrade docker/build-push-action to v6
- Pin helm/kind-action to v1.12.0
- Use merge-multiple for cleaner artifact downloads
- Replace bash polling loops with kubectl wait + curl retry

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add checks: write permission to lint job so trunk-action can post
annotations to GitHub.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove redundant quotes in YAML files (ci.yml, docker-compose.test.yml, configmap-patch.yaml)
- Add shellcheck directive for dynamic source in create-secrets.sh
- Auto-formatted various files (markdown, typescript, python)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Override cookie to ^0.7.0 to fix GHSA-pxg6-pf52-xh8x
(out of bounds characters in cookie name/path/domain).

SvelteKit pins cookie to ^0.6.0, so we use pnpm overrides
to force the patched version.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add extra_packages to prettier definition so trunk installs
prettier-plugin-svelte and prettier-plugin-tailwindcss in its
isolated runtime environment.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Download artifacts to /mnt (more disk space than /tmp)
- Load all 3 images into Docker in parallel
- Load all 3 images into Kind in parallel
- Clean up images in batch at the end

Should reduce image loading time from ~60s to ~20s.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add cleanup step to remove .NET, Android SDK, CodeQL (~10GB)
- Prune Docker images and build cache
- Use /tmp instead of /mnt (permission issues)
- Keep parallel image loading

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
CI:
- Use frontend/package.json for Playwright cache key (more stable)

Backend Dockerfile:
- Use NodeSource for Node.js 22
- Clean npm cache and temp files after claude-code install

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove disk space check and cleanup after loading
- Remove Free disk space step (28GB+ available)
- Keep parallel image loading

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add .message class to MessageBubble for Playwright selectors
- Set CLAUDE_MODEL=haiku in test environment for faster/cheaper tests

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
oldsj and others added 10 commits January 3, 2026 18:53
- Wait for loading to complete before checking response
- Use message count instead of visibility check for last message
- Remove check for "hello" which can scroll off screen

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create mobileTab store for reliable state management
- Use explicit store subscription in layout for consistent reactivity
- Fix Kind deploy script to properly wait for pod deletions
- Add make test-loop target for auto-redeploy on changes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The seed fixtures were using incorrect port mapping. In CI, the
frontend runs on port 3000 and backend on 8000, but the code was
trying to replace '3031' which doesn't match.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix mobile tab reactivity using $derived instead of broken $effect
- Fix seed_task_for_testing to use correct db method (get_main_thread_by_user)
- Use .first() for duplicate message matches in create-task test

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Streamline local testing workflow with:
- `make test`: Playwright UI with Docker backend + local Vite (hot reload)
- `make test-run`: CI mode for headless test runs
- Mock Claude responses (USE_MOCK_CLAUDE=true) for instant feedback
- Backend source mounted for live reload without rebuilds
- Simplified Playwright config using Vite dev server

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix Vite port conflict: add --strictPort flag to fail loudly instead
  of silently switching ports (root cause of flaky tests)
- Fix selector mismatch: replace non-existent [data-role="assistant"]
  with actual .message.bg-term-bg-secondary class
- Simplify test commands: both `make test` and `make test-run` use
  same Vite server (5173), `make test-ci` uses Docker for CI
- Add global-setup.ts and global-teardown.ts for test lifecycle
- Skip tests for unimplemented features (questions UI, error handling)
- Add resetTestData() calls to prevent state leakage between tests

Test results: 14 passing, 18 skipped (intentionally for unimplemented features)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add "Adding New Features (Docs → Specs → Tests)" section explaining
how to keep documentation and tests in sync using the three Playwright
agents: planner, generator, and healer.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add language specifiers to fenced code blocks in CLAUDE.md
- Use #### headings instead of bold text for steps
- Remove redundant quotes in docker-compose.test.yml command

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Change default API_URL from 8081 to 8000 to match Kind cluster port mapping.
CI runs tests against Kind without setting API_URL, so it needs the correct default.
Local docker-compose tests (make test) explicitly set API_URL=8081 via Makefile.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@oldsj oldsj changed the title Replace Docker Compose with Kind for E2E testing Add Kind for CI E2E testing, improve local test workflow Jan 5, 2026
@oldsj
oldsj merged commit 0c1fd22 into main Jan 5, 2026
6 checks passed
@oldsj
oldsj deleted the test-env branch January 5, 2026 03:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant