Next-CRM Playwright Tests #56
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Next-CRM Playwright Tests | |
| permissions: | |
| contents: read | |
| # Controls when the workflow will run | |
| on: | |
| pull_request_review: | |
| types: [ submitted ] # Trigger when a PR review is submitted | |
| #Triggers at 5 AM IST every day | |
| schedule: | |
| - cron: "30 23 * * *" | |
| # Allows you to run this workflow manually from the Actions tab | |
| workflow_dispatch: | |
| jobs: | |
| test: | |
| if: | | |
| github.event_name == 'workflow_dispatch' || | |
| github.event_name == 'schedule' || | |
| (github.event_name == 'pull_request_review' && github.event.review.state == 'approved') | |
| runs-on: self-hosted | |
| container: | |
| image: ubuntu:24.04 | |
| environment: Stage # Retrieve secrets from 'Stage' environment | |
| env: | |
| BASE_URL: ${{ secrets.BASE_URL }} | |
| ADMIN_ID: ${{ secrets.ADMIN_ID }} | |
| ADMIN_EMAIL: ${{ secrets.ADMIN_EMAIL }} | |
| ADMIN_PASS: ${{ secrets.ADMIN_PASS }} | |
| ADMIN_NAME: ${{ secrets.ADMIN_NAME }} | |
| # Hetzner Space (S3) credentials & endpoint | |
| HETZNER_S3_BUCKET: ${{ secrets.HETZNER_S3_BUCKET }} | |
| HETZNER_S3_ACCESS_KEY_ID: ${{ secrets.HETZNER_S3_ACCESS_KEY_ID }} | |
| HETZNER_S3_SECRET_ACCESS_KEY: ${{ secrets.HETZNER_S3_SECRET_ACCESS_KEY }} | |
| HETZNER_S3_ENDPOINT_URL: ${{ secrets.HETZNER_S3_ENDPOINT_URL }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| # Setup Node.js | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "18" | |
| - name: Cache npm modules | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.npm | |
| key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} | |
| restore-keys: | | |
| ${{ runner.os }}-node- | |
| - name: Verify Node & npm | |
| run: | | |
| which node | |
| which npm | |
| node --version | |
| npm --version | |
| - name: Install prerequisites | |
| run: | | |
| apt-get update | |
| apt-get install -y curl sudo | |
| - name: Sanitize branch name | |
| shell: bash | |
| env: | |
| UNTRUSTED_PR_HEAD_REF: ${{ github.event.pull_request.head.ref }} | |
| run: | | |
| if [ "${{ github.event_name }}" = "pull_request_review" ]; then | |
| # PR Review → use the source branch name | |
| RAW_BRANCH="$UNTRUSTED_PR_HEAD_REF" | |
| else | |
| # workflow_dispatch or schedule → use whatever ref we were on | |
| RAW_BRANCH="${GITHUB_REF#refs/heads/}" | |
| fi | |
| SAFE_BRANCH="${RAW_BRANCH//\//-}" | |
| echo "SANITIZED_REF=${SAFE_BRANCH}" >> $GITHUB_ENV | |
| echo "→ Restoring/uploading history under key: ${SAFE_BRANCH}" | |
| - name: Debug—print refs | |
| run: | | |
| echo "EVENT_NAME = ${{ github.event_name }}" | |
| echo "GITHUB_REF = $GITHUB_REF" | |
| echo "SANITIZED_REF = $SANITIZED_REF" | |
| - name: Create local allure-history/history folder | |
| run: mkdir -p allure-history/history | |
| - name: Install MinIO Client (mc) | |
| run: | | |
| curl -fsSL https://dl.min.io/client/mc/release/linux-amd64/mc \ | |
| -o mc && chmod +x mc && sudo mv mc /usr/local/bin/ | |
| - name: Configure mc alias for Hetzner S3 | |
| run: | | |
| mc alias set hetzner \ | |
| ${{ env.HETZNER_S3_ENDPOINT_URL }} \ | |
| ${{ env.HETZNER_S3_ACCESS_KEY_ID }} \ | |
| ${{ env.HETZNER_S3_SECRET_ACCESS_KEY }} | |
| - name: Restore Allure history for this branch (mc) | |
| run: | | |
| if mc ls hetzner/${{ env.HETZNER_S3_BUCKET }}/${{ env.SANITIZED_REF }}/history/ | grep -q .; then | |
| echo "Restoring previous Allure history..." | |
| mc cp --recursive \ | |
| hetzner/${{ env.HETZNER_S3_BUCKET }}/${{ env.SANITIZED_REF }}/history/ \ | |
| allure-history/history/ | |
| else | |
| echo "No Allure history to restore for branch '${{ env.SANITIZED_REF }}'." | |
| fi | |
| - name: Check Local History Directory After History Download | |
| run: ls -la allure-history/history | |
| # Install dependencies | |
| - name: Install dependencies | |
| run: | | |
| cd tests/e2e/ | |
| npm ci | |
| npx playwright install --with-deps | |
| - name: Setup Java | |
| uses: actions/setup-java@v3 | |
| with: | |
| distribution: "temurin" | |
| java-version: "17" | |
| - name: Run e2e Tests. | |
| run: | | |
| cd tests/e2e/ | |
| npm run e2e:tests -- | |
| - name: Restore previous Allure history into results | |
| if: always() | |
| run: | | |
| mkdir -p allure-results/history | |
| cp -R allure-history/history/* allure-results/history/ || echo "No previous history to restore" | |
| - name: Generate Allure (for count extraction) | |
| if: always() | |
| run: | | |
| cd tests/e2e | |
| # clean & generate for count-extraction | |
| npm run allure:report | |
| - name: Merge history into results | |
| if: always() | |
| run: | | |
| cp -R allure-report-for-count-extraction/history/* allure-results/history/ | |
| - name: Generate single-file Allure HTML | |
| if: always() | |
| run: | | |
| cd tests/e2e | |
| npm run allure:htmlReport | |
| - name: Upload updated Allure history for this branch (mc) | |
| if: always() | |
| run: | | |
| mc cp --recursive \ | |
| allure-results/history/ \ | |
| hetzner/${{ env.HETZNER_S3_BUCKET }}/${{ env.SANITIZED_REF }}/history/ | |
| - name: Extract test results | |
| if: ${{ success() || failure() }} | |
| run: | | |
| # Install jq | |
| apt-get update && apt-get install -y jq | |
| # Path to the Allure summary file | |
| SUMMARY_FILE="allure-report-for-count-extraction/widgets/summary.json" | |
| # Check if the summary file exists | |
| if [ ! -f "$SUMMARY_FILE" ]; then | |
| echo "Error: Allure summary file not found at $SUMMARY_FILE" | |
| exit 1 | |
| fi | |
| # Extract passed and failed test counts using jq | |
| PASSED_COUNT=$(jq '.statistic.passed' "$SUMMARY_FILE" || echo 0) | |
| FAILED_COUNT=$(jq '.statistic.failed' "$SUMMARY_FILE" || echo 0) | |
| BROKEN_COUNT=$(jq '.statistic.broken' "$SUMMARY_FILE" || echo 0) | |
| SKIPPED_COUNT=$(jq '.statistic.skipped' "$SUMMARY_FILE" || echo 0) | |
| UNKNOWN_COUNT=$(jq '.statistic.unknown' "$SUMMARY_FILE" || echo 0) | |
| TOTAL_COUNT=$(jq '.statistic.total' "$SUMMARY_FILE" || echo 0) | |
| # Output and export them as GitHub environment variables | |
| echo "Actual Count of Total Tests: $TOTAL_COUNT" | |
| # Optionally set them as output variables | |
| echo "passed_count=$PASSED_COUNT" >> $GITHUB_ENV | |
| echo "failed_count=$FAILED_COUNT" >> $GITHUB_ENV | |
| echo "broken_count=$BROKEN_COUNT" >> $GITHUB_ENV | |
| echo "skipped_count=$SKIPPED_COUNT" >> $GITHUB_ENV | |
| echo "unknown_count=$UNKNOWN_COUNT" >> $GITHUB_ENV | |
| echo "total_count=$TOTAL_COUNT" >> $GITHUB_ENV | |
| TOTAL=$((PASSED_COUNT + FAILED_COUNT + BROKEN_COUNT + SKIPPED_COUNT + UNKNOWN_COUNT)) | |
| # Set environment variables | |
| echo "TOTAL=$TOTAL" >> $GITHUB_ENV | |
| - name: Display counts | |
| if: ${{ success() || failure() }} | |
| run: | | |
| echo "Actual Total Tests: ${{ env.total_count }}" | |
| echo "Passed Tests: ${{ env.passed_count }}" | |
| echo "Failed Tests: ${{ env.failed_count }}" | |
| echo "Broken Tests: ${{ env.broken_count }}" | |
| echo "Skipped Tests: ${{ env.skipped_count }}" | |
| echo "Unknown Tests: ${{ env.unknown_count }}" | |
| - name: Debug – show saved history | |
| if: always() | |
| run: | | |
| echo "PWD: $(pwd)" | |
| echo "Root contents:" | |
| ls -1 | |
| echo "Contents of allure-history/:" | |
| ls -R allure-history || echo "(not found or empty)" | |
| - name: Upload Allure Report | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: Allure-report | |
| path: allure-report | |
| - name: Zip Allure Report | |
| if: ${{ success() || failure() }} | |
| run: | | |
| apt-get update && apt-get install -y zip | |
| REPORT_DIR="allure-report" | |
| OUTPUT_ZIP="report.zip" | |
| if [ -d "$REPORT_DIR" ]; then | |
| echo "Zipping Allure report..." | |
| cd "$(dirname "$REPORT_DIR")" | |
| zip -r "$OUTPUT_ZIP" "$(basename "$REPORT_DIR")" | |
| else | |
| echo "Error - Allure Report not found in $REPORT_DIR" | |
| exit 1 | |
| fi | |
| - name: Set the email body message for pull request merge or schedule message | |
| if: ${{ success() || failure() }} | |
| env: | |
| PR_TITLE: ${{ github.event.pull_request.title }} | |
| PR_URL: ${{ github.event.pull_request.html_url }} | |
| run: | | |
| if [ "${GITHUB_EVENT_NAME}" = "pull_request_review" ]; then | |
| # Sanitize PR_TITLE to prevent environment variable injection | |
| SANITIZED_PR_TITLE="$(echo "$PR_TITLE" | tr -d '\n' | tr -d '\r')" | |
| echo "message=<p>For the latest pull request titled <b><a href='$PR_URL'> $SANITIZED_PR_TITLE</a></b>, the E2E automation tests have been executed on the QE environment. Below is the summary:</p>" >> $GITHUB_ENV | |
| else | |
| echo "message=<p>This is to inform you that the scheduled E2E automation tests have been executed on the QE environment. Below is the summary:</p>" >> $GITHUB_ENV | |
| fi | |
| - name: Send Report via Email | |
| if: ${{ success() || failure() }} | |
| uses: dawidd6/action-send-mail@v3 | |
| with: | |
| server_address: smtp.gmail.com | |
| server_port: 587 | |
| username: ${{ secrets.QA_WORKFLOW_EMAIL }} | |
| password: ${{ secrets.QA_WORKFLOW_EMAIL_PASSWORD }} | |
| subject: Test Automation Report - Next CRM | |
| html_body: | | |
| <html> | |
| <head> | |
| <style> | |
| body { | |
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
| color: #333; | |
| margin: 0; | |
| padding: 0; | |
| background-color: #f9f9f9; | |
| } | |
| .container { | |
| width: 80%; | |
| max-width: 600px; | |
| margin: 20px auto; | |
| background: #fff; | |
| border: 1px solid #ddd; | |
| border-radius: 8px; | |
| padding: 20px; | |
| } | |
| .header { | |
| text-align: center; | |
| padding-bottom: 20px; | |
| border-bottom: 1px solid #ddd; | |
| } | |
| .header h1 { | |
| margin: 0; | |
| color: #333; | |
| } | |
| .content { | |
| margin-top: 20px; | |
| } | |
| .content p { | |
| margin: 0 0 10px; | |
| } | |
| .content ul { | |
| list-style: none; | |
| padding: 0; | |
| } | |
| .content li { | |
| padding: 8px 0; | |
| border-bottom: 1px solid #eee; | |
| } | |
| .content li:last-child { | |
| border-bottom: none; | |
| } | |
| .chart-container { | |
| margin: 20px 0; | |
| text-align: center; | |
| } | |
| .chart-title { | |
| margin-bottom: 10px; | |
| font-weight: bold; | |
| } | |
| .chart-container img { | |
| max-width: 100%; | |
| height: 240px; | |
| } | |
| .footer { | |
| margin-top: 20px; | |
| text-align: left; | |
| font-size: 0.9em; | |
| color: #777; | |
| } | |
| .footer p { | |
| margin: 5px 0; | |
| } | |
| .footer a { | |
| color: #007bff; | |
| text-decoration: none; | |
| } | |
| .footer a:hover { | |
| text-decoration: underline; | |
| } | |
| .content a { | |
| text-decoration: none; | |
| } | |
| .content a:hover { | |
| text-decoration: underline; /* Underline on hover */ | |
| } | |
| table { | |
| width: 100%; | |
| border-collapse: collapse; | |
| margin: 20px 0; | |
| background-color: #ffffff; | |
| border-radius: 5px; | |
| overflow: hidden; | |
| box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); | |
| } | |
| th, td { | |
| border: 1px solid #dddddd; | |
| padding: 12px; | |
| text-align: left; | |
| } | |
| th { | |
| background-color: #4CAF50; | |
| color: white; | |
| } | |
| tr:nth-child(even) { | |
| background-color: #f2f2f2; | |
| } | |
| tr:hover { | |
| background-color: #ddd; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <div class="header"> | |
| <h1>Next-CRM Test Automation Report</h1> | |
| </div> | |
| <div class="content"> | |
| <p>Hi Team,</p> | |
| ${{ env.message }} | |
| <p><b>Automation Test Summary:</b></p> | |
| <ul> | |
| <li><b>Total Tests:</b> ${{ env.TOTAL }}</li> | |
| <li><b>Tests Passed:</b> ${{ env.passed_count }}</li> | |
| <li><b>Tests Failed:</b> ${{ env.failed_count }}</li> | |
| <li><b>Test Broken:</b> ${{env.broken_count }}</li> | |
| </ul> | |
| </div> | |
| <p>To view videos and other report assets to track failure, visit the <a href="https://github.com/rtcamp/next-crm/actions/runs/${{ github.run_id }}#artifacts">GitHub Actions Artifacts</a>.</p> | |
| <p>To view the build details and see what changes have been merged, visit the build link:</p><a href="https://github.com/rtcamp/next-crm/actions/runs/${{ github.run_id }}">Build Details</a> | |
| <p>If you have any questions, please feel free to reach out to QA Team</p> | |
| <div class="footer"> | |
| <p>Best regards,</p> | |
| <p>QA Team</p> | |
| </div> | |
| </div> | |
| </body> | |
| </html> | |
| to: [email protected] | |
| from: [email protected] | |
| - name: Cleanup | |
| if: ${{ always() }} | |
| uses: rtCamp/action-cleanup@master |