Skip to content

Commit 72b2a49

Browse files
author
K
committed
Add comprehensive test framework for nr-web
- Set up Vitest for unit/integration tests and Playwright for E2E tests - Docker-first approach: all tests run in containers by default - Implemented 64 tests covering: * Unit tests: key management, relay management (14 tests) * Integration tests: modals, forms, status messages (26 tests) * E2E tests: onboarding, settings, map, note posting (24 tests) - Added test fixtures and helpers for reusable test data - Created Makefile and docker-compose for easy test execution - Updated documentation with testing guidelines All tests passing. Framework is simple, effective, and easily expandable.
1 parent 51dd0ae commit 72b2a49

32 files changed

Lines changed: 2028 additions & 0 deletions

nr-web/.dockerignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
node_modules
2+
.playwright
3+
coverage
4+
.vitest
5+
test-results
6+
playwright-report
7+
playwright/.cache
8+
*.log
9+
.DS_Store
10+
.git
11+
.gitignore

nr-web/.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,10 @@ next-env.d.ts
3838
# OS
3939
.DS_Store
4040
Thumbs.db
41+
42+
# Test artifacts
43+
coverage
44+
.vitest
45+
test-results
46+
playwright-report
47+
playwright/.cache

nr-web/Dockerfile

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
FROM node:20-slim
2+
3+
WORKDIR /app
4+
5+
# Install system dependencies for Playwright
6+
RUN apt-get update && apt-get install -y \
7+
libnss3 \
8+
libnspr4 \
9+
libatk1.0-0 \
10+
libatk-bridge2.0-0 \
11+
libcups2 \
12+
libdrm2 \
13+
libdbus-1-3 \
14+
libxkbcommon0 \
15+
libxcomposite1 \
16+
libxdamage1 \
17+
libxfixes3 \
18+
libxrandr2 \
19+
libgbm1 \
20+
libasound2 \
21+
&& rm -rf /var/lib/apt/lists/*
22+
23+
# Install pnpm
24+
RUN npm install -g pnpm
25+
26+
# Copy package files from monorepo root
27+
COPY package.json pnpm-lock.yaml* ./
28+
COPY pnpm-workspace.yaml ./
29+
30+
# Copy nr-web package.json
31+
COPY nr-web/package.json ./nr-web/
32+
33+
# Install dependencies
34+
# Skip postinstall scripts since patch-package is for nr-app, not nr-web tests
35+
# If lockfile is outdated, it will be updated during install
36+
# In CI environments, ensure lockfile is up to date before building
37+
RUN pnpm install --frozen-lockfile --ignore-scripts || ( \
38+
echo "⚠️ Lockfile outdated. Updating..." && \
39+
pnpm install --no-frozen-lockfile --ignore-scripts \
40+
)
41+
42+
# Install Playwright browsers (Chromium only for smaller image)
43+
RUN cd nr-web && npx playwright install chromium --with-deps
44+
45+
# Copy test files and source (will be overridden by volume mount in docker-compose)
46+
COPY nr-web/ ./nr-web/
47+
48+
WORKDIR /app/nr-web
49+
50+
# Default command runs all tests
51+
CMD ["pnpm", "test:local:all"]

nr-web/Makefile

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
.PHONY: test test-watch test-ui test-e2e test-all build check-docker help
2+
3+
# Default target
4+
.DEFAULT_GOAL := help
5+
6+
# Check Docker is available
7+
check-docker:
8+
@bash scripts/check-docker.sh
9+
10+
# Update lockfile before building (if needed)
11+
update-lockfile:
12+
@echo "Updating pnpm lockfile..."
13+
cd .. && pnpm install
14+
15+
# Build the Docker image
16+
build: check-docker
17+
@echo "Building test Docker image..."
18+
@echo "Note: If build fails due to outdated lockfile, run: make update-lockfile"
19+
docker-compose build
20+
21+
# Run all tests (default)
22+
test: build
23+
@echo "Running all tests in Docker..."
24+
docker-compose run --rm tests
25+
26+
# Run tests in watch mode
27+
test-watch: build
28+
@echo "Running tests in watch mode..."
29+
docker-compose run --rm tests pnpm test:local:watch
30+
31+
# Run tests with UI
32+
test-ui: build
33+
@echo "Running tests with UI (accessible on http://localhost:51204)..."
34+
docker-compose run --rm -p 51204:51204 tests pnpm test:local:ui
35+
36+
# Run E2E tests only
37+
test-e2e: build
38+
@echo "Running E2E tests in Docker..."
39+
docker-compose run --rm tests pnpm test:local:e2e
40+
41+
# Run unit/integration tests only
42+
test-unit: build
43+
@echo "Running unit/integration tests in Docker..."
44+
docker-compose run --rm tests pnpm test:local
45+
46+
# Run with coverage
47+
test-coverage: build
48+
@echo "Running tests with coverage..."
49+
docker-compose run --rm tests pnpm test:local:coverage
50+
51+
# Clean up Docker resources
52+
clean:
53+
@echo "Cleaning up Docker resources..."
54+
docker-compose down -v
55+
docker system prune -f
56+
57+
# Help message
58+
help:
59+
@echo "nr-web Test Commands (Docker-first):"
60+
@echo ""
61+
@echo " make test - Run all tests (default)"
62+
@echo " make test-watch - Run tests in watch mode"
63+
@echo " make test-ui - Run tests with UI (http://localhost:51204)"
64+
@echo " make test-e2e - Run E2E tests only"
65+
@echo " make test-unit - Run unit/integration tests only"
66+
@echo " make test-coverage - Run tests with coverage"
67+
@echo " make build - Build Docker image"
68+
@echo " make update-lockfile - Update pnpm lockfile (if build fails)"
69+
@echo " make clean - Clean up Docker resources"
70+
@echo ""
71+
@echo "Note: All tests run in Docker by default for consistency."
72+
@echo "For local execution (not recommended), use: pnpm test:local:*"

nr-web/README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,17 @@ This web app provides similar functionality to the `nr-app` mobile app:
2222

2323
## Development Notes
2424

25+
### Testing
26+
27+
Tests are designed to run in Docker by default for consistency and safety. See [tests/README.md](tests/README.md) for details.
28+
29+
**Quick test commands:**
30+
```bash
31+
make test # Run all tests
32+
make test-watch # Watch mode
33+
make test-e2e # E2E tests only
34+
```
35+
2536
### Committing Changes
2637

2738
The repository has pre-commit hooks that run ESLint on the `nr-app` folder. Since `nr-web` is a standalone HTML file and doesn't use the same tooling, you should skip the pre-commit hook when committing changes that only affect `nr-web`:

nr-web/RUN_TESTS.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# Running Tests for nr-web
2+
3+
## Docker-First Approach
4+
5+
**All tests should be run in Docker by default.** This ensures:
6+
- Consistent environment across all developers
7+
- Same Node.js version
8+
- Proper system dependencies for Playwright
9+
- Isolated test execution
10+
- Reproducible results
11+
12+
## Quick Start
13+
14+
```bash
15+
# From the nr-web directory
16+
make test
17+
```
18+
19+
This will:
20+
1. Build the Docker image (if needed)
21+
2. Run all tests (unit, integration, and E2E)
22+
3. Clean up the container after completion
23+
24+
## Available Commands
25+
26+
### Using Make (Recommended)
27+
28+
```bash
29+
make test # Run all tests
30+
make test-watch # Watch mode for development
31+
make test-ui # Run with Vitest UI (http://localhost:51204)
32+
make test-e2e # E2E tests only
33+
make test-unit # Unit/integration tests only
34+
make test-coverage # Run with coverage report
35+
make build # Build Docker image manually
36+
make clean # Clean up Docker resources
37+
make help # Show all commands
38+
```
39+
40+
### Using Docker Compose Directly
41+
42+
```bash
43+
# Run all tests
44+
docker-compose run --rm tests
45+
46+
# Run specific test suite
47+
docker-compose run --rm tests pnpm test:local
48+
docker-compose run --rm tests pnpm test:local:e2e
49+
50+
# Watch mode
51+
docker-compose run --rm tests pnpm test:local:watch
52+
53+
# With UI
54+
docker-compose run --rm -p 51204:51204 tests pnpm test:local:ui
55+
```
56+
57+
## Local Execution (Not Recommended)
58+
59+
If you must run tests locally (not recommended):
60+
61+
```bash
62+
# Install dependencies
63+
pnpm install
64+
65+
# Run tests locally
66+
pnpm test:local
67+
pnpm test:local:watch
68+
pnpm test:local:e2e
69+
```
70+
71+
**Warning**: Local execution may have issues:
72+
- Missing Playwright system dependencies
73+
- Different Node.js versions
74+
- Platform-specific behavior differences
75+
- Environment variable differences
76+
77+
## CI/CD Integration
78+
79+
In CI environments, tests automatically run in Docker:
80+
81+
```yaml
82+
# Example GitHub Actions
83+
- name: Run tests
84+
run: |
85+
cd nr-web
86+
make test
87+
```
88+
89+
## Troubleshooting
90+
91+
### Docker image won't build - Lockfile outdated
92+
93+
If you see an error about `pnpm-lock.yaml` being outdated:
94+
95+
```bash
96+
# Update the lockfile in the monorepo root
97+
cd ..
98+
pnpm install
99+
cd nr-web
100+
101+
# Then rebuild
102+
make build
103+
```
104+
105+
Or use the convenience command:
106+
```bash
107+
make update-lockfile
108+
make build
109+
```
110+
111+
### Docker image won't build - Other issues
112+
```bash
113+
# Clean and rebuild
114+
make clean
115+
make build
116+
```
117+
118+
### Tests fail in Docker but work locally
119+
This is expected - Docker is the source of truth. Fix the tests to work in Docker.
120+
121+
### Permission issues
122+
```bash
123+
# Clean volumes
124+
make clean
125+
```
126+
127+
### Port conflicts
128+
If port 8080 or 51204 are in use, modify `docker-compose.yml` to use different ports.

nr-web/docker-compose.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
services:
2+
tests:
3+
build:
4+
context: ..
5+
dockerfile: nr-web/Dockerfile
6+
volumes:
7+
# Mount source code for development (allows code changes without rebuild)
8+
- ../nr-web:/app/nr-web
9+
# Mount node_modules from container to avoid permission issues
10+
- test-node-modules:/app/nr-web/node_modules
11+
working_dir: /app/nr-web
12+
# Default command runs all tests
13+
command: pnpm test:local:all
14+
# Environment variables
15+
environment:
16+
- CI=${CI:-false}
17+
# Expose ports for E2E test server and Vitest UI
18+
ports:
19+
- "8080:8080" # E2E test server
20+
- "51204:51204" # Vitest UI (if needed)
21+
# Use bridge network (default) - works better than host mode in most environments
22+
23+
volumes:
24+
test-node-modules:

nr-web/package.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name": "@trustroots/nr-web",
3+
"type": "module",
4+
"version": "1.0.0",
5+
"private": true,
6+
"scripts": {
7+
"pretest": "bash scripts/check-docker.sh || exit 1",
8+
"test": "echo '⚠️ Tests must be run in Docker for consistency.' && echo 'Use: make test' && echo 'Or: docker-compose run --rm tests' && exit 1",
9+
"test:docker": "docker-compose run --rm tests",
10+
"test:docker:watch": "docker-compose run --rm tests pnpm test:local:watch",
11+
"test:docker:ui": "docker-compose run --rm -p 51204:51204 tests pnpm test:local:ui",
12+
"test:docker:e2e": "docker-compose run --rm tests pnpm test:local:e2e",
13+
"test:docker:all": "docker-compose run --rm tests pnpm test:local:all",
14+
"test:local": "vitest run",
15+
"test:local:watch": "vitest",
16+
"test:local:ui": "vitest --ui",
17+
"test:local:coverage": "vitest run --coverage",
18+
"test:local:e2e": "playwright test",
19+
"test:local:e2e:ui": "playwright test --ui",
20+
"test:local:all": "pnpm test:local && pnpm test:local:e2e"
21+
},
22+
"devDependencies": {
23+
"@playwright/test": "^1.40.0",
24+
"@vitest/ui": "^1.0.0",
25+
"jsdom": "^23.0.0",
26+
"vitest": "^1.0.0"
27+
}
28+
}

nr-web/playwright.config.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { defineConfig } from '@playwright/test';
2+
import { fileURLToPath } from 'url';
3+
import { dirname, resolve } from 'path';
4+
5+
const __dirname = dirname(fileURLToPath(import.meta.url));
6+
7+
export default defineConfig({
8+
testDir: resolve(__dirname, 'tests/e2e'),
9+
use: {
10+
baseURL: 'http://localhost:8080',
11+
screenshot: 'only-on-failure',
12+
video: 'retain-on-failure',
13+
trace: 'on-first-retry',
14+
},
15+
webServer: {
16+
command: 'node tests/server.js',
17+
port: 8080,
18+
cwd: __dirname,
19+
reuseExistingServer: !process.env.CI,
20+
},
21+
});

nr-web/scripts/check-docker.sh

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/bin/bash
2+
# Script to check if Docker is available and enforce Docker usage
3+
4+
set -e
5+
6+
if ! command -v docker &> /dev/null; then
7+
echo "❌ Docker is not installed or not in PATH"
8+
echo "Please install Docker to run tests: https://docs.docker.com/get-docker/"
9+
exit 1
10+
fi
11+
12+
if ! docker info &> /dev/null; then
13+
echo "❌ Docker daemon is not running"
14+
echo "Please start Docker and try again"
15+
exit 1
16+
fi
17+
18+
if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null; then
19+
echo "❌ docker-compose is not available"
20+
echo "Please install docker-compose or use 'docker compose' (Docker Compose V2)"
21+
exit 1
22+
fi
23+
24+
echo "✅ Docker is available"
25+
exit 0

0 commit comments

Comments
 (0)