name: Tests
on:
    pull_request: {}
    merge_group:
        types: [checks_requested]
    push:
        branches: [develop, master]
    repository_dispatch:
        types: [element-web-notify]
    workflow_call:
        inputs:
            disable_coverage:
                type: boolean
                required: false
                description: "Specify true to skip generating and uploading coverage for tests"
            matrix-js-sdk-sha:
                type: string
                required: false
                description: "The matrix-js-sdk SHA to use"
concurrency:
    group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
    cancel-in-progress: true

env:
    ENABLE_COVERAGE: ${{ github.event_name != 'merge_group' && inputs.disable_coverage != 'true' }}
    # fetchdep.sh needs to know our PR number
    PR_NUMBER: ${{ github.event.pull_request.number }}
    NX_DEFAULT_OUTPUT_STYLE: stream-without-prefixes

permissions: {}

jobs:
    jest_ew:
        name: Jest (Element Web)
        runs-on: ubuntu-24.04
        strategy:
            fail-fast: false
            matrix:
                # Run multiple instances in parallel to speed up the tests
                runner: [1, 2]
        steps:
            - name: Checkout code
              uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
              with:
                  repository: ${{ inputs.matrix-js-sdk-sha && 'element-hq/element-web' || github.repository }}
                  persist-credentials: false

            - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4
            - name: pnpm cache
              uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6
              with:
                  node-version: "lts/*"
                  cache: "pnpm"

            - name: Install Deps
              run: "./scripts/layered.sh"
              env:
                  JS_SDK_GITHUB_BASE_REF: ${{ inputs.matrix-js-sdk-sha }}

            - name: Jest Cache
              uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
              with:
                  path: /tmp/jest_cache
                  key: ${{ hashFiles('**/pnpm-lock.yaml') }}

            - name: Get number of CPU cores
              id: cpu-cores
              uses: SimenB/github-actions-cpu-cores@97ba232459a8e02ff6121db9362b09661c875ab8 # v2

            - name: Run tests
              working-directory: apps/web
              run: |
                  pnpm test \
                      --coverage=$ENABLE_COVERAGE \
                      --ci \
                      --max-workers $MAX_WORKERS \
                      --shard "$SHARD" \
                      --cacheDirectory /tmp/jest_cache
              env:
                  JEST_SONAR_UNIQUE_OUTPUT_NAME: true

                  # tell jest to use coloured output
                  FORCE_COLOR: true
                  MAX_WORKERS: ${{ steps.cpu-cores.outputs.count }}
                  SHARD: ${{ format('{0}/{1}', matrix.runner, strategy.job-total) }}

            - name: Move coverage files into place
              if: env.ENABLE_COVERAGE == 'true'
              working-directory: apps/web
              run: mv coverage/lcov.info coverage/$NODE_VERSION-${{ matrix.runner }}.lcov.info
              env:
                  NODE_VERSION: ${{ steps.setupNode.outputs.node-version }}

            - name: Upload Artifact
              if: env.ENABLE_COVERAGE == 'true'
              uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
              with:
                  name: coverage-${{ matrix.runner }}
                  path: |
                      apps/web/coverage
                      !apps/web/coverage/lcov-report

    complete:
        name: jest-tests
        needs: [jest_ew, vitest_sc]
        if: always()
        runs-on: ubuntu-24.04
        permissions:
            statuses: write
        steps:
            - if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
              run: exit 1

            - name: Skip SonarCloud in merge queue
              if: github.event_name == 'merge_group' || inputs.disable_coverage == 'true'
              uses: guibranco/github-status-action-v2@9bfa8773cdbdc6c185747fd43cd7faa9d7c32f09
              with:
                  authToken: ${{ secrets.GITHUB_TOKEN }}
                  state: success
                  description: SonarCloud skipped
                  context: SonarCloud Code Analysis
                  sha: ${{ github.sha }}
                  target_url: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}

    vitest_sc:
        name: Vitest (Shared Components)
        runs-on: ubuntu-24.04
        steps:
            - name: Checkout code
              uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
              with:
                  repository: ${{ inputs.matrix-js-sdk-sha && 'element-hq/element-web' || github.repository }}
                  persist-credentials: false

            - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4
            - name: pnpm cache
              uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6
              with:
                  node-version: "lts/*"
                  cache: "pnpm"

            - name: Install Shared Component Deps
              working-directory: "packages/shared-components"
              run: "pnpm install"

            - name: Cache storybook & vitest
              uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
              with:
                  path: |
                      packages/shared-components/node_modules/.cache
                      packages/shared-components/node_modules/.vite/vitest
                  key: ${{ hashFiles('pnpm-lock.yaml') }}

            - name: Get installed Playwright version
              working-directory: packages/shared-components
              id: playwright
              run: echo "version=$(pnpm list @playwright/test --depth=0 --json | jq -r '.[].devDependencies["@playwright/test"].version')" >> $GITHUB_OUTPUT

            - name: Cache playwright binaries
              uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
              id: playwright-cache
              with:
                  path: ~/.cache/ms-playwright
                  key: ${{ runner.os }}-${{ runner.arch }}-playwright-${{ steps.playwright.outputs.version }}-onlyshell

            - name: Install Playwright browsers
              working-directory: packages/shared-components
              if: steps.playwright-cache.outputs.cache-hit != 'true'
              run: "pnpm playwright install --with-deps --only-shell"

            - name: Run tests
              working-directory: "packages/shared-components"
              run: pnpm test:unit --coverage=$ENABLE_COVERAGE

            - name: Upload Artifact
              if: env.ENABLE_COVERAGE == 'true'
              uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
              with:
                  name: coverage-sharedcomponents
                  path: |
                      packages/shared-components/coverage
                      !packages/shared-components/coverage/lcov-report
