### Send Commands using C# Source: https://github.com/seclerp/dotnet-chrome-protocol/blob/main/README.md Demonstrates sending commands to the Chrome DevTools Protocol. It includes examples for sending a command and waiting for a response (`SendCommandAsync`), and sending a command without waiting for a response (`FireCommandAsync`). ```csharp // Send and wait for the response var targets = await browserClient.SendCommandAsync(Domains.Target.GetTargets()); await pageClient.SendCommandAsync(Domains.Debugger.Enable()); // Just send and resume execution immediately await pageClient.FireCommandAsync(Domains.Runtime.Evaluate("alert('Hello there')")); ``` -------------------------------- ### Control Chrome with Generated Commands and Types in C# Source: https://context7.com/seclerp/dotnet-chrome-protocol/llms.txt This C# example demonstrates practical usage of generated domains within the Chrome DevTools Protocol client. It covers connecting to the browser, discovering targets, attaching to a page, enabling specific domains (Network, Page, Runtime), subscribing to network events, navigating to a URL, evaluating JavaScript, and handling disconnections. Dependencies include ChromeProtocol.Domains, ChromeProtocol.Runtime.Messaging.WebSockets, ChromeProtocol.Runtime.Messaging.Logging, and Microsoft.Extensions.Logging. ```csharp using ChromeProtocol.Domains; using ChromeProtocol.Runtime.Messaging.WebSockets; using ChromeProtocol.Runtime.Messaging.Logging; using Microsoft.Extensions.Logging; // Setup var logger = LoggerFactory.Create(builder => builder.AddConsole().SetMinimumLevel(LogLevel.Information) ).CreateLogger("CDP"); using var browserClient = new DefaultProtocolClient( new Uri("ws://127.0.0.1:9222"), logger ); await browserClient.ConnectAsync(); try { // Get all targets var targetsResult = await browserClient.SendCommandAsync(Target.GetTargets()); var pageTarget = targetsResult.TargetInfos.First(t => t.Type == "page"); // Attach to page var attachResult = await browserClient.SendCommandAsync( Target.AttachToTarget(pageTarget.TargetId, Flatten: true) ); using var pageClient = browserClient.CreateScoped(attachResult.SessionId.Value); // Enable domains await pageClient.SendCommandAsync(Network.Enable()); await pageClient.SendCommandAsync(Page.Enable()); await pageClient.SendCommandAsync(Runtime.Enable()); // Subscribe to network events var requestSubscription = pageClient.SubscribeAsync(async request => { Console.WriteLine($"Request: {request.Request.Url}"); Console.WriteLine($"Method: {request.Request.Method}"); }); var responseSubscription = pageClient.SubscribeAsync(async response => { Console.WriteLine($"Response: {response.Response.Url}"); Console.WriteLine($"Status: {response.Response.Status}"); }); // Navigate and wait var navigateResult = await pageClient.SendCommandAsync( Page.Navigate("https://example.com", referrer: null) ); Console.WriteLine($"Navigation started: {navigateResult.FrameId.Value}"); // Wait for page load await Task.Delay(TimeSpan.FromSeconds(3)); // Evaluate JavaScript var evalResult = await pageClient.SendCommandAsync( Runtime.Evaluate( expression: "document.title", returnByValue: true ) ); Console.WriteLine($"Page title: {evalResult.Result.Value}"); // Cleanup requestSubscription.Dispose(); responseSubscription.Dispose(); } finally { await browserClient.DisconnectAsync(); } ``` -------------------------------- ### Send CDP Commands and Receive Responses Source: https://context7.com/seclerp/dotnet-chrome-protocol/llms.txt Executes Chrome DevTools Protocol (CDP) commands and retrieves strongly-typed responses. This example demonstrates fetching all available targets (pages, workers, etc.) and iterating through them to display information such as type, title, URL, and target ID. It handles potential `ProtocolErrorException`. ```csharp using ChromeProtocol.Domains; using ChromeProtocol.Runtime.Messaging.WebSockets; var browserClient = new DefaultProtocolClient(new Uri("ws://127.0.0.1:9222"), logger); await browserClient.ConnectAsync(); try { // Get all available targets (pages, workers, etc.) var targetsResponse = await browserClient.SendCommandAsync( Target.GetTargets(), cancellationToken: CancellationToken.None ); Console.WriteLine($"Found {targetsResponse.TargetInfos.Count} targets:"); foreach (var targetInfo in targetsResponse.TargetInfos) { Console.WriteLine($" - {targetInfo.Type}: {targetInfo.Title}"); Console.WriteLine($" URL: {targetInfo.Url}"); Console.WriteLine($" ID: {targetInfo.TargetId.Value}"); } // Find the first page target var pageTarget = targetsResponse.TargetInfos .FirstOrDefault(t => t.Type == "page"); if (pageTarget != null) { Console.WriteLine($"\nFound page target: {pageTarget.TargetId.Value}"); } } catch (ProtocolErrorException ex) { Console.WriteLine($"Protocol error {ex.Info.Code}: {ex.Info.Message}"); } finally { await browserClient.DisconnectAsync(); } ``` -------------------------------- ### Generate CDP Domain Classes with dotnet-cdp Tool Source: https://context7.com/seclerp/dotnet-chrome-protocol/llms.txt Provides command-line instructions for using the dotnet-cdp tool to generate C# classes for Chrome DevTools Protocol (CDP) domains from JSON schema files. It covers global and local installation, generating from official and custom schemas, and merging multiple schemas. The generated code includes static domain classes, type definitions, command/event records, and factory methods. ```bash # Install the tool globally dotnet tool install -g dotnet-cdp # Or install locally in a project dotnet tool install dotnet-cdp # Generate from Chrome's official protocol files dotnet cdp generate \ js_protocol.json \ browser_protocol.json \ --namespace MyApp.DevTools.Generated \ --output ./Generated \ --clean true # Generate from custom/extended protocol schema dotnet cdp generate \ custom_protocol.json \ --namespace MyApp.CustomProtocol \ --output ./CustomGenerated # Multiple schemas are merged (domains combined) dotnet cdp generate \ browser_protocol.json \ js_protocol.json \ mono_protocol.json \ -n DevTools.Extended \ -o ./out ``` -------------------------------- ### Fire and Forget CDP Commands Source: https://context7.com/seclerp/dotnet-chrome-protocol/llms.txt Sends CDP commands without waiting for a response, suitable for operations where the result is not immediately needed. This example shows executing JavaScript in the console and navigating a page to a specified URL. It assumes a scoped client is already attached to a specific page session. ```csharp using ChromeProtocol.Domains; // Assuming pageClient is a scoped client attached to a page var pageClient = browserClient.CreateScoped(sessionId); try { // Execute JavaScript without waiting for result await pageClient.FireCommandAsync( Runtime.Evaluate("console.log('Hello from ChromeProtocol!')"), CancellationToken.None ); // Navigate to a URL await pageClient.FireCommandAsync( Page.Navigate("https://example.com", referrer: null), CancellationToken.None ); Console.WriteLine("Commands fired successfully"); } catch (Exception ex) { Console.WriteLine($"Fire command failed: {ex.Message}"); } ``` -------------------------------- ### Monitor Raw Protocol Messages with C# Source: https://context7.com/seclerp/dotnet-chrome-protocol/llms.txt This C# example shows how to monitor all raw protocol messages exchanged with the Chrome DevTools Protocol client. It's useful for debugging and logging purposes. The code subscribes to connection events (connected, disconnected) and message events (request sent, response received, generic event received), logging details of each. Dependencies include ChromeProtocol.Runtime.Messaging and ChromeProtocol.Runtime.Messaging.WebSockets. ```csharp using ChromeProtocol.Runtime.Messaging; using ChromeProtocol.Runtime.Messaging.WebSockets; using System.Text.Json; var browserClient = new DefaultProtocolClient( new Uri("ws://127.0.0.1:9222"), logger ); // Subscribe to protocol-level events browserClient.OnConnected += (sender, args) => { Console.WriteLine("Connected to browser"); }; browserClient.OnDisconnected += (sender, args) => { Console.WriteLine("Disconnected from browser"); }; browserClient.OnRequestSent += (sender, request) => { Console.WriteLine($"→ Request #{request.Id}: {request.Method}"); if (request.Params != null) { var json = JsonSerializer.Serialize(request.Params); Console.WriteLine($" Params: {json}"); } }; browserClient.OnResponseReceived += (sender, response) => { Console.WriteLine($"← Response #{response.Id}"); if (response.Error != null) { Console.WriteLine($" Error {response.Error.Code}: {response.Error.Message}"); } else if (response.Result != null) { var json = JsonSerializer.Serialize(response.Result); Console.WriteLine($" Result: {json}"); } }; browserClient.OnEventReceived += (sender, protocolEvent) => { Console.WriteLine($"★ Event: {protocolEvent.Method}"); if (protocolEvent.SessionId != null) { Console.WriteLine($" Session: {protocolEvent.SessionId}"); } }; await browserClient.ConnectAsync(); // All protocol messages are now logged await browserClient.SendCommandAsync(Target.GetTargets()); await browserClient.DisconnectAsync(); ``` -------------------------------- ### Subscribe to Chrome Protocol Events with Async/Sync Handlers in C# Source: https://context7.com/seclerp/dotnet-chrome-protocol/llms.txt This example demonstrates how to subscribe to Chrome DevTools Protocol events using disposable subscriptions. It supports both asynchronous and synchronous event handlers, allowing for flexible event processing. The code shows enabling the debugger domain, subscribing to 'Debugger.Paused' with an async handler, and 'Debugger.ScriptParsed' with a sync handler. It also shows how to dispose of subscriptions to stop receiving events. Dependencies include ChromeProtocol.Domains and ChromeProtocol.Runtime.Messaging. ```csharp using ChromeProtocol.Domains; using ChromeProtocol.Runtime.Messaging; var pageClient = browserClient.CreateScoped(sessionId); // Enable debugger domain to receive debugger events await pageClient.SendCommandAsync(Debugger.Enable()); // Async event handler var subscription1 = pageClient.SubscribeAsync(async pausedEvent => { Console.WriteLine("Debugger paused!"); Console.WriteLine($"Reason: {pausedEvent.Reason}"); if (pausedEvent.CallFrames.Count > 0) { var frame = pausedEvent.CallFrames[0]; Console.WriteLine($"Location: {frame.Location.ScriptId.Value}:{frame.Location.LineNumber}"); } // Resume execution await pageClient.SendCommandAsync(Debugger.Resume()); }); // Synchronous event handler var subscription2 = pageClient.SubscribeSync(scriptEvent => { Console.WriteLine($"Script parsed: {scriptEvent.Url}"); }); // Let events flow for a while... await Task.Delay(TimeSpan.FromSeconds(10)); // Cleanup: dispose subscriptions to stop receiving events subscription1.Dispose(); subscription2.Dispose(); ``` -------------------------------- ### Launch Chrome with ChromiumLauncher in C# Source: https://context7.com/seclerp/dotnet-chrome-protocol/llms.txt Launches a local Chrome browser instance with specified arguments and a remote debugging port. It then connects to the browser using a protocol client to retrieve information about the main page. Dependencies include ChromeProtocol.Runtime.Browser and ChromeProtocol.Runtime.Messaging.WebSockets. Requires a valid Chrome executable path. ```csharp using ChromeProtocol.Runtime.Browser; using ChromeProtocol.Runtime.Messaging.WebSockets; // Launch Chrome with remote debugging enabled using var chromium = await ChromiumLauncher.Create() .WithRemoteDebuggingPort(9222) // 0 for random available port .WithUserProfileDirectory("./ChromeUserData") .WithArguments( "--no-default-browser-check", "--no-first-run", "--disable-extensions", "--disable-popup-blocking", "--disable-translate", "--disable-background-networking", "--disable-sync", "--disable-infobars" ) .WithPage("https://google.com") .LaunchLocalAsync(@"C:\Program Files\Google\Chrome\Application\chrome.exe"); Console.WriteLine($"Chrome launched at: {chromium.DebuggingEndpoint}"); // Connect to the launched browser using var browserClient = new DefaultProtocolClient( chromium.DebuggingEndpoint, logger ); await browserClient.ConnectAsync(); try { // Get the page that was opened var targets = await browserClient.SendCommandAsync(Target.GetTargets()); var mainPage = targets.TargetInfos.FirstOrDefault(t => t.Type == "page"); if (mainPage != null) { Console.WriteLine($"Main page: {mainPage.Title}"); Console.WriteLine($"URL: {mainPage.Url}"); } } finally { await browserClient.DisconnectAsync(); // Browser process is automatically terminated when chromium is disposed } ``` -------------------------------- ### Build ChromeProtocol using .NET CLI Source: https://github.com/seclerp/dotnet-chrome-protocol/blob/main/README.md Command to build the ChromeProtocol project using the .NET SDK. Assumes you are in the solution folder. No specific parameters are shown, implying a standard build. ```bash dotnet build ``` -------------------------------- ### dotnet cdp generate command help Source: https://github.com/seclerp/dotnet-chrome-protocol/blob/main/README.md Displays the help information for the `dotnet cdp generate` command, outlining its purpose, usage, arguments, and options for generating protocol definitions. ```bash > dotnet cdp generate --help DESCRIPTION: Generates strongly-typed C# classes for domain types, events and commands from protocol definition files to be used with ChromeProtocol. USAGE: dotnet cdp generate [OPTIONS] EXAMPLES: dotnet cdp generate js_protocol.json mono_protocol.json -n DevTools.Api.Generated -o ./out ARGUMENTS: Path to the .json file with the CDP schema to generate protocol definitions from OPTIONS: DEFAULT -h, --help Prints help information -n, --namespace Generated Namespace for the generated files -o, --output Generated Folder where generated files should be placed --clean True Should output folder be cleaned before performing generation or not ``` -------------------------------- ### Chrome DevTools Protocol Command Structure with Generated Classes in C# Source: https://context7.com/seclerp/dotnet-chrome-protocol/llms.txt Illustrates the usage of generated domain classes for constructing Chrome DevTools Protocol commands. It shows the preference for static factory methods and the alternative of direct instantiation. Commands implement ICommand, and responses are strongly typed. Dependencies include ChromeProtocol.Domains. ```csharp // Static factory method (preferred usage) var command1 = Target.AttachToTarget( TargetId: new Target.TargetIDType("target-id-123"), Flatten: true ); // Or direct instantiation var command2 = new Target.AttachToTargetRequest( TargetId: new Target.TargetIDType("target-id-123"), Flatten: true ); // Commands implement ICommand // Example: AttachToTargetRequest : ICommand // Send command and get typed response var result = await browserClient.SendCommandAsync(command1); // Result is strongly typed Console.WriteLine($"Session ID: {result.SessionId.Value}"); // All domain types use PrimitiveType wrappers for type safety var targetId = new Target.TargetIDType("abc123"); string rawValue = targetId.Value; // Extract underlying value ``` -------------------------------- ### Run ChromeProtocol Tests using .NET CLI Source: https://github.com/seclerp/dotnet-chrome-protocol/blob/main/README.md Executes the unit tests for the ChromeProtocol project. It specifies commands to run tests for the Runtime and Tools components separately. ```bash dotnet test ChromeProtocol.Runtime.Tests dotnet test ChromeProtocol.Tools.Tests ``` -------------------------------- ### Generate Domains using dotnet cdp CLI Source: https://github.com/seclerp/dotnet-chrome-protocol/blob/main/README.md Illustrates how to use the `dotnet cdp` command-line tool to generate C# classes for Chrome DevTools Protocol domains from schema files. This is useful when the pre-generated domains are insufficient. ```bash > dotnet cdp generate js_protocol.json browser_protocol.json --namespace YourApp.Domains --output YourApp.Domains/SomeFolder/Generated ``` -------------------------------- ### Creating and Connecting a Protocol Client Source: https://context7.com/seclerp/dotnet-chrome-protocol/llms.txt This section details how to create a WebSocket-based client to communicate with a Chrome browser instance running with remote debugging enabled. ```APIDOC ## Creating and Connecting a Protocol Client ### Description Create a WebSocket-based client to communicate with a Chrome browser instance running with remote debugging enabled. ### Method Constructor and `ConnectAsync()` ### Endpoint `ws://127.0.0.1:9222` (default, requires Chrome launched with `--remote-debugging-port=9222`) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```csharp using ChromeProtocol.Runtime.Messaging.WebSockets; using Microsoft.Extensions.Logging.Abstractions; // Chrome must be launched with --remote-debugging-port=9222 var debuggingEndpoint = new Uri("ws://127.0.0.1:9222"); var logger = NullLogger.Instance; // Create the protocol client var browserClient = new DefaultProtocolClient(debuggingEndpoint, logger); try { // Connect to the browser (starts background message workers) await browserClient.ConnectAsync(); Console.WriteLine("Connected to Chrome DevTools Protocol"); // Use the client for operations... // Disconnect and cleanup await browserClient.DisconnectAsync(); } catch (Exception ex) { Console.WriteLine($"Connection failed: {ex.Message}"); } finally { browserClient.Dispose(); } ``` ### Response #### Success Response (200) Connection established. Client is ready to send commands. #### Response Example None (connection is established via WebSocket handshake) ### Error Handling - `Exception`: Catches general connection errors. ``` -------------------------------- ### Sending Commands with Response Source: https://context7.com/seclerp/dotnet-chrome-protocol/llms.txt This section explains how to execute Chrome DevTools Protocol (CDP) commands and receive strongly-typed responses, either synchronously or asynchronously. ```APIDOC ## Sending Commands with Response ### Description Execute CDP commands and receive strongly-typed responses synchronously or asynchronously. ### Method `SendCommandAsync()` ### Endpoint Depends on the command being sent, typically to the browser client or a scoped session. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **command** (object) - Required - The CDP command object to send (e.g., `Target.GetTargets()`). - **cancellationToken** (CancellationToken) - Optional - Token to cancel the operation. ### Request Example ```csharp using ChromeProtocol.Domains; using ChromeProtocol.Runtime.Messaging.WebSockets; // Assuming browserClient is already connected // Get all available targets (pages, workers, etc.) var targetsResponse = await browserClient.SendCommandAsync( Target.GetTargets(), cancellationToken: CancellationToken.None ); Console.WriteLine($"Found {targetsResponse.TargetInfos.Count} targets:"); foreach (var targetInfo in targetsResponse.TargetInfos) { Console.WriteLine($" - {targetInfo.Type}: {targetInfo.Title}"); Console.WriteLine($" URL: {targetInfo.Url}"); Console.WriteLine($" ID: {targetInfo.TargetId.Value}"); } // Find the first page target var pageTarget = targetsResponse.TargetInfos .FirstOrDefault(t => t.Type == "page"); if (pageTarget != null) { Console.WriteLine($"\nFound page target: {pageTarget.TargetId.Value}"); } ``` ### Response #### Success Response (200) - **result** (object) - The strongly-typed response object corresponding to the sent command. #### Response Example ```json { "targetInfos": [ { "description": "", "devtoolsFrontendUrl": "/devtools/inspector.html?ws=", "id": "PAGE_TARGET_ID", "title": "New Tab", "type": "page", "url": "chrome://newtab/" } ] } ``` ### Error Handling - `ProtocolErrorException`: Catches errors returned by the Chrome DevTools Protocol. ``` -------------------------------- ### Create Browser Client using C# Source: https://github.com/seclerp/dotnet-chrome-protocol/blob/main/README.md Establishes a connection to the Chrome DevTools Protocol debugging endpoint. It requires the debugging port and a logger implementation. The `ConnectAsync` method initiates the connection. ```csharp // A port should be the one used in --remote-debugging-port argument when launching Chrome var debuggingEndpoint = new Uri("ws://127.0.0.1:1234"); var browserClient = new DefaultProtocolClient(debuggingEndpoint, new ConsoleLogger(...)); await browserClient.ConnectAsync(); ``` -------------------------------- ### Listen for Events using C# Source: https://github.com/seclerp/dotnet-chrome-protocol/blob/main/README.md Provides methods for subscribing to events emitted by the Chrome DevTools Protocol. It shows how to perform asynchronous subscriptions, disposable subscriptions, and single-use subscriptions. ```csharp pageClient.SubscribeAsync(paused => { Console.WriteLine("paused called"); }) // Subscriptions are disposable var subscription = pageClient.SubscribeAsync(changed => ...); ... subscription.Dispose(); // Single use subscription var subscription = pageClient.SubscribeOnce(navigated => { InitializeSomeStuff(); }); ``` -------------------------------- ### Create Scoped Clients for Session Management in C# Source: https://context7.com/seclerp/dotnet-chrome-protocol/llms.txt This snippet shows how to create session-specific clients to isolate operations to individual pages or targets. It connects to the browser, attaches to a target page, and then creates a scoped client. This scoped client ensures all subsequent commands are automatically associated with the correct session ID, simplifying management of individual browser contexts. Dependencies include the ChromeProtocol.Domains namespace. ```csharp using ChromeProtocol.Domains; var browserClient = new DefaultProtocolClient(new Uri("ws://127.0.0.1:9222"), logger); await browserClient.ConnectAsync(); // Get targets and find a page var targets = await browserClient.SendCommandAsync(Target.GetTargets()); var pageTarget = targets.TargetInfos.First(t => t.Type == "page"); // Attach to the target (with flat session mode) var attachResult = await browserClient.SendCommandAsync( Target.AttachToTarget(pageTarget.TargetId, Flatten: true) ); // Create scoped client - all commands automatically include sessionId using var pageClient = browserClient.CreateScoped(attachResult.SessionId.Value); try { // Enable network tracking for this page only await pageClient.SendCommandAsync(Network.Enable()); // Get cookies for this page var cookiesResult = await pageClient.SendCommandAsync( Network.GetCookies(new[] { "https://example.com" }) ); Console.WriteLine($"Found {cookiesResult.Cookies.Count} cookies"); foreach (var cookie in cookiesResult.Cookies) { Console.WriteLine($" {cookie.Name} = {cookie.Value}"); } } finally { pageClient.Dispose(); await browserClient.DisconnectAsync(); } ``` -------------------------------- ### Create Scoped Client using C# Source: https://github.com/seclerp/dotnet-chrome-protocol/blob/main/README.md Creates a client instance scoped to a specific session ID. This allows for targeted command execution and event listening within a particular browser context. ```csharp var pageClient = browserClient.CreateScoped(sessionId); ``` -------------------------------- ### Connect to Chrome DevTools Protocol Client Source: https://context7.com/seclerp/dotnet-chrome-protocol/llms.txt Establishes a WebSocket connection to a Chrome browser instance running with remote debugging enabled. It requires the debugging endpoint URI and an optional logger. The client can be connected and disconnected asynchronously, and it implements `IDisposable` for resource cleanup. ```csharp using ChromeProtocol.Runtime.Messaging.WebSockets; using Microsoft.Extensions.Logging.Abstractions; // Chrome must be launched with --remote-debugging-port=9222 var debuggingEndpoint = new Uri("ws://127.0.0.1:9222"); var logger = NullLogger.Instance; // Create the protocol client var browserClient = new DefaultProtocolClient(debuggingEndpoint, logger); try { // Connect to the browser (starts background message workers) await browserClient.ConnectAsync(); Console.WriteLine("Connected to Chrome DevTools Protocol"); // Use the client for operations... // Disconnect and cleanup await browserClient.DisconnectAsync(); } catch (Exception ex) { Console.WriteLine($"Connection failed: {ex.Message}"); } finally { browserClient.Dispose(); } ``` -------------------------------- ### Fire and Forget Commands Source: https://context7.com/seclerp/dotnet-chrome-protocol/llms.txt This section explains how to send CDP commands without waiting for a response, useful for operations where the result is not immediately needed. ```APIDOC ## Fire and Forget Commands ### Description Send commands without waiting for a response when the result is not needed. ### Method `FireCommandAsync()` ### Endpoint Typically used with a scoped client attached to a specific session (e.g., a page). ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **command** (object) - Required - The CDP command object to send (e.g., `Runtime.Evaluate()`, `Page.Navigate()`). - **cancellationToken** (CancellationToken) - Optional - Token to cancel the operation. ### Request Example ```csharp // Assuming pageClient is a scoped client attached to a page var pageClient = browserClient.CreateScoped(sessionId); try { // Execute JavaScript without waiting for result await pageClient.FireCommandAsync( Runtime.Evaluate("console.log('Hello from ChromeProtocol!')"), CancellationToken.None ); // Navigate to a URL await pageClient.FireCommandAsync( Page.Navigate("https://example.com", referrer: null), CancellationToken.None ); Console.WriteLine("Commands fired successfully"); } catch (Exception ex) { Console.WriteLine($"Fire command failed: {ex.Message}"); } ``` ### Response #### Success Response (200) Command has been sent. No result is returned. #### Response Example None ### Error Handling - `Exception`: Catches general errors during command execution. ``` -------------------------------- ### Subscribe to Strongly-Typed CDP Events in C# Source: https://context7.com/seclerp/dotnet-chrome-protocol/llms.txt Demonstrates how to subscribe to and handle strongly-typed Chrome DevTools Protocol (CDP) events like Target.AttachedToTarget using the dotnet-chrome-protocol library. It shows how to access event properties and trigger auto-attach commands. Dependencies include the ChromeProtocol.Domains namespace and a browser client instance. ```csharp using ChromeProtocol.Domains; // Events implement IEvent and have [MethodName] attributes // Example from Target.cs: // [MethodName("Target.attachedToTarget")] // public record AttachedToTarget(...) : IEvent var pageClient = browserClient.CreateScoped(sessionId); // Subscribe to typed events var subscription = pageClient.SubscribeAsync(async attachedEvent => { // Event properties are strongly typed Console.WriteLine($"Attached to target!"); Console.WriteLine($"Session ID: {attachedEvent.SessionId.Value}"); Console.WriteLine($"Target Type: {attachedEvent.TargetInfo.Type}"); Console.WriteLine($"Target URL: {attachedEvent.TargetInfo.Url}"); Console.WriteLine($"Waiting for debugger: {attachedEvent.WaitingForDebugger}"); // Access nested type information if (attachedEvent.TargetInfo.OpenerId != null) { Console.WriteLine($"Opener ID: {attachedEvent.TargetInfo.OpenerId.Value}"); } }); // Trigger auto-attach await pageClient.SendCommandAsync( Target.SetAutoAttach( AutoAttach: true, WaitForDebuggerOnStart: false, Flatten: true ) ); // Events will be received and handled automatically await Task.Delay(TimeSpan.FromSeconds(5)); subscription.Dispose(); ``` -------------------------------- ### Handle Protocol Errors with ProtocolErrorException in C# Source: https://context7.com/seclerp/dotnet-chrome-protocol/llms.txt Demonstrates how to catch and handle specific Chrome DevTools Protocol errors using ProtocolErrorException. This allows for detailed inspection of error codes, messages, and additional data. It also includes handling for operation cancellations and general exceptions. Dependencies include ChromeProtocol.Runtime.Messaging and ChromeProtocol.Domains. ```csharp using ChromeProtocol.Runtime.Messaging; using ChromeProtocol.Domains; var pageClient = browserClient.CreateScoped(sessionId); try { // Attempt to execute invalid JavaScript var result = await pageClient.SendCommandAsync( Runtime.Evaluate("invalid javascript syntax } Đ {[ "), CancellationToken.None ); Console.WriteLine($"Result: {result.Result}"); } catch (ProtocolErrorException ex) { // CDP error information Console.WriteLine($"Protocol Error Code: {ex.Info.Code}"); Console.WriteLine($"Error Message: {ex.Info.Message}"); if (ex.Info.Data != null) { Console.WriteLine($"Additional Data: {ex.Info.Data}"); } // Full exception details Console.WriteLine($"Stack Trace: {ex.StackTrace}"); } catch (OperationCanceledException) { Console.WriteLine("Operation was cancelled"); } catch (Exception ex) { Console.WriteLine($"Unexpected error: {ex.Message}"); } ``` -------------------------------- ### One-Time Event Subscriptions for Chrome Protocol in C# Source: https://context7.com/seclerp/dotnet-chrome-protocol/llms.txt This snippet illustrates how to subscribe to Chrome DevTools Protocol events that automatically unsubscribe after their first occurrence. It's useful for actions that need to be performed only once, such as after a page navigation is complete. The code demonstrates subscribing to 'Page.FrameNavigated' once and performing state initialization. It triggers navigation and waits for the event to fire before automatically unsubscribing. Dependencies include ChromeProtocol.Runtime.Messaging.Extensions and ChromeProtocol.Domains. ```csharp using ChromeProtocol.Runtime.Messaging.Extensions; using ChromeProtocol.Domains; var pageClient = browserClient.CreateScoped(sessionId); await pageClient.SendCommandAsync(Page.Enable()); // Subscribe once - automatically disposes after first event var subscription = pageClient.SubscribeOnceAsync(async navigatedEvent => { Console.WriteLine("Page navigation completed!"); Console.WriteLine($"Frame ID: {navigatedEvent.Frame.Id.Value}"); Console.WriteLine($"URL: {navigatedEvent.Frame.Url}"); Console.WriteLine($"Security Origin: {navigatedEvent.Frame.SecurityOrigin}"); // Perform initialization after navigation await InitializePageState(pageClient); }); // Trigger navigation await pageClient.FireCommandAsync( Page.Navigate("https://example.com", referrer: null) ); // Wait for navigation to complete (subscription auto-disposes) await Task.Delay(TimeSpan.FromSeconds(5)); // Helper function async Task InitializePageState(IScopedProtocolClient client) { await client.SendCommandAsync(Runtime.Enable()); await client.SendCommandAsync(Debugger.Enable()); Console.WriteLine("Page state initialized"); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.