diff --git a/src/6.0/SpecFlowToMarkdown.Infrastructure.AssemblyLoad/Extractors/ScenarioExtractor.cs b/src/6.0/SpecFlowToMarkdown.Infrastructure.AssemblyLoad/Extractors/ScenarioExtractor.cs index c0b0543..3afd263 100644 --- a/src/6.0/SpecFlowToMarkdown.Infrastructure.AssemblyLoad/Extractors/ScenarioExtractor.cs +++ b/src/6.0/SpecFlowToMarkdown.Infrastructure.AssemblyLoad/Extractors/ScenarioExtractor.cs @@ -73,8 +73,19 @@ public IEnumerable ExtractScenarios(TypeDefinition type) while (currInstr.OpCode == OpCodes.Ldstr) { - tags.Add(currInstr.Operand.ToString()); - currInstr = + if (currInstr.Operand != null) + { + tags.Add( + currInstr + .Operand.ToString()? + .Replace( + ",", + "" + ) + ); + } + + currInstr = currInstr .Previous .Previous diff --git a/src/6.0/SpecFlowToMarkdown.Infrastructure.Markdown/ColourSorter.cs b/src/6.0/SpecFlowToMarkdown.Infrastructure.Markdown/ColourSorter.cs index 64131ae..21face2 100644 --- a/src/6.0/SpecFlowToMarkdown.Infrastructure.Markdown/ColourSorter.cs +++ b/src/6.0/SpecFlowToMarkdown.Infrastructure.Markdown/ColourSorter.cs @@ -6,9 +6,9 @@ namespace SpecFlowToMarkdown.Infrastructure.Markdown { public class ColourSorter : IColourSorter { - private const string PassColour = "#16c60c88"; - private const string FailColour = "#f03a1788"; - private const string OtherColour = "#fff8"; + public const string PassColour = "#16c60c88"; + public const string FailColour = "#f03a1788"; + public const string OtherColour = "#fff8"; public ICollection Sort(int passCount, int failCount, int otherCount) { diff --git a/src/6.0/SpecFlowToMarkdown.Infrastructure.Markdown/Extensions/StringBuilderEx.cs b/src/6.0/SpecFlowToMarkdown.Infrastructure.Markdown/Extensions/StringBuilderEx.cs index 62988de..3720c9e 100644 --- a/src/6.0/SpecFlowToMarkdown.Infrastructure.Markdown/Extensions/StringBuilderEx.cs +++ b/src/6.0/SpecFlowToMarkdown.Infrastructure.Markdown/Extensions/StringBuilderEx.cs @@ -7,7 +7,80 @@ namespace SpecFlowToMarkdown.Infrastructure.Markdown.Extensions { public static class StringBuilderEx { - public static StringBuilder AppendChart( + public static StringBuilder AppendTagChart( + this StringBuilder stringBuilder, + string title, + IDictionary results + ) + { + stringBuilder + .AppendLine() + .AppendLine("```mermaid") + .AppendLine("%%{") + .AppendLine("\tinit: {") + .AppendLine("\t\t'theme': 'base',") + .AppendLine("\t\t'themeVariables': {") + .AppendLine("\t\t\t'xyChart': {") + .AppendLine("\t\t\t\t'titleColor': \"#fff\",") + .AppendLine("\t\t\t\t'xAxisLabelColor': \"#fff\",") + .AppendLine("\t\t\t\t'xAxisTitleColor': \"#fff\",") + .AppendLine("\t\t\t\t'xAxisTickColor': \"#fff\",") + .AppendLine("\t\t\t\t'xAxisLineColor': \"#fff\",") + .AppendLine("\t\t\t\t'yAxisLabelColor': \"#fff\",") + .AppendLine("\t\t\t\t'yAxisTitleColor': \"#fff\",") + .AppendLine("\t\t\t\t'yAxisTickColor': \"#fff\",") + .AppendLine("\t\t\t\t'yAxisLineColor': \"#fff\",") + .AppendLine($"\t\t\t\t'backgroundColor': \"#0000\",") + .AppendLine($"\t\t\t\t'plotColorPalette': \"{ColourSorter.OtherColour}, {ColourSorter.PassColour}, {ColourSorter.FailColour}\""); + + stringBuilder + .AppendLine("\t\t\t}") + .AppendLine("\t\t}") + .AppendLine("\t}") + .AppendLine("}%%"); + + stringBuilder + .AppendLine("xychart-beta") + .AppendLine($"title {title}"); + + var xAxis = string.Join( + ", ", + results.Keys + ); + + stringBuilder + .AppendLine($"x-axis [{xAxis}]") + .AppendLine($"y-axis \"Tests\""); + + var values = results.Values; + + var totalValues = string.Join( + ", ", + values.Select(o => o.Successes + o.Failures + o.Others) + ); + + var successValues = string.Join( + ", ", + values.Select(o => o.Successes) + ); + + var failureValues = string.Join( + ", ", + values.Select(o => o.Failures) + ); + + stringBuilder + .AppendLine($"bar [{totalValues}]") + .AppendLine($"bar [{successValues}]") + .AppendLine($"bar [{failureValues}]"); + + stringBuilder + .AppendLine("```"); + + return stringBuilder; + } + + public static StringBuilder AppendPieChart( this StringBuilder stringBuilder, string title, ICollection legend @@ -26,10 +99,10 @@ ICollection legend .AppendLine("\t\t\t'pieStrokeColor': '#8888',") .AppendLine("\t\t\t'pieOuterStrokeColor': '#8888',"); - for(var i=0; i < legend.Count; i++) + for (var i = 0; i < legend.Count; i++) { var legendItem = legend.ElementAt(i); - + stringBuilder .Append($"\t\t\t'pie{i + 1}': '{legendItem.Colour}'"); @@ -51,7 +124,7 @@ ICollection legend stringBuilder .AppendLine($"\t\"{legendItem.Title}\": {legendItem.Value}"); } - + stringBuilder .AppendLine("```") .AppendLine(); diff --git a/src/6.0/SpecFlowToMarkdown.Infrastructure.Markdown/IResultSummariser.cs b/src/6.0/SpecFlowToMarkdown.Infrastructure.Markdown/IResultSummariser.cs index d0b18ee..952bd70 100644 --- a/src/6.0/SpecFlowToMarkdown.Infrastructure.Markdown/IResultSummariser.cs +++ b/src/6.0/SpecFlowToMarkdown.Infrastructure.Markdown/IResultSummariser.cs @@ -1,5 +1,7 @@ -using SpecFlowToMarkdown.Domain; +using System.Collections.Generic; +using SpecFlowToMarkdown.Domain; using SpecFlowToMarkdown.Domain.Result; +using SpecFlowToMarkdown.Domain.TestAssembly; using SpecFlowToMarkdown.Infrastructure.Markdown.Definition; namespace SpecFlowToMarkdown.Infrastructure.Markdown @@ -11,6 +13,8 @@ public interface IResultSummariser public TestSummary SummariseAllScenarios(TestExecution execution); public TestSummary SummariseAllSteps(TestExecution execution); + + public IDictionary SummariseAllTags(TestExecution execution, SpecFlowAssembly assembly); public TestStatusEnum Assess(int successes, int failures, int others); diff --git a/src/6.0/SpecFlowToMarkdown.Infrastructure.Markdown/MarkdownRenderer.cs b/src/6.0/SpecFlowToMarkdown.Infrastructure.Markdown/MarkdownRenderer.cs index 6bd8386..9b3e0b8 100644 --- a/src/6.0/SpecFlowToMarkdown.Infrastructure.Markdown/MarkdownRenderer.cs +++ b/src/6.0/SpecFlowToMarkdown.Infrastructure.Markdown/MarkdownRenderer.cs @@ -46,6 +46,13 @@ TestExecution execution _resultSummariser .SummariseAllSteps(execution); + var tagSummary = + _resultSummariser + .SummariseAllTags( + execution, + assembly + ); + // Render header headerBuilder .AppendLine($"# {assembly.AssemblyName}"); @@ -54,7 +61,7 @@ TestExecution execution .AppendLine("") .AppendLine("") .AppendLine("") .AppendLine("") .AppendLine("") + .AppendLine("") .AppendLine("") .AppendLine("
") - .AppendChart( + .AppendPieChart( "Features", _colourSorter .Sort( @@ -65,7 +72,7 @@ TestExecution execution ) .AppendLine("") - .AppendChart( + .AppendPieChart( "Scenarios", _colourSorter .Sort( @@ -76,7 +83,7 @@ TestExecution execution ) .AppendLine("") - .AppendChart( + .AppendPieChart( "Steps", _colourSorter .Sort( @@ -86,6 +93,12 @@ TestExecution execution ) ) .AppendLine("") + .AppendTagChart( + "Tags", + tagSummary + ) + .AppendLine("
") .AppendLine(); diff --git a/src/6.0/SpecFlowToMarkdown.Infrastructure.Markdown/ResultSummariser.cs b/src/6.0/SpecFlowToMarkdown.Infrastructure.Markdown/ResultSummariser.cs index 4e859da..d7564e0 100644 --- a/src/6.0/SpecFlowToMarkdown.Infrastructure.Markdown/ResultSummariser.cs +++ b/src/6.0/SpecFlowToMarkdown.Infrastructure.Markdown/ResultSummariser.cs @@ -1,6 +1,8 @@ -using System.Linq; +using System.Collections.Generic; +using System.Linq; using SpecFlowToMarkdown.Domain; using SpecFlowToMarkdown.Domain.Result; +using SpecFlowToMarkdown.Domain.TestAssembly; using SpecFlowToMarkdown.Infrastructure.Markdown.Definition; namespace SpecFlowToMarkdown.Infrastructure.Markdown @@ -113,6 +115,77 @@ public TestSummary SummariseAllSteps(TestExecution execution) }; } + public IDictionary SummariseAllTags(TestExecution execution, SpecFlowAssembly assembly) + { + var results = new Dictionary(); + + var allTags = + assembly + .Features + .SelectMany(o => o.Scenarios.SelectMany(x => x.Tags)) + .Distinct(); + + foreach (var tag in allTags) + { + var result = new TestSummary + { + Successes = 0, + Failures = 0, + Others = 0, + Duration = 0 + }; + + foreach (var feature in assembly.Features) + { + var allTaggedScenarios = + feature + .Scenarios + .Where(x => x.Tags.Contains(tag)); + + foreach (var taggedScenario in allTaggedScenarios) + { + var executionResult = + execution + .ExecutionResults + .FirstOrDefault( + o => o.FeatureTitle == feature.Title && + o.ScenarioTitle == taggedScenario.Title + ); + + if (executionResult != null) + { + switch (Assess(executionResult.Status)) + { + case TestStatusEnum.Success: + result.Successes++; + break; + case TestStatusEnum.Failure: + result.Failures++; + break; + default: + result.Others++; + break; + } + } + } + } + + results + .Add( + tag, + result + ); + } + + return + results + .OrderBy(o => o.Key) + .ToDictionary( + o => o.Key, + o => o.Value + ); + } + public TestStatusEnum Assess(int successes, int failures, int others) { if (failures > 0) return TestStatusEnum.Failure;