c# – Adding Product Versions to SpecFlow+ Runner ReportTemplate.CSHTML

I am editing our API automation solution’s SpecFlow Runner ReportTemplate.cshtml to use a ProductVersionGrabber class I’ve created to execute a simple remote PowerShell command and then consume that from within the ReportTemplate.cshtml and iterate through the List and render out that PowerShell output

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Management.Automation;
using System.Management.Automation.Runspaces;

namespace API.Tools.ProductVersionGrabber
{
   public class ProductVersionGrabber
    {
        public string vmName = Environment.MachineName;
        public List<string> productVersionList = new List<string>();

        public List<string> GrabVersions()
        {
            string envType = GetEnvType(vmName);
            if (envType.StartsWith("QE_AUTO", true, CultureInfo.InvariantCulture))
            {
                productVersionList.AddRange(GetQeAutoProductList());
            }
            else if (envType.StartsWith("DEV_INT", true, CultureInfo.InvariantCulture))
            {
                productVersionList.AddRange(GetDevIntProductList(vmName));
            }
            return productVersionList;
        }

        public List<string> GetProductVersionsChocolatey(string vmName)
        {
            List<string> output = RunPSGrabVersions(vmName);
            return output;
        }

        public string GetEnvType(string envName)
        {
            string envType = null;
            if (envName.StartsWith("QE_AUTO", true, CultureInfo.InvariantCulture))
            {
                envType = "QE_AUTO";
            }
            else if (envName.StartsWith("DEV_INT", true, CultureInfo.InvariantCulture))
            {
                envType = "DEV_INT";
            }
            else
            {
                envType = "QE_AUTO";
            }
            return envType;
        }

        public List<string> GetQeAutoProductList()
        {
            List<string> intProdVers = new List<string>();

            intProdVers.Add("QE_AUTO_1");
            intProdVers.AddRange(GetProductVersionsChocolatey("QE_AUTO_1"));

            intProdVers.Add("QE_AUTO_2");
            intProdVers.AddRange(GetProductVersionsChocolatey("QE_AUTO_2"));

            intProdVers.Add("QE_AUTO_3");
            intProdVers.AddRange(GetProductVersionsChocolatey("QE_AUTO_3"));

            intProdVers.Add("QE_AUTO_4");
            intProdVers.AddRange(GetProductVersionsChocolatey("QE_AUTO_4"));

            intProdVers.Add("QE_AUTO_5");
            intProdVers.AddRange(GetProductVersionsChocolatey("QE_AUTO_5"));

            intProdVers.Add("QE_AUTO_6");
            intProdVers.AddRange(GetProductVersionsChocolatey("QE_AUTO_6"));

            intProdVers.Add("QE_AUTO_7");
            intProdVers.AddRange(GetProductVersionsChocolatey("QE_AUTO_7"));

            return intProdVers;
        }

        public List<string> GetDevIntProductList(string envName)
        {
            List<string> intProdVers = new List<string>();
            intProdVers.Add(envName);
            intProdVers.AddRange(GetProductVersionsChocolatey(envName));
            return intProdVers;
        }

        public List<string> RunPSGrabVersions(string vmName)
        {
            List<string> resultsList = new List<string>();

            InitialSessionState initial = InitialSessionState.CreateDefault();
            Runspace runspace = RunspaceFactory.CreateRunspace(initial);
            runspace.Open();
            PowerShell ps = PowerShell.Create();
            ps.Runspace = runspace;

            ps.AddCommand("invoke-command");
            ps.AddParameter("ComputerName", $"{vmName}.testing.local");
            ScriptBlock command = ScriptBlock.Create("choco list -lar companyName");
            ps.AddParameter("ScriptBlock", command);

            StringBuilder stringBuilder = new StringBuilder();
            foreach (PSObject obj in ps.Invoke())
            {
                resultsList.Add(obj.ToString());
            }

            resultsList.Add(stringBuilder.ToString());
            runspace.Close();

            return resultsList;
        }
    }
}

So that’s the ProductVersionGrabber sanitized of internal info but it’s pretty simple and basic and I’ve done unit tests/console implementations of the class to confirm it outputs the List of machines and installed products without issue so the class itself should be good afaik as a neophyte who’s come back and is rusty on top of it.

The issue itself appears to arise when I make modifications to the ReportTemplate.cshtml, Even just the final using statement appears to anger the thing but our solution does not apparently have a checker for CSHTML (though VSCode does and it doesn’t detect anything untoward outside of the helpers not being “valid” but they were valid before I made these modifications so probably nothing to worry about) and I’m on day 2 of being stuck in a rut and not sure where to turn to find out what’s actually broken/not working.

Helper:

@inherits SpecFlow.Plus.Runner.Reporting.CustomTemplateBase<TestRunResult>
<!DOCTYPE html>
@using System
@using System.Linq
@using System.Globalization
@using TechTalk.SpecRun.Framework
@using TechTalk.SpecRun.Framework.Results
@using TechTalk.SpecRun.Framework.TestSuiteStructure
@using API.Tools.ProductVersionGrabber

@{var timeFormat = "hh\:mm\:ss"; }
@helper GetBuildInfo(string projectName)
{
    var info = projectName.Split('#');
    var branch = info(0);
    var environment = info(1);
    var build = info(2);
    var jobName = info(3);
    var jobType = info(4);
    var productGrabber = new ProductVersionGrabber();
    var output = productGrabber.GrabVersions();


    <li>Branch: @branch</li>
    <li>Environment: @environment</li>
    <li>Build Id: @build</li>
    <li>Job Name: @jobName</li>
    <li>Job Type: @jobType</li>
    <b>Versions:</b>
    <p>
        @foreach (var obj in output)
        {
            @obj<br>
        }
    </p>
}

Helper Use in :

@GetBuildInfo(Model.Configuration.TestProfileSettings.Name)