Пример #1
0
        void WriteStatement(StringBuilder sb, HtmlReportLineItem lineItem)
        {
            var lineItemType = lineItem.TypeName.ToLower();

            if (lineItem.Statement != null || lineItem.Explanation != null)
            {
                sb.AppendLine($@"
					<li class=""row statement"">
						<div class=""col-2 badges""></div>
						<div class=""col-11"">
							<div class=""{lineItemType} statement"" 
								id=""{lineItemType}-{this.lineItemNumber}-statement""
								style=""display: none;"">"                                .RemoveIndentation(4, true));
                if (lineItem.Statement != null)
                {
                    sb.AppendLine($@"
									<div class=""statement-title"">Statement</div>
									<div class=""{lineItemType} statement-content rounded""
										id=""{lineItemType}-{this.lineItemNumber}-statement"">{lineItem.Statement.AddIndentation(4)}</div>"                                        .RemoveIndentation(4, true));
                }
                sb.AppendLine($@"
							</div>
						</div>
					</li>"                    .RemoveIndentation(4, true));
                if (lineItem.Explanation != null)
                {
                    WriteLineItemContent(sb, lineItem, "explanation");
                    // sb.AppendLine($@"
                    //              <div class=""explanation-title"">Explanation</div>
                    //              <div class=""{lineItemType} explanation rounded""
                    //              id=""{lineItemType}-{this.lineItemNumber}-explanation"">{Markdown.ToHtml(lineItem.Explanation).AddIndentation(4)}</div>".RemoveIndentation(4,true));
                }
            }
        }
Пример #2
0
        void WriteStepDetails(StringBuilder sb, HtmlReportLineItem lineItem)
        {
            var inputLink                  = lineItem.Input != null;
            var outputLink                 = lineItem.Output != null;
            var explanationLink            = lineItem.Explanation != null;
            var inputHtmlPreviewLink       = (inputLink && lineItem.InputFormat == TextFormat.htmlpreview ? $"'iframe{lineItemNumber}input'" : "null");
            var outputHtmlPreviewLink      = (outputLink && lineItem.OutputFormat == TextFormat.htmlpreview ? $"'iframe{lineItemNumber}output'" : "null");
            var explanationHtmlPreviewLink = (explanationLink && lineItem.ExplanationFormat == TextFormat.htmlpreview ? $"'iframe{lineItemNumber}explanation'" : "null");

            sb.AppendLine($@"
					<li class=""row"">
						<div class=""col-2 badges""></div>
						<div class=""col-11"">
							<div class=""step-details"">"                            .RemoveIndentation(4));
            if (lineItem.Exception != null)
            {
                sb.AppendLine($@"
								<div class=""{lineItem.TypeName}-exception-link reason-Failed badge pointer button"" 
									id=""{lineItem.TypeName}-{this.lineItemNumber}-exception-link"" 
									onclick=""toggleVisibility('{lineItem.TypeName}-{this.lineItemNumber}-exception')"">
									<i class=""fas fa-bug""></i>&nbsp;<span>Exception</span>
								</div>"                                .RemoveIndentation(4, true));
            }
            if (!string.IsNullOrEmpty(lineItem.Input))
            {
                sb.AppendLine($@"
								<div class=""{lineItem.TypeName}-input-link badge pointer button"" 
									id=""{lineItem.TypeName}-{this.lineItemNumber}-input-link"" 
									onclick=""toggleVisibility('{lineItem.TypeName}-{this.lineItemNumber}-input', {inputHtmlPreviewLink})"">
									<i class=""fas fa-sign-in-alt""></i>&nbsp;<span>Input</span>
								</div>"                                .RemoveIndentation(4, true));
            }
            if (!string.IsNullOrEmpty(lineItem.Output))
            {
                sb.AppendLine($@"
								<div class=""{lineItem.TypeName}-output-link badge pointer button"" 
									id=""{lineItem.TypeName}-{this.lineItemNumber}-output-link"" 
									onclick=""toggleVisibility('{lineItem.TypeName}-{this.lineItemNumber}-output', {outputHtmlPreviewLink})"">
									<i class=""fas fa-sign-out-alt""></i>&nbsp;<span>Output</span>
								</div>"                                .RemoveIndentation(4, true));
            }
            if (!string.IsNullOrEmpty(lineItem.Explanation) || !string.IsNullOrEmpty(lineItem.Statement))
            {
                sb.AppendLine($@"
								<div class=""{lineItem.TypeName}-statement-link badge pointer badge-secondary"" 
									id=""{lineItem.TypeName}-{this.lineItemNumber}-statement-link"" 
									onclick=""toggleVisibility('{lineItem.TypeName}-{this.lineItemNumber}-statement'); toggleVisibility('{lineItem.TypeName}-{this.lineItemNumber}-explanation', {explanationHtmlPreviewLink})"">
									<i class=""fas fa-info""></i>&nbsp;<span>Explanation</span>
								</div>"                                .RemoveIndentation(4, true));
            }
            sb.AppendLine($@"
							</div>
						</div>
					</li>"                    .RemoveIndentation(4));
        }
Пример #3
0
        void WriteException(StringBuilder sb, HtmlReportLineItem lineItem, Exception exception, bool innerException = false)
        {
            var lineItemType = lineItem.TypeName.ToLower();

            if (exception != null && lineItem.Outcome != Outcome.Skipped)
            {
                if (!innerException)
                {
                    sb.AppendLine($@"
					<li class=""row exception"">
						<div class=""col-2 badges""></div>
						<div class=""col-11"">
							<div class=""exception""
								id=""{lineItemType}-{this.lineItemNumber}-exception""
								style=""display: block;"">
								<div class=""exception-title"" 
									id=""step-{this.lineItemNumber}-exception-title"">Exception<div>
									<div class=""exception-details rounded"">
								"                                .RemoveIndentation(4, true));
                }
                sb.AppendLine($@"
										<dl class=""exception dl-horizontal rounded"">
											<dt>Error Type</dt><dd class=""exception-type"">{exception.GetType().Name.HtmlEncode()}</dd>
											<dt>Message</dt><dd class=""exception-message bg-light""><pre><code>{exception.Message.AddIndentation(4).HtmlEncode()}</code></pre></dd>
											<dt>Stack</dt><dd class=""exception-stack bg-light""><pre><code>{exception.StackTrace.AddIndentation(4).HtmlEncode()}</code></pre></dd>
											"                                            .RemoveIndentation(4, true));
                if (exception.InnerException != null)
                {
                    sb.AppendLine($@"
										<dt>Inner Exception</dt>
										<dd class=""inner-exception"">"                                        .RemoveIndentation(4, true));
                    WriteException(sb, lineItem, exception.InnerException, true);
                    sb.AppendLine($@"
										</dd>"                                        .RemoveIndentation(4, true));
                }
                sb.AppendLine($@"
									</dl>"                                    .RemoveIndentation(4, true));
                if (!innerException)
                {
                    sb.AppendLine($@"
								</div>
							</div>
						</div>
					</li>"                    .RemoveIndentation(4, true));
                }
            }
        }
Пример #4
0
        void WriteInputOrOutputWithHtmlPreview(StringBuilder sb, HtmlReportLineItem lineItem, string contentType)
        {
            string previewCode = null;
            string previewHtml = null;

            switch (contentType)
            {
            case "input":
                previewCode = lineItem.Input.HtmlEncode();
                previewHtml = lineItem.Input;
                break;

            case "output":
                previewCode = lineItem.Output.HtmlEncode();
                previewHtml = lineItem.Output;
                break;

            case "explanation":
                previewCode = lineItem.Explanation.HtmlEncode();
                previewHtml = lineItem.Explanation;
                break;
            }
            previewHtml = previewHtml
                          .Replace(System.Environment.NewLine, " \\" + System.Environment.NewLine)
                          .Replace(":", "\\:")
                          .Replace("/", "\\/")
                          .Replace("!", "\\!")
                          .Replace("\"", "\\\"");
            var html = $@"
				<div class=""{contentType} rounded"">
					<div class=""nav nav-tabs"" role=""tablist"" style=""display: {(contentType=="explanation"?"none":"flex")};"">
						<a
							id=""preview{this.lineItemNumber}-tab""
							class=""nav-item nav-link active pointer"" 
							onclick=""toggleVisibility('preview{this.lineItemNumber}{contentType}', true, 'iframe{this.lineItemNumber}{contentType}'); toggleVisibility('code{this.lineItemNumber}{contentType}')"">Preview</a>
						<a
							id=""code{this.lineItemNumber}-tab""
							class=""nav-item nav-link pointer"" 
							onclick=""toggleVisibility('preview{this.lineItemNumber}{contentType}', true, 'iframe{this.lineItemNumber}{contentType}'); toggleVisibility('code{this.lineItemNumber}{contentType}')"">Code</a>
					</div>
					<div class=""tab-content"">
						<div role=""tabpanel"" 
							class=""tab-pane active"" 
							style=""display: block;""
							id=""preview{this.lineItemNumber}{contentType}"">
							<iframe width=""100%"" id=""iframe{this.lineItemNumber}{contentType}""></iframe>
							<script type=""text/javascript"">
								var iframe{this.lineItemNumber}{contentType}doc = document.getElementById('iframe{this.lineItemNumber}{contentType}').contentWindow.document;
								iframe{this.lineItemNumber}{contentType}doc.open();
								var html{this.lineItemNumber}{contentType} = ""{previewHtml.AddIndentation(4)}"";
								iframe{this.lineItemNumber}{contentType}doc.write(html{this.lineItemNumber}{contentType});
								resizeIframe(document.getElementById('iframe{this.lineItemNumber}{contentType}'));
								iframe{this.lineItemNumber}{contentType}doc.close();
							</script>
						</div>
						<div role=""tabpanel"" 
							class=""tab-pane"" 
							style=""display: none;""
							id=""code{this.lineItemNumber}{contentType}"">
							<pre class=""{contentType} prettyprint linenums lang-html"">{previewCode.AddIndentation(4)}</pre>
						</div>
					</div>
				</div>"                .RemoveIndentation(4, true);

            sb.AppendLine(html);
        }
Пример #5
0
        void WriteLineItemContent(StringBuilder sb, HtmlReportLineItem lineItem, string contentType)
        {
            var lineItemType = lineItem.TypeName.ToLower();

            var        text    = "";
            TextFormat format  = new TextFormat();
            var        title   = "";
            var        display = "block";

            switch (contentType)
            {
            case "input":
                text   = lineItem.Input;
                format = lineItem.InputFormat;
                title  = "Input";
                break;

            case "output":
                text   = lineItem.Output;
                format = lineItem.OutputFormat;
                title  = "Output";
                break;

            case "explanation":
                text    = lineItem.Explanation;
                format  = lineItem.ExplanationFormat;
                title   = "Explanation";
                display = "none";
                break;
            }
            if (!String.IsNullOrEmpty(text))
            {
                sb.AppendLine($@"
					<li class=""row {contentType}"">
						<div class=""col-2 badges""></div>
						<div class=""col-11"">
							<div class=""{contentType}"" 
								id=""{lineItemType}-{this.lineItemNumber}-{contentType}""
								style=""display: {display};"">
								<div class=""{contentType}-title"" 
									id=""step-{this.lineItemNumber}-{contentType}-title"">{title}</div>"                                    .RemoveIndentation(4, true));
                if (format == TextFormat.htmlpreview)
                {
                    WriteInputOrOutputWithHtmlPreview(sb, lineItem, contentType);
                }
                else if (format == TextFormat.markdown)
                {
                    text = Markdig.Markdown.ToHtml(text, new MarkdownPipelineBuilder().UseAdvancedExtensions().Build());
                    sb.AppendLine($@"
									<div class=""{contentType} markdown"" id=""{contentType}-{this.lineItemNumber}"">{text.AddIndentation(4)}</div>"                                    .RemoveIndentation(4, true));
                }
                else
                {
                    var className = $"{contentType} prettyprint linenums rounded";
                    if (format != TextFormat.code)
                    {
                        className = className + " lang-" + Enum.GetName(typeof(TextFormat), format);
                    }
                    if (format == TextFormat.markdown)
                    {
                        text = Markdig.Markdown.ToHtml(text);
                    }
                    sb.AppendLine($@"
									<pre class=""{className}"" id=""{contentType}-{this.lineItemNumber}"">{text.HtmlEncode().AddIndentation(4)}</pre>"                                    .RemoveIndentation(4, true));
                }
                sb.AppendLine($@"
							</div>
						</div>
					</li>"                    .RemoveIndentation(4, true));
            }
        }
Пример #6
0
        void WriteBadge(StringBuilder sb, HtmlReportLineItem lineItem, bool header)
        {
            var lineItemType = lineItem.TypeName.ToLower();

            if (header)
            {
                lineItemType = "header";
            }

            var statementAndExplanationLink = lineItem.Statement != null || lineItem.Explanation != null;
            var total = 0;

            if (lineItem.ReasonStats.ContainsKey("Scenarios"))
            {
                foreach (var reasonStat in lineItem.ReasonStats["Scenarios"].Values)
                {
                    total = total + reasonStat;
                }
            }
            sb.AppendLine($@"
				<div class=""col-2 badges"">"                .RemoveIndentation(4, true));

            if (lineItemType == "testrun" || lineItemType == "capability" || lineItemType == "feature" || lineItemType == "header")
            {
                sb.AppendLine($@"
					<div class=""{lineItemType} badge-distro""
						id=""{lineItemType}-{this.lineItemNumber}-badge-distro""
						title=""{lineItem.Reason} Count: Scenarios""
						onclick=""toggleVisibility('{lineItemType}-{this.lineItemNumber}-stats')"">
						<div class=""{lineItemType} badge badge-pill pointer total reason-{lineItem.Reason.EncodeCSSClassName()}""
							id=""{lineItemType}-{this.lineItemNumber}-badge"">{(lineItemType == "step" ? " " : total.ToString())}</div>"                            .RemoveIndentation(4, true));
                if (lineItemType != "scemario" && lineItemType != "step")
                {
                    sb.AppendLine($@"
						<div class=""{lineItemType} distro-corner-tr"">
						</div>
						<div class=""{lineItemType} distro-corner-br"">
						</div>
						<div class=""{lineItemType} distro pointer""
							id=""{lineItemType}-{this.lineItemNumber}-distro"">"                            .RemoveIndentation(4, true));

                    foreach (var sortedReason in this.sortedReasons.Select(x => x).Reverse())
                    {
                        double stat = 0;
                        if (lineItem.ReasonStats.ContainsKey("Scenarios") && lineItem.ReasonStats["Scenarios"].ContainsKey(sortedReason.Reason))
                        {
                            stat = ((double)lineItem.ReasonStats["Scenarios"][sortedReason.Reason] / (double)total) * 100;
                            sb.AppendLine($@"
							<div class=""reason-{sortedReason.Reason.EncodeCSSClassName()}"" style=""height: {stat}%; width: 100%;""></div>"                            .RemoveIndentation(4, true));
                        }
                    }
                    sb.AppendLine($@"
						</div>
					</div>"                    .RemoveIndentation(4, true));
                }
            }
            else
            {
                if (lineItemType == "scenario" || lineItem.Exception == null)
                {
                    var childTotal = lineItem.ChildItems.Count;
                    sb.AppendLine($@"
						<div class=""{lineItemType} badge badge-pill pointer total reason-{lineItem.Reason.EncodeCSSClassName()}""
							id=""{lineItemType}-{this.lineItemNumber}-badge"">{(lineItemType == "step" ? " " : childTotal.ToString())}</div>"                            .RemoveIndentation(4, true));
                }
                else
                {
                    sb.AppendLine($@"
						<div class=""{lineItemType} badge badge-pill pointer exception-link reason-{lineItem.Reason.EncodeCSSClassName()}"" 
							id=""{lineItemType}-{this.lineItemNumber}-exception-link"" 
							onclick=""toggleVisibility('{lineItemType}-{this.lineItemNumber}-exception')"">&nbsp;</div>"                            .RemoveIndentation(4, true));
                }
            }

            sb.AppendLine($@"
				</div>"                .RemoveIndentation(4, true));
        }
Пример #7
0
        internal void WriteLineItem(StringBuilder sb, HtmlReportLineItem lineItem, bool failuresOnly, bool statsExpanded, bool childrenExpanded, bool header)
        {
            this.lineItemNumber++;
            var statementAndExplanationLink = lineItem.Statement != null || lineItem.Explanation != null;
            var inputLink                  = lineItem.Input != null;
            var outputLink                 = lineItem.Output != null;
            var explanationLink            = lineItem.Explanation != null;
            var inputHtmlPreviewLink       = (inputLink && lineItem.InputFormat == TextFormat.htmlpreview ? $"'iframe{lineItemNumber}input'" : "null");
            var outputHtmlPreviewLink      = (outputLink && lineItem.OutputFormat == TextFormat.htmlpreview ? $"'iframe{lineItemNumber}output'" : "null");
            var explanationHtmlPreviewLink = (explanationLink && lineItem.ExplanationFormat == TextFormat.htmlpreview ? $"'iframe{lineItemNumber}explanation'" : "null");

            var lineItemType = lineItem.TypeName.ToLower();

            if (header)
            {
                lineItemType = "header";
            }

            sb.AppendLine($@"
				<li class=""lineitem {lineItemType} row align-items-center"" id=""{lineItemType}-{this.lineItemNumber}"">"                .RemoveIndentation(4, true));

            WriteBadge(sb, lineItem, header);

            if (String.IsNullOrEmpty(lineItem.Name))
            {
                lineItem.Name = "[Missing! (or Full Name Skipped)]";
            }

            sb.AppendLine($@"
					<div class=""col"">
						<div class=""{lineItemType} name"">"                        .RemoveIndentation(4));
            var name = lineItem.Name;

            if (lineItemType == "capability" || lineItemType == "testrun")
            {
                name = name.Replace(config.RootNameSkip, "");
            }
            if (lineItem.FilePath != null)
            {
                sb.AppendLine($@"
						<a class=""{lineItemType} name pointer"" 
							id=""{lineItemType}-{this.lineItemNumber}-name""
							href=""{lineItem.FilePath}"">{name}</a>"                            .RemoveIndentation(4, true));
            }
            else
            {
                sb.AppendLine($@"
						<span class=""{lineItemType} name pointer"" 
							id=""{lineItemType}-{this.lineItemNumber}-name""
							onclick=""toggleVisibility('{lineItemType}-{this.lineItemNumber}-{lineItem.ChildTypeName.ToLower()}', {inputHtmlPreviewLink}, {outputHtmlPreviewLink})""
							href=""{lineItemType}-{this.lineItemNumber}-{lineItem.ChildTypeName.ToLower()}"">{name}</span>"                            .RemoveIndentation(4, true));
            }
            if (lineItem.Assignments != null && lineItem.Assignments.Count > 0)
            {
                sb.Append($@"
						<span class=""{lineItemType} assignments"" 
							id=""{lineItemType}-{this.lineItemNumber}-assignments"">["                            .RemoveIndentation(6, true));
                lineItem.Assignments.ForEach(assignment => {
                    sb.Append($@"{(lineItem.Assignments.IndexOf(assignment)==0?"":", ")}{assignment.HtmlEncode()}");
                });
                sb.AppendLine($@"
						]</span>"                        .RemoveIndentation(6, true));
            }
            if (lineItem.Tags != null && lineItem.Tags.Count > 0)
            {
                sb.Append($@"
						<span class=""{lineItemType} tags"" 
							id=""{lineItemType}-{this.lineItemNumber}-tags"">["                            .RemoveIndentation(6, true));
                lineItem.Tags.ForEach(tag => {
                    sb.Append($@"{(lineItem.Tags.IndexOf(tag)==0?"":", ")}{tag.HtmlEncode()}");
                });
                sb.AppendLine($@"
						]</span>"                        .RemoveIndentation(6, true));
            }
            if (lineItemType != "step" && (!string.IsNullOrEmpty(lineItem.Explanation) || !string.IsNullOrEmpty(lineItem.Statement)))
            {
                sb.AppendLine($@"
						<div class=""{lineItem.TypeName}-statement-link badge pointer badge-secondary"" 
							id=""{lineItem.TypeName}-{this.lineItemNumber}-statement-link"" 
							onclick=""toggleVisibility('{lineItem.TypeName}-{this.lineItemNumber}-statement'); toggleVisibility('{lineItem.TypeName}-{this.lineItemNumber}-explanation', {explanationHtmlPreviewLink})"">
							<i class=""fas fa-info""></i>
						</div>"                        .RemoveIndentation(4, true));
            }
            sb.AppendLine($@"
						</div>
					</div>"                    .RemoveIndentation(4));

            WriteDuration(sb, lineItemType, lineItem.EndTime, lineItem.StartTime);

            sb.AppendLine($@"
				</li>"                .RemoveIndentation(4));

            if (lineItemType != "step")
            {
                WriteStats(sb, lineItemType, lineItem.ReasonStats, statsExpanded);

                WriteStatement(sb, lineItem);
            }

            if (lineItem.ChildTypeName != null)
            {
                var expanded       = (lineItem.Outcome == Outcome.Failed && failuresOnly) || childrenExpanded;
                var display        = expanded ? "block" : "none";
                var childClassName = $"{lineItem.ChildTypeName.ToLower()} list-unstyled";
                sb.AppendLine($@"
					<li class=""row children"">
						<div class=""col-12"">
							<ol class=""{childClassName} container-fluid""
								id=""{lineItemType}-{this.lineItemNumber}-{lineItem.ChildTypeName.ToLower()}""
								style=""display: {display}"">"                                .RemoveIndentation(4));
                foreach (var item in lineItem.ChildItems)
                {
                    WriteLineItem(sb, item, failuresOnly, false, false, false);
                }
                if (lineItem.Exception != null || !string.IsNullOrEmpty(lineItem.Input) || !string.IsNullOrEmpty(lineItem.Output))
                {
                    WriteStepDetails(sb, lineItem);

                    WriteStatement(sb, lineItem);

                    WriteException(sb, lineItem, lineItem.Exception, false);

                    WriteLineItemContent(sb, lineItem, "input");

                    WriteLineItemContent(sb, lineItem, "output");
                }
                sb.AppendLine($@"
							</ol>
						</div>
					</li>"                    .RemoveIndentation(4));
            }
        }