staging #3443
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Playwright Tests | |
| permissions: | |
| contents: read | |
| actions: read | |
| on: | |
| push: | |
| branches: [ main, staging ] | |
| paths-ignore: | |
| - '**/*.md' | |
| - 'LICENSE.txt' | |
| - 'helm/**' | |
| - '.github/workflows/helm-chart.yml' | |
| - '.github/dependabot.yml' | |
| pull_request: | |
| branches: [ main, staging ] | |
| paths-ignore: | |
| - '**/*.md' | |
| - 'LICENSE.txt' | |
| - 'helm/**' | |
| - '.github/workflows/helm-chart.yml' | |
| - '.github/dependabot.yml' | |
| workflow_call: | |
| secrets: | |
| RUN_BROWSER_TESTS: | |
| required: true | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| setup-and-build: | |
| name: Setup, cache dependencies, and build | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 | |
| with: | |
| node-version: 24 | |
| cache: 'npm' | |
| - name: Cache node modules | |
| id: cache-npm | |
| uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 | |
| with: | |
| path: | | |
| ~/.npm | |
| node_modules | |
| ~/.cache/ms-playwright | |
| key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/playwright.config.ts') }}-${{ hashFiles('.github/workflows/playwright.yml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/playwright.config.ts') }}- | |
| ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}- | |
| ${{ runner.os }}-node- | |
| - name: Install dependencies with enhanced retry logic | |
| if: steps.cache-npm.outputs.cache-hit != 'true' | |
| run: | | |
| # Configure npm for better reliability | |
| npm config set registry https://registry.npmjs.org/ | |
| npm config set fetch-retries 5 | |
| npm config set fetch-retry-factor 2 | |
| npm config set fetch-retry-mintimeout 10000 | |
| npm config set fetch-retry-maxtimeout 60000 | |
| npm config set maxsockets 1 | |
| # Install with retry logic | |
| for i in {1..5}; do | |
| echo "Attempt $i: Installing dependencies..." | |
| if npm install --prefer-offline --no-audit --progress=false --loglevel=error; then | |
| echo "Dependencies installed successfully on attempt $i" | |
| break | |
| else | |
| echo "Attempt $i failed" | |
| if [ $i -eq 5 ]; then | |
| echo "All 5 attempts failed. Exiting." | |
| exit 1 | |
| fi | |
| # Progressive backoff with cache cleaning | |
| npm cache clean --force 2>/dev/null || true | |
| sleep_time=$((i * 20 + RANDOM % 30)) | |
| echo "⏳ Waiting ${sleep_time}s before retry..." | |
| sleep $sleep_time | |
| fi | |
| done | |
| - name: Install Playwright Browsers | |
| run: npx playwright install --with-deps chromium firefox | |
| - name: Build application | |
| run: npm run build | |
| - name: Upload build output | |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 | |
| with: | |
| name: nextjs-build-${{ github.run_id }} | |
| path: .next/ | |
| include-hidden-files: true | |
| retention-days: 1 | |
| if-no-files-found: error | |
| test-shards: | |
| name: Run tests (shard ${{ matrix.shard }}/6) | |
| needs: setup-and-build | |
| timeout-minutes: 60 | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| shard: [1, 2, 3, 4, 5, 6] | |
| services: | |
| falkordb: | |
| image: falkordb/falkordb:latest | |
| ports: | |
| - 6379:6379 | |
| falkordb-pat: | |
| image: falkordb/falkordb:latest | |
| ports: | |
| - 6380:6379 | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 | |
| with: | |
| node-version: 24 | |
| cache: 'npm' | |
| - name: Restore dependencies cache | |
| uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 | |
| with: | |
| path: | | |
| ~/.npm | |
| node_modules | |
| ~/.cache/ms-playwright | |
| key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/playwright.config.ts') }}-${{ hashFiles('.github/workflows/playwright.yml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/playwright.config.ts') }}- | |
| ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}- | |
| ${{ runner.os }}-node- | |
| - name: Download build output | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: nextjs-build-${{ github.run_id }} | |
| path: .next/ | |
| - name: Run Playwright tests (shard ${{ matrix.shard }} of 6) | |
| env: | |
| OPENAI_TOKEN: ${{ secrets.OPENAI_TOKEN }} | |
| run: | | |
| export CHAT_URL="http://localhost:8080/" | |
| export NEXTAUTH_URL="http://localhost:3000/" | |
| export NEXTAUTH_SECRET=SECRET | |
| export ENCRYPTION_KEY="a3f5d8c2b7e4f1a0c9d6e8b2f5a7c3d1e9f2a4b8c6d3e7f1a5b9c2d8e4f0a6b3" | |
| export PAT_FALKORDB_HOST=localhost | |
| export PAT_FALKORDB_PORT=6380 | |
| export PAT_FALKORDB_USERNAME=default | |
| export PAT_FALKORDB_PASSWORD="" | |
| export PAT_FALKORDB_GRAPH_NAME=token_management | |
| npm start > nextjs.log 2>&1 & | |
| timeout 60s bash -c 'while !</dev/tcp/localhost/3000; do sleep 1; done' | |
| npx playwright test \ | |
| --grep-invert "@tls|@cluster" \ | |
| --project="[Admin] Chromium" \ | |
| --project="[Read-Write] - Chromium" \ | |
| --project="[Read-Only] - Chromium" \ | |
| --project="[Admin: Settings - Chromium]" \ | |
| --shard=${{ matrix.shard }}/6 \ | |
| --workers=4 \ | |
| --reporter=dot,list | |
| - name: Upload test results | |
| if: always() | |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 | |
| with: | |
| name: playwright-results-shard-${{ matrix.shard }}-${{ github.run_id }} | |
| path: test-results/ | |
| retention-days: 3 | |
| if-no-files-found: ignore | |
| - name: Upload HTML report | |
| if: always() | |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 | |
| with: | |
| name: playwright-report-shard-${{ matrix.shard }}-${{ github.run_id }} | |
| path: playwright-report/ | |
| retention-days: 30 | |
| if-no-files-found: ignore | |
| - name: Upload server logs | |
| if: always() | |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 | |
| with: | |
| name: nextjs-logs-shard-${{ matrix.shard }}-${{ github.run_id }} | |
| path: nextjs.log | |
| retention-days: 3 | |
| if-no-files-found: ignore | |
| run-tls-tests: | |
| name: Run TLS tests | |
| needs: setup-and-build | |
| timeout-minutes: 60 | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 | |
| with: | |
| node-version: 24 | |
| cache: 'npm' | |
| - name: Restore dependencies cache | |
| uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 | |
| with: | |
| path: | | |
| ~/.npm | |
| node_modules | |
| ~/.cache/ms-playwright | |
| key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/playwright.config.ts') }}-${{ hashFiles('.github/workflows/playwright.yml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/playwright.config.ts') }}- | |
| ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}- | |
| ${{ runner.os }}-node- | |
| - name: Download build output | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: nextjs-build-${{ github.run_id }} | |
| path: .next/ | |
| - name: Setup TLS certificates | |
| run: | | |
| mkdir -p tls | |
| # Start container in background and wait for certificate generation | |
| CONTAINER_ID=$(docker run --rm -d -e TLS=1 -v $(pwd)/tls:/var/lib/falkordb/tls falkordb/falkordb:latest) | |
| echo "Started certificate generation container: $CONTAINER_ID" | |
| # Wait for certificates to be generated (look for "Ready to accept connections tls") | |
| timeout 300 bash -c ' | |
| while ! docker logs '"$CONTAINER_ID"' 2>&1 | grep -q "Ready to accept connections tls"; do | |
| echo "Waiting for certificate generation..." | |
| sleep 5 | |
| done | |
| ' || true | |
| # Stop the container gracefully once certificates are ready | |
| echo "Certificates generated, stopping container..." | |
| docker stop $CONTAINER_ID || true | |
| echo "Generated certificates:" | |
| ls -la tls/ | |
| - name: Create Redis TLS config | |
| run: | | |
| cat > redis.conf << 'EOF' | |
| protected-mode no | |
| tls-port 6379 | |
| port 0 | |
| tls-cert-file /var/lib/falkordb/tls/redis.crt | |
| tls-key-file /var/lib/falkordb/tls/redis.key | |
| tls-ca-cert-file /var/lib/falkordb/tls/ca.crt | |
| tls-auth-clients no | |
| EOF | |
| - name: Start FalkorDB with TLS | |
| run: | | |
| echo "Starting FalkorDB with TLS configuration..." | |
| docker run --rm -d --name falkordb-tls -p 6379:6379 \ | |
| -v $(pwd)/redis.conf:/var/lib/falkordb/data/redis.conf \ | |
| -e REDIS_ARGS="/var/lib/falkordb/data/redis.conf" \ | |
| -v $(pwd)/tls:/var/lib/falkordb/tls \ | |
| falkordb/falkordb:latest | |
| echo "Container started with ID: $(docker ps -q -f name=falkordb-tls)" | |
| - name: Wait for FalkorDB TLS to be ready | |
| run: | | |
| echo "Waiting a moment for container to fully start..." | |
| sleep 3 | |
| echo "Checking container status:" | |
| docker ps -a --filter name=falkordb-tls | |
| if docker ps --filter name=falkordb-tls --filter status=running | grep -q falkordb-tls; then | |
| echo "Container is running successfully" | |
| sleep 10 | |
| echo "Container logs:" | |
| docker logs falkordb-tls | |
| echo "Checking if TLS port is available:" | |
| docker exec falkordb-tls redis-cli --version || echo "Redis CLI not available" | |
| else | |
| echo "Container failed to start or exited. Full container details:" | |
| docker ps -a --filter name=falkordb-tls | |
| echo "Getting logs from container (even if exited):" | |
| docker logs falkordb-tls 2>&1 || echo "No logs available" | |
| echo "Checking if port 6379 is in use:" | |
| netstat -ln | grep :6379 || echo "Port 6379 not in use" | |
| echo "Checking Redis config file:" | |
| cat redis.conf | |
| echo "Checking TLS certificate files:" | |
| ls -la tls/ | |
| echo "Testing certificate validity:" | |
| openssl x509 -in tls/redis.crt -text -noout | head -10 || echo "Invalid certificate" | |
| exit 1 | |
| fi | |
| - name: Run TLS tests | |
| run: | | |
| NEXTAUTH_SECRET=SECRET npm start > nextjs.log 2>&1 & | |
| timeout 60s bash -c 'while !</dev/tcp/localhost/3000; do sleep 1; done' | |
| npx playwright test --workers=1 --reporter=dot,list --project="[TLS - Chromium]" --project="[TLS - Firefox]" | |
| - name: Cleanup TLS certificates | |
| if: always() | |
| run: | | |
| rm -rf tls/ | |
| rm -f redis.conf | |
| - name: Stop FalkorDB TLS container | |
| if: always() | |
| run: docker stop falkordb-tls || true | |
| - name: Upload test results | |
| if: always() | |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 | |
| with: | |
| name: playwright-results-tls-${{ github.run_id }} | |
| path: test-results/ | |
| retention-days: 3 | |
| if-no-files-found: ignore | |
| - name: Upload HTML report | |
| if: always() | |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 | |
| with: | |
| name: playwright-report-tls-${{ github.run_id }} | |
| path: playwright-report/ | |
| retention-days: 30 | |
| if-no-files-found: ignore | |
| - name: Upload server logs | |
| if: always() | |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 | |
| with: | |
| name: nextjs-logs-tls-${{ github.run_id }} | |
| path: nextjs.log | |
| retention-days: 3 | |
| if-no-files-found: ignore | |
| run-cluster-tests: | |
| name: Run cluster tests | |
| needs: setup-and-build | |
| timeout-minutes: 60 | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 | |
| with: | |
| node-version: 24 | |
| cache: 'npm' | |
| - name: Restore dependencies cache | |
| uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 | |
| with: | |
| path: | | |
| ~/.npm | |
| node_modules | |
| ~/.cache/ms-playwright | |
| key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/playwright.config.ts') }}-${{ hashFiles('.github/workflows/playwright.yml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/playwright.config.ts') }}- | |
| ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}- | |
| ${{ runner.os }}-node- | |
| - name: Download build output | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: nextjs-build-${{ github.run_id }} | |
| path: .next/ | |
| - name: Start FalkorDB cluster nodes | |
| run: | | |
| echo "Starting 3 FalkorDB cluster nodes..." | |
| # Start node1 on port 6380 | |
| docker run -d \ | |
| --name node1 \ | |
| -p 6380:6379 \ | |
| -e BROWSER=0 \ | |
| -e "REDIS_ARGS=--protected-mode no" \ | |
| falkordb/falkordb | |
| # Start node2 on port 6381 | |
| docker run -d \ | |
| --name node2 \ | |
| -p 6381:6379 \ | |
| -e BROWSER=0 \ | |
| -e "REDIS_ARGS=--protected-mode no" \ | |
| falkordb/falkordb | |
| # Start node3 on port 6382 | |
| docker run -d \ | |
| --name node3 \ | |
| -p 6382:6379 \ | |
| -e BROWSER=0 \ | |
| -e "REDIS_ARGS=--protected-mode no" \ | |
| falkordb/falkordb | |
| echo "All cluster nodes started" | |
| - name: Wait for cluster nodes to be ready | |
| run: | | |
| echo "Waiting for cluster nodes to initialize..." | |
| sleep 30 | |
| echo "Checking cluster node connectivity:" | |
| # Check each port with timeout and retry | |
| for port in 6380 6381 6382; do | |
| echo "Testing connection to localhost:$port..." | |
| max_attempts=10 | |
| attempt=1 | |
| while [ $attempt -le $max_attempts ]; do | |
| if nc -zv localhost $port 2>/dev/null; then | |
| echo "Port $port is accessible (attempt $attempt)" | |
| break | |
| else | |
| echo "Port $port not ready yet (attempt $attempt/$max_attempts)" | |
| if [ $attempt -eq $max_attempts ]; then | |
| echo "Port $port failed to become accessible after $max_attempts attempts" | |
| docker logs node$((port - 6379)) || echo "Failed to get logs for node$((port - 6379))" | |
| exit 1 | |
| fi | |
| sleep 3 | |
| fi | |
| attempt=$((attempt + 1)) | |
| done | |
| done | |
| echo "All cluster nodes are accessible!" | |
| # Show container status | |
| echo "Container status:" | |
| docker ps --filter "name=node[1-3]" | |
| # Show brief logs for each node | |
| for i in {1..3}; do | |
| echo "--- Node$i logs (last 5 lines) ---" | |
| docker logs node$i 2>&1 | tail -5 || echo "No logs available for node$i" | |
| done | |
| - name: Run cluster tests | |
| run: | | |
| NEXTAUTH_SECRET=SECRET npm start > nextjs.log 2>&1 & | |
| timeout 60s bash -c 'while !</dev/tcp/localhost/3000; do sleep 1; done' | |
| npx playwright test --grep "@cluster" --workers=4 --reporter=dot,list | |
| - name: Cleanup cluster | |
| if: always() | |
| run: | | |
| echo "Stopping and removing cluster nodes..." | |
| for i in {1..3}; do | |
| docker stop node$i || true | |
| docker rm node$i || true | |
| done | |
| - name: Upload test results | |
| if: always() | |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 | |
| with: | |
| name: playwright-results-cluster-${{ github.run_id }} | |
| path: test-results/ | |
| retention-days: 3 | |
| if-no-files-found: ignore | |
| - name: Upload HTML report | |
| if: always() | |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 | |
| with: | |
| name: playwright-report-cluster-${{ github.run_id }} | |
| path: playwright-report/ | |
| retention-days: 30 | |
| if-no-files-found: ignore | |
| - name: Upload server logs | |
| if: always() | |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 | |
| with: | |
| name: nextjs-logs-cluster-${{ github.run_id }} | |
| path: nextjs.log | |
| retention-days: 3 | |
| if-no-files-found: ignore | |