Add tracked browser logs and network capture#16310
Conversation
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 16310Or
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 16310" |
Add a child browser logs resource that can launch tracked Chromium sessions, stream console and network request events, and expose the builder through polyglot export.\n\nCo-authored-by: Copilot <[email protected]>
5c31105 to
eab2c02
Compare
Add typed CDP protocol parsing, preserve connection failure reasons in resource logs, and strengthen reconnect handling for tracked browser sessions. Co-authored-by: Copilot <[email protected]>
mitchdenny
left a comment
There was a problem hiding this comment.
5 issues found (1 security, 2 bugs, 1 race condition, 1 formatting).
Fix indentation of <remarks> block in BrowserLogsBuilderExtensions.cs to match surrounding XML doc tags. Thread TimeProvider through RunningSession and its factory so timeout calculations in WaitForBrowserEndpointAsync and TryReconnectAsync use the injected provider instead of TimeProvider.System/DateTime.UtcNow. Co-authored-by: Copilot <[email protected]>
Extract the running-session lifecycle, CDP websocket transport, and event/diagnostic logging into focused files so the browser connection layers can be tested in isolation. Also add targeted comments describing the browser and CDP quirks these layers handle. Co-authored-by: Copilot <[email protected]>
Remove the global certificate-bypass flag from tracked browser launches and make session-manager disposal wait for completion observers without publishing shutdown updates through torn-down services. Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
There was a problem hiding this comment.
Pull request overview
Adds a new Aspire.Hosting capability (WithBrowserLogs(...)) that attaches a *-browser-logs child resource to endpoint-capable resources. The child resource can launch and track Chromium-based browser sessions (CDP), streaming console/errors/exceptions and network lifecycle activity into the dashboard logs, and surfaces live “Browser sessions” metadata/properties for downstream tooling.
Changes:
- Introduces browser log resources, session orchestration, CDP websocket transport, protocol parsing, and event-to-log projection in
src/Aspire.Hosting. - Adds unit tests for resource wiring/config refresh, diagnostics logging, protocol parsing, target selection, session lifecycle, and network log formatting.
- Updates polyglot AppHost/codegen snapshots + capability scanning, and adds localized command strings + a playground demo to validate the end-to-end experience.
Show a summary per file
| File | Description |
|---|---|
| tests/Aspire.Hosting.Tests/BrowserLogsSessionManagerTests.cs | Adds tests for endpoint parsing, user-data-dir resolution, target selection, and diagnostics log formatting. |
| tests/Aspire.Hosting.Tests/BrowserLogsProtocolTests.cs | Adds focused protocol parsing tests for events and command error reporting. |
| tests/Aspire.Hosting.Tests/BrowserLogsBuilderExtensionsTests.cs | Adds extensive tests for resource wiring, config precedence/refresh, session tracking, and network log projection. |
| tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.ts | Updates generated TS SDK snapshot to include withBrowserLogs(...) capability and options. |
| tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/HostingContainerResourceCapabilities.verified.txt | Updates capability list snapshot to include Aspire.Hosting/withBrowserLogs. |
| tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs | Adds ATS scanner test validating the new capability signature. |
| tests/Aspire.Hosting.CodeGeneration.Rust.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.rs | Updates generated Rust SDK snapshot to include with_browser_logs(...). |
| tests/Aspire.Hosting.CodeGeneration.Python.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.py | Updates generated Python SDK snapshot to include with_browser_logs(...) and kwargs support. |
| tests/Aspire.Hosting.CodeGeneration.Java.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.java | Updates generated Java SDK snapshot to include withBrowserLogs(...) and options DTO. |
| tests/Aspire.Hosting.CodeGeneration.Go.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.go | Updates generated Go SDK snapshot to include WithBrowserLogs(...). |
| src/Aspire.Hosting/Resources/xlf/CommandStrings.zh-Hant.xlf | Adds localization entries for the “Open tracked browser” command. |
| src/Aspire.Hosting/Resources/xlf/CommandStrings.zh-Hans.xlf | Adds localization entries for the “Open tracked browser” command. |
| src/Aspire.Hosting/Resources/xlf/CommandStrings.tr.xlf | Adds localization entries for the “Open tracked browser” command. |
| src/Aspire.Hosting/Resources/xlf/CommandStrings.ru.xlf | Adds localization entries for the “Open tracked browser” command. |
| src/Aspire.Hosting/Resources/xlf/CommandStrings.pt-BR.xlf | Adds localization entries for the “Open tracked browser” command. |
| src/Aspire.Hosting/Resources/xlf/CommandStrings.pl.xlf | Adds localization entries for the “Open tracked browser” command. |
| src/Aspire.Hosting/Resources/xlf/CommandStrings.ko.xlf | Adds localization entries for the “Open tracked browser” command. |
| src/Aspire.Hosting/Resources/xlf/CommandStrings.ja.xlf | Adds localization entries for the “Open tracked browser” command. |
| src/Aspire.Hosting/Resources/xlf/CommandStrings.it.xlf | Adds localization entries for the “Open tracked browser” command. |
| src/Aspire.Hosting/Resources/xlf/CommandStrings.fr.xlf | Adds localization entries for the “Open tracked browser” command. |
| src/Aspire.Hosting/Resources/xlf/CommandStrings.es.xlf | Adds localization entries for the “Open tracked browser” command. |
| src/Aspire.Hosting/Resources/xlf/CommandStrings.de.xlf | Adds localization entries for the “Open tracked browser” command. |
| src/Aspire.Hosting/Resources/xlf/CommandStrings.cs.xlf | Adds localization entries for the “Open tracked browser” command. |
| src/Aspire.Hosting/Resources/CommandStrings.resx | Adds the new command name/description resources. |
| src/Aspire.Hosting/Resources/CommandStrings.Designer.cs | Regenerates designer accessors for new resource strings. |
| src/Aspire.Hosting/IBrowserLogsSessionManager.cs | Introduces internal session manager abstraction used by the command handler. |
| src/Aspire.Hosting/BrowserLogsSessionManager.cs | Implements session orchestration + dashboard property/health projection for tracked sessions. |
| src/Aspire.Hosting/BrowserLogsRunningSession.cs | Implements per-browser lifecycle: launch, endpoint discovery, CDP connect/attach, reconnect, cleanup. |
| src/Aspire.Hosting/BrowserLogsResource.cs | Adds internal child resource model + config re-resolution for launch-time refresh. |
| src/Aspire.Hosting/BrowserLogsProtocol.cs | Adds CDP frame parsing/serialization + typed envelopes for key CDP domains. |
| src/Aspire.Hosting/BrowserLogsEventLogger.cs | Projects CDP events into consistent dashboard log lines + connection diagnostics. |
| src/Aspire.Hosting/BrowserLogsDevToolsConnection.cs | Adds CDP websocket transport, command/response correlation, and receive loop. |
| src/Aspire.Hosting/BrowserLogsBuilderExtensions.cs | Adds the public WithBrowserLogs(...) API and the dashboard command wiring/config resolution. |
| playground/BrowserTelemetry/BrowserTelemetry.Web/Scripts/index.js | Expands sample UI logic to emit console, exception, and network activity for validation. |
| playground/BrowserTelemetry/BrowserTelemetry.Web/Pages/Index.cshtml | Updates sample page UI with buttons/status area for browser logging demo. |
| playground/BrowserTelemetry/BrowserTelemetry.AppHost/BrowserTelemetry.AppHost.csproj | Adds UserSecretsId to support configuration overrides in the playground. |
| playground/BrowserTelemetry/BrowserTelemetry.AppHost/AppHost.cs | Enables browser logs in the playground by calling .WithBrowserLogs(). |
Copilot's findings
Files not reviewed (1)
- src/Aspire.Hosting/Resources/CommandStrings.Designer.cs: Language not supported
- Files reviewed: 36/37 changed files
- Comments generated: 3
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
JamesNK
left a comment
There was a problem hiding this comment.
Reviewed the new tracked browser logs feature. Found 4 issues:
- 2 bugs: missing early-exit detection during endpoint polling + stale
DevToolsActivePortfile with persistent profiles - 1 resource leak: no disposal guard in
StartSessionAsyncallows post-dispose browser process leaks - 1 hang risk: unbounded
CloseAsyncinChromeDevToolsConnection.DisposeAsynccan block shutdown indefinitely
Co-authored-by: Copilot <[email protected]>
JamesNK
left a comment
There was a problem hiding this comment.
Thorough review of the new browser logs feature. Very well-structured code with clean separation of concerns across the CDP transport, protocol parsing, event logging, session lifecycle, and resource state management. One resource leak issue flagged (1 bug).
Co-authored-by: Copilot <[email protected]>
|
🎬 CLI E2E Test Recordings — 72 recordings uploaded (commit View recordings
📹 Recordings uploaded automatically from CI run #24783280098 |
…t routing Code-review feedback from gpt-5.4, gpt-5.3-codex, and claude-opus-4.7 on the Phase 2 foundation commits, plus a mechanical pass applying the same lens James used on the original feature PR (#16310). BrowserHostIdentity changes: - Removed ProfileDirectory from the identity. Chromium's singleton is keyed by user-data-dir, not by profile, so different profiles under the same user data root share a browser process. Profile selection is per-target, not per-host. The previous doc comment claiming otherwise was wrong. - Replaced record-struct synthesized equality (which is ordinal case-sensitive on strings) with explicit Equals/GetHashCode using StringComparer.OrdinalIgnoreCase on Windows / Ordinal elsewhere. Without this, paths that differ only in casing would create duplicate hosts on Windows. - Constructor now normalizes paths via Path.GetFullPath + TrimEndingDirectorySeparator so 'C:/foo' and 'C:\foo\' collapse to the same identity. - GetHashCode is null-safe against default(BrowserHostIdentity) since StringComparer.GetHashCode(null) throws. Protocol changes: - Documented above the new Target.* event records that the SUBJECT of these events lives in params (targetId / params.sessionId), not the envelope sessionId. The existing dispatch in BrowserLogsRunningSession filters on envelope sessionId only, so any future fanout layer that naively reuses that filter would silently drop these events. The comment makes the routing requirement unmissable. Co-authored-by: Copilot <[email protected]>
* Add BrowserUserDataMode to separate user data dir from profile Introduce a BrowserUserDataMode enum (Shared/Isolated) on the tracked browser launch path so callers can choose between launching against the browser's real user data directory (like clicking the browser icon) or a temporary, isolated user data directory. - WithBrowserLogs(...) gains a userDataMode parameter - Configuration key: Aspire:Hosting:BrowserLogs[:Resource]:UserDataMode - Default is Isolated to preserve current behavior - Setting Profile while UserDataMode is Isolated is rejected - Shared + omitted profile lets Chromium pick its default profile - Shared + profile resolves the profile inside the real user data dir - Surface effective user data mode as a resource property Co-authored-by: Copilot <[email protected]> * Make Shared the default user data mode and document singleton caveat - Flip BrowserUserDataMode default from Isolated to Shared so the tracked browser behaves like a normal browser launch by default. - Add a remarks section on BrowserUserDataMode.Shared explaining the Chromium singleton/SingletonLock + DevToolsActivePort interaction so callers understand why a second launch against an already-running real browser cannot establish a CDP endpoint. - Update the default-mode test accordingly. Co-authored-by: Copilot <[email protected]> * Add Target lifecycle and Inspector.detached protocol parsing Adds parsing for CDP events used to detect when a tracked target ends: - Target.targetDestroyed - Target.targetCrashed - Target.detachedFromTarget - Inspector.detached Also adds command-name constants (Target.closeTarget, Target.setDiscoverTargets) that the upcoming host abstraction will use to manage tracked targets without calling Browser.close. This is purely additive; nothing wires these events up yet. Co-authored-by: Copilot <[email protected]> * Add IBrowserHost abstraction with ownership distinction Defines the IBrowserHost interface plus BrowserHostIdentity and the BrowserHostOwnership enum. The interface separates 'a browser instance to attach CDP to' from 'a tracked log session' so the same host can back many sessions and so disposal can do the right thing for adopted browsers. Key invariants documented in the file: - Adopted hosts must never close the user's browser - Profile directory participates in identity (different profiles = different process) - Acquire/ReleaseAsync refcount, last release disposes - Completion task surfaces process exit / CDP socket close so sessions can fail fast No callers yet; this commit only adds the contract. Co-authored-by: Copilot <[email protected]> * Apply review feedback to BrowserHostIdentity and document Target event routing Code-review feedback from gpt-5.4, gpt-5.3-codex, and claude-opus-4.7 on the Phase 2 foundation commits, plus a mechanical pass applying the same lens James used on the original feature PR (#16310). BrowserHostIdentity changes: - Removed ProfileDirectory from the identity. Chromium's singleton is keyed by user-data-dir, not by profile, so different profiles under the same user data root share a browser process. Profile selection is per-target, not per-host. The previous doc comment claiming otherwise was wrong. - Replaced record-struct synthesized equality (which is ordinal case-sensitive on strings) with explicit Equals/GetHashCode using StringComparer.OrdinalIgnoreCase on Windows / Ordinal elsewhere. Without this, paths that differ only in casing would create duplicate hosts on Windows. - Constructor now normalizes paths via Path.GetFullPath + TrimEndingDirectorySeparator so 'C:/foo' and 'C:\foo\' collapse to the same identity. - GetHashCode is null-safe against default(BrowserHostIdentity) since StringComparer.GetHashCode(null) throws. Protocol changes: - Documented above the new Target.* event records that the SUBJECT of these events lives in params (targetId / params.sessionId), not the envelope sessionId. The existing dispatch in BrowserLogsRunningSession filters on envelope sessionId only, so any future fanout layer that naively reuses that filter would silently drop these events. The comment makes the routing requirement unmissable. Co-authored-by: Copilot <[email protected]> * Harden browser logs foundation for shared browser adoption Apply the reliability fixes identified from the architecture review before continuing the larger adoption refactor: - Bound ChromeDevToolsConnection.DisposeAsync websocket close with a 3 second timeout so shutdown cannot hang indefinitely on a wedged browser. - Add Target.closeTarget and Target.setDiscoverTargets helpers and enable target discovery after each browser-CDP connection, including reconnects. - Add explicit Target lifecycle correlation helpers so future fanout routes targetDestroyed/targetCrashed by targetId and detachedFromTarget by params.sessionId instead of the usually-null envelope sessionId. - Make shared-mode default browser selection prefer Edge. Isolated mode keeps Chrome-first behavior. This avoids Chrome's default-profile remote-debugging guardrail for the default Shared experience. - Fail fast when Shared mode explicitly targets Google Chrome's default user data directory, with guidance to use Edge or Isolated mode. - Reshape the browser host contract around leases and target-session creation rather than public Acquire/Release refcount methods. This keeps exactly-once release and target ownership in the abstraction that will support adopted browsers. Adds targeted tests for the mode-aware default browser choice, browser host identity normalization/default safety, lease idempotency, and the Chrome shared-profile guard helper. Co-authored-by: Copilot <[email protected]> * Support shared browser host adoption for browser logs Refactor tracked browser logs around shared browser hosts and per-target sessions so shared user-data mode can reuse an existing debug-enabled Chromium instance without ever closing the user's browser. Add endpoint metadata discovery, owned/adopted host ownership, target lifecycle monitoring, and stale metadata handling. Co-authored-by: Copilot <[email protected]> * Improve browser logs diagnostics Add architecture comments for the shared/adopted browser pieces and target discovery. Surface browser host ownership and last-error diagnostics in resource state, preserve failed-session diagnostics, and log host/target/reconnect failures through resource logs. Harden endpoint metadata validation for malformed adoption hints. Co-authored-by: Copilot <[email protected]> * Update browser logs codegen snapshots Refresh ATS code-generation snapshots after adding BrowserUserDataMode to WithBrowserLogs. Co-authored-by: Copilot <[email protected]> * Add browser logs component tests Co-authored-by: Copilot <[email protected]> * Reuse browser endpoint probe HttpClient Co-authored-by: Copilot <[email protected]> * Use typed browser endpoint probe response Co-authored-by: Copilot <[email protected]> * Remove redundant adopted browser disposal guard Co-authored-by: Copilot <[email protected]> * Document browser host registry decisions Co-authored-by: Copilot <[email protected]> * Add browser observation notes to registry comments Co-authored-by: Copilot <[email protected]> * Document browser log runtime behavior Co-authored-by: Copilot <[email protected]> * Name browser logs timeout values Co-authored-by: Copilot <[email protected]> * Rename browser logs CDP transport types Co-authored-by: Copilot <[email protected]> * Document browser endpoint discovery flow Co-authored-by: Copilot <[email protected]> * Link Chromium singleton documentation Co-authored-by: Copilot <[email protected]> * Clarify browser page session model Rename the per-tab browser logs session abstraction around pages, document the host/context/page model, and detect Chromium's Windows lockfile for non-debuggable shared profiles. Co-authored-by: Copilot <[email protected]> * Dispose browser host registry lock Track active registry lock users so BrowserHostRegistry can dispose its SemaphoreSlim without breaking late lease releases after registry disposal. Co-authored-by: Copilot <[email protected]> * Move browser logs configuration resolution Co-authored-by: Copilot <[email protected]> * Clean up browser configuration state Co-authored-by: Copilot <[email protected]> * Move Chromium browser resolution helpers Co-authored-by: Copilot <[email protected]> * Document browser logs JSON formats Co-authored-by: Copilot <[email protected]> * Localize browser logs failure messages Co-authored-by: Copilot <[email protected]> * Move browser launch helpers out of running session Co-authored-by: Copilot <[email protected]> * Clean up browser logs helper ownership Co-authored-by: Copilot <[email protected]> * Address browser logs review feedback Co-authored-by: Copilot <[email protected]> * Add browser logs baseline coverage Co-authored-by: Copilot <[email protected]> * Test browser logs CDP connection Co-authored-by: Copilot <[email protected]> * Test browser logs running session glue Co-authored-by: Copilot <[email protected]> * Test browser page session reconnect Co-authored-by: Copilot <[email protected]> * Redefine Shared/Isolated as Aspire-managed persistent profiles Both BrowserUserDataMode.Shared and Isolated now use Aspire-managed persistent user data directories under %LocalAppData%\Aspire\BrowserData (Windows) or platform equivalents. Shared is machine-wide (per-browser); Isolated is keyed on AppHost:PathSha256. - Shared no longer points at the user's real Chromium profile; it uses ...\BrowserData\shared\<browser>. - Isolated uses ...\BrowserData\isolated\<appHostShaPrefix>\<browser>; replaces the previous temp-dir-per-session model. - Cross-process CDP adoption now runs for both modes via the existing aspire-debug-endpoint.json sidecar. - The browser process is no longer killed when the AppHost shuts down; it lives until the user closes it. - BrowserConfiguration carries the AppHost path SHA, captured once at Resolve time. - Removed dead helpers: IsNonDebuggableBrowserRunning, IsGoogleChromeDefaultUserDataDirectory, TryResolveUserDataDirectory and their resx strings/tests. Co-authored-by: Copilot <[email protected]> * Address PR review feedback - Wrap CleanupAsync lease release + _stopCts.Dispose in try/finally so the CTS is always disposed even when BrowserHostLease times out (JamesNK) - Wrap BrowserLogsSessionManager.DisposeAsync StopAsync loop in try/catch and move lock+factory disposal into finally so one failing session does not strand others (JamesNK) - Increase BrowserHostLease release timeout from 5s to 60s to exceed worst-case browser startup (30s) held under the registry lock, and swallow OperationCanceledException at the lease boundary so disposal never throws (JamesNK) - Comment timeout/poll values in BrowserHost.WaitForBrowserEndpointAsync and add an entry trace log for cold-start visibility (JamesNK) - Comment Local State magic string and case-insensitive profile match in BrowserHostRegistry (JamesNK) Co-authored-by: Copilot <[email protected]> --------- Co-authored-by: Copilot <[email protected]>
…ataMode Documents the browser logs AppHost feature introduced in microsoft/aspire#16310 and enhanced with BrowserUserDataMode in microsoft/aspire#16457. - New page: app-host/browser-logs.mdx - Explains WithBrowserLogs and the child browser logs resource - Documents Shared vs Isolated BrowserUserDataMode - Covers browser selection (msedge, chrome, explicit path) - Shows configuration via Aspire:Hosting:BrowserLogs settings - Includes both C# and TypeScript AppHost code examples - Adds sidebar entry under AppHost > Resource types Co-authored-by: Copilot <[email protected]>
…ataMode Documents the browser logs AppHost feature introduced in microsoft/aspire#16310 and enhanced with BrowserUserDataMode in microsoft/aspire#16457. - New page: app-host/browser-logs.mdx - Explains WithBrowserLogs and the child browser logs resource - Documents Shared vs Isolated BrowserUserDataMode - Covers browser selection (msedge, chrome, explicit path) - Shows configuration via Aspire:Hosting:BrowserLogs settings - Includes both C# and TypeScript AppHost code examples - Adds sidebar entry under AppHost > Resource types Co-authored-by: Copilot <[email protected]>
Description
Adds
WithBrowserLogs(...)toAspire.Hostingso endpoint-capable resources can attach an internal*-browser-logschild resource. The child resource exposesopen-tracked-browser, launches a Chromium-based browser in tracked mode, and streams browser activity back into Aspire’s resource log stream.This PR includes:
BrowserLogsruntime split across builder, resource, session manager, running session, websocket transport, protocol, and event-logging components;.ExcludeFromManifest()andNameValidationPolicyAnnotation.None, so the child stays internal to the AppHost model;IConfiguration, including global and resource-scoped overrides plus launch-time re-resolution whenopen-tracked-browserruns;Browser sessionsmetadata;DevToolsActivePorthandling, post-dispose launch rejection, and failed-websocket-connect cleanup;AspireExportsupport sowithBrowserLogs(...)is emitted in the polyglot AppHost generators while the child resource remains out of manifest publishing.Process management and dataflow
flowchart LR subgraph AppHost["Aspire AppHost"] Parent["Parent endpoint resource"] Child["BrowserLogs child resource"] Command["open-tracked-browser"] SessionMgr["Session manager"] end subgraph Session["One tracked browser session"] Create["Create session-000N"] Launch["Launch browser process"] Discover["Wait for DevToolsActivePort"] Attach["Attach target + navigate URL"] Running["Running session"] Cleanup["Stop / cleanup session"] end Dashboard["Dashboard / aspire logs / aspire describe"] Clients["playwright-cli / CDP clients"] Parent --> Child Child --> Command --> SessionMgr SessionMgr --> Create --> Launch --> Discover --> Attach --> Running Running -->|logs + health + active session state| SessionMgr SessionMgr --> Dashboard SessionMgr -->|Browser sessions property<br/>cdpEndpoint / targetUrl| Clients SessionMgr --> Cleanup Cleanup -->|close browser + release temp profile| LaunchHow Aspire manages browser instances
WithBrowserLogs(...)adds one internal*-browser-logschild resource beneath an endpoint-capable parent resource.open-tracked-browserinvocation asksBrowserLogsSessionManagerto create a new tracked session.BrowserLogsSessionManagerowns per-resource concurrency, assignssession-0001,session-0002, etc., aggregates active sessions, and publishes health/properties for the child resource.BrowserLogsRunningSessionowns exactly one launched browser process plus its attached CDP target. It resolves browser/profile settings at launch time, launches the browser, readsDevToolsActivePort, reuses or creates the page target, enables the required CDP domains, and navigates to the parent resource URL.ChromeDevToolsConnectiontransports raw websocket frames,BrowserLogsProtocolparses and serializes CDP messages, andBrowserEventLoggerturns runtime/log/network events into resource log lines.Browser sessionsproperty as serialized JSON so CLI and dashboard consumers can readbrowser,browserExecutable,profile,processId,targetUrl,cdpEndpoint,pageCdpEndpoint, andtargetId.Validation
Validation included:
Aspire.Hosting.Testscoverage for resource wiring, config refresh, session behavior, protocol parsing, target selection, diagnostics logging, and websocket cleanup on failed connect attempts;withBrowserLogs(...)capability;playground/BrowserTelemetryruns confirming tracked browser launches plus real[network.*], console, and error lines inweb-browser-logs;aspire describe web-browser-logs --format jsonvalidation confirmingBrowser sessionsincludescdpEndpoint,pageCdpEndpoint,targetId, andtargetUrl;playwright-clivalidation against the BrowserTelemetry sample using the surfaced CDP metadata to attach to the tracked browser and confirm the page title/log flow;playground/BrowserTelemetry/BrowserTelemetry.AppHostafter the latest feedback fixes, including the websocket-connect cleanup fix.Checklist
<code/>elements on your triple slash comments?aspire.devissue: