");
+ sb.Append("
Contentstack Management .NET SDK – Enhanced Test Report
");
+
+ if (testData.Results.Count > 0)
+ {
+ sb.Append("
Test results
");
+ sb.Append("
");
+ sb.Append($"
Total{testData.Total}
");
+ sb.Append($"
Passed{testData.Passed}
");
+ sb.Append($"
Failed{testData.Failed}
");
+ sb.Append($"
Skipped{testData.Skipped}
");
+ sb.Append($"
Duration{FormatDuration(testData.TotalDuration)}
");
+ sb.Append("
");
+
+ if (coverageData.Files.Count > 0)
+ {
+ sb.Append(@"
+
All files
+
+
Statements");
+ sb.Append($"{coverageData.SummaryStmts:F1}%
");
+ sb.Append(@"
Branches");
+ sb.Append($"{coverageData.SummaryBranch:F1}%
");
+ sb.Append(@"
Functions");
+ sb.Append($"{coverageData.SummaryFuncs:F1}%
");
+ sb.Append(@"
Lines");
+ sb.Append($"{coverageData.SummaryLines:F1}%
");
+ sb.Append(@"
+
");
+ }
+
+ var useByClass = testData.ByClass.Count > 0;
+ var groupDict = useByClass ? testData.ByClass : testData.ByAssembly;
+ foreach (var kv in groupDict.OrderBy(x => x.Key))
+ {
+ var sectionTitle = useByClass ? kv.Key + ".cs" : kv.Key;
+ var list = kv.Value;
+ var failedCount = list.Count(r => r.Outcome.Equals("Failed", StringComparison.OrdinalIgnoreCase));
+ var badgeClass = failedCount > 0 ? "failed" : "passed";
+ var groupId = Regex.Replace(EscapeAttr(kv.Key), @"[^a-zA-Z0-9_-]", "-");
+ sb.Append($@"
+
▶ {Escape(sectionTitle)} {list.Count} tests
+
");
+
+ foreach (var r in list.OrderBy(x => x.Outcome).ThenBy(x => x.TestName))
+ {
+ AppendTestCase(sb, r);
+ }
+ sb.Append("
");
+ }
+ }
+ else
+ {
+ sb.Append("
No test results (TRX) provided.
");
+ if (coverageData.Files.Count > 0)
+ {
+ sb.Append(@"
+
All files
+
+
Statements");
+ sb.Append($"{coverageData.SummaryStmts:F1}%
");
+ sb.Append(@"
Branches");
+ sb.Append($"{coverageData.SummaryBranch:F1}%
");
+ sb.Append(@"
Functions");
+ sb.Append($"{coverageData.SummaryFuncs:F1}%
");
+ sb.Append(@"
Lines");
+ sb.Append($"{coverageData.SummaryLines:F1}%
");
+ sb.Append(@"
+
");
+ }
+ }
+
+ if (coverageData.Files.Count > 0)
+ {
+ sb.Append(@"
Code coverage
+
+
Per-file coverage
+
+| File | Statements | Branches | Functions | Lines | Uncovered line #s |
+");
+ foreach (var row in coverageData.Files.OrderBy(x => x.File))
+ {
+ var pctClassStmts = row.PctStmts < 50 ? " low" : row.PctStmts < 80 ? " mid" : "";
+ var pctClassBranch = row.PctBranch < 50 ? " low" : row.PctBranch < 80 ? " mid" : "";
+ var pctClassFuncs = row.PctFuncs < 50 ? " low" : row.PctFuncs < 80 ? " mid" : "";
+ var pctClassLines = row.PctLines < 50 ? " low" : row.PctLines < 80 ? " mid" : "";
+ sb.Append($"| {Escape(row.File)} | {row.PctStmts:F1}% | {row.PctBranch:F1}% | {row.PctFuncs:F1}% | {row.PctLines:F1}% | {Escape(row.UncoveredLines)} |
");
+ }
+ sb.Append("
");
+ }
+ else
+ {
+ sb.Append("
Code coverage
Coverage not collected (no Cobertura XML provided).
");
+ }
+
+ sb.Append(GetReportScript());
+ sb.Append("