Network helper class with retry logic on failure
Just wanted to add that you may want to consider using Polly instead of rolling your own retry mechanism - this is a library built specifically for this kind of retry mechanism (as well as many more complicated scenarios). Using Polly would look something like the following.

Note that I have renamed the attempts parameter to retryAttempts to make it clear that this does not define the total number of attempts but rather the total number of retry attempts after the initial one, to keep the behaviour the same as your sample code.

public class NetworkHelper
{
    public static Task&lt;string&gt; LoadAndWaitForSelectorAsync(
        Uri url, string selector, int retryAttempts = 5)
    {
        // Create a policy that will...
        var policy = Policy
            // Retry for any `WaitTaskTimeoutException` raised during execution.
            .Handle&lt;WaitTaskTimeoutException&gt;()
            .WaitAndRetryAsync(
                // Retry the specified number of times after the initial attempt.
                retryCount: retryAttempts,
                // Wait for the given duration between each retry attempt. Note that
                // this can depend on the retry number if required.
                sleepDurationProvider: retryNumber =&gt; TimeSpan.FromSeconds(10));

        // Execute the operation to get the selector within the retry policy. If the
        // final retry attempt does not succeed, the resulting `WaitTaskTimeoutException`
        // will not be handled by the policy and will be thrown.
        return policy.ExecuteAsync(() =&gt; TryGetSelectorAsync(url, selector));
    }

    private static async Task&lt;string&gt; TryGetSelectorAsync(Uri url, string selector)
    {
        using (Page page = await Handler.Browser.NewPageAsync())
        {
            await page.GoToAsync(url.ToString(), timeout: 0);
            await page.WaitForSelectorAsync(selector);
            return await page.GetContentAsync();
        }
    }
}