Skip to content

metaljase/BrowserCaptureRewrite.Playwright

Repository files navigation

BrowserCaptureRewrite.Playwright

BrowserCaptureRewrite.Playwright is a .NET library that implements the abstractions in BrowserCaptureRewrite.Abstractions using Playwright. It can intercept HTTP requests from a web page and capture the corresponding HTTP responses in-flight by targeting specific requests and optionally rewriting those responses - including the response for the web page itself.

Because intercepting and modifying HTTP responses happens in-flight before they reach the browser's rendering engine, you can fundamentally alter the page's behaviour. For example, the initial web page HTML can be rewritten to manipulate the subsequent HTTP requests it makes. Another example: a web page may fetch a JSON file and render its UI based on that data; by modifying the JSON response before the client-side code processes it, you can change the behaviour of the page.

Optionally, resiliency features such as retry logic and timeout handling can be configured, and the ability to manually sign-in is supported, for when the target web page requires authentication.

A key part for capturing in-flight HTTP responses is creating a CaptureSpec instance, which specifies what HTTP responses should be captured. Similarly, rewriting in-flight HTTP responses relies on a RewriteSpec instance, which specifies which responses should be rewritten and how.

With a browser instance, an overload of NavigateAndCaptureResultAsync in PlaywrightPageCaptureService can be called to perform the navigation, capture, and optional rewrite, by providing a CaptureSpec and optionally a RewriteSpec instance. However, it's usually more convenient to call an overload in one of the convenience classes or extension methods instead.

BrowserCaptureRewrite.Samples

BrowserCaptureRewrite.Samples is a .NET console application that uses the sample code in BrowserCaptureRewrite.Samples.Core to demonstrate how BrowserCaptureRewrite.Abstractions and BrowserCaptureRewrite.Playwright can capture or rewrite in-flight HTTP responses from web page URLs.

Setup instructions

Installing BrowserCaptureRewrite.Playwright

Add the BrowserCaptureRewrite.Playwright NuGet package to your project via your IDE, or by running the following command:

dotnet add package Metalhead.BrowserCaptureRewrite.Playwright

Installing Playwright browsers

BrowserCaptureRewrite.Playwright relies on Playwright to drive the browser, so Playwright and its dependencies must be installed. Before doing so, build your project to generate the Playwright installation script:

dotnet build

Run the following command from your project directory to install Playwright and the supported browsers:

NOTE: If your project is not targeting .NET 8.0, replace net8.0 in the path with your target framework.

pwsh bin/Debug/net8.0/playwright.ps1 install

Configuration

The Playwright implementation of BrowserCaptureRewrite.Abstractions must be added to your project's dependency injection container by calling an overload of AddPlaywrightCaptureRewrite(this IServiceCollection), which registers the necessary services for capturing and rewriting in-flight HTTP responses.

Use the parameterless overload to register services with all default options:

builder.Services.AddPlaywrightCaptureRewrite();

Alternatively, see the Configuration section in the BrowserCaptureRewrite.Abstractions repository for details on the options that can be added to appsettings.json or supplied through any .NET configuration provider (environment variables, user secrets, command‑line arguments). These settings control navigation timing, capture timing, browser behaviour, resiliency policies, and connectivity probes. If these options are provided, use the IConfiguration overload:

builder.Services.AddPlaywrightCaptureRewrite(builder.Configuration);

If you prefer to supply hardcoded values instead of using a configuration source, use the Action<PlaywrightCaptureRewriteBuilder> overload. You only need to set the properties for the options types you want to configure - any omitted options type retains its defaults:

builder.Services.AddPlaywrightCaptureRewrite(b =>
{
    b.ConfigureBrowser = o =>
    {
        o.Browser = Metalhead.BrowserCaptureRewrite.Abstractions.Engine.BrowserEngine.Firefox;
        o.Headless = false;
    };

    b.ConfigureResiliencePolicy = o =>
    {
        o.TransportRetryDelaysSeconds = [7, 8, 15, 30, 60, 300];
        o.TimeoutRetryDelaysSeconds = [1, 3, 5];
    };
});

Examples

See the Examples section in the BrowserCaptureRewrite.Abstractions repository for code demonstrating how to capture and rewrite in-flight HTTP responses.

Capture/Rewrite methods

Return types

See the Return types section in the BrowserCaptureRewrite.Abstractions repository.

Extension methods

See the Extension methods section in the BrowserCaptureRewrite.Abstractions repository.

Convenience classes / interfaces

See the Convenience classes/interfaces section in the BrowserCaptureRewrite.Abstractions repository.

Playwright specific methods

Ultimately, the extension methods and convenience methods call through to PlaywrightPageCaptureService (for this implementation) to perform the actual work of navigating to the page URL, capturing the page's response HTML, rendered HTML, in-flight HTTP responses, and optionally rewriting in-flight HTTP responses. It works directly with Playwright's IPage, so it can be used for more custom scenarios where you need direct access to the IPage or want to use Playwright features that aren't abstracted by the other methods.

NOTE: Unlike the extension methods and convenience methods, PageCaptureIncompleteException is not thrown when capture does not complete successfully; therefore, it's recommended PlaywrightPageCaptureService is only used when the other capture methods aren't sufficient.

XML documentation for IPlaywrightPageCaptureService is available in the source code.

IPlaywrightPageCaptureService: Implementations (PlaywrightPageCaptureService) return the page's response HTML, rendered HTML, and in-flight HTTP responses.

Task<PageCaptureResult> NavigateAndCaptureResultAsync(
    IPage page,
    PageCaptureParts captureParts,
    NavigationOptions navOptions,
    CaptureSpec? captureSpec,
    CaptureTimingOptions timingOptions,
    CancellationToken cancellationToken);

Task<PageCaptureResult> NavigateAndCaptureResultAsync(
    IPage page,
    PageCaptureParts captureParts,
    NavigationOptions navOptions,
    CaptureSpec? captureSpec,
    RewriteSpec? rewriteSpec,
    CaptureTimingOptions timingOptions,
    CancellationToken cancellationToken);