Reduce duplication in CTRF/JUnit/HTML report extensions (#9129, #9131, #9132) - #9134

Merged
Amaury Levé (Evangelink) merged 1 commit into
microsoft:mainfrom
Evangelink:dev/amauryleve/fix-duplicate-code-9129-9131-9132
Jun 15, 2026
Merged

Reduce duplication in CTRF/JUnit/HTML report extensions (#9129, #9131, #9132)#9134
Amaury Levé (Evangelink) merged 1 commit into
microsoft:mainfrom
Evangelink:dev/amauryleve/fix-duplicate-code-9129-9131-9132

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Fixes#9129, #9131, #9132 (sub-issues of the #9130 Duplicate Code Detector group).

All three are duplicate-code findings across the CTRF / JUnit / HTML report extensions. The changes touch disjoint files and were validated together.

#9129 — CTRF TestResultCapture duplicated constants + divergent Truncate

  • CtrfReport/TestResultCapture.cs now delegates the 5 size constants and Truncate to the canonical TestResultCaptureHelper (matching JUnit/HTML).
  • This also fixes a latent bug: the old CTRF Truncate could split a UTF-16 surrogate pair, producing an invalid string; the shared helper guards against that.
  • Linked TestResultCaptureHelper.cs into the CtrfReport project (it was not previously linked).

#9131 — Missing TestApplicationBuilder guard in CtrfReportExtensions

  • Added the if (builder is not TestApplicationBuilder) throw ... guard to AddCtrfReportProvider so CTRF fails fast like JUnit/HTML instead of silently succeeding against unsupported custom builders.
  • Added the InvalidTestApplicationBuilderType resource string and regenerated all 13 .xlf files via /t:UpdateXlf.

#9132 — Identical *ReportGeneratorCommandLine structure

  • Extracted ReportGeneratorCommandLineBase into SharedExtensionHelpers, holding the two validation overrides once.
  • Ctrf/JUnit/Html providers now derive from it as small constants + constructor declarations.
  • Pure refactor: provider names (uids), option names, descriptions, arity, and validation are byte-for-byte unchanged, so --help/--info output is unaffected.

Validation

  • All three extension projects build clean (0 warnings, 0 errors) across net8.0/net9.0/netstandard2.0.
  • Microsoft.Testing.Extensions.UnitTests (net9.0): 507 passed, 0 failed, 4 skipped (unrelated Windows crash-report tests).

CopilotAI review requested due to automatic review settings June 15, 2026 08:18

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR primarily refactors the CTRF/JUnit/HTML report extensions to reduce duplicated logic (shared report-generator command line base, shared test-result capture helper usage, and consistent builder-guard behavior), and also adds an unrelated VSTestBridge enhancement to emit managed type/method metadata on TestNodes when available.

Changes:

  • Refactor report-generator command line providers to derive from a new shared ReportGeneratorCommandLineBase.
  • Align CTRF report extension behavior with the other report extensions (shared truncate/constants + TestApplicationBuilder guard + localized resource addition).
  • Add propagation of VSTest TestCase.ManagedType / TestCase.ManagedMethod into emitted TestNode properties, with new unit tests.
Show a summary per file
FileDescription
test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/ObjectModelConvertersTests.csAdds unit coverage for managed type/method propagation into TestNode properties.
src/Platform/SharedExtensionHelpers/ReportGeneratorCommandLineBase.csNew shared base class to de-duplicate common report command-line validation logic.
src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/ObjectModelConverters.csEmits managed type/method properties from VSTest TestCase onto TestNode.
src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Helpers/VSTestTestNodeProperties.csAdds constants for the new managed type/method wire property keys.
src/Platform/Microsoft.Testing.Extensions.JUnitReport/Microsoft.Testing.Extensions.JUnitReport.csprojLinks the new shared ReportGeneratorCommandLineBase helper into the JUnit extension.
src/Platform/Microsoft.Testing.Extensions.JUnitReport/JUnitReportGeneratorCommandLine.csRefactors to inherit from ReportGeneratorCommandLineBase.
src/Platform/Microsoft.Testing.Extensions.HtmlReport/Microsoft.Testing.Extensions.HtmlReport.csprojLinks the new shared ReportGeneratorCommandLineBase helper into the HTML extension.
src/Platform/Microsoft.Testing.Extensions.HtmlReport/HtmlReportGeneratorCommandLine.csRefactors to inherit from ReportGeneratorCommandLineBase.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/TestResultCapture.csSwitches CTRF truncation/constants to delegate to shared TestResultCaptureHelper.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.zh-Hant.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.zh-Hans.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.tr.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.ru.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.pt-BR.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.pl.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.ko.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.ja.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.it.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.fr.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.es.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.de.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.cs.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/ExtensionResources.resxAdds the new InvalidTestApplicationBuilderType resource string.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Microsoft.Testing.Extensions.CtrfReport.csprojLinks shared helpers (command line base + test-result capture helper) into CTRF extension.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/CtrfReportGeneratorCommandLine.csRefactors to inherit from ReportGeneratorCommandLineBase.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/CtrfReportExtensions.csAdds a TestApplicationBuilder guard consistent with other report extensions.

Copilot's findings

  • Files reviewed: 26/26 changed files
  • Comments generated: 2

…, microsoft#9132)
- microsoft#9129: CTRF TestResultCapture now delegates constants and Truncate to the shared TestResultCaptureHelper (fixes surrogate-pair truncation bug); link helper into CtrfReport project.
- microsoft#9131: Add missing 'builder is not TestApplicationBuilder' guard to CtrfReportExtensions.AddCtrfReportProvider to match JUnit/Html; add InvalidTestApplicationBuilderType resource + regenerated xlf.
- microsoft#9132: Extract shared ReportGeneratorCommandLineBase into SharedExtensionHelpers; Ctrf/JUnit/Html command-line providers now derive from it with identical behavior (provider names, option names, descriptions, arity, validation unchanged).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink
Amaury Levé (Evangelink)force-pushed the dev/amauryleve/fix-duplicate-code-9129-9131-9132 branch from 685b40d to 3c55680CompareJune 15, 2026 08:26
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[duplicate-code] Duplicate Code: CTRF TestResultCapture duplicates constants and Truncate logic from TestResultCaptureHelper

3 participants

@Evangelink@azat-msft
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Reduce duplication in CTRF/JUnit/HTML report extensions (#9129, #9131, #9132) - #9134

Merged
Amaury Levé (Evangelink) merged 1 commit into
microsoft:mainfrom
Evangelink:dev/amauryleve/fix-duplicate-code-9129-9131-9132
Jun 15, 2026
Merged

Reduce duplication in CTRF/JUnit/HTML report extensions (#9129, #9131, #9132)#9134
Amaury Levé (Evangelink) merged 1 commit into
microsoft:mainfrom
Evangelink:dev/amauryleve/fix-duplicate-code-9129-9131-9132

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Fixes#9129, #9131, #9132 (sub-issues of the #9130 Duplicate Code Detector group).

All three are duplicate-code findings across the CTRF / JUnit / HTML report extensions. The changes touch disjoint files and were validated together.

#9129 — CTRF TestResultCapture duplicated constants + divergent Truncate

  • CtrfReport/TestResultCapture.cs now delegates the 5 size constants and Truncate to the canonical TestResultCaptureHelper (matching JUnit/HTML).
  • This also fixes a latent bug: the old CTRF Truncate could split a UTF-16 surrogate pair, producing an invalid string; the shared helper guards against that.
  • Linked TestResultCaptureHelper.cs into the CtrfReport project (it was not previously linked).

#9131 — Missing TestApplicationBuilder guard in CtrfReportExtensions

  • Added the if (builder is not TestApplicationBuilder) throw ... guard to AddCtrfReportProvider so CTRF fails fast like JUnit/HTML instead of silently succeeding against unsupported custom builders.
  • Added the InvalidTestApplicationBuilderType resource string and regenerated all 13 .xlf files via /t:UpdateXlf.

#9132 — Identical *ReportGeneratorCommandLine structure

  • Extracted ReportGeneratorCommandLineBase into SharedExtensionHelpers, holding the two validation overrides once.
  • Ctrf/JUnit/Html providers now derive from it as small constants + constructor declarations.
  • Pure refactor: provider names (uids), option names, descriptions, arity, and validation are byte-for-byte unchanged, so --help/--info output is unaffected.

Validation

  • All three extension projects build clean (0 warnings, 0 errors) across net8.0/net9.0/netstandard2.0.
  • Microsoft.Testing.Extensions.UnitTests (net9.0): 507 passed, 0 failed, 4 skipped (unrelated Windows crash-report tests).

CopilotAI review requested due to automatic review settings June 15, 2026 08:18

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR primarily refactors the CTRF/JUnit/HTML report extensions to reduce duplicated logic (shared report-generator command line base, shared test-result capture helper usage, and consistent builder-guard behavior), and also adds an unrelated VSTestBridge enhancement to emit managed type/method metadata on TestNodes when available.

Changes:

  • Refactor report-generator command line providers to derive from a new shared ReportGeneratorCommandLineBase.
  • Align CTRF report extension behavior with the other report extensions (shared truncate/constants + TestApplicationBuilder guard + localized resource addition).
  • Add propagation of VSTest TestCase.ManagedType / TestCase.ManagedMethod into emitted TestNode properties, with new unit tests.
Show a summary per file
FileDescription
test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/ObjectModelConvertersTests.csAdds unit coverage for managed type/method propagation into TestNode properties.
src/Platform/SharedExtensionHelpers/ReportGeneratorCommandLineBase.csNew shared base class to de-duplicate common report command-line validation logic.
src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/ObjectModelConverters.csEmits managed type/method properties from VSTest TestCase onto TestNode.
src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Helpers/VSTestTestNodeProperties.csAdds constants for the new managed type/method wire property keys.
src/Platform/Microsoft.Testing.Extensions.JUnitReport/Microsoft.Testing.Extensions.JUnitReport.csprojLinks the new shared ReportGeneratorCommandLineBase helper into the JUnit extension.
src/Platform/Microsoft.Testing.Extensions.JUnitReport/JUnitReportGeneratorCommandLine.csRefactors to inherit from ReportGeneratorCommandLineBase.
src/Platform/Microsoft.Testing.Extensions.HtmlReport/Microsoft.Testing.Extensions.HtmlReport.csprojLinks the new shared ReportGeneratorCommandLineBase helper into the HTML extension.
src/Platform/Microsoft.Testing.Extensions.HtmlReport/HtmlReportGeneratorCommandLine.csRefactors to inherit from ReportGeneratorCommandLineBase.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/TestResultCapture.csSwitches CTRF truncation/constants to delegate to shared TestResultCaptureHelper.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.zh-Hant.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.zh-Hans.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.tr.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.ru.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.pt-BR.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.pl.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.ko.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.ja.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.it.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.fr.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.es.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.de.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.cs.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/ExtensionResources.resxAdds the new InvalidTestApplicationBuilderType resource string.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Microsoft.Testing.Extensions.CtrfReport.csprojLinks shared helpers (command line base + test-result capture helper) into CTRF extension.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/CtrfReportGeneratorCommandLine.csRefactors to inherit from ReportGeneratorCommandLineBase.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/CtrfReportExtensions.csAdds a TestApplicationBuilder guard consistent with other report extensions.

Copilot's findings

  • Files reviewed: 26/26 changed files
  • Comments generated: 2

…, microsoft#9132)
- microsoft#9129: CTRF TestResultCapture now delegates constants and Truncate to the shared TestResultCaptureHelper (fixes surrogate-pair truncation bug); link helper into CtrfReport project.
- microsoft#9131: Add missing 'builder is not TestApplicationBuilder' guard to CtrfReportExtensions.AddCtrfReportProvider to match JUnit/Html; add InvalidTestApplicationBuilderType resource + regenerated xlf.
- microsoft#9132: Extract shared ReportGeneratorCommandLineBase into SharedExtensionHelpers; Ctrf/JUnit/Html command-line providers now derive from it with identical behavior (provider names, option names, descriptions, arity, validation unchanged).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink
Amaury Levé (Evangelink)force-pushed the dev/amauryleve/fix-duplicate-code-9129-9131-9132 branch from 685b40d to 3c55680CompareJune 15, 2026 08:26
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[duplicate-code] Duplicate Code: CTRF TestResultCapture duplicates constants and Truncate logic from TestResultCaptureHelper

3 participants

@Evangelink@azat-msft
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Reduce duplication in CTRF/JUnit/HTML report extensions (#9129, #9131, #9132) - #9134

Merged
Amaury Levé (Evangelink) merged 1 commit into
microsoft:mainfrom
Evangelink:dev/amauryleve/fix-duplicate-code-9129-9131-9132
Jun 15, 2026
Merged

Reduce duplication in CTRF/JUnit/HTML report extensions (#9129, #9131, #9132)#9134
Amaury Levé (Evangelink) merged 1 commit into
microsoft:mainfrom
Evangelink:dev/amauryleve/fix-duplicate-code-9129-9131-9132

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Fixes#9129, #9131, #9132 (sub-issues of the #9130 Duplicate Code Detector group).

All three are duplicate-code findings across the CTRF / JUnit / HTML report extensions. The changes touch disjoint files and were validated together.

#9129 — CTRF TestResultCapture duplicated constants + divergent Truncate

  • CtrfReport/TestResultCapture.cs now delegates the 5 size constants and Truncate to the canonical TestResultCaptureHelper (matching JUnit/HTML).
  • This also fixes a latent bug: the old CTRF Truncate could split a UTF-16 surrogate pair, producing an invalid string; the shared helper guards against that.
  • Linked TestResultCaptureHelper.cs into the CtrfReport project (it was not previously linked).

#9131 — Missing TestApplicationBuilder guard in CtrfReportExtensions

  • Added the if (builder is not TestApplicationBuilder) throw ... guard to AddCtrfReportProvider so CTRF fails fast like JUnit/HTML instead of silently succeeding against unsupported custom builders.
  • Added the InvalidTestApplicationBuilderType resource string and regenerated all 13 .xlf files via /t:UpdateXlf.

#9132 — Identical *ReportGeneratorCommandLine structure

  • Extracted ReportGeneratorCommandLineBase into SharedExtensionHelpers, holding the two validation overrides once.
  • Ctrf/JUnit/Html providers now derive from it as small constants + constructor declarations.
  • Pure refactor: provider names (uids), option names, descriptions, arity, and validation are byte-for-byte unchanged, so --help/--info output is unaffected.

Validation

  • All three extension projects build clean (0 warnings, 0 errors) across net8.0/net9.0/netstandard2.0.
  • Microsoft.Testing.Extensions.UnitTests (net9.0): 507 passed, 0 failed, 4 skipped (unrelated Windows crash-report tests).

CopilotAI review requested due to automatic review settings June 15, 2026 08:18

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR primarily refactors the CTRF/JUnit/HTML report extensions to reduce duplicated logic (shared report-generator command line base, shared test-result capture helper usage, and consistent builder-guard behavior), and also adds an unrelated VSTestBridge enhancement to emit managed type/method metadata on TestNodes when available.

Changes:

  • Refactor report-generator command line providers to derive from a new shared ReportGeneratorCommandLineBase.
  • Align CTRF report extension behavior with the other report extensions (shared truncate/constants + TestApplicationBuilder guard + localized resource addition).
  • Add propagation of VSTest TestCase.ManagedType / TestCase.ManagedMethod into emitted TestNode properties, with new unit tests.
Show a summary per file
FileDescription
test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/ObjectModelConvertersTests.csAdds unit coverage for managed type/method propagation into TestNode properties.
src/Platform/SharedExtensionHelpers/ReportGeneratorCommandLineBase.csNew shared base class to de-duplicate common report command-line validation logic.
src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/ObjectModelConverters.csEmits managed type/method properties from VSTest TestCase onto TestNode.
src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Helpers/VSTestTestNodeProperties.csAdds constants for the new managed type/method wire property keys.
src/Platform/Microsoft.Testing.Extensions.JUnitReport/Microsoft.Testing.Extensions.JUnitReport.csprojLinks the new shared ReportGeneratorCommandLineBase helper into the JUnit extension.
src/Platform/Microsoft.Testing.Extensions.JUnitReport/JUnitReportGeneratorCommandLine.csRefactors to inherit from ReportGeneratorCommandLineBase.
src/Platform/Microsoft.Testing.Extensions.HtmlReport/Microsoft.Testing.Extensions.HtmlReport.csprojLinks the new shared ReportGeneratorCommandLineBase helper into the HTML extension.
src/Platform/Microsoft.Testing.Extensions.HtmlReport/HtmlReportGeneratorCommandLine.csRefactors to inherit from ReportGeneratorCommandLineBase.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/TestResultCapture.csSwitches CTRF truncation/constants to delegate to shared TestResultCaptureHelper.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.zh-Hant.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.zh-Hans.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.tr.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.ru.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.pt-BR.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.pl.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.ko.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.ja.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.it.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.fr.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.es.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.de.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.cs.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/ExtensionResources.resxAdds the new InvalidTestApplicationBuilderType resource string.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Microsoft.Testing.Extensions.CtrfReport.csprojLinks shared helpers (command line base + test-result capture helper) into CTRF extension.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/CtrfReportGeneratorCommandLine.csRefactors to inherit from ReportGeneratorCommandLineBase.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/CtrfReportExtensions.csAdds a TestApplicationBuilder guard consistent with other report extensions.

Copilot's findings

  • Files reviewed: 26/26 changed files
  • Comments generated: 2

…, microsoft#9132)
- microsoft#9129: CTRF TestResultCapture now delegates constants and Truncate to the shared TestResultCaptureHelper (fixes surrogate-pair truncation bug); link helper into CtrfReport project.
- microsoft#9131: Add missing 'builder is not TestApplicationBuilder' guard to CtrfReportExtensions.AddCtrfReportProvider to match JUnit/Html; add InvalidTestApplicationBuilderType resource + regenerated xlf.
- microsoft#9132: Extract shared ReportGeneratorCommandLineBase into SharedExtensionHelpers; Ctrf/JUnit/Html command-line providers now derive from it with identical behavior (provider names, option names, descriptions, arity, validation unchanged).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink
Amaury Levé (Evangelink)force-pushed the dev/amauryleve/fix-duplicate-code-9129-9131-9132 branch from 685b40d to 3c55680CompareJune 15, 2026 08:26
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[duplicate-code] Duplicate Code: CTRF TestResultCapture duplicates constants and Truncate logic from TestResultCaptureHelper

3 participants

@Evangelink@azat-msft
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Reduce duplication in CTRF/JUnit/HTML report extensions (#9129, #9131, #9132) - #9134

Merged
Amaury Levé (Evangelink) merged 1 commit into
microsoft:mainfrom
Evangelink:dev/amauryleve/fix-duplicate-code-9129-9131-9132
Jun 15, 2026
Merged

Reduce duplication in CTRF/JUnit/HTML report extensions (#9129, #9131, #9132)#9134
Amaury Levé (Evangelink) merged 1 commit into
microsoft:mainfrom
Evangelink:dev/amauryleve/fix-duplicate-code-9129-9131-9132

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Fixes#9129, #9131, #9132 (sub-issues of the #9130 Duplicate Code Detector group).

All three are duplicate-code findings across the CTRF / JUnit / HTML report extensions. The changes touch disjoint files and were validated together.

#9129 — CTRF TestResultCapture duplicated constants + divergent Truncate

  • CtrfReport/TestResultCapture.cs now delegates the 5 size constants and Truncate to the canonical TestResultCaptureHelper (matching JUnit/HTML).
  • This also fixes a latent bug: the old CTRF Truncate could split a UTF-16 surrogate pair, producing an invalid string; the shared helper guards against that.
  • Linked TestResultCaptureHelper.cs into the CtrfReport project (it was not previously linked).

#9131 — Missing TestApplicationBuilder guard in CtrfReportExtensions

  • Added the if (builder is not TestApplicationBuilder) throw ... guard to AddCtrfReportProvider so CTRF fails fast like JUnit/HTML instead of silently succeeding against unsupported custom builders.
  • Added the InvalidTestApplicationBuilderType resource string and regenerated all 13 .xlf files via /t:UpdateXlf.

#9132 — Identical *ReportGeneratorCommandLine structure

  • Extracted ReportGeneratorCommandLineBase into SharedExtensionHelpers, holding the two validation overrides once.
  • Ctrf/JUnit/Html providers now derive from it as small constants + constructor declarations.
  • Pure refactor: provider names (uids), option names, descriptions, arity, and validation are byte-for-byte unchanged, so --help/--info output is unaffected.

Validation

  • All three extension projects build clean (0 warnings, 0 errors) across net8.0/net9.0/netstandard2.0.
  • Microsoft.Testing.Extensions.UnitTests (net9.0): 507 passed, 0 failed, 4 skipped (unrelated Windows crash-report tests).

CopilotAI review requested due to automatic review settings June 15, 2026 08:18

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR primarily refactors the CTRF/JUnit/HTML report extensions to reduce duplicated logic (shared report-generator command line base, shared test-result capture helper usage, and consistent builder-guard behavior), and also adds an unrelated VSTestBridge enhancement to emit managed type/method metadata on TestNodes when available.

Changes:

  • Refactor report-generator command line providers to derive from a new shared ReportGeneratorCommandLineBase.
  • Align CTRF report extension behavior with the other report extensions (shared truncate/constants + TestApplicationBuilder guard + localized resource addition).
  • Add propagation of VSTest TestCase.ManagedType / TestCase.ManagedMethod into emitted TestNode properties, with new unit tests.
Show a summary per file
FileDescription
test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/ObjectModelConvertersTests.csAdds unit coverage for managed type/method propagation into TestNode properties.
src/Platform/SharedExtensionHelpers/ReportGeneratorCommandLineBase.csNew shared base class to de-duplicate common report command-line validation logic.
src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/ObjectModelConverters.csEmits managed type/method properties from VSTest TestCase onto TestNode.
src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Helpers/VSTestTestNodeProperties.csAdds constants for the new managed type/method wire property keys.
src/Platform/Microsoft.Testing.Extensions.JUnitReport/Microsoft.Testing.Extensions.JUnitReport.csprojLinks the new shared ReportGeneratorCommandLineBase helper into the JUnit extension.
src/Platform/Microsoft.Testing.Extensions.JUnitReport/JUnitReportGeneratorCommandLine.csRefactors to inherit from ReportGeneratorCommandLineBase.
src/Platform/Microsoft.Testing.Extensions.HtmlReport/Microsoft.Testing.Extensions.HtmlReport.csprojLinks the new shared ReportGeneratorCommandLineBase helper into the HTML extension.
src/Platform/Microsoft.Testing.Extensions.HtmlReport/HtmlReportGeneratorCommandLine.csRefactors to inherit from ReportGeneratorCommandLineBase.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/TestResultCapture.csSwitches CTRF truncation/constants to delegate to shared TestResultCaptureHelper.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.zh-Hant.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.zh-Hans.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.tr.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.ru.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.pt-BR.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.pl.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.ko.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.ja.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.it.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.fr.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.es.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.de.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.cs.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/ExtensionResources.resxAdds the new InvalidTestApplicationBuilderType resource string.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Microsoft.Testing.Extensions.CtrfReport.csprojLinks shared helpers (command line base + test-result capture helper) into CTRF extension.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/CtrfReportGeneratorCommandLine.csRefactors to inherit from ReportGeneratorCommandLineBase.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/CtrfReportExtensions.csAdds a TestApplicationBuilder guard consistent with other report extensions.

Copilot's findings

  • Files reviewed: 26/26 changed files
  • Comments generated: 2

…, microsoft#9132)
- microsoft#9129: CTRF TestResultCapture now delegates constants and Truncate to the shared TestResultCaptureHelper (fixes surrogate-pair truncation bug); link helper into CtrfReport project.
- microsoft#9131: Add missing 'builder is not TestApplicationBuilder' guard to CtrfReportExtensions.AddCtrfReportProvider to match JUnit/Html; add InvalidTestApplicationBuilderType resource + regenerated xlf.
- microsoft#9132: Extract shared ReportGeneratorCommandLineBase into SharedExtensionHelpers; Ctrf/JUnit/Html command-line providers now derive from it with identical behavior (provider names, option names, descriptions, arity, validation unchanged).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink
Amaury Levé (Evangelink)force-pushed the dev/amauryleve/fix-duplicate-code-9129-9131-9132 branch from 685b40d to 3c55680CompareJune 15, 2026 08:26
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[duplicate-code] Duplicate Code: CTRF TestResultCapture duplicates constants and Truncate logic from TestResultCaptureHelper

3 participants

@Evangelink@azat-msft
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Reduce duplication in CTRF/JUnit/HTML report extensions (#9129, #9131, #9132) - #9134

Merged
Amaury Levé (Evangelink) merged 1 commit into
microsoft:mainfrom
Evangelink:dev/amauryleve/fix-duplicate-code-9129-9131-9132
Jun 15, 2026
Merged

Reduce duplication in CTRF/JUnit/HTML report extensions (#9129, #9131, #9132)#9134
Amaury Levé (Evangelink) merged 1 commit into
microsoft:mainfrom
Evangelink:dev/amauryleve/fix-duplicate-code-9129-9131-9132

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Fixes#9129, #9131, #9132 (sub-issues of the #9130 Duplicate Code Detector group).

All three are duplicate-code findings across the CTRF / JUnit / HTML report extensions. The changes touch disjoint files and were validated together.

#9129 — CTRF TestResultCapture duplicated constants + divergent Truncate

  • CtrfReport/TestResultCapture.cs now delegates the 5 size constants and Truncate to the canonical TestResultCaptureHelper (matching JUnit/HTML).
  • This also fixes a latent bug: the old CTRF Truncate could split a UTF-16 surrogate pair, producing an invalid string; the shared helper guards against that.
  • Linked TestResultCaptureHelper.cs into the CtrfReport project (it was not previously linked).

#9131 — Missing TestApplicationBuilder guard in CtrfReportExtensions

  • Added the if (builder is not TestApplicationBuilder) throw ... guard to AddCtrfReportProvider so CTRF fails fast like JUnit/HTML instead of silently succeeding against unsupported custom builders.
  • Added the InvalidTestApplicationBuilderType resource string and regenerated all 13 .xlf files via /t:UpdateXlf.

#9132 — Identical *ReportGeneratorCommandLine structure

  • Extracted ReportGeneratorCommandLineBase into SharedExtensionHelpers, holding the two validation overrides once.
  • Ctrf/JUnit/Html providers now derive from it as small constants + constructor declarations.
  • Pure refactor: provider names (uids), option names, descriptions, arity, and validation are byte-for-byte unchanged, so --help/--info output is unaffected.

Validation

  • All three extension projects build clean (0 warnings, 0 errors) across net8.0/net9.0/netstandard2.0.
  • Microsoft.Testing.Extensions.UnitTests (net9.0): 507 passed, 0 failed, 4 skipped (unrelated Windows crash-report tests).

CopilotAI review requested due to automatic review settings June 15, 2026 08:18

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR primarily refactors the CTRF/JUnit/HTML report extensions to reduce duplicated logic (shared report-generator command line base, shared test-result capture helper usage, and consistent builder-guard behavior), and also adds an unrelated VSTestBridge enhancement to emit managed type/method metadata on TestNodes when available.

Changes:

  • Refactor report-generator command line providers to derive from a new shared ReportGeneratorCommandLineBase.
  • Align CTRF report extension behavior with the other report extensions (shared truncate/constants + TestApplicationBuilder guard + localized resource addition).
  • Add propagation of VSTest TestCase.ManagedType / TestCase.ManagedMethod into emitted TestNode properties, with new unit tests.
Show a summary per file
FileDescription
test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/ObjectModelConvertersTests.csAdds unit coverage for managed type/method propagation into TestNode properties.
src/Platform/SharedExtensionHelpers/ReportGeneratorCommandLineBase.csNew shared base class to de-duplicate common report command-line validation logic.
src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/ObjectModelConverters.csEmits managed type/method properties from VSTest TestCase onto TestNode.
src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Helpers/VSTestTestNodeProperties.csAdds constants for the new managed type/method wire property keys.
src/Platform/Microsoft.Testing.Extensions.JUnitReport/Microsoft.Testing.Extensions.JUnitReport.csprojLinks the new shared ReportGeneratorCommandLineBase helper into the JUnit extension.
src/Platform/Microsoft.Testing.Extensions.JUnitReport/JUnitReportGeneratorCommandLine.csRefactors to inherit from ReportGeneratorCommandLineBase.
src/Platform/Microsoft.Testing.Extensions.HtmlReport/Microsoft.Testing.Extensions.HtmlReport.csprojLinks the new shared ReportGeneratorCommandLineBase helper into the HTML extension.
src/Platform/Microsoft.Testing.Extensions.HtmlReport/HtmlReportGeneratorCommandLine.csRefactors to inherit from ReportGeneratorCommandLineBase.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/TestResultCapture.csSwitches CTRF truncation/constants to delegate to shared TestResultCaptureHelper.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.zh-Hant.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.zh-Hans.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.tr.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.ru.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.pt-BR.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.pl.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.ko.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.ja.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.it.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.fr.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.es.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.de.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.cs.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/ExtensionResources.resxAdds the new InvalidTestApplicationBuilderType resource string.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Microsoft.Testing.Extensions.CtrfReport.csprojLinks shared helpers (command line base + test-result capture helper) into CTRF extension.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/CtrfReportGeneratorCommandLine.csRefactors to inherit from ReportGeneratorCommandLineBase.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/CtrfReportExtensions.csAdds a TestApplicationBuilder guard consistent with other report extensions.

Copilot's findings

  • Files reviewed: 26/26 changed files
  • Comments generated: 2

…, microsoft#9132)
- microsoft#9129: CTRF TestResultCapture now delegates constants and Truncate to the shared TestResultCaptureHelper (fixes surrogate-pair truncation bug); link helper into CtrfReport project.
- microsoft#9131: Add missing 'builder is not TestApplicationBuilder' guard to CtrfReportExtensions.AddCtrfReportProvider to match JUnit/Html; add InvalidTestApplicationBuilderType resource + regenerated xlf.
- microsoft#9132: Extract shared ReportGeneratorCommandLineBase into SharedExtensionHelpers; Ctrf/JUnit/Html command-line providers now derive from it with identical behavior (provider names, option names, descriptions, arity, validation unchanged).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink
Amaury Levé (Evangelink)force-pushed the dev/amauryleve/fix-duplicate-code-9129-9131-9132 branch from 685b40d to 3c55680CompareJune 15, 2026 08:26
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[duplicate-code] Duplicate Code: CTRF TestResultCapture duplicates constants and Truncate logic from TestResultCaptureHelper

3 participants

@Evangelink@azat-msft
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Reduce duplication in CTRF/JUnit/HTML report extensions (#9129, #9131, #9132) - #9134

Merged
Amaury Levé (Evangelink) merged 1 commit into
microsoft:mainfrom
Evangelink:dev/amauryleve/fix-duplicate-code-9129-9131-9132
Jun 15, 2026
Merged

Reduce duplication in CTRF/JUnit/HTML report extensions (#9129, #9131, #9132)#9134
Amaury Levé (Evangelink) merged 1 commit into
microsoft:mainfrom
Evangelink:dev/amauryleve/fix-duplicate-code-9129-9131-9132

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Fixes#9129, #9131, #9132 (sub-issues of the #9130 Duplicate Code Detector group).

All three are duplicate-code findings across the CTRF / JUnit / HTML report extensions. The changes touch disjoint files and were validated together.

#9129 — CTRF TestResultCapture duplicated constants + divergent Truncate

  • CtrfReport/TestResultCapture.cs now delegates the 5 size constants and Truncate to the canonical TestResultCaptureHelper (matching JUnit/HTML).
  • This also fixes a latent bug: the old CTRF Truncate could split a UTF-16 surrogate pair, producing an invalid string; the shared helper guards against that.
  • Linked TestResultCaptureHelper.cs into the CtrfReport project (it was not previously linked).

#9131 — Missing TestApplicationBuilder guard in CtrfReportExtensions

  • Added the if (builder is not TestApplicationBuilder) throw ... guard to AddCtrfReportProvider so CTRF fails fast like JUnit/HTML instead of silently succeeding against unsupported custom builders.
  • Added the InvalidTestApplicationBuilderType resource string and regenerated all 13 .xlf files via /t:UpdateXlf.

#9132 — Identical *ReportGeneratorCommandLine structure

  • Extracted ReportGeneratorCommandLineBase into SharedExtensionHelpers, holding the two validation overrides once.
  • Ctrf/JUnit/Html providers now derive from it as small constants + constructor declarations.
  • Pure refactor: provider names (uids), option names, descriptions, arity, and validation are byte-for-byte unchanged, so --help/--info output is unaffected.

Validation

  • All three extension projects build clean (0 warnings, 0 errors) across net8.0/net9.0/netstandard2.0.
  • Microsoft.Testing.Extensions.UnitTests (net9.0): 507 passed, 0 failed, 4 skipped (unrelated Windows crash-report tests).

CopilotAI review requested due to automatic review settings June 15, 2026 08:18

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR primarily refactors the CTRF/JUnit/HTML report extensions to reduce duplicated logic (shared report-generator command line base, shared test-result capture helper usage, and consistent builder-guard behavior), and also adds an unrelated VSTestBridge enhancement to emit managed type/method metadata on TestNodes when available.

Changes:

  • Refactor report-generator command line providers to derive from a new shared ReportGeneratorCommandLineBase.
  • Align CTRF report extension behavior with the other report extensions (shared truncate/constants + TestApplicationBuilder guard + localized resource addition).
  • Add propagation of VSTest TestCase.ManagedType / TestCase.ManagedMethod into emitted TestNode properties, with new unit tests.
Show a summary per file
FileDescription
test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/ObjectModelConvertersTests.csAdds unit coverage for managed type/method propagation into TestNode properties.
src/Platform/SharedExtensionHelpers/ReportGeneratorCommandLineBase.csNew shared base class to de-duplicate common report command-line validation logic.
src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/ObjectModelConverters.csEmits managed type/method properties from VSTest TestCase onto TestNode.
src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Helpers/VSTestTestNodeProperties.csAdds constants for the new managed type/method wire property keys.
src/Platform/Microsoft.Testing.Extensions.JUnitReport/Microsoft.Testing.Extensions.JUnitReport.csprojLinks the new shared ReportGeneratorCommandLineBase helper into the JUnit extension.
src/Platform/Microsoft.Testing.Extensions.JUnitReport/JUnitReportGeneratorCommandLine.csRefactors to inherit from ReportGeneratorCommandLineBase.
src/Platform/Microsoft.Testing.Extensions.HtmlReport/Microsoft.Testing.Extensions.HtmlReport.csprojLinks the new shared ReportGeneratorCommandLineBase helper into the HTML extension.
src/Platform/Microsoft.Testing.Extensions.HtmlReport/HtmlReportGeneratorCommandLine.csRefactors to inherit from ReportGeneratorCommandLineBase.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/TestResultCapture.csSwitches CTRF truncation/constants to delegate to shared TestResultCaptureHelper.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.zh-Hant.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.zh-Hans.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.tr.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.ru.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.pt-BR.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.pl.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.ko.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.ja.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.it.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.fr.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.es.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.de.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.cs.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/ExtensionResources.resxAdds the new InvalidTestApplicationBuilderType resource string.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Microsoft.Testing.Extensions.CtrfReport.csprojLinks shared helpers (command line base + test-result capture helper) into CTRF extension.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/CtrfReportGeneratorCommandLine.csRefactors to inherit from ReportGeneratorCommandLineBase.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/CtrfReportExtensions.csAdds a TestApplicationBuilder guard consistent with other report extensions.

Copilot's findings

  • Files reviewed: 26/26 changed files
  • Comments generated: 2

…, microsoft#9132)
- microsoft#9129: CTRF TestResultCapture now delegates constants and Truncate to the shared TestResultCaptureHelper (fixes surrogate-pair truncation bug); link helper into CtrfReport project.
- microsoft#9131: Add missing 'builder is not TestApplicationBuilder' guard to CtrfReportExtensions.AddCtrfReportProvider to match JUnit/Html; add InvalidTestApplicationBuilderType resource + regenerated xlf.
- microsoft#9132: Extract shared ReportGeneratorCommandLineBase into SharedExtensionHelpers; Ctrf/JUnit/Html command-line providers now derive from it with identical behavior (provider names, option names, descriptions, arity, validation unchanged).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink
Amaury Levé (Evangelink)force-pushed the dev/amauryleve/fix-duplicate-code-9129-9131-9132 branch from 685b40d to 3c55680CompareJune 15, 2026 08:26
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[duplicate-code] Duplicate Code: CTRF TestResultCapture duplicates constants and Truncate logic from TestResultCaptureHelper

3 participants

@Evangelink@azat-msft
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Reduce duplication in CTRF/JUnit/HTML report extensions (#9129, #9131, #9132) - #9134

Merged
Amaury Levé (Evangelink) merged 1 commit into
microsoft:mainfrom
Evangelink:dev/amauryleve/fix-duplicate-code-9129-9131-9132
Jun 15, 2026
Merged

Reduce duplication in CTRF/JUnit/HTML report extensions (#9129, #9131, #9132)#9134
Amaury Levé (Evangelink) merged 1 commit into
microsoft:mainfrom
Evangelink:dev/amauryleve/fix-duplicate-code-9129-9131-9132

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Fixes#9129, #9131, #9132 (sub-issues of the #9130 Duplicate Code Detector group).

All three are duplicate-code findings across the CTRF / JUnit / HTML report extensions. The changes touch disjoint files and were validated together.

#9129 — CTRF TestResultCapture duplicated constants + divergent Truncate

  • CtrfReport/TestResultCapture.cs now delegates the 5 size constants and Truncate to the canonical TestResultCaptureHelper (matching JUnit/HTML).
  • This also fixes a latent bug: the old CTRF Truncate could split a UTF-16 surrogate pair, producing an invalid string; the shared helper guards against that.
  • Linked TestResultCaptureHelper.cs into the CtrfReport project (it was not previously linked).

#9131 — Missing TestApplicationBuilder guard in CtrfReportExtensions

  • Added the if (builder is not TestApplicationBuilder) throw ... guard to AddCtrfReportProvider so CTRF fails fast like JUnit/HTML instead of silently succeeding against unsupported custom builders.
  • Added the InvalidTestApplicationBuilderType resource string and regenerated all 13 .xlf files via /t:UpdateXlf.

#9132 — Identical *ReportGeneratorCommandLine structure

  • Extracted ReportGeneratorCommandLineBase into SharedExtensionHelpers, holding the two validation overrides once.
  • Ctrf/JUnit/Html providers now derive from it as small constants + constructor declarations.
  • Pure refactor: provider names (uids), option names, descriptions, arity, and validation are byte-for-byte unchanged, so --help/--info output is unaffected.

Validation

  • All three extension projects build clean (0 warnings, 0 errors) across net8.0/net9.0/netstandard2.0.
  • Microsoft.Testing.Extensions.UnitTests (net9.0): 507 passed, 0 failed, 4 skipped (unrelated Windows crash-report tests).

CopilotAI review requested due to automatic review settings June 15, 2026 08:18

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR primarily refactors the CTRF/JUnit/HTML report extensions to reduce duplicated logic (shared report-generator command line base, shared test-result capture helper usage, and consistent builder-guard behavior), and also adds an unrelated VSTestBridge enhancement to emit managed type/method metadata on TestNodes when available.

Changes:

  • Refactor report-generator command line providers to derive from a new shared ReportGeneratorCommandLineBase.
  • Align CTRF report extension behavior with the other report extensions (shared truncate/constants + TestApplicationBuilder guard + localized resource addition).
  • Add propagation of VSTest TestCase.ManagedType / TestCase.ManagedMethod into emitted TestNode properties, with new unit tests.
Show a summary per file
FileDescription
test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/ObjectModelConvertersTests.csAdds unit coverage for managed type/method propagation into TestNode properties.
src/Platform/SharedExtensionHelpers/ReportGeneratorCommandLineBase.csNew shared base class to de-duplicate common report command-line validation logic.
src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/ObjectModelConverters.csEmits managed type/method properties from VSTest TestCase onto TestNode.
src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Helpers/VSTestTestNodeProperties.csAdds constants for the new managed type/method wire property keys.
src/Platform/Microsoft.Testing.Extensions.JUnitReport/Microsoft.Testing.Extensions.JUnitReport.csprojLinks the new shared ReportGeneratorCommandLineBase helper into the JUnit extension.
src/Platform/Microsoft.Testing.Extensions.JUnitReport/JUnitReportGeneratorCommandLine.csRefactors to inherit from ReportGeneratorCommandLineBase.
src/Platform/Microsoft.Testing.Extensions.HtmlReport/Microsoft.Testing.Extensions.HtmlReport.csprojLinks the new shared ReportGeneratorCommandLineBase helper into the HTML extension.
src/Platform/Microsoft.Testing.Extensions.HtmlReport/HtmlReportGeneratorCommandLine.csRefactors to inherit from ReportGeneratorCommandLineBase.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/TestResultCapture.csSwitches CTRF truncation/constants to delegate to shared TestResultCaptureHelper.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.zh-Hant.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.zh-Hans.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.tr.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.ru.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.pt-BR.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.pl.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.ko.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.ja.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.it.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.fr.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.es.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.de.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.cs.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/ExtensionResources.resxAdds the new InvalidTestApplicationBuilderType resource string.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Microsoft.Testing.Extensions.CtrfReport.csprojLinks shared helpers (command line base + test-result capture helper) into CTRF extension.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/CtrfReportGeneratorCommandLine.csRefactors to inherit from ReportGeneratorCommandLineBase.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/CtrfReportExtensions.csAdds a TestApplicationBuilder guard consistent with other report extensions.

Copilot's findings

  • Files reviewed: 26/26 changed files
  • Comments generated: 2

…, microsoft#9132)
- microsoft#9129: CTRF TestResultCapture now delegates constants and Truncate to the shared TestResultCaptureHelper (fixes surrogate-pair truncation bug); link helper into CtrfReport project.
- microsoft#9131: Add missing 'builder is not TestApplicationBuilder' guard to CtrfReportExtensions.AddCtrfReportProvider to match JUnit/Html; add InvalidTestApplicationBuilderType resource + regenerated xlf.
- microsoft#9132: Extract shared ReportGeneratorCommandLineBase into SharedExtensionHelpers; Ctrf/JUnit/Html command-line providers now derive from it with identical behavior (provider names, option names, descriptions, arity, validation unchanged).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink
Amaury Levé (Evangelink)force-pushed the dev/amauryleve/fix-duplicate-code-9129-9131-9132 branch from 685b40d to 3c55680CompareJune 15, 2026 08:26
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[duplicate-code] Duplicate Code: CTRF TestResultCapture duplicates constants and Truncate logic from TestResultCaptureHelper

3 participants

@Evangelink@azat-msft
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Reduce duplication in CTRF/JUnit/HTML report extensions (#9129, #9131, #9132) - #9134

Merged
Amaury Levé (Evangelink) merged 1 commit into
microsoft:mainfrom
Evangelink:dev/amauryleve/fix-duplicate-code-9129-9131-9132
Jun 15, 2026
Merged

Reduce duplication in CTRF/JUnit/HTML report extensions (#9129, #9131, #9132)#9134
Amaury Levé (Evangelink) merged 1 commit into
microsoft:mainfrom
Evangelink:dev/amauryleve/fix-duplicate-code-9129-9131-9132

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Fixes#9129, #9131, #9132 (sub-issues of the #9130 Duplicate Code Detector group).

All three are duplicate-code findings across the CTRF / JUnit / HTML report extensions. The changes touch disjoint files and were validated together.

#9129 — CTRF TestResultCapture duplicated constants + divergent Truncate

  • CtrfReport/TestResultCapture.cs now delegates the 5 size constants and Truncate to the canonical TestResultCaptureHelper (matching JUnit/HTML).
  • This also fixes a latent bug: the old CTRF Truncate could split a UTF-16 surrogate pair, producing an invalid string; the shared helper guards against that.
  • Linked TestResultCaptureHelper.cs into the CtrfReport project (it was not previously linked).

#9131 — Missing TestApplicationBuilder guard in CtrfReportExtensions

  • Added the if (builder is not TestApplicationBuilder) throw ... guard to AddCtrfReportProvider so CTRF fails fast like JUnit/HTML instead of silently succeeding against unsupported custom builders.
  • Added the InvalidTestApplicationBuilderType resource string and regenerated all 13 .xlf files via /t:UpdateXlf.

#9132 — Identical *ReportGeneratorCommandLine structure

  • Extracted ReportGeneratorCommandLineBase into SharedExtensionHelpers, holding the two validation overrides once.
  • Ctrf/JUnit/Html providers now derive from it as small constants + constructor declarations.
  • Pure refactor: provider names (uids), option names, descriptions, arity, and validation are byte-for-byte unchanged, so --help/--info output is unaffected.

Validation

  • All three extension projects build clean (0 warnings, 0 errors) across net8.0/net9.0/netstandard2.0.
  • Microsoft.Testing.Extensions.UnitTests (net9.0): 507 passed, 0 failed, 4 skipped (unrelated Windows crash-report tests).

CopilotAI review requested due to automatic review settings June 15, 2026 08:18

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR primarily refactors the CTRF/JUnit/HTML report extensions to reduce duplicated logic (shared report-generator command line base, shared test-result capture helper usage, and consistent builder-guard behavior), and also adds an unrelated VSTestBridge enhancement to emit managed type/method metadata on TestNodes when available.

Changes:

  • Refactor report-generator command line providers to derive from a new shared ReportGeneratorCommandLineBase.
  • Align CTRF report extension behavior with the other report extensions (shared truncate/constants + TestApplicationBuilder guard + localized resource addition).
  • Add propagation of VSTest TestCase.ManagedType / TestCase.ManagedMethod into emitted TestNode properties, with new unit tests.
Show a summary per file
FileDescription
test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/ObjectModelConvertersTests.csAdds unit coverage for managed type/method propagation into TestNode properties.
src/Platform/SharedExtensionHelpers/ReportGeneratorCommandLineBase.csNew shared base class to de-duplicate common report command-line validation logic.
src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/ObjectModelConverters.csEmits managed type/method properties from VSTest TestCase onto TestNode.
src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Helpers/VSTestTestNodeProperties.csAdds constants for the new managed type/method wire property keys.
src/Platform/Microsoft.Testing.Extensions.JUnitReport/Microsoft.Testing.Extensions.JUnitReport.csprojLinks the new shared ReportGeneratorCommandLineBase helper into the JUnit extension.
src/Platform/Microsoft.Testing.Extensions.JUnitReport/JUnitReportGeneratorCommandLine.csRefactors to inherit from ReportGeneratorCommandLineBase.
src/Platform/Microsoft.Testing.Extensions.HtmlReport/Microsoft.Testing.Extensions.HtmlReport.csprojLinks the new shared ReportGeneratorCommandLineBase helper into the HTML extension.
src/Platform/Microsoft.Testing.Extensions.HtmlReport/HtmlReportGeneratorCommandLine.csRefactors to inherit from ReportGeneratorCommandLineBase.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/TestResultCapture.csSwitches CTRF truncation/constants to delegate to shared TestResultCaptureHelper.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.zh-Hant.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.zh-Hans.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.tr.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.ru.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.pt-BR.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.pl.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.ko.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.ja.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.it.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.fr.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.es.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.de.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/xlf/ExtensionResources.cs.xlfAdds new localized string entry for invalid builder type guard.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Resources/ExtensionResources.resxAdds the new InvalidTestApplicationBuilderType resource string.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/Microsoft.Testing.Extensions.CtrfReport.csprojLinks shared helpers (command line base + test-result capture helper) into CTRF extension.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/CtrfReportGeneratorCommandLine.csRefactors to inherit from ReportGeneratorCommandLineBase.
src/Platform/Microsoft.Testing.Extensions.CtrfReport/CtrfReportExtensions.csAdds a TestApplicationBuilder guard consistent with other report extensions.

Copilot's findings

  • Files reviewed: 26/26 changed files
  • Comments generated: 2

…, microsoft#9132)
- microsoft#9129: CTRF TestResultCapture now delegates constants and Truncate to the shared TestResultCaptureHelper (fixes surrogate-pair truncation bug); link helper into CtrfReport project.
- microsoft#9131: Add missing 'builder is not TestApplicationBuilder' guard to CtrfReportExtensions.AddCtrfReportProvider to match JUnit/Html; add InvalidTestApplicationBuilderType resource + regenerated xlf.
- microsoft#9132: Extract shared ReportGeneratorCommandLineBase into SharedExtensionHelpers; Ctrf/JUnit/Html command-line providers now derive from it with identical behavior (provider names, option names, descriptions, arity, validation unchanged).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink
Amaury Levé (Evangelink)force-pushed the dev/amauryleve/fix-duplicate-code-9129-9131-9132 branch from 685b40d to 3c55680CompareJune 15, 2026 08:26
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[duplicate-code] Duplicate Code: CTRF TestResultCapture duplicates constants and Truncate logic from TestResultCaptureHelper

3 participants

@Evangelink@azat-msft