From 277961e977a60db15daa5e4f01aa1b75a238fe17 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 22 Aug 2025 11:21:00 +0000 Subject: [PATCH 1/2] Initial plan From 335c8f54bd6cfb9fec860711a9dbeeaf65b52e63 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 22 Aug 2025 11:33:18 +0000 Subject: [PATCH 2/2] Add include_skipped parameter to control skipped tests in summary tables Co-authored-by: mikepenz <1476232+mikepenz@users.noreply.github.com> --- README.md | 1 + __tests__/table.test.ts | 41 ++++++++++++++++++++++++++++++++++++++--- action.yml | 4 ++++ src/main.ts | 2 ++ src/table.ts | 18 +++++++++++++++--- 5 files changed, 60 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 9d9d29e9..e44c90f1 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,7 @@ jobs: | `require_tests` | Optional. Fail if no test are found. | | `require_passed_tests` | Optional. Fail if no passed test are found. (This is stricter than `require_tests`, which accepts skipped tests). | | `include_passed` | Optional. By default the action will skip passed items for the annotations. Enable this flag to include them. | +| `include_skipped` | Optional. Controls whether skipped tests are included in the detailed summary table. Defaults to `true`. | | `check_retries` | Optional. If a testcase is retried, ignore the original failure. | | `check_title_template` | Optional. Template to configure the title format. Placeholders: {{FILE_NAME}}, {{SUITE_NAME}}, {{TEST_NAME}}, {{CLASS_NAME}}, {{BREAD_CRUMB}}. | | `bread_crumb_delimiter` | Optional. Defines the delimiter characters between the breadcrumb elements. Defaults to: `/`. | diff --git a/__tests__/table.test.ts b/__tests__/table.test.ts index bfcc1c94..0958c78f 100644 --- a/__tests__/table.test.ts +++ b/__tests__/table.test.ts @@ -67,7 +67,7 @@ describe('buildSummaryTables', () => { '/' ) - const [table, detailTable, flakyTable] = buildSummaryTables([testResult], true, true, true, true, false) + const [table, detailTable, flakyTable] = buildSummaryTables([testResult], true, true, true, true, true, false) expect(table).toStrictEqual(NORMAL_TABLE) expect(detailTable).toStrictEqual([ @@ -116,12 +116,47 @@ describe('buildSummaryTables', () => { '/' ) - const [table, detailTable, flakyTable] = buildSummaryTables([testResult], true, true, true, true, true) + const [table, detailTable, flakyTable] = buildSummaryTables([testResult], true, true, true, true, true, true) expect(table).toStrictEqual([]) expect(detailTable).toStrictEqual([]) expect(flakyTable).toStrictEqual([]) }) + it('should exclude skipped tests when includeSkipped is false', async () => { + const testResult = await parseTestReports( + 'checkName', + 'summary', + 'test_results/tests/utils/target/surefire-reports/TEST-action.surefire.report.calc.StringUtilsTest.xml', // This file has skipped tests + '*', + true, + true, + true, + [], + '{{SUITE_NAME}}/{{TEST_NAME}}', + '/' + ) + + // Test with includeSkipped = false (should exclude skipped tests from detailed table) + const [, detailTable] = buildSummaryTables([testResult], true, false, true, false, false, false) + + // Check that the detail table doesn't include skipped tests + const flatResults = detailTable.flat() + const hasSkippedTests = flatResults.some( + cell => typeof cell === 'string' && cell.includes('⚠️ skipped') + ) + expect(hasSkippedTests).toBe(false) + + // Test with includeSkipped = true (should include skipped tests in detailed table) + const [, detailTableWithSkipped] = buildSummaryTables([testResult], true, true, true, false, false, false) + + // Check that the detail table includes skipped tests + const flatResultsWithSkipped = detailTableWithSkipped.flat() + const hasSkippedTestsIncluded = flatResultsWithSkipped.some( + cell => typeof cell === 'string' && cell.includes('⚠️ skipped') + ) + expect(hasSkippedTestsIncluded).toBe(true) + }) + it('should group detail tables', async () => { const testResult = await parseTestReports( 'checkName', @@ -136,7 +171,7 @@ describe('buildSummaryTables', () => { '/' ) - const [table, detailTable, flakyTable] = buildSummaryTables([testResult], true, true, true, true, false, true) + const [table, detailTable, flakyTable] = buildSummaryTables([testResult], true, true, true, true, true, false, true) expect(table).toStrictEqual(NORMAL_TABLE) expect(detailTable).toStrictEqual([ diff --git a/action.yml b/action.yml index d7ae3637..13484fbf 100644 --- a/action.yml +++ b/action.yml @@ -65,6 +65,10 @@ inputs: description: 'Include passed tests in the report' required: false default: 'false' + include_skipped: + description: 'Include skipped tests in the report' + required: false + default: 'true' check_title_template: description: |- Template to configure the title format. Placeholders: {{FILE_NAME}}, {{SUITE_NAME}}, {{TEST_NAME}}, {{CLASS_NAME}}, {{BREAD_CRUMB}}. diff --git a/src/main.ts b/src/main.ts index 4e0057ab..8c877b89 100644 --- a/src/main.ts +++ b/src/main.ts @@ -26,6 +26,7 @@ export async function run(): Promise { const requireTests = core.getInput('require_tests') === 'true' const requirePassedTests = core.getInput('require_passed_tests') === 'true' const includePassed = core.getInput('include_passed') === 'true' + const includeSkipped = core.getInput('include_skipped') === 'true' const checkRetries = core.getInput('check_retries') === 'true' const annotateNotice = core.getInput('annotate_notice') === 'true' const jobSummary = core.getInput('job_summary') === 'true' @@ -186,6 +187,7 @@ export async function run(): Promise { const [table, detailTable, flakyTable] = buildSummaryTables( testResults, includePassed, + includeSkipped, detailedSummary, flakySummary, verboseSummary, diff --git a/src/table.ts b/src/table.ts index 24b79e53..4e0f2757 100644 --- a/src/table.ts +++ b/src/table.ts @@ -6,6 +6,7 @@ import {toFormatedTime} from './utils.js' export function buildSummaryTables( testResults: TestResult[], includePassed: boolean, + includeSkipped: boolean, detailedSummary: boolean, flakySummary: boolean, verboseSummary: boolean, @@ -91,7 +92,9 @@ export function buildSummaryTables( table.push(row) const annotations = testResult.globalAnnotations.filter( - annotation => includePassed || annotation.annotation_level !== 'notice' + annotation => + (includePassed || annotation.annotation_level !== 'notice' || annotation.status !== 'success') && + (includeSkipped || annotation.status !== 'skipped') ) if (annotations.length === 0) { @@ -129,6 +132,7 @@ export function buildSummaryTables( internalTestResult, detailsTable, includePassed, + includeSkipped, includeTimeInSummary, passedDetailIcon, skippedDetailIcon @@ -138,7 +142,11 @@ export function buildSummaryTables( } if (flakySummary) { - const flakyAnnotations = annotations.filter(annotation => annotation.retries > 0) + const flakyAnnotations = annotations.filter( + annotation => + annotation.retries > 0 && + (includeSkipped || annotation.status !== 'skipped') + ) if (flakyAnnotations.length > 0) { flakyTable.push([{data: `${testResult.checkName}`, colspan}]) for (const annotation of flakyAnnotations) { @@ -159,13 +167,16 @@ function appendDetailsTable( testResult: ActualTestResult, detailsTable: SummaryTableRow[], includePassed: boolean, + includeSkipped: boolean, includeTimeInSummary: boolean, passedDetailIcon: string, skippedDetailIcon: string ): void { const colspan = includeTimeInSummary ? '3' : '2' const annotations = testResult.annotations.filter( - annotation => includePassed || annotation.annotation_level !== 'notice' + annotation => + (includePassed || annotation.annotation_level !== 'notice' || annotation.status !== 'success') && + (includeSkipped || annotation.status !== 'skipped') ) if (annotations.length > 0) { detailsTable.push([{data: `${testResult.name}`, colspan}]) @@ -191,6 +202,7 @@ function appendDetailsTable( childTestResult, detailsTable, includePassed, + includeSkipped, includeTimeInSummary, passedDetailIcon, skippedDetailIcon