diff --git a/Dockerfile.e2e.dev b/Dockerfile.e2e.dev new file mode 100644 index 000000000..f30073179 --- /dev/null +++ b/Dockerfile.e2e.dev @@ -0,0 +1,20 @@ +FROM node:22-bookworm + +# Install Angular CLI globally and curl for healthcheck +RUN npm install -g @angular/cli && apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/* + +WORKDIR /app + +# Copy everything (source needed for prepare script during npm install) +COPY . . + +# Install dependencies +RUN npm install --legacy-peer-deps + +# Default port (can be overridden via environment variable) +ENV APP_PORT=4242 + +EXPOSE ${APP_PORT} + +# Start Angular dev server with dynamic port +CMD ["sh", "-c", "ng serve --port ${APP_PORT} --host 0.0.0.0"] diff --git a/docker-compose.e2e.yaml b/docker-compose.e2e.yaml new file mode 100644 index 000000000..46cecc5d3 --- /dev/null +++ b/docker-compose.e2e.yaml @@ -0,0 +1,44 @@ +services: + # Angular development server for E2E tests + app: + build: + context: . + dockerfile: Dockerfile.e2e.dev + ports: + - '${APP_PORT:-4242}:${APP_PORT:-4242}' + environment: + - APP_PORT=${APP_PORT:-4242} + healthcheck: + test: ['CMD', 'curl', '-sf', 'http://localhost:${APP_PORT:-4242}'] + interval: 10s + timeout: 5s + retries: 30 + start_period: 120s + + # WebDAV sync server (for sync tests) + webdav: + image: hacdias/webdav:latest + ports: + - '${WEBDAV_PORT:-2345}:${WEBDAV_PORT:-2345}' + environment: + - PORT=${WEBDAV_PORT:-2345} + volumes: + - ./webdav.yaml:/config.yml:ro + - webdav_data:/data + healthcheck: + test: + [ + 'CMD', + 'wget', + '--quiet', + '--tries=1', + '--spider', + 'http://localhost:${WEBDAV_PORT:-2345}/', + ] + interval: 10s + timeout: 5s + retries: 3 + start_period: 10s + +volumes: + webdav_data: diff --git a/e2e/playwright.config.ts b/e2e/playwright.config.ts index eb0efeb80..356cff383 100644 --- a/e2e/playwright.config.ts +++ b/e2e/playwright.config.ts @@ -67,7 +67,7 @@ export default defineConfig({ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ use: { /* Base URL to use in actions like `await page.goto('/')`. */ - baseURL: 'http://localhost:4242', + baseURL: process.env.E2E_BASE_URL || 'http://localhost:4242', /* Collect trace on failure for better debugging. See https://playwright.dev/docs/trace-viewer */ trace: 'retain-on-failure', @@ -127,15 +127,18 @@ export default defineConfig({ ], /* Run your local dev server before starting the tests */ - webServer: { - command: 'npm run startFrontend:e2e', - url: 'http://localhost:4242', - reuseExistingServer: !process.env.CI, // Don't reuse in CI to ensure clean state - // unfortunately for CI we need to wait long for this to go up :( - timeout: 3 * 60 * 1000, // Allow up to 3 minutes for slower CI starts - stdout: 'ignore', // Reduce log noise - stderr: 'pipe', - }, + /* When E2E_BASE_URL is set (e.g., when using Docker), skip starting the server */ + webServer: process.env.E2E_BASE_URL + ? undefined + : { + command: 'npm run startFrontend:e2e', + url: 'http://localhost:4242', + reuseExistingServer: !process.env.CI, // Don't reuse in CI to ensure clean state + // unfortunately for CI we need to wait long for this to go up :( + timeout: 3 * 60 * 1000, // Allow up to 3 minutes for slower CI starts + stdout: 'ignore', // Reduce log noise + stderr: 'pipe', + }, /* Folder for test artifacts such as screenshots, videos, traces, etc. */ outputDir: path.join(__dirname, '..', '.tmp', 'e2e-test-results', 'test-results'), diff --git a/package.json b/package.json index 476b4b831..cdda3b533 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,8 @@ "e2e:show-report": "npx playwright show-report .tmp/e2e-test-results/playwright-report", "e2e:report": "PLAYWRIGHT_HTML_REPORT=1 npx playwright test --config e2e/playwright.config.ts", "e2e:webdav": "docker compose up -d webdav && ./scripts/wait-for-webdav.sh && npm run e2e -- --grep webdav; docker compose down", + "e2e:docker": "docker compose -f docker-compose.e2e.yaml up -d app && ./scripts/wait-for-app.sh && E2E_BASE_URL=http://localhost:${APP_PORT:-4242} npm run e2e; docker compose -f docker-compose.e2e.yaml down", + "e2e:docker:webdav": "docker compose -f docker-compose.e2e.yaml up -d && ./scripts/wait-for-app.sh && ./scripts/wait-for-webdav.sh && E2E_BASE_URL=http://localhost:${APP_PORT:-4242} npm run e2e; docker compose -f docker-compose.e2e.yaml down", "electron": "NODE_ENV=PROD electron .", "electron:build": "tsc -p electron/tsconfig.electron.json", "electron:watch": "tsc -p electron/tsconfig.electron.json --watch", diff --git a/scripts/wait-for-app.sh b/scripts/wait-for-app.sh new file mode 100755 index 000000000..2e043ca49 --- /dev/null +++ b/scripts/wait-for-app.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# Wait for the Angular dev server to be ready + +PORT=${APP_PORT:-4242} +MAX_WAIT=${MAX_WAIT:-180} +INTERVAL=2 + +echo "Waiting for app on port $PORT (max ${MAX_WAIT}s)..." + +elapsed=0 +until curl -sf "http://localhost:$PORT" > /dev/null 2>&1; do + if [ $elapsed -ge $MAX_WAIT ]; then + echo "Timeout: App did not start within ${MAX_WAIT}s" + exit 1 + fi + sleep $INTERVAL + elapsed=$((elapsed + INTERVAL)) + echo " Still waiting... (${elapsed}s)" +done + +echo "App is ready on port $PORT!"