Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 6 additions & 6 deletions .claude/plugins/test-automation/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
"version": "1.0.0",
"description": "Multi-agent test automation workflow for UShadow - from specification to test implementation",
"agents": [
"spec-agent.md",
"qa-agent.md",
"automation-agent.md"
"agents/spec-agent.md",
"agents/qa-agent.md",
"agents/automation-agent.md"
],
"skills": [
"spec.md",
"qa-test-cases.md",
"automate-tests.md"
"skills/spec.md",
"skills/qa-test-cases.md",
"skills/automate-tests.md"
]
}
5 changes: 5 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"enabledPlugins": {
"test-automation": true
}
}
64 changes: 62 additions & 2 deletions .github/workflows/pr-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,22 @@ jobs:
run: |
uv pip install --system -e ".[dev]"

- name: Run unit tests (no secrets required)
- name: Run stable tests (no secrets required)
env:
CI: "true"
SKIP_INTEGRATION: "false"
run: |
pytest -m "no_secrets" --cov=src --cov-report=xml --cov-report=term
# Run only stable tests (exclude TDD tests that are expected to fail)
pytest -m "no_secrets and not tdd" --cov=src --cov-report=xml --cov-report=term

- name: Run TDD tests (allowed to fail)
env:
CI: "true"
SKIP_INTEGRATION: "false"
run: |
# Run TDD tests separately - these are expected to fail
pytest -m "tdd" --verbose || echo "TDD tests failed as expected"
continue-on-error: true

- name: Upload coverage reports
uses: codecov/codecov-action@v4
Expand Down Expand Up @@ -132,3 +142,53 @@ jobs:
if: always()
run: |
docker compose -f ../../docker-compose.test.yml down -v

robot-tests:
name: Robot Framework Tests (Secrets Required)
runs-on: ubuntu-latest
# Only run on workflow_dispatch or when explicitly requested
if: github.event_name == 'workflow_dispatch'

steps:
- uses: actions/checkout@v4

- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Install Robot Framework dependencies
working-directory: robot_tests
run: |
pip install -r requirements.txt

- name: Start backend services
run: |
docker compose up -d mongodb redis backend

- name: Wait for backend to be healthy
run: |
timeout 60 bash -c 'until curl -f http://localhost:8080/health; do sleep 2; done'

- name: Run Robot Framework tests
working-directory: robot_tests
env:
TAILSCALE_AUTH_KEY: ${{ secrets.TAILSCALE_AUTH_KEY }}
TAILSCALE_API_KEY: ${{ secrets.TAILSCALE_API_KEY }}
run: |
robot --outputdir . tests/

- name: Upload Robot test results
uses: actions/upload-artifact@v4
if: always()
with:
name: robot-test-results
path: |
robot_tests/log.html
robot_tests/report.html
robot_tests/output.xml

- name: Cleanup services
if: always()
run: |
docker compose down -v
111 changes: 95 additions & 16 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Quick commands for development and deployment
# All compose operations delegate to setup/run.py for single source of truth

.PHONY: help up down restart logs build clean test go install status health dev prod \
.PHONY: help up down restart logs build clean test test-integration test-tdd test-all test-robot test-robot-api test-robot-features test-robot-quick test-robot-critical test-report go install status health dev prod \
svc-list svc-restart svc-start svc-stop svc-status \
chronicle-env-export chronicle-build-local chronicle-up-local chronicle-down-local chronicle-dev \
release
Expand Down Expand Up @@ -49,10 +49,24 @@ help:
@echo " make svc-stop SVC=x - Stop a service"
@echo ""
@echo "Development commands:"
@echo " make install - Install Python dependencies"
@echo " make test - Run tests"
@echo " make lint - Run linters"
@echo " make format - Format code"
@echo " make install - Install Python dependencies"
@echo " make lint - Run linters"
@echo " make format - Format code"
@echo ""
@echo "Testing commands (Pyramid approach):"
@echo " Backend (pytest):"
@echo " make test - Fast unit tests (~seconds)"
@echo " make test-integration - Integration tests (need services running)"
@echo " make test-all - All backend tests (unit + integration)"
@echo " make test-tdd - TDD tests (expected failures)"
@echo ""
@echo " API/E2E (Robot Framework):"
@echo " make test-robot-quick - Quick smoke tests (~30s)"
@echo " make test-robot-critical - Critical path tests only"
@echo " make test-robot-api - All API integration tests"
@echo " make test-robot-features - Feature-level tests"
@echo " make test-robot - All Robot tests (full suite)"
@echo " make test-report - View last test report in browser"
@echo ""
@echo "Cleanup commands:"
@echo " make clean-logs - Remove log files"
Expand Down Expand Up @@ -230,26 +244,91 @@ health:
# Development commands
install:
@echo "📦 Installing dependencies..."
@if command -v uv > /dev/null 2>&1; then \
cd ushadow/backend && uv pip install -r requirements.txt; \
else \
echo "⚠️ uv not found, using pip (slower). Run: ./scripts/install-uv.sh"; \
cd ushadow/backend && pip install -r requirements.txt; \
fi
cd frontend && npm install
@cd ushadow/backend && \
if [ ! -d .venv ]; then uv venv --python 3.12; fi && \
uv pip install -e ".[dev]" --python .venv/bin/python && \
uv pip install -r ../../robot_tests/requirements.txt --python .venv/bin/python
cd ushadow/frontend && npm install
@echo "✅ Dependencies installed"

# =============================================================================
# Backend Tests (pytest) - Test Pyramid Base
# =============================================================================

# Fast unit tests only (no services needed) - should complete in seconds
test:
cd ushadow/backend && pytest
cd frontend && npm test
@echo "🧪 Running unit tests..."
@cd ushadow/backend && .venv/bin/pytest -m "unit and not tdd" -q --tb=short

# Integration tests (need MongoDB, Redis running)
test-integration:
@echo "🧪 Running integration tests..."
@cd ushadow/backend && .venv/bin/pytest -m "integration and not tdd" -v --tb=short

# TDD tests (expected to fail - for tracking progress)
test-tdd:
@echo "🧪 Running TDD tests (expected failures)..."
@cd ushadow/backend && .venv/bin/pytest -m "tdd" -v

# All backend tests (unit + integration, excludes TDD)
test-all:
@echo "🧪 Running all backend tests..."
@cd ushadow/backend && .venv/bin/pytest -m "not tdd" -v --tb=short

# =============================================================================
# Robot Framework Tests (API/E2E) - Test Pyramid Top
# =============================================================================

# Quick smoke tests - health checks and critical paths (~30 seconds)
test-robot-quick:
@echo "🤖 Running quick smoke tests..."
@cd ushadow/backend && source .venv/bin/activate && \
robot --outputdir ../../robot_results \
--include quick \
../../robot_tests/api/api_health_check.robot \
../../robot_tests/api/service_config_scenarios.robot

# Critical path tests only - must-pass scenarios
test-robot-critical:
@echo "🤖 Running critical path tests..."
@cd ushadow/backend && source .venv/bin/activate && \
robot --outputdir ../../robot_results \
--include critical \
../../robot_tests/api/

# All API integration tests
test-robot-api:
@echo "🤖 Running all API tests..."
@cd ushadow/backend && source .venv/bin/activate && \
robot --outputdir ../../robot_results \
../../robot_tests/api/

# Feature-level tests (memory feedback, etc.)
test-robot-features:
@echo "🤖 Running feature tests..."
@cd ushadow/backend && source .venv/bin/activate && \
robot --outputdir ../../robot_results \
../../robot_tests/features/

# All Robot tests (full suite) - may take several minutes
test-robot:
@echo "🤖 Running full Robot test suite..."
@cd ushadow/backend && source .venv/bin/activate && \
robot --outputdir ../../robot_results \
../../robot_tests/

# View last test report in browser
test-report:
@echo "📊 Opening test report..."
@open robot_results/report.html || xdg-open robot_results/report.html 2>/dev/null || echo "Report at: robot_results/report.html"

lint:
cd ushadow/backend && ruff check .
cd frontend && npm run lint
cd ushadow/frontend && npm run lint

format:
cd ushadow/backend && ruff format .
cd frontend && npm run format
cd ushadow/frontend && npm run format

# Cleanup commands
clean:
Expand Down
5 changes: 2 additions & 3 deletions compose/backend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,15 @@ services:
- PROJECT_ROOT=${PROJECT_ROOT:-${PWD}}
# Compose project name for per-environment Tailscale containers
- COMPOSE_PROJECT_NAME=${COMPOSE_PROJECT_NAME:-ushadow}
# Config directory location
- CONFIG_DIR=/config
- MONGODB_DATABBASE=${MONGODB_DATABASE:-ushadow}
- MONGODB_DATABASE=${MONGODB_DATABASE:-ushadow}
- CORS_ORIGINS=${CORS_ORIGINS:-http://localhost:5173,http://localhost:3000,http://localhost:${WEBUI_PORT}}
volumes:
- ../ushadow/backend:/app
- ../config:/config # Mount config directory (read-write for feature flags)
- ../compose:/compose # Mount compose files for service management
- /app/__pycache__
- /app/.pytest_cache
- /app/.venv # Mask host .venv - container uses its own venv from image
# Docker socket for container management (Tailscale container control)
- /var/run/docker.sock:/var/run/docker.sock
networks:
Expand Down
2 changes: 2 additions & 0 deletions config/config.defaults.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ transcription:

# Service-Specific Preferences (not shared across services)
service_preferences:
chronicle:
database: ushadow
openmemory:
enable_graph: false
neo4j_password: null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Health Endpoint Returns 200 OK
[Documentation] Health endpoint should always return 200 even if services are degraded
...
... This allows monitoring systems to detect the service is running
[Tags] health smoke api
[Tags] health smoke api quick

${response}= GET On Session ${SESSION} ${HEALTH_ENDPOINT}
... expected_status=200
Expand Down
Loading
Loading