mirror of
https://github.com/czlonkowski/n8n-mcp.git
synced 2026-03-28 13:13:08 +00:00
Remove duplicate, low-value, and fragmented test files while preserving all meaningful coverage. Enable parallel test execution and remove the entire benchmark infrastructure. Key changes: - Consolidate workflow-validator tests (13 files -> 3) - Consolidate config-validator tests (9 files -> 3) - Consolidate telemetry tests (11 files -> 6) - Merge AI validator tests (2 files -> 1) - Remove example/demo test files, mock-testing files, and already-skipped tests - Remove benchmark infrastructure (10 files, CI workflow, 4 npm scripts) - Enable parallel test execution (remove singleThread: true) - Remove retry:2 that was masking flaky tests - Slim CI publish-results job Results: 224 -> 191 test files, 4690 -> 4303 tests, 121K -> 106K lines Local runtime: 319s -> 27s (11.9x speedup) Conceived by Romuald Członkowski - www.aiadvisors.pl/en Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
261 lines
8.5 KiB
YAML
261 lines
8.5 KiB
YAML
name: Test Suite
|
|
on:
|
|
push:
|
|
branches: [main, feat/comprehensive-testing-suite]
|
|
paths-ignore:
|
|
- '**.md'
|
|
- '**.txt'
|
|
- 'docs/**'
|
|
- 'examples/**'
|
|
- '.github/FUNDING.yml'
|
|
- '.github/ISSUE_TEMPLATE/**'
|
|
- '.github/pull_request_template.md'
|
|
- '.gitignore'
|
|
- 'LICENSE*'
|
|
- 'ATTRIBUTION.md'
|
|
- 'SECURITY.md'
|
|
- 'CODE_OF_CONDUCT.md'
|
|
pull_request:
|
|
branches: [main]
|
|
paths-ignore:
|
|
- '**.md'
|
|
- '**.txt'
|
|
- 'docs/**'
|
|
- 'examples/**'
|
|
- '.github/FUNDING.yml'
|
|
- '.github/ISSUE_TEMPLATE/**'
|
|
- '.github/pull_request_template.md'
|
|
- '.gitignore'
|
|
- 'LICENSE*'
|
|
- 'ATTRIBUTION.md'
|
|
- 'SECURITY.md'
|
|
- 'CODE_OF_CONDUCT.md'
|
|
|
|
permissions:
|
|
contents: read
|
|
issues: write
|
|
pull-requests: write
|
|
checks: write
|
|
|
|
jobs:
|
|
test:
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 15 # Increased from 10 to accommodate larger database with community nodes
|
|
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 unit tests first (without MSW)
|
|
- name: Run unit tests with coverage
|
|
run: npm run test:unit -- --coverage --coverage.thresholds.lines=0 --coverage.thresholds.functions=0 --coverage.thresholds.branches=0 --coverage.thresholds.statements=0 --reporter=default --reporter=junit
|
|
env:
|
|
CI: true
|
|
|
|
# Run integration tests separately (with MSW setup)
|
|
- name: Run integration tests
|
|
run: npm run test:integration -- --reporter=default --reporter=junit
|
|
env:
|
|
CI: true
|
|
N8N_API_URL: ${{ secrets.N8N_API_URL }}
|
|
N8N_API_KEY: ${{ secrets.N8N_API_KEY }}
|
|
N8N_TEST_WEBHOOK_GET_URL: ${{ secrets.N8N_TEST_WEBHOOK_GET_URL }}
|
|
N8N_TEST_WEBHOOK_POST_URL: ${{ secrets.N8N_TEST_WEBHOOK_POST_URL }}
|
|
N8N_TEST_WEBHOOK_PUT_URL: ${{ secrets.N8N_TEST_WEBHOOK_PUT_URL }}
|
|
N8N_TEST_WEBHOOK_DELETE_URL: ${{ secrets.N8N_TEST_WEBHOOK_DELETE_URL }}
|
|
|
|
# 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
|
|
|
|
# Create test report comment for PRs
|
|
- name: Create test report comment
|
|
if: github.event_name == 'pull_request' && always()
|
|
uses: actions/github-script@v7
|
|
continue-on-error: true
|
|
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);
|
|
}
|
|
|
|
try {
|
|
// 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
|
|
});
|
|
}
|
|
} catch (error) {
|
|
console.error('Failed to create/update PR comment:', error.message);
|
|
console.log('This is likely due to insufficient permissions for external PRs.');
|
|
console.log('Test results have been saved to the job summary instead.');
|
|
}
|
|
|
|
# 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
|
|
|
|
# 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
|
|
|
|
# Publish test results as checks
|
|
publish-results:
|
|
needs: test
|
|
runs-on: ubuntu-latest
|
|
if: always()
|
|
permissions:
|
|
checks: write
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Download test results
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
path: artifacts
|
|
|
|
- name: Publish test results
|
|
uses: dorny/test-reporter@v1
|
|
if: always()
|
|
continue-on-error: true
|
|
with:
|
|
name: Test Results
|
|
path: 'artifacts/test-results-*/test-results/junit.xml'
|
|
reporter: java-junit
|
|
fail-on-error: false
|
|
fail-on-empty: false |