- Move getTestConfig() calls from module level to test execution time - Add CI-specific debug logging to diagnose environment loading issues - Add verification step in CI workflow to check .env.test availability - Ensure environment variables are loaded before tests access config The issue was that config was being accessed at module import time, which could happen before the global setup runs in some CI environments.
299 lines
11 KiB
YAML
299 lines
11 KiB
YAML
name: Test Suite
|
|
on:
|
|
push:
|
|
branches: [main, feat/comprehensive-testing-suite]
|
|
pull_request:
|
|
branches: [main]
|
|
|
|
jobs:
|
|
test:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 20
|
|
cache: 'npm'
|
|
|
|
- name: Install dependencies
|
|
run: npm ci
|
|
|
|
# Verify test environment setup
|
|
- name: Verify test environment
|
|
run: |
|
|
echo "Current directory: $(pwd)"
|
|
echo "Checking for .env.test file:"
|
|
ls -la .env.test || echo ".env.test not found!"
|
|
echo "First few lines of .env.test:"
|
|
head -5 .env.test || echo "Cannot read .env.test"
|
|
|
|
# Run tests with coverage and multiple reporters
|
|
- name: Run tests with coverage
|
|
run: npm run test:ci
|
|
env:
|
|
CI: true
|
|
|
|
# Generate test summary
|
|
- name: Generate test summary
|
|
if: always()
|
|
run: node scripts/generate-test-summary.js
|
|
|
|
# Generate detailed reports
|
|
- name: Generate detailed reports
|
|
if: always()
|
|
run: node scripts/generate-detailed-reports.js
|
|
|
|
# Upload test results artifacts
|
|
- name: Upload test results
|
|
if: always()
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: test-results-${{ github.run_number }}-${{ github.run_attempt }}
|
|
path: |
|
|
test-results/
|
|
test-summary.md
|
|
test-reports/
|
|
retention-days: 30
|
|
if-no-files-found: warn
|
|
|
|
# Upload coverage artifacts
|
|
- name: Upload coverage reports
|
|
if: always()
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: coverage-${{ github.run_number }}-${{ github.run_attempt }}
|
|
path: |
|
|
coverage/
|
|
retention-days: 30
|
|
if-no-files-found: warn
|
|
|
|
# Upload coverage to Codecov
|
|
- name: Upload coverage to Codecov
|
|
if: always()
|
|
uses: codecov/codecov-action@v4
|
|
with:
|
|
token: ${{ secrets.CODECOV_TOKEN }}
|
|
files: ./coverage/lcov.info
|
|
flags: unittests
|
|
name: codecov-umbrella
|
|
fail_ci_if_error: false
|
|
verbose: true
|
|
|
|
# Run linting
|
|
- name: Run linting
|
|
run: npm run lint
|
|
|
|
# Run type checking
|
|
- name: Run type checking
|
|
run: npm run typecheck || true # Allow to fail initially
|
|
|
|
# Run benchmarks
|
|
- name: Run benchmarks
|
|
id: benchmarks
|
|
run: npm run benchmark:ci
|
|
continue-on-error: true
|
|
|
|
# Upload benchmark results
|
|
- name: Upload benchmark results
|
|
if: always() && steps.benchmarks.outcome != 'skipped'
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: benchmark-results-${{ github.run_number }}-${{ github.run_attempt }}
|
|
path: |
|
|
benchmark-results.json
|
|
retention-days: 30
|
|
if-no-files-found: warn
|
|
|
|
# Create test report comment for PRs
|
|
- name: Create test report comment
|
|
if: github.event_name == 'pull_request' && always()
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const fs = require('fs');
|
|
let summary = '## Test Results\n\nTest summary generation failed.';
|
|
|
|
try {
|
|
if (fs.existsSync('test-summary.md')) {
|
|
summary = fs.readFileSync('test-summary.md', 'utf8');
|
|
}
|
|
} catch (error) {
|
|
console.error('Error reading test summary:', error);
|
|
}
|
|
|
|
// Find existing comment
|
|
const { data: comments } = await github.rest.issues.listComments({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
issue_number: context.issue.number,
|
|
});
|
|
|
|
const botComment = comments.find(comment =>
|
|
comment.user.type === 'Bot' &&
|
|
comment.body.includes('## Test Results')
|
|
);
|
|
|
|
if (botComment) {
|
|
// Update existing comment
|
|
await github.rest.issues.updateComment({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
comment_id: botComment.id,
|
|
body: summary
|
|
});
|
|
} else {
|
|
// Create new comment
|
|
await github.rest.issues.createComment({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
issue_number: context.issue.number,
|
|
body: summary
|
|
});
|
|
}
|
|
|
|
# Generate job summary
|
|
- name: Generate job summary
|
|
if: always()
|
|
run: |
|
|
echo "# Test Run Summary" >> $GITHUB_STEP_SUMMARY
|
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
|
|
if [ -f test-summary.md ]; then
|
|
cat test-summary.md >> $GITHUB_STEP_SUMMARY
|
|
else
|
|
echo "Test summary generation failed." >> $GITHUB_STEP_SUMMARY
|
|
fi
|
|
|
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
echo "## 📥 Download Artifacts" >> $GITHUB_STEP_SUMMARY
|
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
echo "- [Test Results](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})" >> $GITHUB_STEP_SUMMARY
|
|
echo "- [Coverage Report](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})" >> $GITHUB_STEP_SUMMARY
|
|
echo "- [Benchmark Results](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})" >> $GITHUB_STEP_SUMMARY
|
|
|
|
# Store test metadata
|
|
- name: Store test metadata
|
|
if: always()
|
|
run: |
|
|
cat > test-metadata.json << EOF
|
|
{
|
|
"run_id": "${{ github.run_id }}",
|
|
"run_number": "${{ github.run_number }}",
|
|
"run_attempt": "${{ github.run_attempt }}",
|
|
"sha": "${{ github.sha }}",
|
|
"ref": "${{ github.ref }}",
|
|
"event_name": "${{ github.event_name }}",
|
|
"repository": "${{ github.repository }}",
|
|
"actor": "${{ github.actor }}",
|
|
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
|
"node_version": "$(node --version)",
|
|
"npm_version": "$(npm --version)"
|
|
}
|
|
EOF
|
|
|
|
- name: Upload test metadata
|
|
if: always()
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: test-metadata-${{ github.run_number }}-${{ github.run_attempt }}
|
|
path: test-metadata.json
|
|
retention-days: 30
|
|
|
|
# Separate job to process and publish test results
|
|
publish-results:
|
|
needs: test
|
|
runs-on: ubuntu-latest
|
|
if: always()
|
|
permissions:
|
|
checks: write
|
|
pull-requests: write
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
# Download all artifacts
|
|
- name: Download all artifacts
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
path: artifacts
|
|
|
|
# Publish test results as checks
|
|
- name: Publish test results
|
|
uses: dorny/test-reporter@v1
|
|
if: always()
|
|
with:
|
|
name: Test Results
|
|
path: 'artifacts/test-results-*/test-results/junit.xml'
|
|
reporter: java-junit
|
|
fail-on-error: false
|
|
|
|
# Create a combined artifact with all results
|
|
- name: Create combined results artifact
|
|
if: always()
|
|
run: |
|
|
mkdir -p combined-results
|
|
cp -r artifacts/* combined-results/ 2>/dev/null || true
|
|
|
|
# Create index file
|
|
cat > combined-results/index.html << 'EOF'
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>n8n-mcp Test Results</title>
|
|
<style>
|
|
body { font-family: Arial, sans-serif; margin: 40px; }
|
|
h1 { color: #333; }
|
|
.section { margin: 20px 0; padding: 20px; border: 1px solid #ddd; border-radius: 5px; }
|
|
a { color: #0066cc; text-decoration: none; }
|
|
a:hover { text-decoration: underline; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1>n8n-mcp Test Results</h1>
|
|
<div class="section">
|
|
<h2>Test Reports</h2>
|
|
<ul>
|
|
<li><a href="test-results-${{ github.run_number }}-${{ github.run_attempt }}/test-reports/report.html">📊 Detailed HTML Report</a></li>
|
|
<li><a href="test-results-${{ github.run_number }}-${{ github.run_attempt }}/test-results/html/index.html">📈 Vitest HTML Report</a></li>
|
|
<li><a href="test-results-${{ github.run_number }}-${{ github.run_attempt }}/test-reports/report.md">📄 Markdown Report</a></li>
|
|
<li><a href="test-results-${{ github.run_number }}-${{ github.run_attempt }}/test-summary.md">📝 PR Summary</a></li>
|
|
<li><a href="test-results-${{ github.run_number }}-${{ github.run_attempt }}/test-results/junit.xml">🔧 JUnit XML</a></li>
|
|
<li><a href="test-results-${{ github.run_number }}-${{ github.run_attempt }}/test-results/results.json">🔢 JSON Results</a></li>
|
|
<li><a href="test-results-${{ github.run_number }}-${{ github.run_attempt }}/test-reports/report.json">📊 Full JSON Report</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="section">
|
|
<h2>Coverage Reports</h2>
|
|
<ul>
|
|
<li><a href="coverage-${{ github.run_number }}-${{ github.run_attempt }}/html/index.html">HTML Coverage Report</a></li>
|
|
<li><a href="coverage-${{ github.run_number }}-${{ github.run_attempt }}/lcov.info">LCOV Report</a></li>
|
|
<li><a href="coverage-${{ github.run_number }}-${{ github.run_attempt }}/coverage-summary.json">Coverage Summary JSON</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="section">
|
|
<h2>Benchmark Results</h2>
|
|
<ul>
|
|
<li><a href="benchmark-results-${{ github.run_number }}-${{ github.run_attempt }}/benchmark-results.json">Benchmark Results JSON</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="section">
|
|
<h2>Metadata</h2>
|
|
<ul>
|
|
<li><a href="test-metadata-${{ github.run_number }}-${{ github.run_attempt }}/test-metadata.json">Test Run Metadata</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="section">
|
|
<p><em>Generated at $(date -u +%Y-%m-%dT%H:%M:%SZ)</em></p>
|
|
<p><em>Run: #${{ github.run_number }} | SHA: ${{ github.sha }}</em></p>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
EOF
|
|
|
|
- name: Upload combined results
|
|
if: always()
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: all-test-results-${{ github.run_number }}
|
|
path: combined-results/
|
|
retention-days: 90 |