name: E2E tests

on:
  push:
    branches: [main, master, next]
  pull_request:
  workflow_dispatch:

jobs:
  install:
    name: Install
    runs-on: ubuntu-latest
    timeout-minutes: 5
    outputs:
      playwright-version: ${{ steps.playwright-version.outputs.version }}
    steps:
      - name: Check out repository
        uses: actions/checkout@v5

      - name: Set up node
        uses: actions/setup-node@v5
        with:
          node-version: 20
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Bundle library
        run: npm run build

      - name: Get playwright version
        id: playwright-version
        run: echo "version=$(cat ./package-lock.json | jq -re '.packages["node_modules/@playwright/test"].version')" >> $GITHUB_OUTPUT

      - name: Upload dist folder
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: dist-folder
          path: dist
          retention-days: 1

  test:
    name: Run playwright tests (${{ matrix.shard }})
    runs-on: ubuntu-latest
    container:
      image: mcr.microsoft.com/playwright:v${{ needs.install.outputs.playwright-version }}-jammy
    timeout-minutes: 20
    needs: install
    strategy:
      fail-fast: false
      matrix:
        shard: [1/4, 2/4, 3/4, 4/4]
        # project: [chromium, firefox, webkit]
    steps:
      - name: Check out repository
        uses: actions/checkout@v5

      - name: Set up node
        uses: actions/setup-node@v5
        with:
          node-version: 20
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Download dist folder
        uses: actions/download-artifact@v4
        with:
          name: dist-folder
          path: dist

      - name: Run tests
        run: HOME=/root npx playwright test --config ./tests/config/playwright.config.ts --shard ${{ matrix.shard }} # --workers 1

      - name: Sanitize shard name
        id: sanitize-shard
        run: echo "shard=$(echo ${{ matrix.shard }} | tr -d '/')" >> $GITHUB_OUTPUT

      - name: Upload blob report
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: blob-report-${{ steps.sanitize-shard.outputs.shard }}
          path: tests/reports/blobs
          retention-days: 1

  report:
    name: Create report
    if: always()
    runs-on: ubuntu-latest
    timeout-minutes: 5
    needs: test
    permissions:
      pull-requests: write
      contents: write
    steps:
      - name: Check out repository
        uses: actions/checkout@v5

      - name: Set up node
        uses: actions/setup-node@v5
        with:
          node-version: 20
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Download blob reports
        uses: actions/download-artifact@v4
        with:
          pattern: blob-report-*
          path: playwright-blob-reports
          merge-multiple: true

      - name: Merge blob reports
        run: PLAYWRIGHT_JSON_OUTPUT_NAME=results.json npx playwright merge-reports --reporter html,json ./playwright-blob-reports

      - name: Upload HTML report
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: html-report # --attempt-${{ github.run_attempt }}
          path: playwright-report
          retention-days: 14

      - name: Check repo context
        id: context-check
        run: |
          if [ "${{ github.event_name }}" = "pull_request" ]; then
            if [ "${{ github.event.pull_request.head.repo.full_name }}" = "${{ github.repository }}" ]; then
              echo "internal=true" >> $GITHUB_OUTPUT
            else
              echo "internal=false" >> $GITHUB_OUTPUT
            fi
          else
            echo "internal=true" >> $GITHUB_OUTPUT
          fi

      - name: Check out reports branch
        if: steps.context-check.outputs.internal == 'true'
        uses: actions/checkout@v5
        with:
          ref: test-reports
          path: test-reports-branch
          fetch-depth: 0

      - name: Generate report name and URL
        id: report-id
        if: steps.context-check.outputs.internal == 'true'
        run: |
          name=$(date +"%Y-%m-%d-%H-%M-%S")
          echo "name=$name" >> $GITHUB_OUTPUT
          echo "path=reports/$name" >> $GITHUB_OUTPUT
          echo "url=https://swup.github.io/swup/reports/$name/" >> $GITHUB_OUTPUT

      - name: Copy html report and push reports branch
        if: steps.context-check.outputs.internal == 'true'
        run: |
          mkdir -p test-reports-branch/${{ steps.report-id.outputs.path }}
          cp -r playwright-report/. test-reports-branch/${{ steps.report-id.outputs.path }}
          cd test-reports-branch
          git config user.name github-actions
          git config user.email github-actions@github.com
          git add reports
          git commit -m "Add test report for run ${{ github.run_id }} (attempt: ${{ github.run_attempt }})"
          while true; do
            git pull --rebase
            if [ $? -ne 0 ]; then
              echo "Failed to rebase. Please review manually."
              exit 1
            fi
            git push
            if [ $? -eq 0 ]; then
              echo "Successfully pushed HTML report to repo."
              exit 0
            fi
          done

      - name: Output report url
        if: steps.context-check.outputs.internal == 'true'
        run: |
          echo "::notice title=Published Playwright test report::${{ steps.report-id.outputs.url }}"

      - name: Create report comment
        id: report-summary
        uses: daun/playwright-report-summary@v3.3.0
        with:
          report-file: results.json
          report-url: ${{ steps.report-id.outputs.url }}
          job-summary: true
