Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
d3b2910
🩹 [Patch]: Refactor emoji retrieval logic and add Get-EmojiByKind fun…
MariusStorhaug Mar 3, 2025
525c5ba
🩹 [Patch]: Update emoji test assertions to use correct properties
MariusStorhaug Mar 3, 2025
65ed69b
🩹 [Patch]: Enhance emoji retrieval functions to support property sele…
MariusStorhaug Mar 3, 2025
4cf5ec0
🩹 [Patch]: Update emoji test scripts to require a mandatory Path para…
MariusStorhaug Mar 3, 2025
351bae7
🩹 [Patch]: Rename Convert-PesterConfigurationToHashtable filter to Co…
MariusStorhaug Mar 3, 2025
e6dcb30
Fix formatting inconsistencies in Helpers.psm1 and Emoji.Configuratio…
MariusStorhaug Mar 3, 2025
93710d9
🩹 [Patch]: Add ReportAsJson input to output test reports in JSON form…
MariusStorhaug Mar 3, 2025
a04ad4f
🩹 [Patch]: Move PSMODULE_INVOKE_PESTER_INPUT_ReportAsJson environment…
MariusStorhaug Mar 3, 2025
7a7d643
🩹 [Patch]: Enhance JSON report export logic to include test result co…
MariusStorhaug Mar 3, 2025
829eddd
🩹 [Patch]: Update TestResultOutputPath to use the parent directory of…
MariusStorhaug Mar 3, 2025
60bedd6
🩹 [Patch]: Update output paths for test results and code coverage rep…
MariusStorhaug Mar 3, 2025
5560ccf
🩹 [Patch]: Update JSON export logic to directly replace XML file exte…
MariusStorhaug Mar 3, 2025
49c7a82
Add retention days for uploaded test results and code coverage reports
MariusStorhaug Mar 3, 2025
fb07823
🩹 [Patch]: Add error handling for missing files in artifact uploads a…
MariusStorhaug Mar 3, 2025
8e76510
🩹 [Patch]: Replace Write-Host with Write-Output for exporting test re…
MariusStorhaug Mar 3, 2025
6de7946
🩹 [Patch]: Refactor ConvertFrom-PesterConfiguration to improve clarit…
MariusStorhaug Mar 3, 2025
964d3c8
🩹 [Patch]: Refactor Get-PesterTestTree to improve structure and reada…
MariusStorhaug Mar 3, 2025
cb1bfd6
Enhance Get-PesterTestTree to support path tracking and improve JSON …
MariusStorhaug Mar 3, 2025
c077b01
🩹 [Patch]: Update Get-PesterTestTree to return duration properties as…
MariusStorhaug Mar 3, 2025
85f43d9
Enhance JSON export of code coverage results by adding compression fo…
MariusStorhaug Mar 3, 2025
1ca395d
🩹 [Patch]: Update JSON export depth for code coverage results to impr…
MariusStorhaug Mar 3, 2025
926172d
Adjust JSON export depth for test results to enhance performance and …
MariusStorhaug Mar 3, 2025
05d58bb
Enhance Get-PesterTestTree to return duration properties as ticks for…
MariusStorhaug Mar 3, 2025
25f381f
Adjust JSON export depth for test results to improve performance and …
MariusStorhaug Mar 3, 2025
b1b3250
Enhance JSON export for test results by increasing depth and adding c…
MariusStorhaug Mar 3, 2025
8132b09
Remove compression from JSON export for test results and code coverag…
MariusStorhaug Mar 3, 2025
e03ec14
Convert container configurations to hashtables in Get-PesterTestTree …
MariusStorhaug Mar 3, 2025
7026911
Enhance ConvertFrom-PesterConfiguration to handle container settings …
MariusStorhaug Mar 3, 2025
4666be3
Enhance ConvertFrom-PesterConfiguration to improve verbose logging an…
MariusStorhaug Mar 3, 2025
5183b58
Refactor ConvertFrom-PesterConfiguration to use a list for container …
MariusStorhaug Mar 3, 2025
e727052
Enhance ConvertFrom-PesterConfiguration to include detailed verbose l…
MariusStorhaug Mar 3, 2025
85720e2
Update ConvertFrom-PesterConfiguration to use FullName for container …
MariusStorhaug Mar 3, 2025
fd3cbf2
Optimize JSON output generation by adding compression for test result…
MariusStorhaug Mar 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ jobs:
| **Input** | **Description** | **Default** |
|--------------------------------------|--------------------------------------------------------------------------------------------------------|---------------------------------|
| `Path` | Path to where tests are located or a configuration file. | *(none)* |
| `ReportAsJson` | Output generated reports in JSON format in addition to the configured format through Pester. | `true` |
| `Run_Path` | Directories/files to be searched for tests. | *(none)* |
| `Run_ExcludePath` | Directories/files to exclude from the run. | *(none)* |
| `Run_ScriptBlock` | ScriptBlocks containing tests to be executed. | *(none)* |
Expand Down
11 changes: 11 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ inputs:
description: |
Path to where tests are located or a configuration file.
required: false
ReportAsJson:
description: |
Output generated reports in JSON format in addition to the configured format through Pester.
required: false
default: 'true'
Run_Path:
description: |
Directories to be searched for tests, paths directly to test files, or combination of both.
Expand Down Expand Up @@ -267,6 +272,8 @@ runs:
shell: pwsh
continue-on-error: true
working-directory: ${{ inputs.WorkingDirectory }}
env:
PSMODULE_INVOKE_PESTER_INPUT_ReportAsJson: ${{ inputs.ReportAsJson }}
id: test
run: ${{ github.action_path }}/scripts/main.ps1

Expand All @@ -276,13 +283,17 @@ runs:
with:
name: ${{ steps.test.outputs.TestSuiteName }}-TestResults
path: ${{ steps.test.outputs.TestResultOutputPath }}
retention-days: 1
if-no-files-found: error

- name: Upload code coverage report - [${{ steps.test.outputs.TestSuiteName }}-CodeCoverage]
uses: actions/upload-artifact@v4
if: ${{ steps.test.outputs.CodeCoverageEnabled == 'true' && (success() || failure()) }}
with:
name: ${{ steps.test.outputs.TestSuiteName }}-CodeCoverage
path: ${{ steps.test.outputs.CodeCoverageOutputPath }}
retention-days: 1
if-no-files-found: error

- name: Status
shell: pwsh
Expand Down
198 changes: 163 additions & 35 deletions scripts/Helpers.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ function New-PesterConfigurationHashtable {
$result
}

filter Convert-PesterConfigurationToHashtable {
filter ConvertFrom-PesterConfiguration {
<#
.SYNOPSIS
Converts a PesterConfiguration object into a hashtable containing only modified settings.
Expand All @@ -396,7 +396,7 @@ filter Convert-PesterConfigurationToHashtable {
When the -IncludeDefaults switch is provided, it includes settings that have not been modified, outputting their default values.

.EXAMPLE
New-PesterConfiguration | Convert-PesterConfigurationToHashtable | Format-Hashtable
New-PesterConfiguration | ConvertFrom-PesterConfiguration -AsHashtable | Format-Hashtable

Output:
```powershell
Expand Down Expand Up @@ -475,7 +475,7 @@ filter Convert-PesterConfigurationToHashtable {
.EXAMPLE
$config = New-PesterConfiguration
$config.Run.PassThru = $true
Convert-PesterConfigurationToHashtable -PesterConfiguration $config -OnlyModified | Format-Hashtable
ConvertFrom-PesterConfiguration -PesterConfiguration $config -OnlyModified -AsHashtable | Format-Hashtable

Output:
```powershell
Expand Down Expand Up @@ -504,33 +504,57 @@ filter Convert-PesterConfigurationToHashtable {

# Include default values in the output hashtable.
[Parameter()]
[switch] $OnlyModified
[switch] $OnlyModified,

# Output as a hashtable
[Parameter()]
[switch] $AsHashtable
)

# Prepare the output hashtable
$result = @{}

# Iterate over each top-level category (Run, Filter, etc.)
foreach ($category in $PesterConfiguration.PSObject.Properties.Name) {
$categoryObj = $PesterConfiguration.$category
foreach ($category in $PesterConfiguration.PSObject.Properties) {
$categoryName = $category.Name
$categoryValue = $category.Value
$subHash = @{}

# Iterate over each setting within the category
foreach ($settingName in $categoryObj.PSObject.Properties.Name) {
if ($OnlyModified) {
if ($setting.IsModified) {
$subHash[$settingName] = $setting.Value
foreach ($setting in $categoryValue.PSObject.Properties) {
$settingName = $setting.Name
$settingValue = $setting.Value
$settingValue = $OnlyModified ? $settingValue.Value : ($settingValue.IsModified ? $settingValue.Value : $settingValue.Default)
Write-Verbose "[$categoryName] [$settingName] = $settingValue" -Verbose
if ($categoryName -eq 'Run' -and $settingName -eq 'Container') {
Write-Verbose ($settingValue | ConvertTo-Json -Depth 1 | Out-String) -Verbose
$containers = [System.Collections.Generic.List[object]]::new()
foreach ($container in $settingValue) {
$containers.Add(
[pscustomobject]@{
Path = $container.Item.FullName
Data = $container.Data
}
)
}
$subHash[$settingName] = $containers
} else {
$subHash[$settingName] = if ($setting.IsModified) { $setting.Value } else { $setting.Default }
$subHash[$settingName] = $settingValue
}
}

# Add the category sub-hashtable to the result even if empty, to preserve structure.
$result[$category] = $subHash
if ($AsHashtable) {
$result[$categoryName] = $subHash
} else {
$result[$categoryName] = [pscustomobject]$subHash
}
}

return $result
if ($AsHashtable) {
return $result
}
return [PSCustomObject]$result
}

filter Clear-PesterConfigurationEmptyValue {
Expand Down Expand Up @@ -639,38 +663,142 @@ filter Get-PesterTestTree {
Mandatory,
ValueFromPipeline
)]
[object] $InputObject
[object] $InputObject,

# Path to this node.
[Parameter()]
[string[]] $Path
)

$children = [System.Collections.Generic.List[object]]::new()
Write-Verbose "Processing object of type: $($InputObject.GetType().Name)"
switch ($InputObject.GetType().Name) {
'Run' {
$inputObject | Add-Member -MemberType NoteProperty -Name Depth -Value 0
$inputObject | Add-Member -MemberType NoteProperty -Name ItemType -Value 'TestSuite'
$inputObject | Add-Member -MemberType NoteProperty -Name Name -Value $($testResults.Configuration.TestResult.TestSuiteName.Value) -Force
$inputObject | Add-Member -MemberType NoteProperty -Name Children -Value $inputObject.Containers
$inputObject
$inputObject.Containers | Get-PesterTestTree
$Name = $InputObject.Configuration.TestResult.TestSuiteName.Value
$childPath = @($Path, $Name)
$children.Add(($InputObject.Containers | Get-PesterTestTree -Path $childPath))
$configuration = $InputObject.Configuration | ConvertFrom-PesterConfiguration
[pscustomobject]@{
Depth = 0
ItemType = 'TestSuite'
Name = $Name
Path = @()
Children = $children
Result = $InputObject.Result
FailedCount = $InputObject.FailedCount
FailedBlocksCount = $InputObject.FailedBlocksCount
FailedContainersCount = $InputObject.FailedContainersCount
PassedCount = $InputObject.PassedCount
SkippedCount = $InputObject.SkippedCount
InconclusiveCount = $InputObject.InconclusiveCount
NotRunCount = $InputObject.NotRunCount
TotalCount = $InputObject.TotalCount
Executed = $InputObject.Executed
ExecutedAt = $InputObject.ExecutedAt
Version = $InputObject.Version
PSVersion = $InputObject.PSVersion
Plugins = $InputObject.Plugins
PluginConfiguration = $InputObject.PluginConfiguration
PluginData = $InputObject.PluginData
Configuration = $configuration
Duration = [int64]$InputObject.Duration.Ticks
DiscoveryDuration = [int64]$InputObject.DiscoveryDuration.Ticks
UserDuration = [int64]$InputObject.UserDuration.Ticks
FrameworkDuration = [int64]$InputObject.FrameworkDuration.Ticks
}
}
'Container' {
$inputObject | Add-Member -MemberType NoteProperty -Name Depth -Value 1
$inputObject | Add-Member -MemberType NoteProperty -Name ItemType -Value 'Container'
$inputObject | Add-Member -MemberType NoteProperty -Name Name -Value ((Split-Path $InputObject.Name -Leaf) -replace '.Tests.ps1') -Force
$inputObject | Add-Member -MemberType NoteProperty -Name Children -Value $InputObject.Blocks
$inputObject
$InputObject.Blocks | Get-PesterTestTree
$Name = (Split-Path $InputObject.Name -Leaf) -replace '.Tests.ps1'
$childPath = @($Path, $Name)
$children.Add(($InputObject.Blocks | Get-PesterTestTree -Path $childPath))
[pscustomobject]@{
Depth = 1
ItemType = 'Container'
Name = $Name
Path = $Path
Children = $children
Result = $InputObject.Result
FailedCount = $InputObject.FailedCount
FailedBlocksCount = $InputObject.FailedBlocksCount
FailedContainersCount = $InputObject.FailedContainersCount
PassedCount = $InputObject.PassedCount
SkippedCount = $InputObject.SkippedCount
InconclusiveCount = $InputObject.InconclusiveCount
NotRunCount = $InputObject.NotRunCount
TotalCount = $InputObject.TotalCount
Executed = $InputObject.Executed
ExecutedAt = $InputObject.ExecutedAt
Version = $InputObject.Version
PSVersion = $InputObject.PSVersion
Plugins = $InputObject.Plugins
PluginConfiguration = $InputObject.PluginConfiguration
PluginData = $InputObject.PluginData
Duration = [int64]$InputObject.Duration.Ticks
DiscoveryDuration = [int64]$InputObject.DiscoveryDuration.Ticks
UserDuration = [int64]$InputObject.UserDuration.Ticks
FrameworkDuration = [int64]$InputObject.FrameworkDuration.Ticks
}
}
'Block' {
$inputObject | Add-Member -MemberType NoteProperty -Name Depth -Value ($InputObject.Path.Count + 1)
$inputObject | Add-Member -MemberType NoteProperty -Name Name -Value ($InputObject.ExpandedName) -Force
$inputObject | Add-Member -MemberType NoteProperty -Name Children -Value $InputObject.Order
$inputObject
$InputObject.Order | Get-PesterTestTree
$Name = ($InputObject.ExpandedName)
$childPath = @($Path, $Name)
$children.Add(($InputObject.Order | Get-PesterTestTree -Path $childPath))
[pscustomobject]@{
Depth = ($InputObject.Path.Count + 1)
ItemType = $InputObject.ItemType
Name = $Name
Path = $Path
Children = $children
Result = $InputObject.Result
FailedCount = $InputObject.FailedCount
FailedBlocksCount = $InputObject.FailedBlocksCount
FailedContainersCount = $InputObject.FailedContainersCount
PassedCount = $InputObject.PassedCount
SkippedCount = $InputObject.SkippedCount
InconclusiveCount = $InputObject.InconclusiveCount
NotRunCount = $InputObject.NotRunCount
TotalCount = $InputObject.TotalCount
Executed = $InputObject.Executed
ExecutedAt = $InputObject.ExecutedAt
Version = $InputObject.Version
PSVersion = $InputObject.PSVersion
Plugins = $InputObject.Plugins
PluginConfiguration = $InputObject.PluginConfiguration
PluginData = $InputObject.PluginData
Duration = [int64]$InputObject.Duration.Ticks
DiscoveryDuration = [int64]$InputObject.DiscoveryDuration.Ticks
UserDuration = [int64]$InputObject.UserDuration.Ticks
FrameworkDuration = [int64]$InputObject.FrameworkDuration.Ticks
}
}
'Test' {
$inputObject | Add-Member -MemberType NoteProperty -Name Depth -Value ($InputObject.Path.Count + 1)
$inputObject | Add-Member -MemberType NoteProperty -Name Name -Value ($InputObject.ExpandedName) -Force
$inputObject
$Name = ($InputObject.ExpandedName)
[pscustomobject]@{
Depth = ($InputObject.Path.Count + 1)
ItemType = $InputObject.ItemType
Name = $Name
Path = $Path
Result = $InputObject.Result
FailedCount = $InputObject.FailedCount
FailedBlocksCount = $InputObject.FailedBlocksCount
FailedContainersCount = $InputObject.FailedContainersCount
PassedCount = $InputObject.PassedCount
SkippedCount = $InputObject.SkippedCount
InconclusiveCount = $InputObject.InconclusiveCount
NotRunCount = $InputObject.NotRunCount
TotalCount = $InputObject.TotalCount
Executed = $InputObject.Executed
ExecutedAt = $InputObject.ExecutedAt
Version = $InputObject.Version
PSVersion = $InputObject.PSVersion
Plugins = $InputObject.Plugins
PluginConfiguration = $InputObject.PluginConfiguration
PluginData = $InputObject.PluginData
Duration = [int64]$InputObject.Duration.Ticks
DiscoveryDuration = [int64]$InputObject.DiscoveryDuration.Ticks
UserDuration = [int64]$InputObject.UserDuration.Ticks
FrameworkDuration = [int64]$InputObject.FrameworkDuration.Ticks
}
}
default {
Write-Error "Unknown object type: [$($InputObject.GetType().Name)]"
Expand Down Expand Up @@ -853,7 +981,7 @@ filter Set-PesterReportConfigurationSummary {
[Pester.Run] $TestResults
)

$configurationHashtable = $TestResults.Configuration | Convert-PesterConfigurationToHashtable | Format-Hashtable
$configurationHashtable = $TestResults.Configuration | ConvertFrom-PesterConfiguration -AsHashtable | Format-Hashtable

Details 'Configuration' {
CodeBlock 'pwsh' {
Expand Down
6 changes: 3 additions & 3 deletions scripts/init.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ LogGroup 'Init - Export containers' {
Write-Output "Containers from configuration: [$($existingContainers.Count)]"
foreach ($existingContainer in $existingContainers) {
Write-Output "Processing container [$existingContainer]"
$containers += $existingContainer | Convert-PesterConfigurationToHashtable
$containers += $existingContainer | ConvertTo-Hashtable
}
}
Write-Output "Containers from configuration: [$($containers.Count)]"
Expand Down Expand Up @@ -223,8 +223,8 @@ LogGroup 'Init - Export containers' {

LogGroup 'Init - Export configuration' {
$artifactName = $configuration.TestResult.TestSuiteName ?? 'Pester'
$configuration.TestResult.OutputPath = "$pwd/test_reports/$artifactName-TestResult-Report.xml"
$configuration.CodeCoverage.OutputPath = "$pwd/test_reports/$artifactName-CodeCoverage-Report.xml"
$configuration.TestResult.OutputPath = "$pwd/TestResult/$artifactName-TestResult-Report.xml"
$configuration.CodeCoverage.OutputPath = "$pwd/CodeCoverage/$artifactName-CodeCoverage-Report.xml"
$configuration.Run.PassThru = $true

Format-Hashtable -Hashtable $configuration
Expand Down
Loading
Loading