name: Playwright test reusable workflow

on:
  workflow_call:
    inputs:
      shard:
        description: "Shard number"
        required: true
        type: string
      db:
        required: true
        type: string

jobs:
  playwright:
    runs-on: [self-hosted, v3]
    timeout-minutes: 100
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: remove use-node-version from .npmrc
        run: sed -i '/^use-node-version/d' .npmrc
      - name: Setup Node
        uses: actions/setup-node@v3
        with:
          node-version: 22.12.0
      - name: Setup pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 9
      - name: Get pnpm store directory
        shell: bash
        run: |
          echo "STORE_PATH=/root/setup-pnpm/node_modules/.bin/store/v3" >> $GITHUB_ENV
      - uses: actions/cache@v3
        name: Setup pnpm cache
        with:
          path: ${{ env.STORE_PATH }}
          key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
          restore-keys: |
            ${{ runner.os }}-pnpm-store-
      - name: setup pg
        if: ${{ inputs.db == 'pg' || ( inputs.db == 'sqlite' && inputs.shard == '1' ) }}
        working-directory: ./
        run: |
          service postgresql start
          cd /var/lib/postgresql/ && sudo -u postgres psql -c "SELECT 'dropdb '||datname||'' FROM pg_database WHERE datistemplate = false AND datallowconn = true And datname NOT IN ('postgres')" |grep ' dropdb ' |  sudo -u postgres /bin/bash ; cd
          sudo -u postgres psql -c "ALTER USER postgres WITH PASSWORD 'password';" 
          sudo -u postgres psql -c "ALTER USER postgres WITH SUPERUSER;" 
          service postgresql restart
      - name: Kill stale servers
        run: |
          # export NODE_OPTIONS=\"--max_old_space_size=16384\";
          kill -9 $(lsof -t -i:8080) || echo "no process running on 8080"
          kill -9 $(lsof -t -i:3000) || echo "no process running on 3000"
      - name: Set CI env
        run: export CI=true
      - name: Set NC Edition
        run: export EE=false
      - name: install dependencies
        run: pnpm bootstrap
      - name: Setup mysql
        if: ${{ inputs.db == 'mysql' }}
        working-directory: ./packages/nocodb/tests/mysql-sakila-db
        run: |
          # Get a list of non-system databases and construct the DROP DATABASE statement for each
          service mysql start
          mysql -u'root' -p'password' -e "SHOW DATABASES" --skip-column-names | grep -Ev "(information_schema|mysql|performance_schema|sys)" | while read db; do
          mysql -u'root' -p'password' -e "DROP DATABASE IF EXISTS \`$db\`";
          done
          # keep sql_mode default except remove "STRICT_TRANS_TABLES"
          mysql -u'root' -p'password' -e "SET GLOBAL sql_mode = 'ONLY_FULL_GROUP_BY,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';"
          # this is only needed for connecting to sakila db as its refeferred in multiple places in test code          
          mysql -u'root' -p'password' < 01-mysql-sakila-schema.sql   
          mysql -u'root' -p'password' < 02-mysql-sakila-insert-data.sql
      - name: Run backend
        if: ${{ inputs.db == 'sqlite' }}
        working-directory: ./packages/nocodb
        run: |
          pnpm run watch:run:playwright &> ${{ inputs.db }}_${{ inputs.shard }}_test_backend.log &
      - name: Run backend:mysql
        if: ${{ inputs.db == 'mysql' }}
        working-directory: ./packages/nocodb
        run: |
          pnpm run watch:run:playwright:mysql &> ${{ inputs.db }}_${{ inputs.shard }}_test_backend.log &
      - name: Run backend:pg
        if: ${{ inputs.db == 'pg' }}
        working-directory: ./packages/nocodb
        run: |
          pnpm run watch:run:playwright:pg &> ${{ inputs.db }}_${{ inputs.shard }}_test_backend.log &
      - name: download ui build from artf server
        working-directory: ./packages/nc-gui/
        run: |
          # expects the variables to be available in runner context.
          rm -rf .output.zip .output
          FILE="$(echo ${GITHUB_REPOSITORY} | sed "s,/,-,g")-${GITHUB_RUN_ID}.zip"
          BUILD_FILE_URL=http://65.21.27.147/gh-artifacts/ui-builds/${FILE}
          time curl -o output.zip ${BUILD_FILE_URL} -n
          unzip -oq output.zip 

          # path="gh-artifacts/runs/${GITHUB_RUN_ID}/ui-build/.output"
          # target_dir="/mnt/${path}"
          # if [[ -d ${target_dir} ]]; then
          #   echo "Directory ${target_dir} exists."
          #   cp -r ${target_dir} . || echo "playwright reports directory does not exists" >>  ${target_dir}/playwright-report/index.html
          # else
          #   echo "Error: Directory ${target_dir} does not exists."
          #   exit 1
          # fi
      - name: start frontend
        working-directory: ./packages/nc-gui/
        run: |
          pnpm run ci:start
      - name: Install Playwright Browsers
        working-directory: ./tests/playwright
        run: pnpm exec playwright install --with-deps chromium
      - name: Wait for frontend and backend
        run: |
          while ! curl --output /dev/null --silent --head --fail http://localhost:3000; do
            printf '.'
            sleep 2
          done
          echo "Frontend is up"
          while ! curl --output /dev/null --silent --head --fail http://localhost:8080; do
            printf '.'
            sleep 2
          done          
          echo "Backend is up"
        timeout-minutes: 5
      - name: Run Playwright Tests
        working-directory: ./tests/playwright
        run: E2E_DB_TYPE=${{ inputs.db }} npm run ci:test:shard:${{ inputs.shard }}
        timeout-minutes: 60
      # Stress test added/modified tests
      - name: Fetch develop branch
        working-directory: ./tests/playwright
        run: git fetch origin develop
      - name: Stress test
        working-directory: ./tests/playwright
        run: E2E_DB_TYPE=${{ inputs.db }} node ./scripts/stressTestNewlyAddedTest.js

      #      # Quick tests (pg on sqlite shard 0 and sqlite on sqlite shard 1)
      #      - name: Run quick server and tests (pg)
      #        if: ${{ inputs.db == 'sqlite' && inputs.shard == '1' }}
      #        working-directory: ./packages/nocodb
      #        run: |
      #          kill -9 $(lsof -t -i:8080)
      #          npm run watch:run:playwright:pg:cyquick > quick_${{ inputs.shard }}_test_backend.log &
      #      - name: Run quick server and tests (sqlite)
      #        if: ${{ inputs.db == 'sqlite' && inputs.shard == '2' }}
      #        working-directory: ./packages/nocodb
      #        run: |
      #          kill -9 $(lsof -t -i:8080)
      #          npm run watch:run:playwright:quick > quick_${{ inputs.shard }}_test_backend.log &
      #      - name: Wait for backend for sqlite-tests
      #        if: ${{ inputs.db == 'sqlite' }}
      #        working-directory: ./tests/playwright
      #        run: |
      #          while ! curl --output /dev/null --silent --head --fail http://localhost:8080; do
      #            printf '.'
      #            sleep 2
      #          done
      #        timeout-minutes: 1
      #      - name: Run quick tests
      #        if: ${{ inputs.db == 'sqlite' }}
      #        working-directory: ./tests/playwright
      #        run: PLAYWRIGHT_HTML_REPORT=playwright-report-quick npm run test:quick

      - uses: actions/upload-artifact@v4
        if: ${{ inputs.db == 'sqlite' }}
        with:
          name: quick-backend-log-${{ inputs.shard }}-test-backend
          path: ./packages/nocodb/quick_${{ inputs.shard }}_test_backend.log
          retention-days: 2
      - uses: actions/upload-artifact@v4
        if: ${{ inputs.db == 'sqlite' }}
        with:
          name: playwright-report-quick-${{ inputs.shard }}
          path: ./tests/playwright/playwright-report-quick/
          retention-days: 2

      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: playwright-report-${{ inputs.db }}-${{ inputs.shard }}
          path: ./tests/playwright/playwright-report/
          retention-days: 2
      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: playwright-report-stress-${{ inputs.db }}-${{ inputs.shard }}
          path: ./tests/playwright/playwright-report-stress/
          retention-days: 2
      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: backend-logs-${{ inputs.db }}-${{ inputs.shard }}
          path: ./packages/nocodb/${{ inputs.db }}_${{ inputs.shard }}_test_backend.log
          retention-days: 2
      - name: stop database servers
        if: always()
        working-directory: ./packages/nocodb
        run: |
          service postgresql stop
          service mysql stop
      - name: Copy Artifacts to Local Artifacts Dir
        if: always()
        working-directory: ./
        run: |
          # expects the variables to be available in runner context.
          path="gh-artifacts/runs/${GITHUB_RUN_ID}/run-attempt/${GITHUB_RUN_ATTEMPT}/job_name/"${GITHUB_JOB}"-${{ inputs.shard }}/${RANDOM}-$(date +%s)"
          target_dir="/mnt/${path}"
          mkdir -p ${target_dir}
          mkdir -p ${target_dir}/playwright-report
          # start : add any artifacts to be copied here
          cp -r ./tests/playwright/playwright-report ${target_dir}/  || echo "playwright reports directory does not exists" >>  ${target_dir}/playwright-report/index.html
          cp ./packages/nocodb/*_test_backend.log ${target_dir}/ || echo "backend logs file does not exists" >> ${target_dir}/index.html
          # end: artifacts copy
          SUMMARY='[Artifacts]('${REPORTS_HOST:-http://135.181.48.96}/${path}')
          [playwright-report]('${REPORTS_HOST:-http://135.181.48.96}/${path}'/playwright-report)'
          echo "$SUMMARY" >> $GITHUB_STEP_SUMMARY
