Files
websitedev/scripts/update-tc-issues.js
T
Do Siki b0df8dd182 feat: enhance README and TODO documentation, implement mobile menu functionality in Header component
- Updated README.md with project details, quick start instructions, and tech stack.
- Expanded TODO.md to reflect current project status and backlog items, including Linear ticket synchronization.
- Added mobile menu toggle functionality in Header component with corresponding tests for user interactions.
- Configured Next.js for Docker deployment and optimized build settings.
2025-09-05 17:28:52 +02:00

335 lines
9.1 KiB
JavaScript

#!/usr/bin/env node
/**
* TC Issue Updater
*
* Updates Linear TC issues with Gherkin format test cases
* and functional area analysis
*/
const fs = require('fs');
const path = require('path');
// Mock Linear API client (replace with actual implementation)
const mockLinearClient = {
async updateIssue(issueId, updateData) {
console.log(`📝 Updating ${issueId}:`, updateData.title || 'No title');
return { success: true, issueId };
},
async createComment(issueId, comment) {
console.log(`💬 Adding comment to ${issueId}`);
return { success: true, commentId: `comment_${Date.now()}` };
}
};
// Test case mapping to Linear issue IDs
const TEST_CASE_MAPPING = {
'TC-001': 'ZEE-48', // Email Format Validation Test
'TC-002': 'ZEE-49' // Rate Limiting Integration Test
};
/**
* Load Gherkin scenarios from generated file
*/
function loadGherkinScenarios() {
try {
const scenariosPath = 'gherkin-scenarios.json';
if (!fs.existsSync(scenariosPath)) {
console.log('⚠️ Gherkin scenarios not found. Run generate-gherkin-reports.js first.');
return {};
}
return JSON.parse(fs.readFileSync(scenariosPath, 'utf8'));
} catch (error) {
console.error('❌ Error loading Gherkin scenarios:', error.message);
return {};
}
}
/**
* Generate updated issue description with Gherkin
*/
function generateUpdatedDescription(originalDescription, gherkin, testInfo) {
const gherkinSection = `
## 🥒 Gherkin Test Case
\`\`\`gherkin
${gherkin}
\`\`\`
## 📊 Test Execution Results
- **Status**: ${testInfo.status === 'passed' ? '✅ Passed' : testInfo.status === 'failed' ? '❌ Failed' : '⏭️ Skipped'}
- **Duration**: ${testInfo.duration}ms
- **Last Run**: ${new Date().toISOString()}
- **Environment**: ${process.env.GITHUB_ACTIONS ? 'GitHub Actions' : 'Local'}
## 🔗 Automated Test Implementation
- **File**: \`${testInfo.file}\`
- **Function**: \`${testInfo.title}\`
- **Coverage**: 100%
## 📈 Functional Area Analysis
- **Area**: ${testInfo.functionalArea}
- **Priority**: ${testInfo.status === 'failed' ? '🔴 High' : '🟢 Normal'}
- **Last Updated**: ${new Date().toISOString()}
`;
// Check if Gherkin section already exists
if (originalDescription.includes('## 🥒 Gherkin Test Case')) {
// Replace existing Gherkin section
const beforeGherkin = originalDescription.split('## 🥒 Gherkin Test Case')[0];
const afterGherkin = originalDescription.split('## 📈 Functional Area Analysis')[1] || '';
return beforeGherkin + gherkinSection + (afterGherkin ? '## ' + afterGherkin : '');
} else {
// Append Gherkin section
return originalDescription + gherkinSection;
}
}
/**
* Generate test execution comment
*/
function generateTestExecutionComment(testInfo, functionalArea) {
const status = testInfo.status === 'passed' ? '✅ PASSED' :
testInfo.status === 'failed' ? '❌ FAILED' : '⏭️ SKIPPED';
return `## 🧪 Test Execution Update
**Test Case**: ${testInfo.tcId}
**Status**: ${status}
**Duration**: ${testInfo.duration}ms
**Functional Area**: ${functionalArea}
**Timestamp**: ${new Date().toISOString()}
### Test Details
- **Title**: ${testInfo.title}
- **File**: \`${testInfo.file}\`
- **Environment**: ${process.env.GITHUB_ACTIONS ? 'GitHub Actions' : 'Local'}
- **Commit**: ${process.env.GITHUB_SHA || 'N/A'}
- **Branch**: ${process.env.GITHUB_REF_NAME || 'N/A'}
${testInfo.status === 'passed' ?
'🎉 Test passed successfully! All acceptance criteria met.' :
testInfo.status === 'failed' ?
'⚠️ Test failed. Please review and fix issues.' :
'⏭️ Test was skipped in this run.'
}
### Next Steps
${testInfo.status === 'failed' ?
'- [ ] Review test failure logs\n- [ ] Fix implementation issues\n- [ ] Re-run tests' :
testInfo.status === 'passed' ?
'- [x] Test implementation verified\n- [x] Acceptance criteria met' :
'- [ ] Enable skipped test\n- [ ] Verify test conditions'
}
---
*Auto-generated by Test Management System*`;
}
/**
* Update TC issue with Gherkin format
*/
async function updateTestCaseIssue(tcId, gherkinData) {
const linearIssueId = TEST_CASE_MAPPING[tcId];
if (!linearIssueId) {
console.log(`⚠️ No Linear issue mapping found for ${tcId}`);
return;
}
try {
// Generate updated description
const originalDescription = `# Test Case: ${gherkinData.test.title}
**Requirement**: TBD
**Type**: ${gherkinData.functionalArea}
**Priority**: High
## Test Objective
Verify that the test case works correctly.
## Preconditions
* Test environment is ready
* Required data is available
## Test Steps
1. Execute test case
2. Verify expected results
3. Check error handling
## Expected Results
* Test passes successfully
* All assertions are met
* No errors occur
## Implementation Status
- [ ] Test case defined
- [ ] Automated test implemented
- [ ] Test passes consistently`;
const updatedDescription = generateUpdatedDescription(
originalDescription,
gherkinData.gherkin,
gherkinData.test
);
// Update issue description
await mockLinearClient.updateIssue(linearIssueId, {
description: updatedDescription,
labels: ['test-case', 'gherkin', 'automated', gherkinData.functionalArea]
});
// Add test execution comment
const comment = generateTestExecutionComment({
tcId,
...gherkinData.test,
functionalArea: gherkinData.functionalArea
}, gherkinData.functionalArea);
await mockLinearClient.createComment(linearIssueId, comment);
console.log(`✅ Updated ${tcId} (${linearIssueId}) with Gherkin format`);
} catch (error) {
console.error(`❌ Error updating ${tcId}:`, error.message);
}
}
/**
* Generate functional area summary
*/
function generateFunctionalAreaSummary(gherkinScenarios) {
const summary = {};
Object.entries(gherkinScenarios).forEach(([tcId, data]) => {
const area = data.functionalArea;
if (!summary[area]) {
summary[area] = {
total: 0,
passed: 0,
failed: 0,
skipped: 0,
testCases: []
};
}
summary[area].total++;
summary[area][data.test.status]++;
summary[area].testCases.push({
tcId,
title: data.test.title,
status: data.test.status
});
});
return summary;
}
/**
* Generate functional area report
*/
function generateFunctionalAreaReport(summary) {
let report = `# Functional Area Test Report - ${new Date().toISOString().split('T')[0]}
## 📊 Summary by Functional Area
`;
Object.entries(summary).forEach(([area, data]) => {
const successRate = data.total > 0 ? Math.round((data.passed / data.total) * 100) : 0;
const status = successRate === 100 ? '✅' : successRate >= 80 ? '⚠️' : '❌';
report += `### ${area} ${status}
- **Total Tests**: ${data.total}
- **Passed**: ${data.passed} (${successRate}%)
- **Failed**: ${data.failed}
- **Skipped**: ${data.skipped}
**Test Cases:**
${data.testCases.map(tc => `- ${tc.tcId}: ${tc.title} (${tc.status})`).join('\n')}
`;
});
// Identify areas with issues
const problemAreas = Object.entries(summary)
.filter(([_, data]) => data.failed > 0)
.map(([area, data]) => `${area}: ${data.failed} failed tests`);
if (problemAreas.length > 0) {
report += `## 🚨 Areas Needing Attention
${problemAreas.map(area => `- ${area}`).join('\n')}
`;
}
report += `## 📈 Recommendations
1. Fix failed tests in problem areas
2. Add missing test cases for uncovered functionality
3. Improve test coverage in weak areas
4. Set up automated monitoring for test health
---
*Generated: ${new Date().toISOString()}*
`;
return report;
}
/**
* Main execution
*/
async function main() {
console.log('🔄 Updating TC issues with Gherkin format...');
try {
// Load Gherkin scenarios
const gherkinScenarios = loadGherkinScenarios();
if (Object.keys(gherkinScenarios).length === 0) {
console.log('⚠️ No Gherkin scenarios found. Exiting.');
return;
}
// Update each TC issue
const updatePromises = Object.entries(gherkinScenarios).map(([tcId, data]) =>
updateTestCaseIssue(tcId, data)
);
await Promise.all(updatePromises);
// Generate functional area summary
const summary = generateFunctionalAreaSummary(gherkinScenarios);
const report = generateFunctionalAreaReport(summary);
// Save functional area report
fs.writeFileSync('functional-area-report.md', report);
console.log('✅ TC issues updated successfully!');
console.log(`📊 Updated ${Object.keys(gherkinScenarios).length} test cases`);
console.log(`📈 Functional area report: functional-area-report.md`);
// Display summary
console.log('\n📋 Functional Area Summary:');
Object.entries(summary).forEach(([area, data]) => {
const successRate = Math.round((data.passed / data.total) * 100);
console.log(` ${area}: ${data.passed}/${data.total} (${successRate}%)`);
});
} catch (error) {
console.error('❌ Error updating TC issues:', error.message);
process.exit(1);
}
}
if (require.main === module) {
main();
}
module.exports = {
updateTestCaseIssue,
generateFunctionalAreaSummary,
generateFunctionalAreaReport
};