PunimTag Web Application - Major Feature Release #1

Open
tanyar09 wants to merge 106 commits from dev into master
Showing only changes of commit a1e4544a42 - Show all commits

View File

@ -412,93 +412,8 @@ jobs:
if [ -f test-results.xml ]; then
echo "✅ Test results XML file generated"
# Parse JUnit XML if python is available
python3 << 'PYTHON_EOF' || true
import xml.etree.ElementTree as ET
import sys
try:
tree = ET.parse('test-results.xml')
root = tree.getroot()
# Get test suite statistics
testsuites = root.findall('.//testsuite')
total_tests = 0
total_failures = 0
total_errors = 0
total_skipped = 0
total_time = 0.0
for suite in testsuites:
total_tests += int(suite.get('tests', 0))
total_failures += int(suite.get('failures', 0))
total_errors += int(suite.get('errors', 0))
total_skipped += int(suite.get('skipped', 0))
total_time += float(suite.get('time', 0))
total_passed = total_tests - total_failures - total_errors - total_skipped
print(f"")
print(f"📈 TEST STATISTICS:")
print(f" Total Tests: {total_tests}")
print(f" ✅ Passed: {total_passed}")
print(f" ❌ Failed: {total_failures}")
print(f" ⚠️ Errors: {total_errors}")
print(f" ⏭️ Skipped: {total_skipped}")
print(f" ⏱️ Duration: {total_time:.2f}s")
print(f"")
# List failed tests
if total_failures > 0 or total_errors > 0:
print(f"❌ FAILED TESTS:")
print(f" ───────────────────────────────────────────────────────────")
for suite in testsuites:
for testcase in suite.findall('.//testcase'):
failure = testcase.find('failure')
error = testcase.find('error')
if failure is not None or error is not None:
test_name = testcase.get('name', 'unknown')
class_name = testcase.get('classname', 'unknown')
full_name = f"{class_name}::{test_name}" if class_name != 'unknown' else test_name
message = ""
if failure is not None:
message = failure.get('message', '')[:100] # Truncate long messages
elif error is not None:
message = error.get('message', '')[:100]
print(f" • {full_name}")
if message:
print(f" └─ {message}")
print(f"")
# Coverage summary if available
try:
with open('coverage.xml', 'r') as f:
import xml.etree.ElementTree as ET2
cov_tree = ET2.parse('coverage.xml')
cov_root = cov_tree.getroot()
line_rate = float(cov_root.get('line-rate', 0)) * 100
branch_rate = float(cov_root.get('branch-rate', 0)) * 100
print(f"📊 CODE COVERAGE:")
print(f" Line Coverage: {line_rate:.1f}%")
print(f" Branch Coverage: {branch_rate:.1f}%")
print(f"")
except:
pass
# Overall status
if total_failures == 0 and total_errors == 0:
print(f"✅ ALL TESTS PASSED")
else:
print(f"❌ {total_failures + total_errors} TEST(S) FAILED")
# Don't exit with error here - let the test step handle failure
PYTHON_EOF
# Parse JUnit XML if python is available (simplified to avoid YAML parsing issues)
python3 -c "import xml.etree.ElementTree as ET; tree = ET.parse('test-results.xml') if __import__('os').path.exists('test-results.xml') else None; root = tree.getroot() if tree else None; suites = root.findall('.//testsuite') if root else []; total = sum(int(s.get('tests', 0)) for s in suites); failures = sum(int(s.get('failures', 0)) for s in suites); errors = sum(int(s.get('errors', 0)) for s in suites); skipped = sum(int(s.get('skipped', 0)) for s in suites); time = sum(float(s.get('time', 0)) for s in suites); passed = total - failures - errors - skipped; print(f'\n📈 TEST STATISTICS:\n Total Tests: {total}\n ✅ Passed: {passed}\n ❌ Failed: {failures}\n ⚠️ Errors: {errors}\n ⏭️ Skipped: {skipped}\n ⏱️ Duration: {time:.2f}s\n'); print('✅ ALL TESTS PASSED' if failures == 0 and errors == 0 else f'❌ {failures + errors} TEST(S) FAILED')" || true
else
echo "⚠️ Test results XML not found"
echo " Run 'pytest tests/ -v' locally to see detailed results."
@ -520,105 +435,8 @@ PYTHON_EOF
echo ""
if [ -f test-results.xml ]; then
python3 << 'PYTHON_EOF' || true
import xml.etree.ElementTree as ET
import sys
try:
tree = ET.parse('test-results.xml')
root = tree.getroot()
testsuites = root.findall('.//testsuite')
total_tests = 0
total_failures = 0
total_errors = 0
total_skipped = 0
total_time = 0.0
for suite in testsuites:
total_tests += int(suite.get('tests', 0))
total_failures += int(suite.get('failures', 0))
total_errors += int(suite.get('errors', 0))
total_skipped += int(suite.get('skipped', 0))
total_time += float(suite.get('time', 0))
total_passed = total_tests - total_failures - total_errors - total_skipped
# Status emoji
if total_failures == 0 and total_errors == 0:
status_emoji = "✅"
status_text = "All tests passed"
else:
status_emoji = "❌"
status_text = f"{total_failures + total_errors} test(s) failed"
print(f"### {status_emoji} {status_text}")
print("")
print("| Metric | Count |")
print("|--------|-------|")
print(f"| Total Tests | {total_tests} |")
print(f"| ✅ Passed | {total_passed} |")
print(f"| ❌ Failed | {total_failures} |")
print(f"| ⚠️ Errors | {total_errors} |")
print(f"| ⏭️ Skipped | {total_skipped} |")
print(f"| ⏱️ Duration | {total_time:.2f}s |")
print("")
# List failed tests
if total_failures > 0 or total_errors > 0:
print("### ❌ Failed Tests")
print("")
for suite in testsuites:
for testcase in suite.findall('.//testcase'):
failure = testcase.find('failure')
error = testcase.find('error')
if failure is not None or error is not None:
test_name = testcase.get('name', 'unknown')
class_name = testcase.get('classname', 'unknown')
full_name = f"{class_name}::{test_name}" if class_name != 'unknown' else test_name
message = ""
if failure is not None:
message = failure.get('message', '')[:200]
elif error is not None:
message = error.get('message', '')[:200]
print(f"- **{full_name}**")
if message:
print(f" - `{message}`")
print("")
# Coverage summary
try:
with open('coverage.xml', 'r') as f:
import xml.etree.ElementTree as ET2
cov_tree = ET2.parse('coverage.xml')
cov_root = cov_tree.getroot()
line_rate = float(cov_root.get('line-rate', 0)) * 100
branch_rate = float(cov_root.get('branch-rate', 0)) * 100
print("### 📊 Code Coverage")
print("")
print(f"- **Line Coverage:** {line_rate:.1f}%")
print(f"- **Branch Coverage:** {branch_rate:.1f}%")
print("")
except:
pass
print("### 💡 Tips")
print("")
print("- To run tests locally: `pytest tests/ -v`")
print("- To run a specific test: `pytest tests/test_api_auth.py::TestLogin::test_login_success -v`")
print("- To see coverage: `pytest tests/ --cov=backend --cov-report=html`")
print("- Check the 'Run backend tests' step above for full pytest output")
except Exception as e:
print(f"⚠️ Could not parse test results: {e}")
print("")
print("Check the 'Run backend tests' step above for detailed output.")
PYTHON_EOF
# Parse test results with a simple Python one-liner to avoid YAML issues
python3 -c "import xml.etree.ElementTree as ET; t=ET.parse('test-results.xml'); s=t.findall('.//testsuite'); total=sum(int(x.get('tests',0)) for x in s); fails=sum(int(x.get('failures',0)) for x in s); errs=sum(int(x.get('errors',0)) for x in s); skips=sum(int(x.get('skipped',0)) for x in s); time=sum(float(x.get('time',0)) for x in s); passed=total-fails-errs-skips; emoji='✅' if fails==0 and errs==0 else '❌'; status='All tests passed' if fails==0 and errs==0 else f'{fails+errs} test(s) failed'; print(f'### {emoji} {status}\n\n| Metric | Count |\n|--------|-------|\n| Total Tests | {total} |\n| ✅ Passed | {passed} |\n| ❌ Failed | {fails} |\n| ⚠️ Errors | {errs} |\n| ⏭️ Skipped | {skips} |\n| ⏱️ Duration | {time:.2f}s |\n\n### 💡 Tips\n\n- To run tests locally: `pytest tests/ -v`\n- Check the Run backend tests step above for full pytest output')" || echo "⚠️ Could not parse test results"
} >> "$GITHUB_STEP_SUMMARY" || true
else
{