### Full Example: Puppeteer Sharp with AOT and Custom Serialization Source: https://www.puppeteersharp.com/docs/AOT.html This example demonstrates launching a browser, navigating to a page, and using `EvaluateFunctionAsync` with a custom class, all within an AOT-compatible setup. ```csharp class MainClass { public static async Task Main(string[] args) { Puppeteer.ExtraJsonSerializerContext = DemoJsonSerializationContext.Default; var options = new LaunchOptions { Headless = true }; var browserFetcher = new BrowserFetcher(); await browserFetcher.DownloadAsync(); await using var browser = await Puppeteer.LaunchAsync(options); await using var page = await browser.NewPageAsync(); await page.GoToAsync("https://www.google.com"); var result = await page.EvaluateFunctionAsync("test => test", new TestClass { Name = "Dario"}); } } public class TestClass { public string Name { get; set; } } [JsonSerializable(typeof(TestClass))] public partial class DemoJsonSerializationContext : JsonSerializerContext {} ``` -------------------------------- ### Combine Multiple Locator Configurations Source: https://www.puppeteersharp.com/docs/Locators.html Chain multiple configuration methods to precisely control locator behavior. This example sets timeout, visibility, enabled state, viewport scrolling, and bounding box stability. ```csharp await page.Locator("button.submit") .SetTimeout(10000) .SetVisibility(VisibilityOption.Visible) .SetWaitForEnabled(true) .SetEnsureElementIsInTheViewport(true) .SetWaitForStableBoundingBox(true) .ClickAsync(); ``` -------------------------------- ### Race Multiple Locators Source: https://www.puppeteersharp.com/docs/Locators.html Races multiple locators and resolves with the first one to find an element. This example clicks the first available button (accept or dismiss). ```csharp await Locator.Race( page.Locator("button.accept"), page.Locator("button.dismiss") ).ClickAsync(); ``` -------------------------------- ### Wait for and Get Page Title Source: https://www.puppeteersharp.com/docs/Locators.html Waits for the locator to get a value from the page, returned as a JSON-deserialized object. This example retrieves the page title as a string. ```csharp var value = await page.LocatorFunction("() => document.title") .WaitAsync(); ``` -------------------------------- ### Get All Links from a Page Source: https://www.puppeteersharp.com/docs/Page.EvaluateExpressionAsync.GetAllLinks.html This snippet demonstrates how to fetch all hyperlink URLs from a given web page. It launches a browser, navigates to a URL, and then evaluates a JavaScript expression to collect all `href` attributes from `` tags. Ensure you have PuppeteerSharp installed and the necessary browser binaries downloaded. ```csharp using (var browser = await Puppeteer.LaunchAsync(options)) using (var page = await browser.NewPageAsync()) { await page.GoToAsync("http://www.google.com"); var jsSelectAllAnchors = @"Array.from(document.querySelectorAll('a')).map(a => a.href);"; var urls = await page.EvaluateExpressionAsync(jsSelectAllAnchors); foreach (string url in urls) { Console.WriteLine($"Url: {url}"); } Console.WriteLine("Press any key to continue..."); Console.ReadLine(); } ``` -------------------------------- ### Map Locator Elements with JavaScript Function Source: https://www.puppeteersharp.com/docs/Locators.html Creates a new locator that maps the located element using a JavaScript function. This example retrieves the text content of elements. ```csharp var text = await page.Locator("div.content") .Map("element => element.textContent") .WaitAsync(); ``` -------------------------------- ### Wait for Element Handle Source: https://www.puppeteersharp.com/docs/Locators.html Waits for the locator to get a handle from the page. ```csharp var handle = await page.Locator("button.submit").WaitHandleAsync(); ``` -------------------------------- ### WaitHandleAsync Source: https://www.puppeteersharp.com/docs/Locators.html Waits for the locator to get a handle from the page. ```APIDOC ## WaitHandleAsync ### Description Waits for the locator to get a handle from the page. ### Method `WaitHandleAsync` ### Request Example ```csharp var handle = await page.Locator("button.submit").WaitHandleAsync(); ``` ``` -------------------------------- ### Interact with Elements in Frames using Locators Source: https://www.puppeteersharp.com/docs/Locators.html Locators can be used within frames to find and interact with elements. First, get a reference to the frame, then create a locator within that frame's context. ```csharp var frame = page.MainFrame.ChildFrames[0]; await frame.Locator("button.submit").ClickAsync(); ``` -------------------------------- ### WaitAsync Source: https://www.puppeteersharp.com/docs/Locators.html Waits for the locator to get a value from the page and returns it as a JSON-deserialized object of type T. ```APIDOC ## WaitAsync ### Description Waits for the locator to get a value from the page, returned as a JSON-deserialized object. ### Method `WaitAsync` ### Parameters - **T** (Type) - The type to deserialize the returned value into. ### Request Example ```csharp var value = await page.LocatorFunction("() => document.title") .WaitAsync(); ``` ``` -------------------------------- ### Get Inner Text of an Element Source: https://www.puppeteersharp.com/docs/index.html Retrieves the inner text content of a specific HTML element using its selector. This involves querying the element and then accessing its 'innerText' property. ```csharp using var page = await browser.NewPageAsync(); await page.GoToAsync("https://example.com"); var pageHeaderHandle = await page.QuerySelectorAsync("h1"); var innerTextHandle = await pageHeaderHandle.GetPropertyAsync("innerText"); var innerText = await innerTextHandle.JsonValueAsync(); ``` -------------------------------- ### Manually Configure Browser Sandbox Permissions Source: https://www.puppeteersharp.com/docs/IssuesGeneratingPdfFiles.html Execute the setup.exe with administrator privileges to manually configure sandbox permissions for the downloaded browser. This is a workaround if automatic configuration fails. ```powershell cd .\setup.exe --configure-browser-in-directory="" ``` -------------------------------- ### Taking a Screenshot of a Web Page Source: https://www.puppeteersharp.com/docs/Page.ScreenshotAsync.html This snippet demonstrates how to download the necessary browser revision, set up launch options, navigate to a URL, and take a screenshot, saving it to a specified file. Ensure BrowserFetcher is used to download the browser. ```csharp using var browserFetcher = new BrowserFetcher(); await browserFetcher.DownloadAsync(BrowserFetcher.DefaultRevision); var url = "https://www.somepage.com"; var file = ".\\somepage.jpg"; var launchOptions = new LaunchOptions() { Headless = false }; using (var browser = await Puppeteer.LaunchAsync(launchOptions)) using (var page = await browser.NewPageAsync()) { await page.GoToAsync(url); await page.ScreenshotAsync(file); } ``` -------------------------------- ### Waiting for a Selector and Interacting Source: https://www.puppeteersharp.com/docs/Page.WaitForSelectorAsync.Searching.html This C# snippet demonstrates how to launch a browser, navigate to a page, type into a search box, wait for a specific selector to appear, and then click it. It's useful for scenarios where you need to ensure an element is present before interacting with it. ```csharp using (var browser = await Puppeteer.LaunchAsync(options)) using (var page = await browser.NewPageAsync()) { await page.GoToAsync("https://developers.google.com/web/"); // Type into search box. await page.TypeAsync("#searchbox input", "Headless Chrome"); // Wait for suggest overlay to appear and click "show all results". var allResultsSelector = ".devsite-suggest-all-results"; await page.WaitForSelectorAsync(allResultsSelector); await page.ClickAsync(allResultsSelector); // continue the operation } ``` -------------------------------- ### Generate PDF Source: https://www.puppeteersharp.com/docs/index.html Launches a browser, navigates to a URL, and generates a PDF file of the page. The browser instance should be disposed of properly. ```csharp using var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true }); var page = await browser.NewPageAsync(); await page.GoToAsync("https://www.google.com"); await page.PdfAsync("output.pdf"); ``` -------------------------------- ### WaitAsync with CancellationToken Source: https://www.puppeteersharp.com/docs/Locators.html Shows how to use CancellationToken with the WaitAsync method for locator actions, allowing for cancellation of waiting operations. ```csharp await page.Locator("div.loaded").WaitAsync(new LocatorActionOptions { CancellationToken = cts.Token }); ``` -------------------------------- ### Take Screenshot Source: https://www.puppeteersharp.com/docs/index.html Launches a browser, navigates to a URL, and takes a screenshot of the page. Ensure the browser is closed after use. ```csharp using var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true }); var page = await browser.NewPageAsync(); await page.GoToAsync("https://www.google.com"); await page.ScreenshotAsync("screenshot.png"); ``` -------------------------------- ### Basic Click Action Source: https://www.puppeteersharp.com/docs/LocatorActions.html Clicks the located element after it passes all configured preconditions. ```csharp await page.Locator("button.submit").ClickAsync(); ``` -------------------------------- ### ClickAsync with CancellationToken Source: https://www.puppeteersharp.com/docs/Locators.html Demonstrates how to pass a CancellationToken to the ClickAsync method of a locator to set a timeout for the click operation. ```csharp using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); await page.Locator("button.submit").ClickAsync(new LocatorClickOptions { CancellationToken = cts.Token }); ``` -------------------------------- ### Configuring Locator Preconditions Source: https://www.puppeteersharp.com/docs/LocatorActions.html Configures specific preconditions for a locator before performing an action, such as waiting for stability, enabled state, or viewport visibility. ```csharp await page.Locator("button.animated") .SetWaitForStableBoundingBox(true) // wait for animation to finish .SetWaitForEnabled(true) // wait for button to be enabled .SetEnsureElementIsInTheViewport(true) // scroll into view .ClickAsync(); ``` -------------------------------- ### Create LoggerFactory for Console Logging Source: https://www.puppeteersharp.com/docs/LogCDPCommunication.html This snippet shows how to create an ILoggerFactory using Microsoft.Extensions.Logging to log CDP messages to the console. The ConsoleLoggerFormat is set to Systemd for structured logging. Ensure the Microsoft.Extensions.Logging.Console NuGet package is added. ```csharp private static ILoggerFactory GetLoggerFactory() { var loggerFactory = Microsoft.Extensions.Logging.LoggerFactory.Create(builder => { builder .AddConsole(options => options.Format = ConsoleLoggerFormat.Systemd) .SetMinimumLevel(LogLevel.Trace); }); return loggerFactory; } ``` -------------------------------- ### Create LoggerFactory for Serilog File Logging Source: https://www.puppeteersharp.com/docs/LogCDPCommunication.html This snippet demonstrates how to create an ILoggerFactory configured with Serilog to log CDP messages to a file. Ensure the Serilog.Extensions.Logging.File NuGet package is added. ```csharp private static ILoggerFactory GetLoggerFactory(string file) { var factory = new LoggerFactory(); var filter = new FilterLoggerSettings { { "Connection", LogLevel.Trace } }; factory.WithFilter(filter).AddFile(file, LogLevel.Trace); return factory; } ``` -------------------------------- ### Use Locators to Interact with Elements Source: https://www.puppeteersharp.com/docs/index.html Demonstrates using locators for robust element selection with auto-retry and auto-wait capabilities. Useful for clicking buttons and filling input fields. ```csharp using var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true }); var page = await browser.NewPageAsync(); await page.GoToAsync("https://example.com"); // Click a button with auto-wait await page.Locator("button.submit").ClickAsync(); // Fill an input await page.Locator("input[name='email']").FillAsync("user@example.com"); ``` -------------------------------- ### Launch Puppeteer with Serilog File Logger Source: https://www.puppeteersharp.com/docs/LogCDPCommunication.html Integrates the Serilog file logger created previously into Puppeteer.LaunchAsync. This allows CDP messages to be written to the specified log file. ```csharp using (var browser = await Puppeteer.LaunchAsync(browserOptions, GetLoggerFactory(fileName))) { //Some code } ``` -------------------------------- ### Launch Browser from Custom Executable Path Source: https://www.puppeteersharp.com/docs/ReuseChrome.html Launch PuppeteerSharp using LaunchOptions, setting the ExecutablePath to the downloaded Chrome's location. This allows reusing a previously downloaded Chrome instance. ```csharp var options = new LaunchOptions { Headless = true, ExecutablePath = installedBrowser.GetExecutablePath() }; await using var browser = await Puppeteer.LaunchAsync(options); await using var page = await browser.NewPageAsync(); await page.GoToAsync("about:blank"); ``` -------------------------------- ### Configure Locator Visibility Source: https://www.puppeteersharp.com/docs/Locators.html Specify whether to wait for an element to be visible or hidden before performing an action. This is useful for handling dynamic content loading. ```csharp // Wait for element to be visible before clicking await page.Locator("button.submit") .SetVisibility(VisibilityOption.Visible) .ClickAsync(); // Wait for a loading spinner to disappear await page.Locator(".spinner") .SetVisibility(VisibilityOption.Hidden) .WaitAsync(); ``` -------------------------------- ### Download and Use Specific Chrome Versions Source: https://www.puppeteersharp.com/docs/DownloadFetcher.Download.html Use BrowserFetcher to download specific Chrome versions by their version number. Then, launch PuppeteerSharp using the downloaded executable path to perform browser automation tasks. ```csharp Console.WriteLine("Downloading browsers"); var browserFetcher = new BrowserFetcher(SupportedBrowser.Chrome); var chrome118 = await browserFetcher.DownloadAsync("118.0.5993.70"); var chrome119 = await browserFetcher.DownloadAsync("119.0.5997.0"); Console.WriteLine("Navigating"); await using (var browser = await Puppeteer.LaunchAsync(new() { ExecutablePath = chrome118.GetExecutablePath(), })) { await using var page = await browser.NewPageAsync(); await page.GoToAsync("https://www.whatismybrowser.com/"); Console.WriteLine("Generating PDF"); await page.PdfAsync(Path.Combine(Directory.GetCurrentDirectory(), "118.pdf")); Console.WriteLine("Export completed"); } await using (var browser = await Puppeteer.LaunchAsync(new() { ExecutablePath = chrome119.GetExecutablePath(), })) { await using var page = await browser.NewPageAsync(); await page.GoToAsync("https://www.whatismybrowser.com/"); Console.WriteLine("Generating PDF"); await page.PdfAsync(Path.Combine(Directory.GetCurrentDirectory(), "119.pdf")); Console.WriteLine("Export completed"); } ``` -------------------------------- ### ClickAsync Source: https://www.puppeteersharp.com/docs/LocatorActions.html Clicks the located element. The locator waits for the element to pass all configured preconditions before clicking. ```APIDOC ## ClickAsync ### Description Clicks the located element. The locator waits for the element to pass all configured preconditions before clicking. ### Method `ClickAsync` ### Parameters #### Request Body - **Options** (`LocatorClickOptions`) - Optional - Options for the click action. - **Button** (`MouseButton`) - Optional - Mouse button to use. Defaults to `MouseButton.Left`. - **Count** (`int`) - Optional - Number of clicks (e.g., 2 for double-click). Defaults to `1`. - **Delay** (`int`) - Optional - Time in milliseconds between mousedown and mouseup. Defaults to `0`. - **OffSet** (`Offset?`) - Optional - Click offset relative to the element's padding box. Defaults to `null`. - **CancellationToken** (`CancellationToken`) - Optional - Token to cancel the action. Defaults to `default`. ### Request Example **Double-click:** ```csharp await page.Locator("div.editable").ClickAsync(new LocatorClickOptions { Count = 2 }); ``` **Right-click:** ```csharp await page.Locator("div.context-menu-target").ClickAsync(new LocatorClickOptions { Button = MouseButton.Right }); ``` **Click with offset:** ```csharp await page.Locator("canvas").ClickAsync(new LocatorClickOptions { OffSet = new Offset { X = 100, Y = 50 } }); ``` **Slow click (with delay):** ```csharp await page.Locator("button.submit").ClickAsync(new LocatorClickOptions { Delay = 100 }); ``` ### Response This method does not return a value. ``` -------------------------------- ### Connect to Remote Browser Source: https://www.puppeteersharp.com/docs/index.html Connects to an already running browser instance using its WebSocket endpoint. Requires a valid browser endpoint URL and potentially an API key. ```csharp var options = new ConnectOptions() { BrowserWSEndpoint = $"wss://www.externalbrowser.io?token={apikey}" }; var url = "https://www.google.com/"; using var browser = await Puppeteer.ConnectAsync(options); using var page = await browser.NewPageAsync(); await page.GoToAsync(url); await page.PdfAsync("output.pdf"); ``` -------------------------------- ### Inject HTML Content Source: https://www.puppeteersharp.com/docs/index.html Sets the HTML content of a page directly and then optionally generates a PDF. Useful for creating pages dynamically. ```csharp using var page = await browser.NewPageAsync(); await page.SetContentAsync("
My Receipt
"); var result = await page.GetContentAsync(); await page.PdfAsync("output.pdf"); ``` -------------------------------- ### Launch Puppeteer with Console Logger Source: https://www.puppeteersharp.com/docs/LogCDPCommunication.html Integrates the console logger created previously into Puppeteer.LaunchAsync. This directs CDP messages to the console output. ```csharp using (var browser = await Puppeteer.LaunchAsync(browserOptions, GetLoggerFactory())) { //Some code } ``` -------------------------------- ### Create a custom JsonSerializerContext Source: https://www.puppeteersharp.com/docs/AOT.html Create a partial class that inherits from `JsonSerializerContext` and is attributed with `JsonSerializable` for the custom class. This context is required for serializing custom objects. ```csharp [JsonSerializable(typeof(TestClass))] public partial class DemoJsonSerializationContext : JsonSerializerContext {} ``` -------------------------------- ### Specify Download Path for BrowserFetcher Source: https://www.puppeteersharp.com/docs/ReuseChrome.html Use BrowserFetcherOptions to set a custom download path for Chrome. This ensures Chrome is downloaded to your specified location instead of the default. ```csharp var downloadPath = "/Users/dario/chrome"; var browserFetcherOptions = new BrowserFetcherOptions { Path = downloadPath }; var browserFetcher = new BrowserFetcher(browserFetcherOptions); var installedBrowser = await browserFetcher.DownloadAsync(); ``` -------------------------------- ### Configure Locator Enabled State Source: https://www.puppeteersharp.com/docs/Locators.html Set whether to wait for the element to be enabled before acting. The default is `true`, ensuring interactions only happen with active elements. ```csharp await page.Locator("button.submit") .SetWaitForEnabled(true) .ClickAsync(); ``` -------------------------------- ### WaitAsync Source: https://www.puppeteersharp.com/docs/Locators.html Waits for the locator to locate an element matching the configured preconditions. ```APIDOC ## WaitAsync ### Description Waits for the locator to locate an element matching the configured preconditions. ### Method `WaitAsync` ### Request Example ```csharp // Wait for an element to appear await page.Locator("div.loaded").WaitAsync(); ``` ``` -------------------------------- ### Configure Locator Timeout Source: https://www.puppeteersharp.com/docs/Locators.html Set a custom timeout in milliseconds for locator actions. The default timeout is 30 seconds. ```csharp await page.Locator("button.submit") .SetTimeout(5000) .ClickAsync(); ``` -------------------------------- ### Wait for Element to Appear Source: https://www.puppeteersharp.com/docs/Locators.html Waits for the locator to locate an element matching the configured preconditions. ```csharp // Wait for an element to appear await page.Locator("div.loaded").WaitAsync(); ``` -------------------------------- ### Create Function Locator Source: https://www.puppeteersharp.com/docs/Locators.html Use `Page.LocatorFunction()` to create a locator that evaluates a JavaScript function. This is useful for more complex element selection logic. ```csharp var locator = page.LocatorFunction("() => document.querySelector('button')"); await locator.ClickAsync(); ``` -------------------------------- ### ClickAsync Source: https://www.puppeteersharp.com/docs/Locators.html Clicks the located element. Options for button, count, delay, and offset can be provided. ```APIDOC ## ClickAsync ### Description Clicks the located element. ### Method `ClickAsync` ### Parameters See Locator Actions for click options (button, count, delay, offset). ### Request Example ```csharp await page.Locator("button.submit").ClickAsync(); ``` ``` -------------------------------- ### Launch Chrome with Extension Loaded Source: https://www.puppeteersharp.com/docs/ChromeExtension.html Use PuppeteerSharp to launch a Chrome browser instance with a specific Chrome extension loaded. This is essential for testing extension functionality. ```csharp using var browserFetcher = new BrowserFetcher(); await browserFetcher.DownloadAsync(BrowserFetcher.DefaultRevision); var pathToExtension = "path/to/extension"; var launchOptions = new LaunchOptions() { Headless = false, Args = new [] { $"--disable-extensions-except=\"{pathToExtension}\"", $"--load-extension=\"{pathToExtension}\"" } }; using (var browser = await Puppeteer.LaunchAsync(launchOptions)) using (var page = await browser.NewPageAsync()) { // test your extension here } ``` -------------------------------- ### Configure Locator Bounding Box Stability Source: https://www.puppeteersharp.com/docs/Locators.html Set whether to wait for the element's bounding box to stabilize before acting. The default is `true`, preventing interactions with elements that are still animating or repositioning. ```csharp await page.Locator("button.submit") .SetWaitForStableBoundingBox(true) .ClickAsync(); ``` -------------------------------- ### Create CSS Selector Locator Source: https://www.puppeteersharp.com/docs/Locators.html Use `Page.Locator()` with a CSS selector to create a locator. This locator will be used to find and interact with the specified element. ```csharp var locator = page.Locator("button.submit"); await locator.ClickAsync(); ``` -------------------------------- ### Check Sandbox Permissions After Browser Download Source: https://www.puppeteersharp.com/docs/IssuesGeneratingPdfFiles.html Verify if PuppeteerSharp successfully applied sandbox permissions after downloading the browser. This is crucial for PDF generation on servers. ```csharp var browserFetcher = new BrowserFetcher(); var installedBrowser = await browserFetcher.DownloadAsync(BrowserFetcher.); if (!installedBrowser.PermissionsFixed) { Console.WriteLine("Sandbox permissions were not applied. You need to run your application as an administrator."); return; } ``` -------------------------------- ### Wait For Selector Source: https://www.puppeteersharp.com/docs/index.html Waits for a specific DOM element to appear in the page before proceeding. This is crucial for single-page applications or pages with dynamic content. ```csharp using var page = await browser.NewPageAsync(); await page.GoToAsync("http://www.spapage.com"); await page.WaitForSelectorAsync("div.main-content"); await page.PdfAsync("output.pdf"); ``` -------------------------------- ### Evaluate JavaScript to Extract Links and Map to .NET Objects Source: https://www.puppeteersharp.com/docs/Page.EvaluateFunctionAsync.ComplexJSObjects.html Executes JavaScript to select link elements, extract their titles and URLs, and returns them as an array of .NET objects. Ensure the JavaScript return type matches the generic type parameter of EvaluateFunctionAsync. ```csharp using (var browser = await Puppeteer.LaunchAsync(options)) using (var page = await browser.NewPageAsync()) { await page.GoToAsync("https://news.ycombinator.com/"); Console.WriteLine("Get all urls from page"); var jsCode = @"() => { const selectors = Array.from(document.querySelectorAll('a[class=""storylink""]')); return selectors.map( t=> {return { title: t.innerHTML, url: t.href}}); }"; var results = await page.EvaluateFunctionAsync(jsCode); foreach (var result in results) { Console.WriteLine(result.ToString()); } Console.WriteLine("Press any key to continue..."); Console.ReadLine(); } ``` -------------------------------- ### Map Source: https://www.puppeteersharp.com/docs/Locators.html Creates a new locator that maps the located element using a JavaScript function. ```APIDOC ## Map ### Description Creates a new locator that maps the located element using a JavaScript function. ### Method `Map` ### Parameters - **mapFn** (string) - A JavaScript function that transforms the element. ### Request Example ```csharp var text = await page.Locator("div.content") .Map("element => element.textContent") .WaitAsync(); ``` ``` -------------------------------- ### FillAsync Source: https://www.puppeteersharp.com/docs/LocatorActions.html Fills the located element with a value. Automatically detects the element type and handles it appropriately. ```APIDOC ## FillAsync ### Description Fills the located element with a value. Automatically detects the element type and handles it appropriately: * **``**: Focuses, clears, and types the value. * **`