Add WebSocket transport for the dotnettestcli protocol (browser-wasm support) - #10118
Conversation
…support) Decouples the 'dotnet test' pipe protocol from System.IO.Pipes so it can bootstrap on runtimes without named-pipe support (browser-wasm), while keeping the existing '--server dotnettestcli --dotnet-test-pipe <name>' behavior and wire format byte-for-byte unchanged. Core transport refactor: - Widen NamedPipeConnectionBase.WriteMessageAsync/ReadNextMessageAsync from PipeStream to Stream; isolate WaitForPipeDrain behind an 'is PipeStream' check. - DotnetTestConnection now talks to an IClient (NamedPipeClient or DotnetTestWebSocketClient) instead of hard-coding NamedPipeClient, resolved via the new DotnetTestTransportKind/TryGetDotnetTestTransport. New WebSocket transport: - ClientWebSocketDuplexStream adapts System.Net.WebSockets.WebSocket to a Stream for non-browser runtimes. - BrowserWebSocketDuplexStream talks to the browser's native WebSocket via JSImport/JSExport (same pattern as BrowserOutputDevice), with a self-contained embedded JS module imported through a data: URL. - DotnetTestWebSocketClient implements IClient over either adapter, appending the per-run auth token as a query-string parameter (browsers can't set custom headers on the WebSocket handshake - same approach ASP.NET Core SignalR uses). CLI/validation: - New hidden options --dotnet-test-transport, --dotnet-test-websocket-endpoint, --dotnet-test-websocket-token. - PlatformCommandLineProvider rejects conflicting/incomplete transport option combinations and the named-pipe transport on browser-wasm/wasi-wasm early, with actionable messages. Protocol: - Additive handshake property Transport (id 16, NamedPipe/WebSocket) for diagnostics; ProtocolConstants.SupportedVersions bumped to 1.5.0. - docs/mstest-runner-protocol/004-protocol-dotnet-test-pipe.md updated to describe the transport-neutral protocol and the new WebSocket transport (§15). Known gaps documented in §15.6: the reverse server-control channel stays named-pipe-only (disabled on browser/wasi), wasi-wasm has no transport yet, and stdio multiplexing was deliberately not attempted. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 282499c0-c68f-41eb-890a-ad47bb78ce54
- BrowserWebSocketDuplexStream: honor cancellationToken during reads via a new WaitForReceiveAsync helper that races the JS receive() promise against the token, so a cancelled request/timeout no longer hangs forever on browser-wasm. - ClientWebSocketDuplexStream: fix a zero-length-message EOF bug (a legitimate empty, non-Close WebSocket message was misreported as end-of-stream), and convert the retry from recursion to a loop to avoid a potential StackOverflowException against a peer sending many consecutive empty messages. - DotnetTestWebSocketClient.RequestReplyAsync: catch transport exceptions from ReadNextMessageAsync (previously only the write path was guarded), since an abrupt WebSocket disconnect surfaces as a thrown exception rather than a clean 0-byte EOF the way a named pipe does. Factored the shared connection-loss handling (exit-process vs. throw) into HandleMissingResponseAsync. - Added tests: large-message round-trip spanning multiple WebSocket receives, server-closes-without-responding (verifies IOException + no process exit when exitProcessOnConnectionLoss is false), and cancellation of a pending RequestReplyAsync (verifies OperationCanceledException instead of a hang). Found via 3 rounds of code review (2 code-review passes + 1 rubber-duck pass); all reported findings fixed and re-verified. Full solution build and the Microsoft.Testing.Platform.UnitTests / DotnetTestProtocolContract.UnitTests suites pass (1459 + 24 tests). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 282499c0-c68f-41eb-890a-ad47bb78ce54
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Pull request overview
Adds WebSocket transport support for the dotnettestcli protocol, primarily enabling browser-wasm while retaining named-pipe compatibility.
Changes:
- Adds browser and non-browser WebSocket stream adapters.
- Adds transport selection, validation, authentication, and handshake metadata.
- Updates protocol documentation, resources, API baselines, and tests.
Show a summary per file
| File | Description |
|---|---|
test/UnitTests/Microsoft.Testing.Platform.UnitTests/IPC/ProtocolTests.cs |
Updates protocol-version expectation. |
test/UnitTests/Microsoft.Testing.Platform.UnitTests/IPC/DotnetTestWebSocketClientTests.cs |
Adds non-browser WebSocket transport tests. |
test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/PlatformCommandLineProviderTests.cs |
Tests transport-option validation. |
test/UnitTests/Microsoft.Testing.Platform.DotnetTestProtocolContract.UnitTests/DotnetTestProtocolContractTests.cs |
Pins transport contract constants. |
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoTests.cs |
Updates core help expectations. |
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoAllExtensionsTests.cs |
Updates extended help expectations. |
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DotnetTestPipe/DotnetTestPipeBaselineTests.cs |
Updates named-pipe protocol baseline. |
src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/Transport/DotnetTestWebSocketClient.cs |
Implements the WebSocket protocol client. |
src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/Transport/ClientWebSocketDuplexStream.cs |
Adapts .NET WebSockets to Stream. |
src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/Transport/BrowserWebSocketDuplexStream.cs |
Adds browser JavaScript WebSocket interop. |
src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/DotnetTestDataConsumer.cs |
Enables browser use of the consumer. |
src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Constants.cs |
Adds transport constants and protocol 1.5. |
src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/DotnetTestHelper.cs |
Resolves the selected transport. |
src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/DotnetTestConnection.cs |
Dispatches protocol traffic by transport. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf |
Adds localized resource entries. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf |
Adds localized resource entries. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf |
Adds localized resource entries. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf |
Adds localized resource entries. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf |
Adds localized resource entries. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf |
Adds localized resource entries. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf |
Adds localized resource entries. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf |
Adds localized resource entries. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf |
Adds localized resource entries. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf |
Adds localized resource entries. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf |
Adds localized resource entries. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf |
Adds localized resource entries. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf |
Adds localized resource entries. |
src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx |
Defines transport messages and descriptions. |
src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.cs |
Exposes validation resources to tests. |
src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeConnectionBase.cs |
Generalizes framing from pipes to streams. |
src/Platform/Microsoft.Testing.Platform/InternalAPI/InternalAPI.Unshipped.txt |
Records new internal APIs. |
src/Platform/Microsoft.Testing.Platform/InternalAPI/InternalAPI.Shipped.txt |
Removes prior framing signatures. |
src/Platform/Microsoft.Testing.Platform/CommandLine/PlatformCommandLineProvider.cs |
Adds transport CLI options and validation. |
src/Platform/Microsoft.Testing.Extensions.TrxReport/InternalAPI/InternalAPI.Unshipped.txt |
Records generalized framing APIs. |
src/Platform/Microsoft.Testing.Extensions.TrxReport/InternalAPI/InternalAPI.Shipped.txt |
Removes prior framing signatures. |
src/Platform/Microsoft.Testing.Extensions.Retry/InternalAPI/InternalAPI.Unshipped.txt |
Records generalized framing APIs. |
src/Platform/Microsoft.Testing.Extensions.Retry/InternalAPI/InternalAPI.Shipped.txt |
Removes prior framing signatures. |
src/Platform/Microsoft.Testing.Extensions.MSBuild/InternalAPI.Unshipped.txt |
Records generalized framing APIs. |
src/Platform/Microsoft.Testing.Extensions.MSBuild/InternalAPI.Shipped.txt |
Removes prior framing signatures. |
src/Platform/Microsoft.Testing.Extensions.HangDump/InternalAPI/InternalAPI.Unshipped.txt |
Records generalized framing APIs. |
src/Platform/Microsoft.Testing.Extensions.HangDump/InternalAPI/InternalAPI.Shipped.txt |
Removes prior framing signatures. |
docs/mstest-runner-protocol/004-protocol-dotnet-test-pipe.md |
Documents transport-neutral framing and WebSockets. |
Review details
- Files reviewed: 42/42 changed files
- Comments generated: 10
- Review effort level: Medium
…write cancellation Addresses 3 findings from an independent review of commit 6472e52: 1. Secret leak (High): TestApplication.LogInformationAsync logged the raw --diagnostic command-line arguments verbatim, including the value following --dotnet-test-websocket-token, contradicting protocol doc SS15.4. Added CommandLineArgumentsRedactor, a reusable formatter that masks the token value in both space-separated and --option=value/--option:value inline forms (handling a missing value and a repeated option), while preserving every other argument exactly. Wired into the one call site that logs command-line arguments. New CommandLineArgumentsRedactorTests proves the token is absent and the placeholder is present across all these shapes. 2. Empty final message treated as EOF (Medium/High): already fixed by the prior "Address code review findings" commit (ClientWebSocketDuplexStream now loops on any zero-length non-Close result, not just non-final fragments) - re-verified, no further change needed here. 3. Browser cancellation (High): BrowserWebSocketDuplexStream.ReadAsync already honored CancellationToken (added in the prior commit); WriteAsync did not. Since WebSocket.send() in the JS module is synchronous (queues the frame and returns immediately), there is no in-flight operation to race - added an upfront ThrowIfCancellationRequested() so an already-cancelled token is still observed before doing the uncancellable-once-issued send. Also closed a message-loss gap in the existing read-cancellation path: on cancellation, the abandoned JS receive() promise is now explicitly cleared via a new cancelReceive JS function, so a message the peer sends afterward is queued for the next receive() call instead of silently resolving (and being discarded by) the stale, abandoned one. Verified via `dotnet build` (net8.0/net9.0) and `dotnet publish -r browser-wasm` (via samples/BrowserPlayground) that the JS interop signatures remain valid for the wasm JS-interop source generator; true behavioral testing of the JS cancellation path requires the SDK-side WebSocket gateway (not part of this repo) to drive it end-to-end under a real browser/node runtime, so this residual gap is now documented precisely in doc SS15.6 rather than silently left unstated. Also updated docs/mstest-runner-protocol/004-protocol-dotnet-test-pipe.md: - SS15.3: added a CSP caveat - the data: URL dynamic import requires the page's Content-Security-Policy to permit it; the prior "no additional assets" claim was correct but incomplete under a strict script-src. - SS15.4: documented that the diagnostic log redaction now also covers the raw --dotnet-test-websocket-token command-line argument, not just the connection URI. - SS15.6: documented the exact residual testing gap for the browser JS cancellation path. Full solution build (.\build.cmd -c Debug) green. Microsoft.Testing.Platform.UnitTests: 1469 tests passing (was 1459; +10 new CommandLineArgumentsRedactorTests). dotnet publish -r browser-wasm (samples/BrowserPlayground) succeeds, confirming the browser JS-interop signatures compile/link correctly for browser-wasm. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 282499c0-c68f-41eb-890a-ad47bb78ce54
There was a problem hiding this comment.
Review details
Comments suppressed due to low confidence (2)
src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/Transport/BrowserWebSocketDuplexStream.cs:172
- The browser connection attempt does not observe
cancellationToken: after the module import completes,OpenAsynchas no token and can remain pending until the browser's network timeout. This can hang startup/shutdown indefinitely for an unreachable endpoint, unlike the non-browserClientWebSocket.ConnectAsyncpath. Please make the JS open operation abortable (closing the connecting socket on cancellation) and propagateOperationCanceledException.
src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/Transport/BrowserWebSocketDuplexStream.cs:37 - This new NET-only internal type and its accessible members are missing from
InternalAPI/net/InternalAPI.Unshipped.txt. The project includes that baseline for non-netstandard targets (Microsoft.Testing.Platform.csproj:90-91), and existing browser-only internals are tracked there (for exampleBrowserOutputDeviceinInternalAPI/net/InternalAPI.Shipped.txt:16-17), so RS0016 will fail those builds.
- Files reviewed: 45/45 changed files
- Comments generated: 2
- Review effort level: Medium
This comment has been minimized.
This comment has been minimized.
Adds ReadAsync_WhenServerSendsEmptyBinaryMessageBeforeReply_IgnoresItInsteadOfTreatingAsEof to DotnetTestWebSocketClientTests, which drives a loopback server that injects a genuine zero-length, non-Close binary WebSocket frame immediately before the real protocol reply frame. Asserts the client still receives the correct reply instead of treating the empty message as EOF/disconnect, locking in the ClientWebSocketDuplexStream.ReadAsync fix from f49d7e6 and 554fb6b as a regression test requested by the final independent-review verifier. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 282499c0-c68f-41eb-890a-ad47bb78ce54
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Review details
Comments suppressed due to low confidence (4)
src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/Transport/BrowserWebSocketDuplexStream.cs:37
- This framework-specific internal type is compiled for the
nettargets, but none of its type or override signatures are listed inInternalAPI/net/InternalAPI.Unshipped.txt. This project explicitly includes that API baseline for non-netstandard targets (Microsoft.Testing.Platform.csproj:90-91), and the analogousBrowserOutputDeviceis tracked inInternalAPI/net/InternalAPI.Shipped.txt:16-17; therefore RS0016 will fail under warnings-as-errors. Add all trackedBrowserWebSocketDuplexStreammembers to the net-specific unshipped file.
src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/Transport/BrowserWebSocketDuplexStream.cs:172 - The cancellation token is no longer observed once
OpenAsyncstarts. If the browser WebSocket handshake stalls,IClient.ConnectAsyncand platform startup can remain pending after shutdown cancellation. Make the JS-side open operation cancellable, or race it against the token and ensure any socket that opens after cancellation is closed.
src/Platform/Microsoft.Testing.Platform/CommandLine/PlatformCommandLineProvider.cs:278 - The endpoint is only checked for option presence, so values such as
not-a-uri,https://..., or an empty string pass validation and later fail inCreateWebSocketClient/ClientWebSocket.ConnectAsyncwith an unhandled URI or scheme exception. Validate that the argument is an absolutews://orwss://URI here so this CLI surface fails early with an actionable message.
bool hasTransportOption = commandLineOptions.TryGetOptionArgumentList(DotNetTestTransportOptionKey, out string[]? transportArgs)
&& transportArgs is { Length: 1 };
bool isWebSocketTransport = hasTransportOption && DotNetTestTransportWebSocketArgument.Equals(transportArgs![0], StringComparison.OrdinalIgnoreCase);
bool hasEndpoint = commandLineOptions.IsOptionSet(DotNetTestWebSocketEndpointOptionKey);
bool hasToken = commandLineOptions.IsOptionSet(DotNetTestWebSocketTokenOptionKey);
src/Platform/Microsoft.Testing.Platform/CommandLine/PlatformCommandLineProvider.cs:300
- This fallback error still says
--dotnet-test-pipeis required, but the command now also supports WebSocket and on browser-wasm the suggested pipe option is explicitly unsupported. Report that either a pipe name or the complete WebSocket option set is required; otherwise the new valid transport is omitted and browser users are directed toward an impossible configuration.
// 3. Nothing selects a transport at all (covers: no options given, or --dotnet-test-transport pipe
// given explicitly without the required --dotnet-test-pipe name).
if (!hasPipe && !isWebSocketTransport)
{
return ValidationResult.InvalidTask(string.Format(CultureInfo.InvariantCulture, PlatformResources.PlatformCommandLineDotnetTestCliRequiresPipe, DotnetTestCliProtocolName, DotNetTestPipeOptionKey));
}
- Files reviewed: 45/45 changed files
- Comments generated: 8
- Review effort level: Medium
Harden the browser transport cancellation and close paths, validate WebSocket bootstrap inputs, restore immutable internal API baselines, and add browser-wasm protocol/cancellation coverage plus handshake assertions. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 282499c0-c68f-41eb-890a-ad47bb78ce54
This comment has been minimized.
This comment has been minimized.
Redact option-shaped token values, release browser JS proxies on disposal, and atomically arbitrate receive cancellation against message delivery. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 282499c0-c68f-41eb-890a-ad47bb78ce54
This comment has been minimized.
This comment has been minimized.
Keep expanded response-file arguments as the sensitivity context while preserving the original displayed command line, and handle empty sensitive values without throwing. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 282499c0-c68f-41eb-890a-ad47bb78ce54
This comment has been minimized.
This comment has been minimized.
Avoid replacing whitespace-only sensitive values in error text and accurately describe browser WebSocket interop as import-only. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 282499c0-c68f-41eb-890a-ad47bb78ce54
This comment has been minimized.
This comment has been minimized.
Match parser trimming when sanitizing validation diagnostics and correct the protocol documentation to describe import-only browser interop. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 282499c0-c68f-41eb-890a-ad47bb78ce54
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Review details
Comments suppressed due to low confidence (1)
src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineArgumentsRedactor.cs:61
string.Replacetreats the raw argument as an unrestricted substring, so short invalid endpoint/token values corrupt unrelated validation text. For example, an endpoint value ofareplaces everyain the “requires an absolute…” diagnostic with the redaction marker. Redaction should target only the exact argument occurrence emitted by the parser/validator (ideally before formatting), rather than globally replacing arbitrary substrings in the completed message.
error = error.Replace(original, RedactedPlaceholder);
- Files reviewed: 48/48 changed files
- Comments generated: 0 new
- Review effort level: Medium
Avoid unrestricted short-value substring replacement while preserving malformed quoted-token sanitization. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 282499c0-c68f-41eb-890a-ad47bb78ce54
🧪 Test quality grade — PR #10118
This advisory comment was generated automatically. Grades are heuristic Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
network:
allowed:
- defaults
- "awmgmcpg"See Network Configuration for more information.
|
Summary
Decouples the
dotnet testpipe protocol (a.k.a.dotnettestcli) fromSystem.IO.Pipesso it can also bootstrap over a WebSocket transport — needed for runtimes without named-pipe support (browser-wasm) — while keeping the existing--server dotnettestcli --dotnet-test-pipe <name>behavior and framing/serializer contract unchanged.Protocol and transport are decoupled:
DotnetTestConnectionnow depends on a smallIClientabstraction (implemented identically in shape byNamedPipeClientand the newDotnetTestWebSocketClient), and the shared framing inNamedPipeConnectionBaseoperates on a plainStreaminstead ofPipeStreamspecifically.What's new
NamedPipeConnectionBase.WriteMessageAsync/ReadNextMessageAsyncwidened fromPipeStreamtoStream(pipe-drain behavior isolated behind anis PipeStreamcheck, so named-pipe behavior is unaffected).ServerMode/DotnetTest/Transport/):DotnetTestWebSocketClient—IClientimplementation, handles connect/auth/request-reply.ClientWebSocketDuplexStream— adaptsSystem.Net.WebSockets.WebSocketto aStreamon non-browser runtimes.BrowserWebSocketDuplexStream— talks to the host's nativeWebSocketvia[JSImport]/[JSExport]JS interop. Real browsers supplyWebSocketdirectly; Node 20 hosts use its built-in implementation via--experimental-websocket, with no npm dependency.--dotnet-test-transport {pipe|websocket},--dotnet-test-websocket-endpoint,--dotnet-test-websocket-token, with validation that rejects conflicting/incomplete option combinations, malformed/non-WebSocket endpoints, empty tokens, and the named-pipe transport onbrowser-wasm/wasi-wasmearly with actionable errors.Transportproperty (id 16,NamedPipe/WebSocket) for diagnostics;ProtocolConstants.SupportedVersionsbumped to1.5.0. Framing and serializer formats are unchanged; older peers ignore the additive property.docs/mstest-runner-protocol/004-protocol-dotnet-test-pipe.mdupdated — the intro now states protocol vs. transport, and §15 documents the WebSocket transport, its security model, validation, Node/browser bootstrap, target-runtime coverage, and known gaps.Known gaps (documented in doc §15.6, not silently degraded)
wasi-wasmhas no transport implemented yet (noClientWebSocket, no JS host to interop with) — command-line validation rejects it outright with an actionable error.Review process
This PR went through multiple automated and independent review rounds. Findings fixed include browser connect/read/write cancellation, legal zero-length WebSocket messages, abrupt connection loss, diagnostic token/endpoint redaction, CLI endpoint/token validation, immutable InternalAPI baseline tracking, transport handshake assertions, and browser-wasm target-runtime coverage.
The latest CI follow-up fixed Node 20 hosting: Node 20.20 does not expose
WebSocketglobally unless launched with--experimental-websocket. The browser-wasm WebSocket acceptance bootstrap now passes that built-in runtime flag rather than adding an external npm polyfill. Real-browser bootstrap is unchanged.Testing
.\build.cmd -pack -bl) green.Microsoft.Testing.Platform.UnitTests: 1485 tests passing.Microsoft.Testing.Platform.DotnetTestProtocolContract.UnitTests: 24 tests passing (protocol contract unaffected).DotnetTestPipeacceptance tests: 19 passing (named-pipe transport behavior unaffected).HelpInfoTests/HelpInfoAllExtensionsTests: 30 passing (new CLI options reflected correctly).MSTestDotnetTestCliTests: 6 passing.DotnetTestWebSocketClientTests: real loopback WebSocket round-trip, auth URI, large-message, connection-loss, cancellation, and zero-length-message-before-reply coverage.CommandLineArgumentsRedactorTests: token and endpoint sanitization, missing values, repeated options, option-shaped secrets, and inline forms.Follow-up work (out of scope, not part of this repo)
The SDK-side loopback WebSocket gateway/listener (accepting the outbound connection, validating the token, speaking the existing binary frame format) needs to be implemented in
dotnet/sdk. When launching abrowser-wasmbundle under Node 20, the SDK must pass--experimental-websocketto Node. Vendoring the updatedConstants.cs/ObjectFieldIds.csthere is optional since the newTransporthandshake property is additive/ignorable.Co-authored-by: Copilot App 223556219+Copilot@users.noreply.github.com
Copilot-Session: 282499c0-c68f-41eb-890a-ad47bb78ce54