name: E2E Tests

on:
  push:
    branches: [master]
  pull_request:
    branches: [master]

concurrency:
  group: e2e-${{ github.ref }}
  cancel-in-progress: true

jobs:
  e2e:
    name: Playwright E2E
    runs-on: ubuntu-latest
    timeout-minutes: 20

    services:
      postgres:
        image: postgis/postgis:16-3.4
        env:
          POSTGRES_DB: goodgo_test
          POSTGRES_USER: goodgo
          POSTGRES_PASSWORD: goodgo_test_secret
        ports:
          - 5432:5432
        options: >-
          --health-cmd "pg_isready -U goodgo -d goodgo_test"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
          --health-start-period 30s

      redis:
        image: redis:7-alpine
        ports:
          - 6379:6379
        options: >-
          --health-cmd "redis-cli ping"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

      typesense:
        image: typesense/typesense:27.1
        ports:
          - 8108:8108
        env:
          TYPESENSE_API_KEY: ts_ci_key
          TYPESENSE_DATA_DIR: /data
        options: >-
          --health-cmd "curl -sf http://localhost:8108/health || exit 1"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

      minio:
        image: minio/minio:latest
        ports:
          - 9000:9000
        env:
          MINIO_ROOT_USER: ${{ vars.CI_MINIO_ACCESS_KEY || 'ci_minio_user' }}
          MINIO_ROOT_PASSWORD: ${{ vars.CI_MINIO_SECRET_KEY || 'ci_minio_secret_key_32chars!!' }}
        options: >-
          --health-cmd "curl -sf http://localhost:9000/minio/health/live || exit 1"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

    env:
      DATABASE_URL: postgresql://goodgo:goodgo_test_secret@localhost:5432/goodgo_test
      REDIS_URL: redis://localhost:6379
      REDIS_HOST: localhost
      REDIS_PORT: 6379
      TYPESENSE_URL: http://localhost:8108
      TYPESENSE_HOST: localhost
      TYPESENSE_PORT: 8108
      TYPESENSE_PROTOCOL: http
      TYPESENSE_API_KEY: ts_ci_key
      MINIO_ENDPOINT: localhost
      MINIO_PORT: 9000
      MINIO_ACCESS_KEY: ${{ vars.CI_MINIO_ACCESS_KEY || 'ci_minio_user' }}
      MINIO_SECRET_KEY: ${{ vars.CI_MINIO_SECRET_KEY || 'ci_minio_secret_key_32chars!!' }}
      MINIO_BUCKET: goodgo-uploads
      NODE_ENV: test
      CI: true
      # API and Web ports for Playwright webServer
      API_PORT: 3001
      WEB_PORT: 3000
      API_BASE_URL: http://localhost:3001/api/v1/
      WEB_BASE_URL: http://localhost:3000
      NEXT_PUBLIC_API_URL: http://localhost:3001/api/v1
      JWT_SECRET: e2e-test-jwt-secret-key-minimum-32-chars-long-enough
      JWT_REFRESH_SECRET: e2e-test-refresh-secret-key-minimum-32-chars-ok
      JWT_EXPIRES_IN: 15m
      JWT_REFRESH_EXPIRES_IN: 7d
      BCRYPT_ROUNDS: 4
      VNPAY_TMN_CODE: TESTCODE
      VNPAY_HASH_SECRET: TESTHASHSECRETTESTHASHSECRETTEST
      VNPAY_URL: https://sandbox.vnpayment.vn/paymentv2/vpcpay.html
      VNPAY_RETURN_URL: http://localhost:3000/payment/return
      GOOGLE_CLIENT_ID: test-google-client-id
      GOOGLE_CLIENT_SECRET: test-google-client-secret
      GOOGLE_CALLBACK_URL: http://localhost:3001/api/v1/auth/google/callback
      ZALO_APP_ID: test-zalo-app-id
      ZALO_APP_SECRET: test-zalo-app-secret
      ZALO_CALLBACK_URL: http://localhost:3001/api/v1/auth/zalo/callback

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Install pnpm
        uses: pnpm/action-setup@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: pnpm

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Cache Playwright browsers
        id: playwright-cache
        uses: actions/cache@v4
        with:
          path: ~/.cache/ms-playwright
          key: playwright-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}

      - name: Install Playwright browsers
        if: steps.playwright-cache.outputs.cache-hit != 'true'
        run: npx playwright install --with-deps chromium

      - name: Install Playwright system deps
        if: steps.playwright-cache.outputs.cache-hit == 'true'
        run: npx playwright install-deps chromium

      - name: Generate Prisma client
        run: pnpm db:generate

      - name: Run database migrations
        run: pnpm db:migrate:deploy

      - name: Seed database
        run: pnpm db:seed

      - name: Run E2E tests
        run: pnpm test:e2e

      - name: Upload Playwright report
        if: ${{ !cancelled() }}
        uses: actions/upload-artifact@v4
        with:
          name: playwright-report
          path: playwright-report/
          retention-days: 14

      - name: Upload Playwright traces
        if: failure()
        uses: actions/upload-artifact@v4
        with:
          name: playwright-traces
          path: test-results/
          retention-days: 7
