name: E2E Functional Tests Template

on:
  workflow_call:
    inputs:
      MM_TEST_SERVER_URL:
        description: "The test server URL"
        required: false
        type: string
      MM_TEST_USER_NAME:
        description: "The admin username of the test instance"
        required: false
        type: string
      MM_TEST_PASSWORD:
        description: "The admin password of the test instance"
        required: false
        type: string
      DESKTOP_VERSION:
        description: "The desktop version to test"
        required: false
        default: ${{ github.ref }}
        type: string
      runs-on:
        type: string
        description: "The E2E tests underlying OS"
        required: true
        default: "ubuntu-22.04"
      nightly:
        type: boolean
        description: "True if this is nightly build"
        required: false
        default: false
      cmt:
        type: boolean
        description: "True if this is Compatibility Matrix Testing"
        required: false
        default: false
      TYPE:
        type: boolean
        description: "True if this is Triggered from PR"
        required: false
        default: false
      MM_SERVER_VERSION:
        type: string
        required: false
        default: "9.9.1"
    outputs:
      NEW_FAILURES_LINUX:
        description: "The output to comment"
        value: ${{ jobs.e2e.outputs.NEW_FAILURES_LINUX }}
      NEW_FAILURES_MACOS:
        description: "The output to comment"
        value: ${{ jobs.e2e.outputs.NEW_FAILURES_MACOS }}
      NEW_FAILURES_WINDOWS:
        description: "The output to comment"
        value: ${{ jobs.e2e.outputs.NEW_FAILURES_WINDOWS }}
      REPORT_LINK_LINUX:
        description: "Link to Linux report"
        value: ${{ jobs.e2e.outputs.REPORT_LINK_LINUX }}
      REPORT_LINK_MACOS:
        description: "Link to MacOS report"
        value: ${{ jobs.e2e.outputs.REPORT_LINK_MACOS }}
      REPORT_LINK_WINDOWS:
        description: "Link to Windows report"
        value: ${{ jobs.e2e.outputs.REPORT_LINK_WINDOWS }}
      STATUS_LINUX:
        description: "The status of the linux test"
        value: ${{ jobs.e2e.outputs.STATUS_LINUX }}
      STATUS_MACOS:
        description: "The status of the macOS test"
        value: ${{ jobs.e2e.outputs.STATUS_MACOS }}
      STATUS_WINDOWS:
        description: "The status of the windows test"
        value: ${{ jobs.e2e.outputs.STATUS_WINDOWS }}

  workflow_dispatch:
    inputs:
      MM_TEST_SERVER_URL:
        description: "The test server URL"
        required: false
        type: string
      MM_TEST_USER_NAME:
        description: "The admin username of the test instance"
        required: false
        type: string
      MM_TEST_PASSWORD:
        description: "The admin password of the test instance"
        required: false
        type: string
      DESKTOP_VERSION:
        description: "The desktop version to test"
        required: false
        default: "master"
        type: string
      runs-on:
        type: string
        description: "The E2E tests underlying OS"
        required: true
        default: "ubuntu-22.04"
      nightly:
        type: boolean
        description: "True if this is nightly build"
        required: false
        default: false
      cmt:
        type: boolean
        description: "True if this is Compatibility Matrix Testing"
        required: false
        default: false
      TYPE:
        type: boolean
        description: "True if this is Triggered from PR"
        required: false
        default: false
      MM_SERVER_VERSION:
        type: string
        required: false
        default: "9.9.1"

env:
  AWS_S3_BUCKET: "mattermost-cypress-report"
  BRANCH: ${{ github.head_ref || github.ref_name }}
  BUILD_TAG: ${{ github.event.pull_request.head.sha || github.sha }}
  JIRA_PROJECT_KEY: "MM"
  MM_TEST_SERVER_URL: ${{ inputs.MM_TEST_SERVER_URL || secrets.MM_DESKTOP_E2E_SERVER_URL }}
  MM_TEST_USER_NAME: ${{ inputs.MM_TEST_USER_NAME || secrets.MM_DESKTOP_E2E_USER_NAME }}
  MM_TEST_PASSWORD: ${{ inputs.MM_TEST_PASSWORD || secrets.MM_DESKTOP_E2E_USER_CREDENTIALS }}
  PULL_REQUEST: "https://github.com/mattermost/desktop/pull/${{ github.event.number }}"
  ZEPHYR_ENVIRONMENT_NAME: "Desktop app"
  ZEPHYR_FOLDER_ID: "12413253"
  TEST_CYCLE_LINK_PREFIX: ${{ secrets.MM_DESKTOP_E2E_TEST_CYCLE_LINK_PREFIX }}
  AWS_ACCESS_KEY_ID: ${{ secrets.MM_DESKTOP_E2E_AWS_ACCESS_KEY_ID }}
  AWS_SECRET_ACCESS_KEY: ${{ secrets.MM_DESKTOP_E2E_AWS_SECRET_ACCESS_KEY }}
  AWS_REGION: "us-east-1"
  WEBHOOK_URL: ${{ secrets.MM_DESKTOP_E2E_WEBHOOK_URL }}
  ZEPHYR_API_KEY: ${{ secrets.MM_DESKTOP_E2E_ZEPHYR_API_KEY }}
  REPORT_LINK: "none"
  NODE_VERSION: 18
  SERVER_VERSION: ${{ inputs.MM_SERVER_VERSION || '9.9.1' }}
  DESKTOP_VERSION: ${{ inputs.DESKTOP_VERSION }}
  PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1

jobs:
  e2e:
    name: e2e-on-${{ inputs.runs-on }}
    runs-on: ${{ inputs.runs-on }}
    defaults:
      run:
        shell: bash
    outputs:
      NEW_FAILURES_LINUX: ${{ steps.analyze-flaky-tests.outputs.NEW_FAILURES_LINUX }}
      NEW_FAILURES_MACOS: ${{ steps.analyze-flaky-tests.outputs.NEW_FAILURES_MACOS }}
      NEW_FAILURES_WINDOWS: ${{ steps.analyze-flaky-tests.outputs.NEW_FAILURES_WINDOWS }}
      REPORT_LINK_LINUX: ${{ steps.analyze-flaky-tests.outputs.REPORT_LINK_LINUX }}
      REPORT_LINK_MACOS: ${{ steps.analyze-flaky-tests.outputs.REPORT_LINK_MACOS }}
      REPORT_LINK_WINDOWS: ${{ steps.analyze-flaky-tests.outputs.REPORT_LINK_WINDOWS }}
      STATUS_LINUX: ${{ steps.analyze-flaky-tests.outputs.STATUS_LINUX }}
      STATUS_WINDOWS: ${{ steps.analyze-flaky-tests.outputs.STATUS_WINDOWS }}
      STATUS_MACOS: ${{ steps.analyze-flaky-tests.outputs.STATUS_MACOS }}
    steps:
      - name: e2e/set-required-variables
        id: variables
        run: |
          RUNNER_OS=$(echo "${{ runner.os }}" | tr '[:upper:]' '[:lower:]')
          echo "RUNNER_OS=${RUNNER_OS}" >> $GITHUB_ENV
          
          # Define build type and suffix
          case "${{ github.event_name }}" in
            "pull_request")
              echo "BUILD_SUFFIX=desktop-pr-${RUNNER_OS}" >> $GITHUB_OUTPUT
              echo "TYPE=PR" >> $GITHUB_ENV
              ;;
            "workflow_dispatch")
              if ${{ inputs.cmt }}; then
                echo "BUILD_SUFFIX=desktop-release-${RUNNER_OS}" >> $GITHUB_OUTPUT
                echo "TYPE=CMT" >> $GITHUB_ENV
                echo "ZEPHYR_ENABLE=true" >> $GITHUB_ENV
                echo "ZEPHYR_FOLDER_${RUNNER_OS^^}_REPORT=${{ 
                  runner.os == 'Linux' && '12358649' || 
                  runner.os == 'macOS' && '12358650' || 
                  '12358651' 
                }}" >> $GITHUB_ENV
              else
                echo "BUILD_SUFFIX=desktop-manual-trigger-${RUNNER_OS}" >> $GITHUB_OUTPUT
                echo "TYPE=MANUAL" >> $GITHUB_ENV
              fi
              ;;
            "push")
              if [[ "${{ github.ref }}" == "refs/heads/master" ]]; then
                echo "BUILD_SUFFIX=desktop-master-push-${RUNNER_OS}" >> $GITHUB_OUTPUT
                echo "TYPE=MASTER" >> $GITHUB_ENV
                echo "ZEPHYR_ENABLE=true" >> $GITHUB_ENV
              fi
              ;;
          esac
          
          if ${{ inputs.nightly }}; then
            echo "BUILD_SUFFIX=desktop-nightly-${RUNNER_OS}" >> $GITHUB_OUTPUT
            echo "TYPE=NIGHTLY" >> $GITHUB_ENV
            echo "ZEPHYR_ENABLE=true" >> $GITHUB_ENV
            echo "ZEPHYR_FOLDER_${RUNNER_OS^^}_REPORT=${{ 
              runner.os == 'Linux' && '12363689' || 
              runner.os == 'macOS' && '12363687' || 
              '12363690' 
            }}" >> $GITHUB_ENV
          fi

      - name: e2e/set-build-id
        run: echo "BUILD_ID=${{ github.run_id }}-${{ steps.variables.outputs.BUILD_SUFFIX }}" >> $GITHUB_ENV

      - name: e2e/checkout-repo
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
        with:
          ref: ${{ inputs.DESKTOP_VERSION }}

      - name: e2e/setup-node
        uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
        with:
          node-version-file: "package.json"
          cache: "npm"
          cache-dependency-path: package-lock.json

      - name: e2e/cache-node-modules
        id: cache-node-modules
        uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
        with:
          path: |
            node_modules
            C:\Users\runneradmin\.electron-gyp
          key: ${{ runner.os }}-build-node-modules-${{ hashFiles('./package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-build-node-modules
            ${{ runner.os }}-build-
            ${{ runner.os }}-

      - name: e2e/setup-python
        uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
        with:
          python-version: "3.10"

      - name: e2e/install-os-dependencies
        uses: ./.github/actions/install-os-dependencies
        with:
          os: ${{ runner.os }}

      - name: e2e/install-node-dependencies
        run: |
          npm ci
          cd e2e && npm ci
          npx electron-rebuild --platform=${{ env.RUNNER_OS }} -f -t prod,optional,dev -w robotjs --module-dir ../

      - name: e2e/run-playright-tests-linux
        if: runner.os == 'Linux'
        run: |
          eval "$(dbus-launch --sh-syntax)"
          export NO_AT_BRIDGE=1

          npm run build-test
          cd e2e
          export PW_CHROMIUM_ARGS="--disable-gpu --no-sandbox --disable-dev-shm-usage"
          xvfb-run --auto-servernum --server-args='-screen 0 1024x768x24' npm run run:e2e || true
          npm run send-report
        env:
          SERVER_VERSION: ${{ inputs.MM_SERVER_VERSION }}
          DESKTOP_VERSION: ${{ inputs.DESKTOP_VERSION }}

      - name: e2e/run-playright-tests-macos
        if: runner.os == 'macOS'
        run: |
          sudo spctl --master-disable
          xattr -dr com.apple.quarantine ./node_modules/electron
          npm run build-test
          cd e2e
          npm run run:e2e || true
          npm run send-report
        env:
          SERVER_VERSION: ${{ inputs.MM_SERVER_VERSION }}
          DESKTOP_VERSION: ${{ inputs.DESKTOP_VERSION }}

      - name: e2e/run-playright-tests-windows
        if: runner.os == 'Windows'
        run: |
          npm run build-test
          cd e2e
          npm run run:e2e || true
          npm run send-report
        env:
          SERVER_VERSION: ${{ inputs.MM_SERVER_VERSION }}
          DESKTOP_VERSION: ${{ inputs.DESKTOP_VERSION }}

      - name: Capture Report Link
        run: echo "REPORT_LINK=$(cat e2e/report-link.txt)" >> $GITHUB_ENV

      - name: e2e/analyze-flaky-tests
        id: analyze-flaky-tests
        uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
        with:
          script: |
            process.chdir('./e2e');
            const { analyzeFlakyTests } = require('./utils/analyze-flaky-test.js');
            const { newFailedTests, os } = analyzeFlakyTests();

            switch (os) {
              case 'linux':
                core.setOutput('NEW_FAILURES_LINUX', newFailedTests.length);
                core.setOutput('REPORT_LINK_LINUX', "${{ env.REPORT_LINK}}");
                newFailedTests.length > 0 ? core.setOutput('STATUS_LINUX', 'failure') : core.setOutput('STATUS_LINUX', 'success');
                break;
              case 'darwin':
                core.setOutput('NEW_FAILURES_MACOS', newFailedTests.length);
                core.setOutput('REPORT_LINK_MACOS', "${{ env.REPORT_LINK}}");
                newFailedTests.length > 0 ? core.setOutput('STATUS_MACOS', 'failure') : core.setOutput('STATUS_MACOS', 'success');
                break;
              case 'win32':
                core.setOutput('NEW_FAILURES_WINDOWS', newFailedTests.length);
                core.setOutput('REPORT_LINK_WINDOWS', "${{ env.REPORT_LINK}}");
                newFailedTests.length > 0 ? core.setOutput('STATUS_WINDOWS', 'failure') : core.setOutput('STATUS_WINDOWS', 'success');
                break;
              default:
                throw new Error(`Unsupported OS: ${os}`);
            }

      - name: Upload test results
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: test-results-${{ runner.os }}
          path: e2e/mochawesome-report
          retention-days: 7
