Skip to content

fix: disable TLS for internal PostgreSQL connection #208

fix: disable TLS for internal PostgreSQL connection

fix: disable TLS for internal PostgreSQL connection #208

Workflow file for this run

name: Web E2E Tests
on:
pull_request:
branches: [main]
paths:
- 'web/**'
- 'backend/**'
- '.github/workflows/test-web.yml'
push:
branches: [main]
paths:
- 'web/**'
- 'backend/**'
- '.github/workflows/test-web.yml'
concurrency:
group: web-tests-${{ github.ref }}
cancel-in-progress: true
jobs:
test-web:
name: Web E2E Tests (300+ tests)
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
- name: Start Docker Compose Stack
run: |
cd backend
docker compose up -d
# Wait for all services to be healthy (60 second timeout)
echo "Waiting for services to be healthy..."
for i in {1..60}; do
HEALTHY=$(docker compose ps | grep -c "healthy" || true)
if [ "$HEALTHY" -ge 4 ]; then
echo "βœ… All services are healthy"
break
fi
echo "Waiting... ($i/60)"
sleep 1
done
# List running services
echo ""
echo "Running services:"
docker compose ps
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Install web dependencies
run: |
cd web
bun install --frozen-lockfile
- name: Install Playwright browsers
run: |
cd web
bunx playwright install --with-deps chromium
- name: Run E2E tests
run: |
cd web
bunx playwright test
env:
BACKEND_URL: http://localhost:8787
- name: Stop Docker Compose Stack
if: always()
run: |
cd backend
docker compose down -v
- name: Parse test results
if: always()
id: parse-results
run: |
if [ -f web/test-results/results.json ]; then
PASSED=$(jq '.stats.expected // 0' web/test-results/results.json)
FAILED=$(jq '.stats.unexpected // 0' web/test-results/results.json)
SKIPPED=$(jq '.stats.skipped // 0' web/test-results/results.json)
DURATION=$(jq '.stats.duration // 0' web/test-results/results.json)
DURATION_SEC=$((DURATION / 1000))
echo "passed=$PASSED" >> $GITHUB_OUTPUT
echo "failed=$FAILED" >> $GITHUB_OUTPUT
echo "skipped=$SKIPPED" >> $GITHUB_OUTPUT
echo "duration=$DURATION_SEC" >> $GITHUB_OUTPUT
# Calculate total and pass rate
TOTAL=$((PASSED + FAILED + SKIPPED))
if [ $TOTAL -gt 0 ]; then
PASS_RATE=$((PASSED * 100 / TOTAL))
echo "total=$TOTAL" >> $GITHUB_OUTPUT
echo "pass_rate=$PASS_RATE" >> $GITHUB_OUTPUT
fi
else
echo "❌ No test results file found"
fi
- name: Upload test report
if: always()
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: web/playwright-report/
retention-days: 14
- name: Upload test results (JSON)
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results-json
path: web/test-results/
retention-days: 14
- name: Upload test videos
if: failure()
uses: actions/upload-artifact@v4
with:
name: test-videos
path: web/test-results/**/*.webm
retention-days: 7
- name: Upload test traces
if: failure()
uses: actions/upload-artifact@v4
with:
name: test-traces
path: web/test-results/**/*.zip
retention-days: 7
- name: Comment PR with detailed results
if: always() && github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const testResultsPath = 'web/test-results/results.json';
let comment = '## πŸ§ͺ Web E2E Test Results\n\n';
if (fs.existsSync(testResultsPath)) {
try {
const results = JSON.parse(fs.readFileSync(testResultsPath, 'utf8'));
const { stats } = results;
const passed = stats.expected || 0;
const failed = stats.unexpected || 0;
const skipped = stats.skipped || 0;
const total = passed + failed + skipped;
const duration = ((stats.duration || 0) / 1000).toFixed(2);
const passRate = total > 0 ? Math.round((passed / total) * 100) : 0;
comment += '### Summary\n';
comment += `| Metric | Value |\n`;
comment += `|--------|-------|\n`;
comment += `| βœ… **Passed** | **${passed}** |\n`;
comment += `| ❌ **Failed** | **${failed}** |\n`;
comment += `| ⏭️ **Skipped** | **${skipped}** |\n`;
comment += `| πŸ“Š **Total** | **${total}** |\n`;
comment += `| 🎯 **Pass Rate** | **${passRate}%** |\n`;
comment += `| ⏱️ **Duration** | **${duration}s** |\n\n`;
// Test coverage by category
if (results.suites && results.suites.length > 0) {
comment += '### Test Coverage\n';
const categories = {};
results.suites.forEach(suite => {
const parts = suite.title.split(' - ');
const category = parts[0] || 'Other';
if (!categories[category]) {
categories[category] = { passed: 0, failed: 0 };
}
suite.tests?.forEach(test => {
if (test.status === 'passed') categories[category].passed++;
else if (test.status === 'failed') categories[category].failed++;
});
});
Object.entries(categories).forEach(([name, stats]) => {
const status = stats.failed === 0 ? 'βœ…' : '❌';
comment += `- ${status} **${name}**: ${stats.passed}/${stats.passed + stats.failed}\n`;
});
comment += '\n';
}
if (failed > 0) {
comment += '### Failed Tests\n';
let failCount = 0;
results.suites?.forEach(suite => {
suite.tests?.forEach(test => {
if (test.status === 'failed' && failCount < 10) {
comment += `- ❌ ${test.title}\n`;
failCount++;
}
});
});
if (failCount >= 10) {
comment += `- ... and ${failed - 10} more\n`;
}
comment += '\n';
}
comment += `**[View full report β†’](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})**\n`;
} catch (e) {
console.error('Error parsing results:', e);
comment += '⚠️ Error parsing test results\n';
comment += `**[View full report β†’](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})**\n`;
}
} else {
comment += '⚠️ No test results file found\n';
comment += `**[View full report β†’](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})**\n`;
}
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: comment
}).catch((e) => {
console.error('Error posting comment:', e);
});
- name: Report test status
if: always()
run: |
echo "## Test Execution Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Metric | Value |" >> $GITHUB_STEP_SUMMARY
echo "|--------|-------|" >> $GITHUB_STEP_SUMMARY
echo "| Passed | ${{ steps.parse-results.outputs.passed || '?' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Failed | ${{ steps.parse-results.outputs.failed || '?' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Skipped | ${{ steps.parse-results.outputs.skipped || '?' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Total | ${{ steps.parse-results.outputs.total || '?' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Pass Rate | ${{ steps.parse-results.outputs.pass_rate || '?' }}% |" >> $GITHUB_STEP_SUMMARY
echo "| Duration | ${{ steps.parse-results.outputs.duration || '?' }}s |" >> $GITHUB_STEP_SUMMARY
- name: Fail if tests failed
if: failure() && steps.parse-results.outputs.failed > 0
run: |
echo "❌ Tests failed!"
exit 1
- name: 'notify vercel'
uses: 'vercel/repository-dispatch/actions/status@v1'
with:
name: Vercel - sidechain - tests-web