Skip to content

[Experiment] Add browser WebAssembly launcher package - #11305

Draft
Amaury Levé (Evangelink) wants to merge 50 commits into
mainfrom
dev/amauryleve/mtp-browser-extension
Draft

Amaury Levé (Evangelink) wants to merge 50 commits into
mainfrom
dev/amauryleve/mtp-browser-extension

Conversation

@Evangelink

@Evangelink Amaury Levé (Evangelink) commented Sep 15, 2026 •

Copy link
Copy Markdown
Member

Warning

EXPERIMENT / PROTOTYPE ONLY — this pull request exists for design validation. It is not a shipping commitment, does not establish a supported package or API, and must not be interpreted as a product roadmap promise.

Pull request

Summary

This prototype adds an optional Microsoft.Testing.Platform.Browser package that runs pure-managed browser-WASM MTP applications through dotnet test, following dotnet/sdk#55906. It builds on the authenticated HTTP transport from #10143 and single-threaded browser/WASI TRX support from #10324 while keeping browser dependencies and servicing cadence out of core MTP.

Current aligned source state:

  • TestFX: c81b63af69e367a826f614f5728e9f0c50d576fa
  • pinned SDK shared runner: 66309ab55fce95ee42e5e2236c02f7371332dbf8
  • immutable product/package baseline: b6c7cac92f7eeb788ae026471239ff110207bc24

A project opts in with a Microsoft.Testing.Platform.Browser package reference and an explicit Chromium-family executable. MTP remains authoritative for discovery, execution, filtering, progress/results, cancellation, and artifact production. The optional package owns browser/page/host lifecycle only; the browser app sends results and artifacts directly to the SDK HTTP gateway.

Design and decision record

The maintained cross-repository design discussion is dotnet/sdk#55906. The implementation boundary is:

  • Core MTP/TestFX: managed discovery/execution, filters, result/progress transport, HTTP cancellation, bounded chunked artifact export, and browser-safe scheduling.
  • SDK: launcher selection contract, authenticated gateway, module aggregation, artifact destination/quota ownership, and the shared composed-acceptance runner.
  • Browser package: generated private page assets, Playwright stdio driver, explicit browser launch, startup/heartbeat/console/JS diagnostics, and complete host/browser cleanup.

The package uses Playwright's private stdio protocol and never opens an unauthenticated TCP DevTools endpoint. Bootstrap bearer data is expanded from the SDK-owned response file in memory and is not placed in URLs or logs.

xHarness was investigated but not reused at runtime. Its Selenium/WebDriver server, URL query arguments, DOM tests_done, and console/result parsing conflict with direct MTP HTTP reporting. Its browser startup, container flags, retry, timeout, and cleanup experience informed this implementation.

Protocol additions are capability-gated and backward compatible:

  • protocol 1.5.0 handshake properties advertise HTTP control and artifact limits;
  • existing control serializers are reused over a second authenticated HTTP client;
  • artifact payloads use bounded raw TLV chunks with SDK-owned paths and quotas;
  • missing transfer capability remains compatibility-warning behavior, while a negotiated transfer failure is terminal.

BrowserTestingPackages.slnf is the conventional package-only build graph: eight package roots plus the non-packable MSTest.GlobalConfigsGenerator build dependency. Acceptance is built separately at evaluated NetCurrent. Package version lookups in AcceptanceTestBase are lazy, so reduced feeds do not fail on unrelated absent packages; missing or duplicate packages still fail exactly when requested.

CI uses existing capacity-backed public pools:

  • Windows: windows.vs2026preview.scout.amd64.open, required by the repo SDK's MSBuild 18.7 minimum and UWP package assets;
  • Linux: build.ubuntu.2204.amd64.open, with the SDK-owned CI-only InstallBrowser.sh prerequisite (fingerprint-verified Google signed APT repository when Chrome is absent).

No system-tool/cache deletion or SDK component omission is used.

Demonstration

Canonical consumer shape:

<Project Sdk="Microsoft.NET.Sdk.WebAssembly">
  <PropertyGroup>
    <TargetFramework>net12.0</TargetFramework>
    <OutputType>Exe</OutputType>
    <EnableMSTestRunner>true</EnableMSTestRunner>
    <TestingPlatformBrowserExecutable>PATH_TO_CHROMIUM</TestingPlatformBrowserExecutable>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="MSTest.TestFramework" Version="VERSION" />
    <PackageReference Include="MSTest.TestAdapter" Version="VERSION" />
    <PackageReference Include="Microsoft.Testing.Platform.Browser" Version="0.1.0-alpha" />
  </ItemGroup>
</Project>

The strict composed suite exercises normal run, --list-tests, matching/zero/project filters, managed cancellation (exit 3), intentional test failure aggregation, >1 MiB two-chunk artifact export and byte integrity, quota rejection, package/runtime layout, desktop non-interference, and process cleanup.

Current CI evidence from TestFX build 1632026, testing merge commit f1c7147a236bb16641e85058956d91138a228f1f with SDK 66309ab55fce95ee42e5e2236c02f7371332dbf8:

  • Linux job: passed, test run 45287224, 11/11 passed, 0 failed/incomplete/not-applicable; Chrome 155.0.8059.39; diagnostic artifact (2,075,499 bytes).
  • Windows job: passed, test run 45287840, 11/11 passed, 0 failed/incomplete/not-applicable; Edge 153.0.4234.48; diagnostic artifact (2,147,863 bytes).

Both downloaded TestFX artifacts pass the SDK-owned exact-11-case validator, record succeeded=true, and record exit 0 for all six composed commands.

Aligned SDK build 1632034 independently passed its browser jobs: Linux run 45287292 and Windows run 45287874, each 11/11 passed with zero failed/incomplete/not-applicable.

These are four independent green composed jobs: TestFX Windows/Linux and SDK Windows/Linux. No screenshot is included because the product behavior is process/protocol based; the linked TRX runs and narrow diagnostic artifacts are the clearer reproducible evidence.

Validation and regression proof

Focused repository validation:

  • build.cmd -c Release -pack -projects BrowserTestingPackages.slnf -mt 0 -bl -bln BrowserTestingPackages-fresh.binlog from a new detached checkout at bbbbfd23d4de8ed70a261b52a326804492b4b037: passed, exit 0, 0 warnings/errors. Exactly eight non-symbol shipping nupkgs were produced and every nuspec repository commit matched that exact source SHA.
  • build.cmd -c Release -projects test\IntegrationTests\Microsoft.Testing.Platform.Acceptance.IntegrationTests\Microsoft.Testing.Platform.Acceptance.IntegrationTests.csproj -mt 0 -bl -bln AcceptanceTestBaseLazy-final.binlog: passed, exit 0, 0 warnings/errors.
  • direct MTP run filtered to AcceptanceTestBaseTests: 1/1 passed, 0 skipped. It proves unused absent packages are not resolved, required absent packages fail with found 0, and duplicate packages fail with found 2.
  • direct MTP run filtered to BrowserPackage_ContainsPrivateCrossPlatformPlaywrightRuntime while Shipping contained exactly the required eight dev nupkgs: 1/1 passed, 0 skipped; the original 43-package local feed was restored afterward.
  • BuildDriverTests: 2/2 passed, covering nonzero build.cmd failure propagation/binlog creation and root-wrapper forwarding of -mt 0.
  • strict shared composed acceptance in TestFX build 1632026: Linux 11/11, Windows 11/11, no skips.
  • strict shared composed acceptance in SDK build 1632034: Linux 11/11, Windows 11/11, no skips.

The required-test manifest contains 11 exact TRX names and the shared validator requires every name exactly once, all Passed, zero skipped, and a valid TRX. Every generated fixture uses a unique short NuGet cache and compares all eight restored project.assets.json SHA-512 values with the staged nupkg bytes.

Immutable aligned package evidence remains at source b6c7cac92f7eeb788ae026471239ff110207bc24 under artifacts/validation/Microsoft.Testing.Platform.Browser/b6c7cac92-aligned/Shipping; the Browser nupkg SHA-256 is 2D078CB340E45A0E6C1CC5894BFF3148E29218683F36D5D038F24B3C78E67580.

At this body update, the two required browser jobs and all GitHub policy checks are green. The TestFX aggregate build 1632026 still has an unrelated Windows Release leg in progress; Windows Debug, Linux Release, Windows application-model acceptance, and both browser jobs have passed. The SDK aggregate 1632034 likewise still has unrelated platform legs in progress; both browser jobs have passed.

Remaining external release gates are official signing/publication approval, third-party license/SBOM/provenance review, dependency flow/merge of the matching SDK implementation, release-branch/backport decisions, runtime validation before advertising untested OS/architecture combinations, and an identified servicing owner for Playwright/Node/browser cadence. The package remains experimental and is emitted to Shipping only for acceptance/cross-repository validation.

Introduce an optional Microsoft.Testing.Platform.Browser package with Chromium/CDP launch supervision, secure SDK HTTP bootstrap injection, build-transitive browser assets, and focused unit and acceptance coverage.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 1c54e99e-de18-4bcd-a5c4-6163e4aeb78c
Bundle the private cross-platform Playwright runtime from clean builds, allow launcher runtime roll-forward, and make startup cancellation and teardown reliably close owned browser resources.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 1c54e99e-de18-4bcd-a5c4-6163e4aeb78c
Preserve framework-provided ComputeRunArguments host contracts, including quoted empty arguments, while keeping explicit browser host overrides. Replace raw page globals with the documented testingPlatformBrowser contract version 1 and launcher-private completion binding.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keep browser URLs on the validated loopback origin, use the invoking SDK muxer, avoid Playwright payload copies in unit tests, coordinate package-owned host assets, and secure the launch-info handoff with private per-run directories and handle-based validation.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Add a one-shot, origin-validated fatal-error method to the versioned browser page contract so framework bootstrap and completion negotiation failures terminate the launcher immediately instead of waiting for the completion timeout.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Support no-build packing, preserve doubled quotes and multiline launcher arguments, wrap late Directory.Build host providers, avoid false-positive custom host asset coverage, and clean generated launcher configuration files.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Activate wrapping only for SDK-marked dotnet test invocations with HTTP bootstrap contract version 1, reject browser-inapplicable file and report options, and cover ordinary run, filtered/skipped/failing execution, and multi-target activation.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Require SDK invocation IDs for per-evaluation launcher configs, clean legacy and invocation-specific files, and link post-launch cancellation into the completion race and cleanup path.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Comment thread src/Platform/Microsoft.Testing.Platform.Browser/ChromiumBrowser.cs Fixed
Comment thread src/Platform/Microsoft.Testing.Platform.Browser/HostProcess.cs Fixed
Comment thread src/Platform/Microsoft.Testing.Platform.Browser/HostProcess.cs Fixed
Comment thread src/Platform/Microsoft.Testing.Platform.Browser/HostProcess.cs Fixed
@microsoft-github-policy-service microsoft-github-policy-service Bot added the state/needs-review Awaiting review from the team. label Sep 15, 2026
@github-actions github-actions Bot removed the state/needs-review Awaiting review from the team. label Sep 15, 2026

Copilot AI 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.

Copilot review overview

🟡 Changes recommended

Browser crash and cleanup paths can hang, while MSBuild hook composition can bypass launcher integration.

Get a fresh assessment by requesting another Copilot review.

Review tier: Balanced
Findings: 1 High severity · 3 Medium severity

Open (4)
What changed in this PR

Adds an experimental browser-WASM launcher package that integrates MTP applications with dotnet test through Playwright and the SDK HTTP gateway.

Changes:

  • Adds browser launch, monitoring, diagnostics, security validation, and host assets.
  • Adds MSBuild activation, packaging, versioning, and solution registration.
  • Adds extensive unit and browser acceptance coverage.

A final security/lifecycle review is advisable because this introduces process-launch and token-injection boundaries.

File Description
TestFx.slnx Registers the browser project.
NonWindowsTests.slnf Adds non-Windows build coverage.
MutationTesting.slnx Adds the project to mutation builds.
Microsoft.Testing.Platform.slnf Adds the project to the MTP solution.
Directory.Build.props Defines independent browser package versioning.
Directory.Packages.props Centrally references Playwright.
Microsoft.Testing.Extensions.UnitTests.csproj Links browser helpers into unit tests.
BrowserLauncherOptionsTests.cs Tests parsing, security, cleanup, and platform behavior.
BrowserPackageExecutionTests.cs Adds package-level browser acceptance coverage.
Microsoft.Testing.Platform.Browser.csproj Defines launcher packaging and private runtime payload.
PACKAGE.md Documents setup, contracts, and limitations.
Program.cs Implements launcher orchestration.
BrowserExecutableLocator.cs Discovers Chromium-family executables.
BrowserLauncherOptions.cs Parses and validates launcher/bootstrap inputs.
BrowserRunMonitor.cs Monitors completion and process exits.
ChromiumBrowser.cs Manages Playwright and the browser-page API.
DiagnosticBuffer.cs Bounds and redacts diagnostics.
HostProcess.cs Starts and monitors the WASM host.
PlaywrightNodeExecutable.cs Locates and prepares Playwright’s Node runtime.
build/​Microsoft.Testing.Platform.Browser.props Forwards direct-consumer properties.
build/​Microsoft.Testing.Platform.Browser.targets Forwards direct-consumer targets.
buildTransitive/​Microsoft.Testing.Platform.Browser.props Forwards transitive properties.
buildTransitive/​Microsoft.Testing.Platform.Browser.targets Forwards transitive targets.
buildMultiTargeting/​Microsoft.Testing.Platform.Browser.props Defines launcher defaults and hook setup.
buildMultiTargeting/​Microsoft.Testing.Platform.Browser.targets Adds host assets and clean behavior.
Microsoft.Testing.Platform.Browser.After.targets Wraps computed browser host commands.
Microsoft.Testing.Platform.Browser.main.js Supervises managed browser execution.
index.html Provides the default browser host page.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/Platform/Microsoft.Testing.Platform.Browser/ChromiumBrowser.cs Outdated
Comment thread src/Platform/Microsoft.Testing.Platform.Browser/HostProcess.cs Outdated
@microsoft-github-policy-service microsoft-github-policy-service Bot added the state/needs-review Awaiting review from the team. label Sep 15, 2026
@github-actions github-actions Bot removed the state/needs-review Awaiting review from the team. label Sep 15, 2026
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

Use the WebAssembly SDK and package-owned static host assets for the primary browser acceptance model, document the generated managed entry point and direct MTP HTTP transport, and recognize WasmAppHost App url readiness without matching debug URLs.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 16, 2026 12:27

Copilot AI 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.

Copilot review overview

🟡 Changes recommended

The Unix launch-info directory has a cross-user trust-boundary flaw, and module-load failures can stall until the completion timeout.

Get a fresh assessment by requesting another Copilot review.

Review tier: Balanced
Findings: 2 High severity · 3 Medium severity

Open (5)
Previously missed (1)

In code that hasn't changed since last review

Medium severity Handle module-load failures before waiting for completion

src/​Platform/​Microsoft.Testing.Platform.Browser/​buildMultiTargeting/​assets/​Microsoft.Testing.Platform.Browser.main.js:4

A static module import is resolved before this supervisor body runs. If _framework/dotnet.js is missing or fails to load, neither complete nor reportFatalError is called, so the launcher waits for the full completion timeout (600 seconds by default) instead of reporting the bootstrap failure promptly. Load the module dynamically inside the guarded try and terminate through the versioned fatal-error API when bootstrap fails.

Comment thread src/Platform/Microsoft.Testing.Platform.Browser/HostProcess.cs Outdated
@microsoft-github-policy-service microsoft-github-policy-service Bot added the state/needs-review Awaiting review from the team. label Sep 16, 2026
@github-actions github-actions Bot removed the state/needs-review Awaiting review from the team. label Sep 16, 2026
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI 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.

Comment thread src/Platform/Microsoft.Testing.Platform.Browser/BrowserWorker.cs Outdated
Comment thread eng/browser-testing/sdk.json Outdated
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI 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.

🟡 Changes recommended

Missing internal API baselines and a POSIX parent-loss cleanup race must be resolved before approval.

10 open findings
Previously missed (1)

In code that hasn't changed since last review

Medium severity Prevent worker exit before fallback process-group cleanup

src/​Platform/​Microsoft.Testing.Platform.Browser/​WorkerParentMonitor.cs:15

Because this monitor is a background thread, the runtime may terminate it before the delayed process-group kill runs. On parent EOF, cancellation can make the worker's main path return in under ten seconds even when a host/browser cleanup operation failed and left descendants alive; once the last foreground thread exits, this sleeping monitor disappears and the POSIX group is never killed. Coordinate parent-loss cleanup with the worker lifecycle so the worker cannot exit until the fallback group kill has run (while preserving the normal supervisor/worker shutdown handshake).

🧠 Review effort: Balanced

Comment on lines +238 to +239
[Embedded]
internal static class FileArtifactTransferRequestFieldsId

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed in 4a728fc83. Added both field-ID types and all constants to the Platform, HangDump, Retry, TrxReport, and Extensions.MSBuild internal API baselines; the tracked projects rebuild cleanly.

Auto-replied by the GitHub Copilot app

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI 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.

🔵 Needs a closer look

Page closure can stall runs, signing exemptions are overly broad, and validation evidence does not match the currently pinned source pair.

10 open findings
Previously missed (1)

In code that hasn't changed since last review

Medium severity Treat page Close events as immediate run failures

src/​Platform/​Microsoft.Testing.Platform.Browser/​ChromiumBrowser.cs:295

A page can close while Chromium remains connected (for example, application code can call window.close()). BrowserRunMonitor observes only _completion, host exit, and browser disconnection, so that case waits for the full 600-second completion timeout instead of failing immediately. Treat the page Close event as a terminal failure just like Crash.

🧠 Review effort: Balanced

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI 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.

Comment thread eng/Signing.props Outdated
path,
FileMode.Open,
FileAccess.Read,
FileShare.None);
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI 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.

🔵 Needs a closer look

The cross-repository protocol and process-security changes require human review, and two correctness issues remain unresolved.

13 open findings
Previously missed (1)

In code that hasn't changed since last review

Medium severity Make diagnostic forwarding best-effort after transport failure

src/​Platform/​Microsoft.Testing.Platform/​ServerMode/​DotnetTest/​DotnetTestConnection.cs:849

If the artifact request failed because the HTTP transport disconnected, forwarding this diagnostic over the same client throws (typically “transport is not connected”) before CreateArtifactTransferExceptionAsync can return. That secondary failure replaces the useful artifact-path/root-cause exception. Treat display forwarding as best-effort here while still propagating caller cancellation.

🧠 Review effort: Balanced

Comment thread eng/verify-nupkgs.ps1 Outdated
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI 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.

Comment thread src/Platform/Microsoft.Testing.Platform.Browser/BrowserRunMonitor.cs Outdated
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI 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.

🔵 Needs a closer look

Artifact negotiation, exactly-once transfer behavior, protocol documentation, and current validation evidence remain unresolved.

14 open findings
Previously missed (4)

In code that hasn't changed since last review

Medium severity Require a positive peer file-count limit before artifact transfer

src/​Platform/​Microsoft.Testing.Platform/​ServerMode/​DotnetTest/​DotnetTestConnection.cs:253

Artifact transfer is enabled even when the peer omits its file-count limit, then the host invents a 10,000-file limit. That accepts a partially declared capability and can exceed the SDK's actual quota before failing mid-transfer. Require a positive FileArtifactTransferMaxFileCount alongside the other advertised limits.

Medium severity Prevent duplicate artifact transfers from concurrent notifications

src/​Platform/​Microsoft.Testing.Platform/​ServerMode/​DotnetTest/​DotnetTestConnection.cs:661

ConcurrentDictionary.GetOrAdd may run this async value factory more than once for the same path. Concurrent artifact notifications can therefore upload duplicate bytes, consume quota twice, and leave an orphan SDK artifact even though only one task is cached. Cache a Lazy<Task<string>> (or synchronize creation per path) so each path starts exactly one transfer.

Low severity Refresh validation evidence and CI status for the current pin

eng/​browser-testing/​sdk.json:3

The composed-validation pin has moved to df5a595…, while the PR description still claims validation against SDK 5b0e5fbe…, identifies b41d763f0 as the current TestFX head, and says final CI is green. The current PR head is 303a5d8c… and checks are still queued/in progress, so refresh the immutable evidence and CI statement after this exact pin/head completes validation.

Low severity Update protocol documentation for version 1.5 capabilities

src/​Platform/​Microsoft.Testing.Platform/​ServerMode/​DotnetTest/​IPC/​Constants.cs:233

Protocol 1.5 now implements HTTP reverse control and chunked artifact transfer, but the canonical docs/mstest-runner-protocol/004-protocol-dotnet-test-pipe.md still lists versions only through 1.4, documents serializer IDs only through 14, and calls browser reverse control future work. Update that protocol specification with the new capability keys, serializers, and fallback behavior in this PR.

🧠 Review effort: Balanced

Copilot AI 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.

🔵 Needs a closer look

Page-close handling, package completeness validation, signing scope, and stale validation claims remain unresolved.

14 open findings
Previously missed (2)

In code that hasn't changed since last review

Medium severity Fail completion promptly when the browser page closes

src/​Platform/​Microsoft.Testing.Platform.Browser/​ChromiumBrowser.cs:295

A page can close without crashing or disconnecting Chromium (for example, via window.close()). That leaves both browserCompletion and WaitForExitAsync pending, so the run reports only after the completion timeout (10 minutes by default) instead of failing immediately. Subscribe to IPage.Close and complete _completion exceptionally, just as the crash handler does.

Low severity Update validation evidence for the current commit pairing

eng/​browser-testing/​sdk.json:3

The validation evidence in the PR description is for SDK commit 5b0e5fbe3a and TestFx head b41d763f0, but this pin is now df5a595… and the current PR head is 303a5d8…; the current composed browser run was still in progress when reviewed. Update the description with evidence for this exact pairing before retaining the “Final CI is green” claim.

🧠 Review effort: Balanced

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI 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.

🔵 Needs a closer look

The cross-repository protocol and process-lifecycle changes require human review, and artifact caching plus current-head validation evidence remain unresolved.

14 open findings
Previously missed (1)

In code that hasn't changed since last review

Low severity Update validation claims to match the current source and CI state

eng/​browser-testing/​sdk.json:3

The PR body’s validation claim no longer matches this pin or the current source state: it says the current head is b41d763f0, the aligned SDK is 5b0e5fbe3a, and final CI is green, but the actual head is 580258bd5a7d..., this file now selects 6868a2467c1f..., and the current Windows/Linux composed checks (build 1631986) are still in progress. The historical b6c7cac92/5b0e5fbe3a evidence therefore does not validate the source and counterpart selected by this revision. Please update the body after the current composed run completes (including current TestFx/SDK SHAs and accessible evidence), or explicitly label the existing results as historical and current-head validation as pending.

🧠 Review effort: Balanced

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI 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.

Comment thread eng/browser-testing/sdk.json
@github-actions

This comment has been minimized.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
throw new InvalidOperationException("The browser package cache suffix must be relative.");
}

string path = System.IO.Path.Combine(basePath, suffix);

Copilot AI 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.

//
// 1.5.0 extends the existing control messages to authenticated HTTP through a capability-gated second client,
// and adds capability-gated chunked transfer for artifacts stored in a browser/WASI virtual filesystem.
internal const string SupportedVersions = "1.0.0;1.1.0;1.2.0;1.3.0;1.4.0;1.5.0";
@github-actions

Copy link
Copy Markdown
Contributor

Final test-triage resolution — Azure Pipelines build 1632474

Build 1632474 (PR #11305 merge) completed successfully (buildResult: succeeded). Out of 115,385 normalized test records (114,589 passed, 790 skipped), 6 failures were observed, all on the Windows Release leg, all from Windows App Model Diagnostics artifacts. No timeline signals, no diagnostic/crash artifacts, and no slow-test regressions were reported.

Root cause: not test-product defects. Every failure is a self-validating "probe" asset intentionally designed to fail on a first attempt and pass on retry, exercising the Retry/AppContainer-host extension itself:

Test Behavior Outcome
WinUIMtpPackagedApp.UnitTest1.RetryFailsFirstAttempt Deliberately fails attempt 1 via Assert.AreNotEqual keyed on TESTINGPLATFORM_DOTNETTEST_ATTEMPTNUMBER; comment states "This probe deliberately fails the first retry attempt and passes the next one." Failed → Passed (retry)
PackagedWinUI.PackagedWinUITestCases.RetryTestMethod_PassesOnSecondAppContainerHost Writes a marker file and calls Assert.Fail("The first AppContainer host fails so Retry must activate a second host.") on first run only Failed → Passed (retry)
NativeTests.Outcome (×4 occurrences, generated from a parameterized test-asset template in PackagedAppNativeDotnetTestTests.cs) Template computes fail = outcome == "Failed" || (outcome == "Retry" && !marker exists) and calls Assert.IsFalse(fail, "expected host failure") — these are intentional "host failure" simulation scenarios used to validate the native sidecar retry/outcome reporting path Each later passed on its corresponding retry attempt within the same run

All 6 "failures" have a matching passed retry record in the same build (same sourceFile/retry-directory lineage), confirming expected fail-then-pass design behavior rather than flakiness or regression. No stable product assertion failure, no deterministic race, and no platform-specific defect signature was found. diagnostics.json is empty and timeline.compact.json has no records, so there is no crash/hang or infrastructure signal to pursue.

Conclusion: No actionable test defect. No issue created — these are expected-by-design retry/host-failure test probes validating the MSTest/MTP Retry extension and native-sidecar outcome-reporting path, not genuine regressions.

🤖 Automated content by GitHub Copilot. Generated by the Pipeline Test Triage workflow. · copilot · auto · 49.3 AIC · ⌖ 11.2 AIC · ⊞ 9.9K

Sign up for free to 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.

2 participants