Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 40 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,47 @@ jobs:
run: npm ci

- name: Run tests with coverage
run: npm run test:coverage
run: |
npm run test:coverage 2>&1 | tee test-output.log
echo "TEST_EXIT_CODE=${PIPESTATUS[0]}" >> $GITHUB_ENV

- name: Upload coverage report
- name: Parse test results
if: always()
id: test-results
run: ./.github/workflows/scripts/parse-test-results.sh test-output.log

- name: Generate test summary
if: always()
run: |
PASSED="${{ steps.test-results.outputs.passed }}"
FAILED="${{ steps.test-results.outputs.failed }}"
TOTAL="${{ steps.test-results.outputs.total }}"

./.github/workflows/scripts/generate-test-summary.sh "$PASSED" "$FAILED" "$TOTAL" "$TEST_EXIT_CODE"

- name: Create test results check
if: always() && github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const createTestCheck = require('./.github/workflows/scripts/create-test-check.js');
await createTestCheck({
github,
context,
passed: '${{ steps.test-results.outputs.passed }}',
failed: '${{ steps.test-results.outputs.failed }}',
total: '${{ steps.test-results.outputs.total }}'
});

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
directory: ./coverage
fail_ci_if_error: false
verbose: true

- name: Upload coverage report as artifact
if: always()
uses: actions/upload-artifact@v5
with:
Expand Down
31 changes: 31 additions & 0 deletions .github/workflows/scripts/create-test-check.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Create a GitHub check run with test results.
*
* This script creates a GitHub check that displays test results on pull requests.
* It's designed to be used with actions/github-script.
*
* @param {Object} params - Parameters object
* @param {Object} params.github - GitHub API client from actions/github-script
* @param {Object} params.context - GitHub Actions context
* @param {string} params.passed - Number of passed tests
* @param {string} params.failed - Number of failed tests
* @param {string} params.total - Total number of tests
*/
module.exports = async ({ github, context, passed, failed, total }) => {
const conclusion = failed === '0' && total !== '0' ? 'success' : (total === '0' ? 'neutral' : 'failure');
const summary = `${total} tests run, ${passed} passed, ${failed} failed`;

await github.rest.checks.create({
owner: context.repo.owner,
repo: context.repo.repo,
name: 'Test Results',
head_sha: context.payload.pull_request.head.sha,
status: 'completed',
conclusion: conclusion,
output: {
title: summary,
summary: summary,
text: `**Test Execution Summary**\n\n- Total: ${total}\n- Passed: ${passed} ✅\n- Failed: ${failed} ${failed === '0' ? '✅' : '❌'}`
}
});
};
44 changes: 44 additions & 0 deletions .github/workflows/scripts/generate-test-summary.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/bin/bash
set -euo pipefail

# Generate a test summary markdown for GitHub Actions step summary.
#
# This script creates a formatted markdown table showing test results and writes it
# to GITHUB_STEP_SUMMARY. It also exits with the original test exit code.
#
# Usage:
# ./scripts/generate-test-summary.sh <passed> <failed> <total> <exit_code>
#
# Example:
# ./scripts/generate-test-summary.sh 182 0 182 0

if [ $# -lt 4 ]; then
echo "Error: Missing required arguments"
echo "Usage: $0 <passed> <failed> <total> <exit_code>"
exit 1
fi

PASSED="$1"
FAILED="$2"
TOTAL="$3"
EXIT_CODE="$4"

echo "### Test Results 📊" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"

if [ "$FAILED" = "0" ] && [ "$TOTAL" != "0" ]; then
echo "✅ **All tests passed!**" >> "$GITHUB_STEP_SUMMARY"
elif [ "$TOTAL" = "0" ]; then
echo "⚠️ **Could not parse test results**" >> "$GITHUB_STEP_SUMMARY"
else
echo "❌ **Some tests failed**" >> "$GITHUB_STEP_SUMMARY"
fi

echo "" >> "$GITHUB_STEP_SUMMARY"
echo "| Metric | Count |" >> "$GITHUB_STEP_SUMMARY"
echo "|--------|-------|" >> "$GITHUB_STEP_SUMMARY"
echo "| Total Tests | $TOTAL |" >> "$GITHUB_STEP_SUMMARY"
echo "| Passed | $PASSED |" >> "$GITHUB_STEP_SUMMARY"
echo "| Failed | $FAILED |" >> "$GITHUB_STEP_SUMMARY"

exit "$EXIT_CODE"
47 changes: 47 additions & 0 deletions .github/workflows/scripts/parse-test-results.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/bin/bash
set -euo pipefail

# Parse test results from web-test-runner output and export to GitHub Actions output.
#
# This script extracts test result counts (passed/failed/total) from the test output log
# and writes them to GITHUB_OUTPUT for use in subsequent workflow steps.
#
# Usage:
# ./.github/workflows/scripts/parse-test-results.sh <test-output-log-file>
#
# Example:
# npm run test:coverage 2>&1 | tee test-output.log
# ./.github/workflows/scripts/parse-test-results.sh test-output.log

if [ $# -lt 1 ]; then
echo "Error: Missing required argument"
echo "Usage: $0 <test-output-log-file>"
exit 1
fi

TEST_OUTPUT_LOG="$1"

if [ ! -f "$TEST_OUTPUT_LOG" ]; then
echo "Error: Test output log file not found: $TEST_OUTPUT_LOG"
exit 1
fi

# Extract test results from web-test-runner output
# Format: "Chrome: |████| 7/7 test files | 182 passed, 0 failed"
if grep -q "passed" "$TEST_OUTPUT_LOG"; then
PASSED=$(grep -oP '\d+ passed' "$TEST_OUTPUT_LOG" | tail -1 | grep -oP '\d+' || echo "0")
FAILED=$(grep -oP '\d+ failed' "$TEST_OUTPUT_LOG" | tail -1 | grep -oP '\d+' || echo "0")
TOTAL=$((PASSED + FAILED))

echo "passed=$PASSED" >> "$GITHUB_OUTPUT"
echo "failed=$FAILED" >> "$GITHUB_OUTPUT"
echo "total=$TOTAL" >> "$GITHUB_OUTPUT"

echo "✅ Parsed test results: $PASSED passed, $FAILED failed (total: $TOTAL)"
else
echo "passed=0" >> "$GITHUB_OUTPUT"
echo "failed=0" >> "$GITHUB_OUTPUT"
echo "total=0" >> "$GITHUB_OUTPUT"

echo "⚠️ Could not parse test results from $TEST_OUTPUT_LOG"
fi