added frontend
This commit is contained in:
132
hartmann-foto-documentation-frontend/test_runner.dart
Normal file
132
hartmann-foto-documentation-frontend/test_runner.dart
Normal file
@@ -0,0 +1,132 @@
|
||||
#!/usr/bin/env dart
|
||||
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:logger/web.dart';
|
||||
|
||||
/// Converts Flutter JSON test results to JUnit XML format
|
||||
/// Usage: dart test_runner.dart [test_results.json] [output.xml]
|
||||
void main(List<String> arguments) {
|
||||
var logger = Logger(
|
||||
printer: PrettyPrinter(methodCount: 2, errorMethodCount: 8, colors: true, printEmojis: true, dateTimeFormat: DateTimeFormat.onlyTimeAndSinceStart),
|
||||
);
|
||||
if (arguments.length < 2) {
|
||||
logger.i('Usage: dart test_runner.dart <json_file> <xml_output>');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
final jsonFile = arguments[0];
|
||||
final xmlFile = arguments[1];
|
||||
|
||||
try {
|
||||
final jsonContent = File(jsonFile).readAsStringSync();
|
||||
final lines = jsonContent.trim().split('\n');
|
||||
|
||||
final tests = <TestResult>[];
|
||||
int totalTests = 0;
|
||||
int failures = 0;
|
||||
int skipped = 0;
|
||||
double duration = 0.0;
|
||||
|
||||
// Parse JSON lines from flutter test output
|
||||
for (final line in lines) {
|
||||
if (line.trim().isEmpty) continue;
|
||||
|
||||
try {
|
||||
final data = jsonDecode(line) as Map<String, dynamic>;
|
||||
final type = data['type'] as String?;
|
||||
|
||||
if (type == 'testStart') {
|
||||
final test = data['test'] as Map<String, dynamic>;
|
||||
final name = test['name'] as String;
|
||||
final id = test['id'] as int;
|
||||
tests.add(TestResult(id: id, name: name));
|
||||
totalTests++;
|
||||
} else if (type == 'testDone') {
|
||||
final testId = data['testID'] as int;
|
||||
final result = data['result'] as String;
|
||||
final time = data['time'] as int? ?? 0;
|
||||
final error = data['error'] as String?;
|
||||
final stackTrace = data['stackTrace'] as String?;
|
||||
|
||||
duration += time / 1000.0; // Convert to seconds
|
||||
|
||||
final testIndex = tests.indexWhere((t) => t.id == testId);
|
||||
if (testIndex != -1) {
|
||||
tests[testIndex].result = result;
|
||||
tests[testIndex].duration = time / 1000.0;
|
||||
tests[testIndex].error = error;
|
||||
tests[testIndex].stackTrace = stackTrace;
|
||||
|
||||
if (result == 'error' || result == 'failure') {
|
||||
failures++;
|
||||
} else if (result == 'skip') {
|
||||
skipped++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// Skip malformed JSON lines
|
||||
logger.i('Warning: Could not parse line: $line');
|
||||
}
|
||||
}
|
||||
|
||||
// Generate JUnit XML
|
||||
final xml = generateJUnitXML(tests, totalTests, failures, skipped, duration);
|
||||
File(xmlFile).writeAsStringSync(xml);
|
||||
|
||||
logger.i('Converted ${tests.length} test results to JUnit XML: $xmlFile');
|
||||
|
||||
// Exit with error code if there were failures
|
||||
if (failures > 0) {
|
||||
exit(1);
|
||||
}
|
||||
} catch (e) {
|
||||
logger.e('Error: $e');
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
class TestResult {
|
||||
final int id;
|
||||
final String name;
|
||||
String result = 'pending';
|
||||
double duration = 0.0;
|
||||
String? error;
|
||||
String? stackTrace;
|
||||
|
||||
TestResult({required this.id, required this.name});
|
||||
}
|
||||
|
||||
String generateJUnitXML(List<TestResult> tests, int total, int failures, int skipped, double duration) {
|
||||
final buffer = StringBuffer();
|
||||
|
||||
buffer.writeln('<?xml version="1.0" encoding="UTF-8"?>');
|
||||
buffer.writeln('<testsuite name="Flutter Tests" tests="$total" failures="$failures" skipped="$skipped" time="$duration">');
|
||||
|
||||
for (final test in tests) {
|
||||
final escapedName = _escapeXml(test.name);
|
||||
buffer.writeln(' <testcase name="$escapedName" time="${test.duration}">');
|
||||
|
||||
if (test.result == 'error' || test.result == 'failure') {
|
||||
final escapedError = _escapeXml(test.error ?? 'Test failed');
|
||||
final escapedStackTrace = _escapeXml(test.stackTrace ?? '');
|
||||
|
||||
buffer.writeln(' <failure message="$escapedError">');
|
||||
buffer.writeln(' <![CDATA[$escapedStackTrace]]>');
|
||||
buffer.writeln(' </failure>');
|
||||
} else if (test.result == 'skip') {
|
||||
buffer.writeln(' <skipped/>');
|
||||
}
|
||||
|
||||
buffer.writeln(' </testcase>');
|
||||
}
|
||||
|
||||
buffer.writeln('</testsuite>');
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
String _escapeXml(String text) {
|
||||
return text.replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>').replaceAll('"', '"').replaceAll("'", ''');
|
||||
}
|
||||
Reference in New Issue
Block a user