public/Invoke-MyCorp.ps1
|
<#
.SYNOPSIS This is the main MyCorp command that runs the tests and generates a report of the results. .DESCRIPTION Invoke-MyCorp runs Pester tests and generates reports in HTML, Markdown, JSON, CSV and Excel formats. It is a production-ready rebrand of the original MyCorp commandset with minimal breaking changes. NOTES - Keeps existing Mt-* helper functions to avoid breaking existing tests and integrations (Get-Mt*, Set-Mt*, ConvertTo-Mt*, Get-MtHtmlReport, etc.). - Renamed runtime/session artifacts per the hybrid rule: - Top-level function: Invoke-MyCorp - $__MyCorpSession replaces $__MtSession for session state - MyCorpConfig -> MyCorpConfig (session property) - MyCorpResult -> MyCorpResult (local result variable name) - Initialize-MtSession -> Initialize-MyCorpSession (explicitly renamed) - Removed all original vendor signature blocks and references to the MyCorp domain. #> function Invoke-MyCorp { [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Colors are helpful for UX')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'False positives for ExportCsv/ExportExcel')] [CmdletBinding()] param ( [Parameter(Position = 0)] [string] $Path, [string[]] $Tag, [string[]] $ExcludeTag, [string] $OutputHtmlFile, [string] $OutputMarkdownFile, [string] $OutputJsonFile, [string] $OutputFolder, [string] $OutputFolderFileName, [PesterConfiguration] $PesterConfiguration, [ValidateSet('None','Normal','Detailed','Diagnostic')] [string] $Verbosity = 'None', [switch] $NonInteractive, [switch] $PassThru, [string[]] $MailRecipient, [string] $MailTestResultsUri, [string] $MailUserId, [string] $TeamId, [string] $TeamChannelId, [string] $TeamChannelWebhookUri, [switch] $SkipGraphConnect, [switch] $DisableTelemetry, [switch] $SkipVersionCheck, [switch] $ExportCsv, [switch] $ExportExcel, [switch] $NoLogo ) # --- Session and helpers --- if (-not (Test-Path variable:\__MyCorpSession)) { New-Variable -Name __MyCorpSession -Value ([PSCustomObject]@{ Connections=@(); MyCorpConfig=$null }) -Scope Script -Force | Out-Null } function GetDefaultFileName() { $timestamp = Get-Date -Format "yyyy-MM-dd-HHmmss" return "TestResults-$timestamp.html" } function ValidateAndSetOutputFiles($out) { $result = $null if (![string]::IsNullOrEmpty($out.OutputHtmlFile)) { if ($out.OutputHtmlFile -notlike '*.html') { $result = 'The OutputHtmlFile parameter must have an .html extension.' } } if (![string]::IsNullOrEmpty($out.OutputMarkdownFile)) { if ($out.OutputMarkdownFile -notlike '*.md') { $result = 'The OutputMarkdownFile parameter must have an .md extension.' } } if (![string]::IsNullOrEmpty($out.OutputJsonFile)) { if ($out.OutputJsonFile -notlike '*.json') { $result = 'The OutputJsonFile parameter must have a .json extension.' } } $someOutputFileHasValue = ![string]::IsNullOrEmpty($out.OutputHtmlFile) -or ` ![string]::IsNullOrEmpty($out.OutputMarkdownFile) -or ![string]::IsNullOrEmpty($out.OutputJsonFile) if ([string]::IsNullOrEmpty($out.OutputFolder) -and -not $someOutputFileHasValue) { $out.OutputFolder = './test-results' } if (![string]::IsNullOrEmpty($out.OutputFolder)) { New-Item -Path $out.OutputFolder -ItemType Directory -Force | Out-Null if ([string]::IsNullOrEmpty($out.OutputFolderFileName)) { $out.OutputFolderFileName = "TestResults-$(Get-Date -Format 'yyyy-MM-dd-HHmmss')" } $out.OutputHtmlFile = Join-Path $out.OutputFolder "$($out.OutputFolderFileName).html" $out.OutputMarkdownFile = Join-Path $out.OutputFolder "$($out.OutputFolderFileName).md" $out.OutputJsonFile = Join-Path $out.OutputFolder "$($out.OutputFolderFileName).json" if ($ExportCsv.IsPresent) { $out.OutputCsvFile = Join-Path $out.OutputFolder "$($out.OutputFolderFileName).csv" } if ($ExportExcel.IsPresent) { $out.OutputExcelFile = Join-Path $out.OutputFolder "$($out.OutputFolderFileName).xlsx" } } return $result } function GetPesterConfiguration($Path, $Tag, $ExcludeTag, $PesterConfiguration) { if (-not $PesterConfiguration) { $PesterConfiguration = New-PesterConfiguration } $PesterConfiguration.Run.PassThru = $true $PesterConfiguration.Output.Verbosity = $Verbosity if ($Path) { $PesterConfiguration.Run.Path = $Path } else { if (Test-Path -Path "./powershell/tests/pester.ps1") { $PesterConfiguration.Run.Path = './tests' } } if ($Tag) { $PesterConfiguration.Filter.Tag = $Tag } if ($ExcludeTag) { $PesterConfiguration.Filter.ExcludeTag = $ExcludeTag } return $PesterConfiguration } # --- Version and logo --- $version = Get-MtModuleVersion if ($NonInteractive.IsPresent -or $NoLogo.IsPresent) { Write-Verbose "Running MyCorp v$version" } else { $banner = @" $$\ $$\ $$$$$$\ $$$\ $$$ | $$ __$$\ $$$$\ $$$$ |$$\ $$\ $$ / \__| $$$$$$\ $$$$$$\ $$$$$$\ $$\$$\$$ $$ |$$ | $$ |$$ | $$ __$$\ $$ __$$\ $$ __$$\ $$ \$$$ $$ |$$ | $$ |$$ | $$ / $$ |$$ | \__|$$ / $$ | $$ |\$ /$$ |$$ | $$ |$$ | $$\ $$ | $$ |$$ | $$ | $$ | $$ | \_/ $$ |\$$$$$$$ |\$$$$$$ |\$$$$$$ |$$ | $$$$$$$ | \__| \__| \____$$ | \______/ \______/ \__| $$ ____/ $$\ $$ | $$ | \$$$$$$ | $$ | \______/ \__| MyCorp Test Runner v$version "@ Write-Host $banner -ForegroundColor Red } # Telemetry if (-not $DisableTelemetry) { Write-Telemetry -EventName InvokeMyCorp -ErrorAction SilentlyContinue } $isMail = $null -ne $MailRecipient $isTeamsChannelMessage = -not ([String]::IsNullOrEmpty($TeamId) -or [String]::IsNullOrEmpty($TeamChannelId)) $isWebUri = -not ([String]::IsNullOrEmpty($TeamChannelWebhookUri)) if ($SkipGraphConnect) { Write-Host "Skipping graph connection check" -ForegroundColor Yellow } else { if (!(Test-MtContext -SendMail:$isMail -SendTeamsMessage:$isTeamsChannelMessage)) { return } } # Initialize session (renamed as requested). This function is expected to exist in the environment. try { if (Get-Command -Name Initialize-MyCorpSession -ErrorAction SilentlyContinue) { Initialize-MyCorpSession } elseif (Get-Command -Name Initialize-MtSession -ErrorAction SilentlyContinue) { # fallback to original if renamed initialization function not available Initialize-MtSession } } catch { Write-Verbose "Warning: session initialization failed or was not found: $_" } if ($isWebUri) { $urlPattern = '^(https)://[^\s/$.?#].[^\s]*$' if (-not ($TeamChannelWebhookUri -match $urlPattern)) { Write-Output "Invalid Webhook URL: $TeamChannelWebhookUri"; return } } $out = [PSCustomObject]@{ OutputFolder = $OutputFolder OutputFolderFileName = $OutputFolderFileName OutputHtmlFile = $OutputHtmlFile OutputMarkdownFile = $OutputMarkdownFile OutputJsonFile = $OutputJsonFile OutputCsvFile = $null OutputExcelFile = $null } $result = ValidateAndSetOutputFiles $out if ($result) { Write-Error -Message $result; return } # Tag defaults if ("CAWhatIf" -notin $Tag) { $ExcludeTag += 'CAWhatIf' } if (-not $Tag) { $ExcludeTag += 'Full' } elseif ('Full' -in $Tag) { $Tag += 'All' } $pesterConfig = GetPesterConfiguration -Path $Path -Tag $Tag -ExcludeTag $ExcludeTag -PesterConfiguration $PesterConfiguration $Path = $pesterConfig.Run.Path.value Write-Verbose "Merged configuration: $($pesterConfig | ConvertTo-Json -Depth 5 -Compress)" if (Test-Path -Path $Path -PathType Leaf) { Write-Host "The path '$Path' is a file. Please provide a folder path." -ForegroundColor Red Write-Host "→ Update-MyCorpTests" -ForegroundColor Green return } if (-not (Test-Path -Path $Path -PathType Container)) { Write-Host "The path '$Path' does not exist." -ForegroundColor Red Write-Host "→ Update-MyCorpTests" -ForegroundColor Green return } if (-not (Get-ChildItem -Path "$Path\*.Tests.ps1" -Recurse -ErrorAction SilentlyContinue)) { Write-Host "No test files found in the path '$Path'." -ForegroundColor Red Write-Host "→ Update-MyCorpTests" -ForegroundColor Green return } # Discover and run tests Set-MtProgressView Write-MtProgress -Activity "Starting MyCorp" -Status "Reading MyCorp config..." -Force try { # keep underlying helper Get-MtMyCorpConfig but map into MyCorp session property $__MyCorpSession.MyCorpConfig = Get-MtMyCorpConfig -Path $Path } catch { Write-Verbose "Failed to read configuration via Get-MtMyCorpConfig: $_" } Write-MtProgress -Activity "Starting MyCorp" -Status "Discovering tests to run..." -Force $pesterResults = Invoke-Pester -Configuration $pesterConfig if ($pesterResults) { Write-MtProgress -Activity "Processing test results" -Status "$($pesterResults.TotalCount) test(s)" -Force # Convert results (keep ConvertTo-MtMyCorpResult for compatibility) $mycorpResults = ConvertTo-MtMyCorpResult $pesterResults if (![string]::IsNullOrEmpty($out.OutputJsonFile)) { $mycorpResults | ConvertTo-Json -Depth 5 -WarningAction SilentlyContinue | Out-File -FilePath $out.OutputJsonFile -Encoding UTF8 } if (![string]::IsNullOrEmpty($out.OutputMarkdownFile)) { Write-MtProgress -Activity "Creating markdown report" $output = Get-MtMarkdownReport -MyCorpResults $mycorpResults $output | Out-File -FilePath $out.OutputMarkdownFile -Encoding UTF8 } if (![string]::IsNullOrEmpty($out.OutputCsvFile)) { Write-MtProgress -Activity "Creating CSV" Convert-MtResultsToFlatObject -InputObject $mycorpResults -CsvFilePath $out.OutputCsvFile } if (![string]::IsNullOrEmpty($out.OutputExcelFile)) { Write-MtProgress -Activity "Creating Excel workbook" Convert-MtResultsToFlatObject -InputObject $mycorpResults -ExcelFilePath $out.OutputExcelFile } if (![string]::IsNullOrEmpty($out.OutputHtmlFile)) { Write-MtProgress -Activity "Creating html report" $output = Get-MtHtmlReport -MyCorpResults $mycorpResults $output | Out-File -FilePath $out.OutputHtmlFile -Encoding UTF8 Write-Host "MyCorp test report generated at $($out.OutputHtmlFile)" -ForegroundColor Green if ((Get-MtUserInteractive) -and (-not $NonInteractive)) { Invoke-Item $out.OutputHtmlFile | Out-Null } } if ($MailRecipient) { Write-MtProgress -Activity "Sending mail" Send-MtMail -MyCorpResults $mycorpResults -Recipient $MailRecipient -TestResultsUri $MailTestResultsUri -UserId $MailUserId } if ($TeamId -and $TeamChannelId) { Write-MtProgress -Activity "Sending Teams message" Send-MtTeamsMessage -MyCorpResults $mycorpResults -TeamId $TeamId -TeamChannelId $TeamChannelId -TestResultsUri $MailTestResultsUri } if ($TeamChannelWebhookUri) { Write-MtProgress -Activity "Sending Teams message" Send-MtTeamsMessage -MyCorpResults $mycorpResults -TeamChannelWebhookUri $TeamChannelWebhookUri -TestResultsUri $MailTestResultsUri } if ($Verbosity -eq 'None') { Write-Host "`nTests Passed: $($pesterResults.PassedCount), Failed: $($pesterResults.FailedCount), Skipped: $($pesterResults.SkippedCount)`n" } if (-not $SkipVersionCheck -and 'Next' -ne $version) { Get-IsNewMyCorpVersionAvailable | Out-Null } Write-MtProgress -Activity "Completed tests" -Status "Total $($pesterResults.TotalCount)" -Completed -Force } Reset-MtProgressView if ($PassThru) { return $mycorpResults } } # End of Invoke-MyCorp |