How to use TaskQueue class of PuppeteerSharp.Helpers package

Best Puppeteer-sharp code snippet using PuppeteerSharp.Helpers.TaskQueue

Page.cs

Source:Page.cs Github

copy

Full Screen

...30    /// </example>31    [DebuggerDisplay("Page {Url}")]32    public class Page : IDisposable33    {34        private readonly TaskQueue _screenshotTaskQueue;35        private readonly EmulationManager _emulationManager;36        private readonly Dictionary<string, Delegate> _pageBindings;37        private readonly TaskCompletionSource<bool> _closeCompletedTcs = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);38        private TaskCompletionSource<bool> _sessionClosedTcs;39        private readonly TimeoutSettings _timeoutSettings;40        private static readonly Dictionary<string, decimal> _unitToPixels = new Dictionary<string, decimal> {41            {"px", 1},42            {"in", 96},43            {"cm", 37.8m},44            {"mm", 3.78m}45        };46        private Page(47            CDPSession client,48            Target target,49            TaskQueue screenshotTaskQueue)50        {51            Client = client;52            Target = target;53            Keyboard = new Keyboard(client);54            Mouse = new Mouse(client, Keyboard);55            Touchscreen = new Touchscreen(client, Keyboard);56            Coverage = new Coverage(client);57            //_fileChooserInterceptors = new ConcurrentDictionary<Guid, TaskCompletionSource<FileChooser>>();58            _timeoutSettings = new TimeoutSettings();59            _emulationManager = new EmulationManager(client);60            _pageBindings = new Dictionary<string, Delegate>();61            //_workers = new Dictionary<string, Worker>();62            Accessibility = new Accessibility(client);63            _screenshotTaskQueue = screenshotTaskQueue;64            _ = target.CloseTask.ContinueWith((arg) =>65            {66                try67                {68                    Close?.Invoke(this, EventArgs.Empty);69                }70                finally71                {72                    IsClosed = true;73                    _closeCompletedTcs.TrySetResult(true);74                }75            });76        }77        #region Public Properties78        /// <summary>79        /// Chrome DevTools Protocol session.80        /// </summary>81        public CDPSession Client { get; }82        /// <summary>83        /// Raised when the JavaScript <c>load</c> <see href="https://developer.mozilla.org/en-US/docs/Web/Events/load"/> event is dispatched.84        /// </summary>85        public event EventHandler Load;86        /// <summary>87        /// Raised when the page crashes88        /// </summary>89        public event EventHandler<ErrorEventArgs> Error;90        /// <summary>91        /// Raised when the JavaScript <c>DOMContentLoaded</c> <see href="https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded"/> event is dispatched.92        /// </summary>93        public event EventHandler DOMContentLoaded;94        /// <summary>95        /// Raised when JavaScript within the page calls one of console API methods, e.g. <c>console.log</c> or <c>console.dir</c>. Also emitted if the page throws an error or a warning.96        /// The arguments passed into <c>console.log</c> appear as arguments on the event handler.97        /// </summary>98        /// <example>99        /// An example of handling <see cref="Console"/> event:100        /// <code>101        /// <![CDATA[102        /// page.Console += (sender, e) => 103        /// {104        ///     for (var i = 0; i < e.Message.Args.Count; ++i)105        ///     {106        ///         System.Console.WriteLine($"{i}: {e.Message.Args[i]}");107        ///     }108        /// }109        /// ]]>110        /// </code>111        /// </example>112        //public event EventHandler<ConsoleEventArgs> Console;113        /// <summary>114        /// Raised when a frame is attached.115        /// </summary>116        public event EventHandler<FrameEventArgs> FrameAttached;117        /// <summary>118        /// Raised when a frame is detached.119        /// </summary>120        public event EventHandler<FrameEventArgs> FrameDetached;121        /// <summary>122        /// Raised when a frame is navigated to a new url.123        /// </summary>124        public event EventHandler<FrameEventArgs> FrameNavigated;125        /// <summary>126        /// Raised when a <see cref="Response"/> is received.127        /// </summary>128        /// <example>129        /// An example of handling <see cref="Response"/> event:130        /// <code>131        /// <![CDATA[132        /// var tcs = new TaskCompletionSource<string>();133        /// page.Response += async(sender, e) =>134        /// {135        ///     if (e.Response.Url.Contains("script.js"))136        ///     {137        ///         tcs.TrySetResult(await e.Response.TextAsync());138        ///     }139        /// };140        ///141        /// await Task.WhenAll(142        ///     page.GoToAsync(TestConstants.ServerUrl + "/grid.html"),143        ///     tcs.Task);144        /// Console.WriteLine(await tcs.Task);145        /// ]]>146        /// </code>147        /// </example>148        public event EventHandler<ResponseCreatedEventArgs> Response;149        /// <summary>150        /// Raised when a page issues a request. The <see cref="Request"/> object is read-only.151        /// In order to intercept and mutate requests, see <see cref="SetRequestInterceptionAsync(bool)"/>152        /// </summary>153        public event EventHandler<RequestEventArgs> Request;154        /// <summary>155        /// Raised when a request finishes successfully.156        /// </summary>157        public event EventHandler<RequestEventArgs> RequestFinished;158        /// <summary>159        /// Raised when a request fails, for example by timing out.160        /// </summary>161        public event EventHandler<RequestEventArgs> RequestFailed;162        /// <summary>163        /// Raised when an uncaught exception happens within the page.164        /// </summary>165        public event EventHandler<PageErrorEventArgs> PageError;166        ///// <summary>167        ///// Emitted when a dedicated WebWorker (<see href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API"/>) is spawned by the page.168        ///// </summary>169        //public event EventHandler<WorkerEventArgs> WorkerCreated;170        ///// <summary>171        ///// Emitted when a dedicated WebWorker (<see href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API"/>) is terminated.172        ///// </summary>173        //public event EventHandler<WorkerEventArgs> WorkerDestroyed;174        /// <summary>175        /// Raised when the page closes.176        /// </summary>177        public event EventHandler Close;178        /// <summary>179        /// Raised when the page opens a new tab or window.180        /// </summary>181        public event EventHandler<PopupEventArgs> Popup;182        /// <summary>183        /// This setting will change the default maximum time for the following methods:184        /// - <see cref="GoToAsync(string, NavigationOptions)"/>185        /// - <see cref="GoBackAsync(NavigationOptions)"/>186        /// - <see cref="GoForwardAsync(NavigationOptions)"/>187        /// - <see cref="ReloadAsync(NavigationOptions)"/>188        /// - <see cref="SetContentAsync(string, NavigationOptions)"/>189        /// - <see cref="WaitForNavigationAsync(NavigationOptions)"/>190        /// **NOTE** <see cref="DefaultNavigationTimeout"/> takes priority over <seealso cref="DefaultTimeout"/>191        /// </summary>192        public int DefaultNavigationTimeout193        {194            get => _timeoutSettings.NavigationTimeout;195            set => _timeoutSettings.NavigationTimeout = value;196        }197        /// <summary>198        /// This setting will change the default maximum times for the following methods:199        /// - <see cref="GoBackAsync(NavigationOptions)"/>200        /// - <see cref="GoForwardAsync(NavigationOptions)"/>201        /// - <see cref="GoToAsync(string, NavigationOptions)"/>202        /// - <see cref="ReloadAsync(NavigationOptions)"/>203        /// - <see cref="SetContentAsync(string, NavigationOptions)"/>204        /// - <see cref="WaitForFunctionAsync(string, object[])"/>205        /// - <see cref="WaitForNavigationAsync(NavigationOptions)"/>206        /// - <see cref="WaitForRequestAsync(string, WaitForOptions)"/>207        /// - <see cref="WaitForResponseAsync(string, WaitForOptions)"/>208        /// - <see cref="WaitForXPathAsync(string, WaitForSelectorOptions)"/>209        /// - <see cref="WaitForSelectorAsync(string, WaitForSelectorOptions)"/>210        /// - <see cref="WaitForExpressionAsync(string, WaitForFunctionOptions)"/>211        /// </summary>212        public int DefaultTimeout213        {214            get => _timeoutSettings.Timeout;215            set => _timeoutSettings.Timeout = value;216        }217        /// <summary>218        /// Gets page's main frame219        /// </summary>220        /// <remarks>221        /// Page is guaranteed to have a main frame which persists during navigations.222        /// </remarks>223        public Frame MainFrame => FrameManager.MainFrame;224        /// <summary>225        /// Gets all frames attached to the page.226        /// </summary>227        /// <value>An array of all frames attached to the page.</value>228        public Frame[] Frames => FrameManager.GetFrames();229        ///// <summary>230        ///// Gets all workers in the page.231        ///// </summary>232        //public Worker[] Workers => _workers.Values.ToArray();233        /// <summary>234        /// Shortcut for <c>page.MainFrame.Url</c>235        /// </summary>236        public string Url => MainFrame.Url;237        /// <summary>238        /// Gets that target this page was created from.239        /// </summary>240        public Target Target { get; }241        /// <summary>242        /// Gets this page's keyboard243        /// </summary>244        public Keyboard Keyboard { get; }245        /// <summary>246        /// Gets this page's touchscreen247        /// </summary>248        public Touchscreen Touchscreen { get; }249        /// <summary>250        /// Gets this page's coverage251        /// </summary>252        public Coverage Coverage { get; }253        /// <summary>254        /// Gets this page's mouse255        /// </summary>256        public Mouse Mouse { get; }257        /// <summary>258        /// Gets this page's viewport259        /// </summary>260        public ViewPortOptions Viewport { get; private set; }261        /// <summary>262        /// List of supported metrics provided by the <see cref="Metrics"/> event.263        /// </summary>264        public static readonly IEnumerable<string> SupportedMetrics = new List<string>265        {266            "Timestamp",267            "Documents",268            "Frames",269            "JSEventListeners",270            "Nodes",271            "LayoutCount",272            "RecalcStyleCount",273            "LayoutDuration",274            "RecalcStyleDuration",275            "ScriptDuration",276            "TaskDuration",277            "JSHeapUsedSize",278            "JSHeapTotalSize"279        };280        /// <summary>281        /// Get the browser the page belongs to.282        /// </summary>283        public Browser Browser => Target.Browser;284        /// <summary>285        /// Get the browser context that the page belongs to.286        /// </summary>287        public BrowserContext BrowserContext => Target.BrowserContext;288        /// <summary>289        /// Get an indication that the page has been closed.290        /// </summary>291        public bool IsClosed { get; private set; }292        /// <summary>293        /// Gets the accessibility.294        /// </summary>295        public Accessibility Accessibility { get; }296        internal bool JavascriptEnabled { get; set; } = true;297        internal bool HasPopupEventListeners => Popup?.GetInvocationList().Any() == true;298        internal FrameManager FrameManager { get; private set; }299        private Task SessionClosedTask300        {301            get302            {303                if (_sessionClosedTcs == null)304                {305                    _sessionClosedTcs = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);306                    Client.Disconnected += clientDisconnected;307                    void clientDisconnected(object sender, EventArgs e)308                    {309                        _sessionClosedTcs.TrySetException(new TargetClosedException("Target closed", "Session closed"));310                        Client.Disconnected -= clientDisconnected;311                    }312                }313                return _sessionClosedTcs.Task;314            }315        }316        #endregion317        #region Public Methods318        /// <summary>319        /// A utility function to be used with <see cref="Extensions.EvaluateFunctionAsync{T}(Task{JSHandle}, string, object[])"/>320        /// </summary>321        /// <param name="selector">A selector to query page for</param>322        /// <returns>Task which resolves to a <see cref="JSHandle"/> of <c>document.querySelectorAll</c> result</returns>323        public Task<JSHandle> QuerySelectorAllHandleAsync(string selector)324            => EvaluateFunctionHandleAsync("selector => Array.from(document.querySelectorAll(selector))", selector);325        /// <summary>326        /// Executes a script in browser context327        /// </summary>328        /// <param name="script">Script to be evaluated in browser context</param>329        /// <remarks>330        /// If the script, returns a Promise, then the method would wait for the promise to resolve and return its value.331        /// </remarks>332        /// <returns>Task which resolves to script return value</returns>333        public async Task<JSHandle> EvaluateExpressionHandleAsync(string script)334        {335            var context = await MainFrame.GetExecutionContextAsync().ConfigureAwait(false);336            return await context.EvaluateExpressionHandleAsync(script).ConfigureAwait(false);337        }338        /// <summary>339        /// Executes a script in browser context340        /// </summary>341        /// <param name="pageFunction">Script to be evaluated in browser context</param>342        /// <param name="args">Function arguments</param>343        /// <remarks>344        /// If the script, returns a Promise, then the method would wait for the promise to resolve and return its value.345        /// <see cref="JSHandle"/> instances can be passed as arguments346        /// </remarks>347        /// <returns>Task which resolves to script return value</returns>348        public async Task<JSHandle> EvaluateFunctionHandleAsync(string pageFunction, params object[] args)349        {350            var context = await MainFrame.GetExecutionContextAsync().ConfigureAwait(false);351            return await context.EvaluateFunctionHandleAsync(pageFunction, args).ConfigureAwait(false);352        }353        /// <summary>354        /// Activating request interception enables <see cref="Request.AbortAsync(RequestAbortErrorCode)">request.AbortAsync</see>, 355        /// <see cref="Request.ContinueAsync(Payload)">request.ContinueAsync</see> and <see cref="Request.RespondAsync(ResponseData)">request.RespondAsync</see> methods.356        /// </summary>357        /// <returns>The request interception task.</returns>358        /// <param name="value">Whether to enable request interception..</param>359        public Task SetRequestInterceptionAsync(bool value)360            => FrameManager.NetworkManager.SetRequestInterceptionAsync(value);361        /// <summary>362        /// Set offline mode for the page.363        /// </summary>364        /// <returns>Result task</returns>365        /// <param name="value">When <c>true</c> enables offline mode for the page.</param>366        public Task SetOfflineModeAsync(bool value) => FrameManager.NetworkManager.SetOfflineModeAsync(value);367        /// <summary>368        /// Adds a <c><![CDATA[<script>]]></c> tag into the page with the desired url or content369        /// </summary>370        /// <param name="options">add script tag options</param>371        /// <remarks>372        /// Shortcut for <c>page.MainFrame.AddScriptTagAsync(options)</c>373        /// </remarks>374        /// <returns>Task which resolves to the added tag when the script's onload fires or when the script content was injected into frame</returns>375        /// <seealso cref="Frame.AddScriptTagAsync(AddTagOptions)"/>376        public Task<ElementHandle> AddScriptTagAsync(AddTagOptions options) => MainFrame.AddScriptTagAsync(options);377        /// <summary>378        /// Adds a <c><![CDATA[<script>]]></c> tag into the page with the desired url or content379        /// </summary>380        /// <param name="url">script url</param>381        /// <remarks>382        /// Shortcut for <c>page.MainFrame.AddScriptTagAsync(new AddTagOptions { Url = url })</c>383        /// </remarks>384        /// <returns>Task which resolves to the added tag when the script's onload fires or when the script content was injected into frame</returns>385        public Task<ElementHandle> AddScriptTagAsync(string url) => AddScriptTagAsync(new AddTagOptions { Url = url });386        /// <summary>387        /// Adds a <c><![CDATA[<link rel="stylesheet">]]></c> tag into the page with the desired url or a <c><![CDATA[<link rel="stylesheet">]]></c> tag with the content388        /// </summary>389        /// <param name="options">add style tag options</param>390        /// <remarks>391        /// Shortcut for <c>page.MainFrame.AddStyleTagAsync(options)</c>392        /// </remarks>393        /// <returns>Task which resolves to the added tag when the stylesheet's onload fires or when the CSS content was injected into frame</returns>394        /// <seealso cref="Frame.AddStyleTag(AddTagOptions)"/>395        public Task<ElementHandle> AddStyleTagAsync(AddTagOptions options) => MainFrame.AddStyleTagAsync(options);396        /// <summary>397        /// Adds a <c><![CDATA[<link rel="stylesheet">]]></c> tag into the page with the desired url or a <c><![CDATA[<link rel="stylesheet">]]></c> tag with the content398        /// </summary>399        /// <param name="url">stylesheel url</param>400        /// <remarks>401        /// Shortcut for <c>page.MainFrame.AddStyleTagAsync(new AddTagOptions { Url = url })</c>402        /// </remarks>403        /// <returns>Task which resolves to the added tag when the stylesheet's onload fires or when the CSS content was injected into frame</returns>404        public Task<ElementHandle> AddStyleTagAsync(string url) => AddStyleTagAsync(new AddTagOptions { Url = url });405        /// <summary>406        /// Adds a function called <c>name</c> on the page's <c>window</c> object.407        /// When called, the function executes <paramref name="puppeteerFunction"/> in C# and returns a <see cref="Task"/> which resolves when <paramref name="puppeteerFunction"/> completes.408        /// </summary>409        /// <param name="name">Name of the function on the window object</param>410        /// <param name="puppeteerFunction">Callback function which will be called in Puppeteer's context.</param>411        /// <remarks>412        /// If the <paramref name="puppeteerFunction"/> returns a <see cref="Task"/>, it will be awaited.413        /// Functions installed via <see cref="ExposeFunctionAsync(string, Action)"/> survive navigations414        /// </remarks>415        /// <returns>Task</returns>416        public Task ExposeFunctionAsync(string name, Action puppeteerFunction)417            => ExposeFunctionAsync(name, (Delegate)puppeteerFunction);418        /// <summary>419        /// Adds a function called <c>name</c> on the page's <c>window</c> object.420        /// When called, the function executes <paramref name="puppeteerFunction"/> in C# and returns a <see cref="Task"/> which resolves to the return value of <paramref name="puppeteerFunction"/>.421        /// </summary>422        /// <typeparam name="TResult">The result of <paramref name="puppeteerFunction"/></typeparam>423        /// <param name="name">Name of the function on the window object</param>424        /// <param name="puppeteerFunction">Callback function which will be called in Puppeteer's context.</param>425        /// <remarks>426        /// If the <paramref name="puppeteerFunction"/> returns a <see cref="Task"/>, it will be awaited.427        /// Functions installed via <see cref="ExposeFunctionAsync{TResult}(string, Func{TResult})"/> survive navigations428        /// </remarks>429        /// <returns>Task</returns>430        public Task ExposeFunctionAsync<TResult>(string name, Func<TResult> puppeteerFunction)431            => ExposeFunctionAsync(name, (Delegate)puppeteerFunction);432        /// <summary>433        /// Adds a function called <c>name</c> on the page's <c>window</c> object.434        /// When called, the function executes <paramref name="puppeteerFunction"/> in C# and returns a <see cref="Task"/> which resolves to the return value of <paramref name="puppeteerFunction"/>.435        /// </summary>436        /// <typeparam name="TResult">The result of <paramref name="puppeteerFunction"/></typeparam>437        /// <typeparam name="T">The parameter of <paramref name="puppeteerFunction"/></typeparam>438        /// <param name="name">Name of the function on the window object</param>439        /// <param name="puppeteerFunction">Callback function which will be called in Puppeteer's context.</param>440        /// <remarks>441        /// If the <paramref name="puppeteerFunction"/> returns a <see cref="Task"/>, it will be awaited.442        /// Functions installed via <see cref="ExposeFunctionAsync{T, TResult}(string, Func{T, TResult})"/> survive navigations443        /// </remarks>444        /// <returns>Task</returns>445        public Task ExposeFunctionAsync<T, TResult>(string name, Func<T, TResult> puppeteerFunction)446            => ExposeFunctionAsync(name, (Delegate)puppeteerFunction);447        /// <summary>448        /// Adds a function called <c>name</c> on the page's <c>window</c> object.449        /// When called, the function executes <paramref name="puppeteerFunction"/> in C# and returns a <see cref="Task"/> which resolves to the return value of <paramref name="puppeteerFunction"/>.450        /// </summary>451        /// <typeparam name="TResult">The result of <paramref name="puppeteerFunction"/></typeparam>452        /// <typeparam name="T1">The first parameter of <paramref name="puppeteerFunction"/></typeparam>453        /// <typeparam name="T2">The second parameter of <paramref name="puppeteerFunction"/></typeparam>454        /// <param name="name">Name of the function on the window object</param>455        /// <param name="puppeteerFunction">Callback function which will be called in Puppeteer's context.</param>456        /// <remarks>457        /// If the <paramref name="puppeteerFunction"/> returns a <see cref="Task"/>, it will be awaited.458        /// Functions installed via <see cref="ExposeFunctionAsync{T1, T2, TResult}(string, Func{T1, T2, TResult})"/> survive navigations459        /// </remarks>460        /// <returns>Task</returns>461        public Task ExposeFunctionAsync<T1, T2, TResult>(string name, Func<T1, T2, TResult> puppeteerFunction)462            => ExposeFunctionAsync(name, (Delegate)puppeteerFunction);463        /// <summary>464        /// Adds a function called <c>name</c> on the page's <c>window</c> object.465        /// When called, the function executes <paramref name="puppeteerFunction"/> in C# and returns a <see cref="Task"/> which resolves to the return value of <paramref name="puppeteerFunction"/>.466        /// </summary>467        /// <typeparam name="TResult">The result of <paramref name="puppeteerFunction"/></typeparam>468        /// <typeparam name="T1">The first parameter of <paramref name="puppeteerFunction"/></typeparam>469        /// <typeparam name="T2">The second parameter of <paramref name="puppeteerFunction"/></typeparam>470        /// <typeparam name="T3">The third parameter of <paramref name="puppeteerFunction"/></typeparam>471        /// <param name="name">Name of the function on the window object</param>472        /// <param name="puppeteerFunction">Callback function which will be called in Puppeteer's context.</param>473        /// <remarks>474        /// If the <paramref name="puppeteerFunction"/> returns a <see cref="Task"/>, it will be awaited.475        /// Functions installed via <see cref="ExposeFunctionAsync{T1, T2, T3, TResult}(string, Func{T1, T2, T3, TResult})"/> survive navigations476        /// </remarks>477        /// <returns>Task</returns>478        public Task ExposeFunctionAsync<T1, T2, T3, TResult>(string name, Func<T1, T2, T3, TResult> puppeteerFunction)479            => ExposeFunctionAsync(name, (Delegate)puppeteerFunction);480        /// <summary>481        /// Adds a function called <c>name</c> on the page's <c>window</c> object.482        /// When called, the function executes <paramref name="puppeteerFunction"/> in C# and returns a <see cref="Task"/> which resolves to the return value of <paramref name="puppeteerFunction"/>.483        /// </summary>484        /// <typeparam name="TResult">The result of <paramref name="puppeteerFunction"/></typeparam>485        /// <typeparam name="T1">The first parameter of <paramref name="puppeteerFunction"/></typeparam>486        /// <typeparam name="T2">The second parameter of <paramref name="puppeteerFunction"/></typeparam>487        /// <typeparam name="T3">The third parameter of <paramref name="puppeteerFunction"/></typeparam>488        /// <typeparam name="T4">The fourth parameter of <paramref name="puppeteerFunction"/></typeparam>489        /// <param name="name">Name of the function on the window object</param>490        /// <param name="puppeteerFunction">Callback function which will be called in Puppeteer's context.</param>491        /// <remarks>492        /// If the <paramref name="puppeteerFunction"/> returns a <see cref="Task"/>, it will be awaited.493        /// Functions installed via <see cref="ExposeFunctionAsync{T1, T2, T3, T4, TResult}(string, Func{T1, T2, T3, T4, TResult})"/> survive navigations494        /// </remarks>495        /// <returns>Task</returns>496        public Task ExposeFunctionAsync<T1, T2, T3, T4, TResult>(string name, Func<T1, T2, T3, T4, TResult> puppeteerFunction)497            => ExposeFunctionAsync(name, (Delegate)puppeteerFunction);498        /// <summary>499        /// Gets the full HTML contents of the page, including the doctype.500        /// </summary>501        /// <returns>Task which resolves to the HTML content.</returns>502        /// <seealso cref="Frame.GetContentAsync"/>503        public Task<string> GetContentAsync() => FrameManager.MainFrame.GetContentAsync();504        /// <summary>505        /// Sets the HTML markup to the page506        /// </summary>507        /// <param name="html">HTML markup to assign to the page.</param>508        /// <param name="options">The navigations options</param>509        /// <returns>Task.</returns>510        /// <seealso cref="Frame.SetContentAsync(string, NavigationOptions)"/>511        public Task SetContentAsync(string html, NavigationOptions options = null) => FrameManager.MainFrame.SetContentAsync(html, options);512        /// <summary>513        /// Navigates to an url514        /// </summary>515        /// <remarks>516        /// <see cref="GoToAsync(string, int?, WaitUntilNavigation[])"/> will throw an error if:517        /// - there's an SSL error (e.g. in case of self-signed certificates).518        /// - target URL is invalid.519        /// - the `timeout` is exceeded during navigation.520        /// - the remote server does not respond or is unreachable.521        /// - the main resource failed to load.522        /// 523        /// <see cref="GoToAsync(string, int?, WaitUntilNavigation[])"/> will not throw an error when any valid HTTP status code is returned by the remote server, 524        /// including 404 "Not Found" and 500 "Internal Server Error".  The status code for such responses can be retrieved by calling <see cref="Response.Status"/>525        /// 526        /// > **NOTE** <see cref="GoToAsync(string, int?, WaitUntilNavigation[])"/> either throws an error or returns a main resource response. 527        /// The only exceptions are navigation to `about:blank` or navigation to the same URL with a different hash, which would succeed and return `null`.528        /// 529        /// > **NOTE** Headless mode doesn't support navigation to a PDF document. See the <see fref="https://bugs.chromium.org/p/chromium/issues/detail?id=761295">upstream issue</see>.530        /// 531        /// Shortcut for <seealso cref="Frame.GoToAsync(string, int?, WaitUntilNavigation[])"/>532        /// </remarks>533        /// <param name="url">URL to navigate page to. The url should include scheme, e.g. https://.</param>534        /// <param name="options">Navigation parameters.</param>535        /// <returns>Task which resolves to the main resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect.</returns>536        /// <seealso cref="GoToAsync(string, int?, WaitUntilNavigation[])"/>537        public Task<Response> GoToAsync(string url, NavigationOptions options) => FrameManager.MainFrame.GoToAsync(url, options);538        /// <summary>539        /// Navigates to an url540        /// </summary>541        /// <param name="url">URL to navigate page to. The url should include scheme, e.g. https://.</param>542        /// <param name="timeout">Maximum navigation time in milliseconds, defaults to 30 seconds, pass <c>0</c> to disable timeout. </param>543        /// <param name="waitUntil">When to consider navigation succeeded, defaults to <see cref="WaitUntilNavigation.Load"/>. Given an array of <see cref="WaitUntilNavigation"/>, navigation is considered to be successful after all events have been fired</param>544        /// <returns>Task which resolves to the main resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect</returns>545        /// <seealso cref="GoToAsync(string, NavigationOptions)"/>546        public Task<Response> GoToAsync(string url, int? timeout = null, WaitUntilNavigation[] waitUntil = null)547            => GoToAsync(url, new NavigationOptions { Timeout = timeout, WaitUntil = waitUntil });548        /// <summary>549        /// Navigates to an url550        /// </summary>551        /// <param name="url">URL to navigate page to. The url should include scheme, e.g. https://.</param>552        /// <param name="waitUntil">When to consider navigation succeeded.</param>553        /// <returns>Task which resolves to the main resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect</returns>554        /// <seealso cref="GoToAsync(string, NavigationOptions)"/>555        public Task<Response> GoToAsync(string url, WaitUntilNavigation waitUntil)556            => GoToAsync(url, new NavigationOptions { WaitUntil = new[] { waitUntil } });557        /// <summary>558        /// generates a pdf of the page with <see cref="MediaType.Print"/> css media. To generate a pdf with <see cref="MediaType.Screen"/> media call <see cref="EmulateMediaAsync(MediaType)"/> with <see cref="MediaType.Screen"/>559        /// </summary>560        /// <param name="file">The file path to save the PDF to. paths are resolved using <see cref="Path.GetFullPath(string)"/></param>561        /// <returns></returns>562        /// <remarks>563        /// Generating a pdf is currently only supported in Chrome headless564        /// </remarks>565        public Task PdfAsync(string file) => PdfAsync(file, new PdfOptions());566        /// <summary>567        ///  generates a pdf of the page with <see cref="MediaType.Print"/> css media. To generate a pdf with <see cref="MediaType.Screen"/> media call <see cref="EmulateMediaAsync(MediaType)"/> with <see cref="MediaType.Screen"/>568        /// </summary>569        /// <param name="file">The file path to save the PDF to. paths are resolved using <see cref="Path.GetFullPath(string)"/></param>570        /// <param name="options">pdf options</param>571        /// <returns></returns>572        /// <remarks>573        /// Generating a pdf is currently only supported in Chrome headless574        /// </remarks>575        public async Task PdfAsync(string file, PdfOptions options)576            => await PdfInternalAsync(file, options).ConfigureAwait(false);577        /// <summary>578        /// generates a pdf of the page with <see cref="MediaType.Print"/> css media. To generate a pdf with <see cref="MediaType.Screen"/> media call <see cref="EmulateMediaAsync(MediaType)"/> with <see cref="MediaType.Screen"/>579        /// </summary>580        /// <returns>Task which resolves to a <see cref="Stream"/> containing the PDF data.</returns>581        /// <remarks>582        /// Generating a pdf is currently only supported in Chrome headless583        /// </remarks>584        public Task<Stream> PdfStreamAsync() => PdfStreamAsync(new PdfOptions());585        /// <summary>586        /// Generates a pdf of the page with <see cref="MediaType.Print"/> css media. To generate a pdf with <see cref="MediaType.Screen"/> media call <see cref="EmulateMediaAsync(MediaType)"/> with <see cref="MediaType.Screen"/>587        /// </summary>588        /// <param name="options">pdf options</param>589        /// <returns>Task which resolves to a <see cref="Stream"/> containing the PDF data.</returns>590        /// <remarks>591        /// Generating a pdf is currently only supported in Chrome headless592        /// </remarks>593        public async Task<Stream> PdfStreamAsync(PdfOptions options)594            => new MemoryStream(await PdfDataAsync(options).ConfigureAwait(false));595        /// <summary>596        /// Generates a pdf of the page with <see cref="MediaType.Print"/> css media. To generate a pdf with <see cref="MediaType.Screen"/> media call <see cref="EmulateMediaAsync(MediaType)"/> with <see cref="MediaType.Screen"/>597        /// </summary>598        /// <returns>Task which resolves to a <see cref="byte"/>[] containing the PDF data.</returns>599        /// <remarks>600        /// Generating a pdf is currently only supported in Chrome headless601        /// </remarks>602        public Task<byte[]> PdfDataAsync() => PdfDataAsync(new PdfOptions());603        /// <summary>604        /// Generates a pdf of the page with <see cref="MediaType.Print"/> css media. To generate a pdf with <see cref="MediaType.Screen"/> media call <see cref="EmulateMediaAsync(MediaType)"/> with <see cref="MediaType.Screen"/>605        /// </summary>606        /// <param name="options">pdf options</param>607        /// <returns>Task which resolves to a <see cref="byte"/>[] containing the PDF data.</returns>608        /// <remarks>609        /// Generating a pdf is currently only supported in Chrome headless610        /// </remarks>611        public Task<byte[]> PdfDataAsync(PdfOptions options) => PdfInternalAsync(null, options);612        internal async Task<byte[]> PdfInternalAsync(string file, PdfOptions options)613        {614            var paperWidth = PaperFormat.Letter.Width;615            var paperHeight = PaperFormat.Letter.Height;616            if (options.Format != null)617            {618                paperWidth = options.Format.Width;619                paperHeight = options.Format.Height;620            }621            else622            {623                if (options.Width != null)624                {625                    paperWidth = ConvertPrintParameterToInches(options.Width);626                }627                if (options.Height != null)628                {629                    paperHeight = ConvertPrintParameterToInches(options.Height);630                }631            }632            var marginTop = ConvertPrintParameterToInches(options.MarginOptions.Top);633            var marginLeft = ConvertPrintParameterToInches(options.MarginOptions.Left);634            var marginBottom = ConvertPrintParameterToInches(options.MarginOptions.Bottom);635            var marginRight = ConvertPrintParameterToInches(options.MarginOptions.Right);636            var result = await Client.SendAsync<PagePrintToPDFResponse>("Page.printToPDF", new PagePrintToPDFRequest637            {638                TransferMode = "ReturnAsStream",639                Landscape = options.Landscape,640                DisplayHeaderFooter = options.DisplayHeaderFooter,641                HeaderTemplate = options.HeaderTemplate,642                FooterTemplate = options.FooterTemplate,643                PrintBackground = options.PrintBackground,644                Scale = options.Scale,645                PaperWidth = paperWidth,646                PaperHeight = paperHeight,647                MarginTop = marginTop,648                MarginBottom = marginBottom,649                MarginLeft = marginLeft,650                MarginRight = marginRight,651                PageRanges = options.PageRanges,652                PreferCSSPageSize = options.PreferCSSPageSize653            }).ConfigureAwait(false);654            return await ProtocolStreamReader.ReadProtocolStreamByteAsync(Client, result.Stream, file).ConfigureAwait(false);655        }656        /// <summary>657        /// Enables/Disables Javascript on the page658        /// </summary>659        /// <returns>Task.</returns>660        /// <param name="enabled">Whether or not to enable JavaScript on the page.</param>661        public Task SetJavaScriptEnabledAsync(bool enabled)662        {663            if (enabled == JavascriptEnabled)664            {665                return Task.CompletedTask;666            }667            JavascriptEnabled = enabled;668            return Client.SendAsync("Emulation.setScriptExecutionDisabled", new EmulationSetScriptExecutionDisabledRequest669            {670                Value = !enabled671            });672        }673        /// <summary>674        /// Toggles bypassing page's Content-Security-Policy.675        /// </summary>676        /// <param name="enabled">sets bypassing of page's Content-Security-Policy.</param>677        /// <returns></returns>678        /// <remarks>679        /// CSP bypassing happens at the moment of CSP initialization rather then evaluation.680        /// Usually this means that <see cref="SetBypassCSPAsync(bool)"/> should be called before navigating to the domain.681        /// </remarks>682        public Task SetBypassCSPAsync(bool enabled) => Client.SendAsync("Page.setBypassCSP", new PageSetBypassCSPRequest683        {684            Enabled = enabled685        });686        /// <summary>687        /// Emulates a media such as screen or print.688        /// </summary>689        /// <returns>Task.</returns>690        /// <param name="media">Media to set.</param>691        [Obsolete("User EmulateMediaTypeAsync instead")]692        public Task EmulateMediaAsync(MediaType media) => EmulateMediaTypeAsync(media);693        /// <summary>694        /// Emulates a media such as screen or print.695        /// </summary>696        /// <param name="type">Media to set.</param>697        /// <example>698        /// <code>699        /// <![CDATA[700        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('screen').matches)");701        /// // → true702        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('print').matches)");703        /// // → true704        /// await page.EmulateMediaTypeAsync(MediaType.Print);705        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('screen').matches)");706        /// // → false707        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('print').matches)");708        /// // → true709        /// await page.EmulateMediaTypeAsync(MediaType.None);710        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('screen').matches)");711        /// // → true712        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('print').matches)");713        /// // → true714        /// ]]>715        /// </code>716        /// </example>717        /// <returns>Emulate media type task.</returns>718        public Task EmulateMediaTypeAsync(MediaType type)719            => Client.SendAsync("Emulation.setEmulatedMedia", new EmulationSetEmulatedMediaTypeRequest { Media = type });720        /// <summary>721        /// Given an array of media feature objects, emulates CSS media features on the page.722        /// </summary>723        /// <param name="features">Features to apply</param>724        /// <example>725        /// <code>726        /// <![CDATA[727        /// await page.EmulateMediaFeaturesAsync(new MediaFeature[]{ new MediaFeature { MediaFeature =  MediaFeature.PrefersColorScheme, Value = "dark" }});728        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('(prefers-color-scheme: dark)').matches)");729        /// // → true730        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('(prefers-color-scheme: light)').matches)");731        /// // → false732        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('(prefers-color-scheme: no-preference)').matches)");733        /// // → false734        /// await page.EmulateMediaFeaturesAsync(new MediaFeature[]{ new MediaFeature { MediaFeature = MediaFeature.PrefersReducedMotion, Value = "reduce" }});735        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('(prefers-reduced-motion: reduce)').matches)");736        /// // → true737        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('(prefers-color-scheme: no-preference)').matches)");738        /// // → false739        /// await page.EmulateMediaFeaturesAsync(new MediaFeature[]740        /// { 741        ///   new MediaFeature { MediaFeature = MediaFeature.PrefersColorScheme, Value = "dark" },742        ///   new MediaFeature { MediaFeature = MediaFeature.PrefersReducedMotion, Value = "reduce" },743        /// });744        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('(prefers-color-scheme: dark)').matches)");745        /// // → true746        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('(prefers-color-scheme: light)').matches)");747        /// // → false748        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('(prefers-color-scheme: no-preference)').matches)");749        /// // → false750        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('(prefers-reduced-motion: reduce)').matches)");751        /// // → true752        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('(prefers-color-scheme: no-preference)').matches)");753        /// // → false754        /// ]]>755        /// </code>756        /// </example>757        /// <returns>Emulate features task</returns>758        public Task EmulateMediaFeaturesAsync(IEnumerable<MediaFeatureValue> features)759            => Client.SendAsync("Emulation.setEmulatedMedia", new EmulationSetEmulatedMediaFeatureRequest { Features = features });760        /// <summary>761        /// Sets the viewport.762        /// In the case of multiple pages in a single browser, each page can have its own viewport size.763        /// <see cref="SetViewportAsync(ViewPortOptions)"/> will resize the page. A lot of websites don't expect phones to change size, so you should set the viewport before navigating to the page.764        /// </summary>765        /// <example>766        ///<![CDATA[767        /// using(var page = await browser.NewPageAsync())768        /// {769        ///     await page.SetViewPortAsync(new ViewPortOptions770        ///     {771        ///         Width = 640, 772        ///         Height = 480, 773        ///         DeviceScaleFactor = 1774        ///     });775        ///     await page.goto('https://www.example.com');776        /// }777        /// ]]>778        /// </example>779        /// <returns>The viewport task.</returns>780        /// <param name="viewport">Viewport options.</param>781        public async Task SetViewportAsync(ViewPortOptions viewport)782        {783            var needsReload = await _emulationManager.EmulateViewport(viewport).ConfigureAwait(false);784            Viewport = viewport;785            if (needsReload)786            {787                await ReloadAsync().ConfigureAwait(false);788            }789        }790        /// <summary>791        /// Closes the page.792        /// </summary>793        /// <param name="options">Close options.</param>794        /// <returns>Task.</returns>795        public Task CloseAsync(PageCloseOptions options = null)796        {797            if (!(Client?.Connection?.IsClosed ?? true))798            {799                var runBeforeUnload = options?.RunBeforeUnload ?? false;800                if (runBeforeUnload)801                {802                    return Client.SendAsync("Page.close");803                }804                return Client.Connection.SendAsync("Target.closeTarget", new TargetCloseTargetRequest805                {806                    TargetId = Target.TargetId807                }).ContinueWith(task => Target.CloseTask);808            }809            return _closeCompletedTcs.Task;810        }811        /// <summary>812        /// Reloads the page813        /// </summary>814        /// <param name="options">Navigation options</param>815        /// <returns>Task which resolves to the main resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect</returns>816        /// <seealso cref="ReloadAsync(int?, WaitUntilNavigation[])"/>817        public async Task<Response> ReloadAsync(NavigationOptions options)818        {819            var navigationTask = WaitForNavigationAsync(options);820            await Task.WhenAll(821              navigationTask,822              Client.SendAsync("Page.reload")823            ).ConfigureAwait(false);824            return navigationTask.Result;825        }826        /// <summary>827        /// Reloads the page828        /// </summary>829        /// <param name="timeout">Maximum navigation time in milliseconds, defaults to 30 seconds, pass <c>0</c> to disable timeout. </param>830        /// <param name="waitUntil">When to consider navigation succeeded, defaults to <see cref="WaitUntilNavigation.Load"/>. Given an array of <see cref="WaitUntilNavigation"/>, navigation is considered to be successful after all events have been fired</param>831        /// <returns>Task which resolves to the main resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect</returns>832        /// <seealso cref="ReloadAsync(NavigationOptions)"/>833        public Task<Response> ReloadAsync(int? timeout = null, WaitUntilNavigation[] waitUntil = null)834            => ReloadAsync(new NavigationOptions { Timeout = timeout, WaitUntil = waitUntil });835        /// <summary>836        /// Waits for a function to be evaluated to a truthy value837        /// </summary>838        /// <param name="script">Function to be evaluated in browser context</param>839        /// <param name="options">Optional waiting parameters</param>840        /// <param name="args">Arguments to pass to <c>script</c></param>841        /// <returns>A task that resolves when the <c>script</c> returns a truthy value</returns>842        /// <seealso cref="Frame.WaitForFunctionAsync(string, WaitForFunctionOptions, object[])"/>843        public Task<JSHandle> WaitForFunctionAsync(string script, WaitForFunctionOptions options = null, params object[] args)844            => MainFrame.WaitForFunctionAsync(script, options ?? new WaitForFunctionOptions(), args);845        /// <summary>846        /// Waits for an expression to be evaluated to a truthy value847        /// </summary>848        /// <param name="script">Expression to be evaluated in browser context</param>849        /// <param name="options">Optional waiting parameters</param>850        /// <returns>A task that resolves when the <c>script</c> returns a truthy value</returns>851        /// <seealso cref="Frame.WaitForExpressionAsync(string, WaitForFunctionOptions)"/>852        public Task<JSHandle> WaitForExpressionAsync(string script, WaitForFunctionOptions options = null)853            => MainFrame.WaitForExpressionAsync(script, options ?? new WaitForFunctionOptions());854        /// <summary>855        /// Waits for a selector to be added to the DOM856        /// </summary>857        /// <param name="selector">A selector of an element to wait for</param>858        /// <param name="options">Optional waiting parameters</param>859        /// <returns>A task that resolves when element specified by selector string is added to DOM.860        /// Resolves to `null` if waiting for `hidden: true` and selector is not found in DOM.</returns>861        /// <seealso cref="WaitForXPathAsync(string, WaitForSelectorOptions)"/>862        /// <seealso cref="Frame.WaitForSelectorAsync(string, WaitForSelectorOptions)"/>863        public Task<ElementHandle> WaitForSelectorAsync(string selector, WaitForSelectorOptions options = null)864            => MainFrame.WaitForSelectorAsync(selector, options ?? new WaitForSelectorOptions());865        /// <summary>866        /// Waits for a xpath selector to be added to the DOM867        /// </summary>868        /// <param name="xpath">A xpath selector of an element to wait for</param>869        /// <param name="options">Optional waiting parameters</param>870        /// <returns>A task which resolves when element specified by xpath string is added to DOM. 871        /// Resolves to `null` if waiting for `hidden: true` and xpath is not found in DOM.</returns>872        /// <example>873        /// <code>874        /// <![CDATA[875        /// var browser = await Puppeteer.LaunchAsync(new LaunchOptions());876        /// var page = await browser.NewPageAsync();877        /// string currentURL = null;878        /// page879        ///     .WaitForXPathAsync("//img")880        ///     .ContinueWith(_ => Console.WriteLine("First URL with image: " + currentURL));881        /// foreach (var current in new[] { "https://example.com", "https://google.com", "https://bbc.com" })882        /// {883        ///     currentURL = current;884        ///     await page.GoToAsync(currentURL);885        /// }886        /// await browser.CloseAsync();887        /// ]]>888        /// </code>889        /// </example>890        /// <seealso cref="WaitForSelectorAsync(string, WaitForSelectorOptions)"/>891        /// <seealso cref="Frame.WaitForXPathAsync(string, WaitForSelectorOptions)"/>892        public Task<ElementHandle> WaitForXPathAsync(string xpath, WaitForSelectorOptions options = null)893            => MainFrame.WaitForXPathAsync(xpath, options ?? new WaitForSelectorOptions());894        /// <summary>895        /// This resolves when the page navigates to a new URL or reloads.896        /// It is useful for when you run code which will indirectly cause the page to navigate.897        /// </summary>898        /// <param name="options">navigation options</param>899        /// <returns>Task which resolves to the main resource response. 900        /// In case of multiple redirects, the navigation will resolve with the response of the last redirect.901        /// In case of navigation to a different anchor or navigation due to History API usage, the navigation will resolve with `null`.902        /// </returns>903        /// <remarks>904        /// Usage of the <c>History API</c> <see href="https://developer.mozilla.org/en-US/docs/Web/API/History_API"/> to change the URL is considered a navigation905        /// </remarks>906        /// <example>907        /// <code>908        /// <![CDATA[909        /// var navigationTask = page.WaitForNavigationAsync();910        /// await page.ClickAsync("a.my-link");911        /// await navigationTask;912        /// ]]>913        /// </code>914        /// </example>915        public Task<Response> WaitForNavigationAsync(NavigationOptions options = null) => FrameManager.WaitForFrameNavigationAsync(FrameManager.MainFrame, options);916        /// <summary>917        /// Waits for a request.918        /// </summary>919        /// <example>920        /// <code>921        /// <![CDATA[922        /// var firstRequest = await page.WaitForRequestAsync("http://example.com/resource");923        /// return firstRequest.Url;924        /// ]]>925        /// </code>926        /// </example>927        /// <returns>A task which resolves when a matching request was made.</returns>928        /// <param name="url">URL to wait for.</param>929        /// <param name="options">Options.</param>930        public Task<Request> WaitForRequestAsync(string url, WaitForOptions options = null)931            => WaitForRequestAsync(request => request.Url == url, options);932        /// <summary>933        /// Waits for a request.934        /// </summary>935        /// <example>936        /// <code>937        /// <![CDATA[938        /// var request = await page.WaitForRequestAsync(request => request.Url === "http://example.com" && request.Method === HttpMethod.Get;939        /// return request.Url;940        /// ]]>941        /// </code>942        /// </example>943        /// <returns>A task which resolves when a matching request was made.</returns>944        /// <param name="predicate">Function which looks for a matching request.</param>945        /// <param name="options">Options.</param>946        public async Task<Request> WaitForRequestAsync(Func<Request, bool> predicate, WaitForOptions options = null)947        {948            var timeout = options?.Timeout ?? DefaultTimeout;949            var requestTcs = new TaskCompletionSource<Request>(TaskCreationOptions.RunContinuationsAsynchronously);950            void requestEventListener(object sender, RequestEventArgs e)951            {952                if (predicate(e.Request))953                {954                    requestTcs.TrySetResult(e.Request);955                    FrameManager.NetworkManager.Request -= requestEventListener;956                }957            }958            FrameManager.NetworkManager.Request += requestEventListener;959            await Task.WhenAny(requestTcs.Task, SessionClosedTask).WithTimeout(timeout, t =>960            {961                FrameManager.NetworkManager.Request -= requestEventListener;962                return new TimeoutException($"Timeout of {t.TotalMilliseconds} ms exceeded");963            }).ConfigureAwait(false);964            if (SessionClosedTask.IsFaulted)965            {966                await SessionClosedTask.ConfigureAwait(false);967            }968            return await requestTcs.Task.ConfigureAwait(false);969        }970        /// <summary>971        /// Waits for a response.972        /// </summary>973        /// <example>974        /// <code>975        /// <![CDATA[976        /// var firstResponse = await page.WaitForResponseAsync("http://example.com/resource");977        /// return firstResponse.Url;978        /// ]]>979        /// </code>980        /// </example>981        /// <returns>A task which resolves when a matching response is received.</returns>982        /// <param name="url">URL to wait for.</param>983        /// <param name="options">Options.</param>984        public Task<Response> WaitForResponseAsync(string url, WaitForOptions options = null)985            => WaitForResponseAsync(response => response.Url == url, options);986        /// <summary>987        /// Waits for a response.988        /// </summary>989        /// <example>990        /// <code>991        /// <![CDATA[992        /// var response = await page.WaitForResponseAsync(response => response.Url === "http://example.com" && response.Status === HttpStatus.Ok;993        /// return response.Url;994        /// ]]>995        /// </code>996        /// </example>997        /// <returns>A task which resolves when a matching response is received.</returns>998        /// <param name="predicate">Function which looks for a matching response.</param>999        /// <param name="options">Options.</param>1000        public async Task<Response> WaitForResponseAsync(Func<Response, bool> predicate, WaitForOptions options = null)1001        {1002            var timeout = options?.Timeout ?? DefaultTimeout;1003            var responseTcs = new TaskCompletionSource<Response>(TaskCreationOptions.RunContinuationsAsynchronously);1004            void responseEventListener(object sender, ResponseCreatedEventArgs e)1005            {1006                if (predicate(e.Response))1007                {1008                    responseTcs.TrySetResult(e.Response);1009                    FrameManager.NetworkManager.Response -= responseEventListener;1010                }1011            }1012            FrameManager.NetworkManager.Response += responseEventListener;1013            await Task.WhenAny(responseTcs.Task, SessionClosedTask).WithTimeout(timeout).ConfigureAwait(false);1014            if (SessionClosedTask.IsFaulted)1015            {1016                await SessionClosedTask.ConfigureAwait(false);1017            }1018            return await responseTcs.Task.ConfigureAwait(false);1019        }1020        /// <summary>1021        /// Navigate to the previous page in history.1022        /// </summary>1023        /// <returns>Task that resolves to the main resource response. In case of multiple redirects, 1024        /// the navigation will resolve with the response of the last redirect. If can not go back, resolves to null.</returns>1025        /// <param name="options">Navigation parameters.</param>1026        public Task<Response> GoBackAsync(NavigationOptions options = null) => GoAsync(-1, options);1027        /// <summary>1028        /// Navigate to the next page in history.1029        /// </summary>1030        /// <returns>Task that resolves to the main resource response. In case of multiple redirects, 1031        /// the navigation will resolve with the response of the last redirect. If can not go forward, resolves to null.</returns>1032        /// <param name="options">Navigation parameters.</param>1033        public Task<Response> GoForwardAsync(NavigationOptions options = null) => GoAsync(1, options);1034        /// <summary>1035        /// Resets the background color and Viewport after taking Screenshots using BurstMode.1036        /// </summary>1037        /// <returns>The burst mode off.</returns>1038        public Task SetBurstModeOffAsync()1039        {1040            return Task.CompletedTask;1041        }1042        #endregion1043        internal void OnPopup(Page popupPage) => Popup?.Invoke(this, new PopupEventArgs { PopupPage = popupPage });1044        #region Private Method1045        internal static async Task<Page> CreateAsync(1046            CDPSession client,1047            Target target,1048            bool ignoreHTTPSErrors,1049            ViewPortOptions defaultViewPort,1050            TaskQueue screenshotTaskQueue)1051        {1052            var page = new Page(client, target, screenshotTaskQueue);1053            await page.InitializeAsync(ignoreHTTPSErrors).ConfigureAwait(false);1054            if (defaultViewPort != null)1055            {1056                await page.SetViewportAsync(defaultViewPort).ConfigureAwait(false);1057            }1058            return page;1059        }1060        private async Task InitializeAsync(bool ignoreHTTPSErrors)1061        {1062            FrameManager = await FrameManager.CreateFrameManagerAsync(Client, this, ignoreHTTPSErrors, _timeoutSettings).ConfigureAwait(false);1063            var networkManager = FrameManager.NetworkManager;1064            Client.MessageReceived += Client_MessageReceived;1065            FrameManager.FrameAttached += (sender, e) => FrameAttached?.Invoke(this, e);1066            FrameManager.FrameDetached += (sender, e) => FrameDetached?.Invoke(this, e);...

Full Screen

Full Screen

Browser.cs

Source:Browser.cs Github

copy

Full Screen

...46            Connection = connection;47            IgnoreHTTPSErrors = options.IgnoreHTTPSErrors;48            AppMode = options.AppMode;49            _targets = new Dictionary<string, Target>();50            ScreenshotTaskQueue = new TaskQueue();51            Connection.Closed += (object sender, EventArgs e) => Disconnected?.Invoke(this, new EventArgs());52            Connection.MessageReceived += Connect_MessageReceived;53            _closeCallBack = closeCallBack;54        }55        #region Private members56        private readonly Dictionary<string, Target> _targets;57        private readonly Func<Task> _closeCallBack;58        #endregion59        #region Properties60        /// <summary>61        /// 62        /// </summary>63        public event EventHandler Closed;64        /// <summary>65        /// Raised when puppeteer gets disconnected from the Chromium instance. This might happen because one of the following66        /// - Chromium is closed or crashed67        /// - <see cref="Disconnect"/> method was called68        /// </summary>69        public event EventHandler Disconnected;70        /// <summary>71        /// Raised when the url of a target changes72        /// </summary>73        public event EventHandler<TargetChangedArgs> TargetChanged;74        /// <summary>75        /// Raised when a target is created, for example when a new page is opened by <c>window.open</c> <see href="https://developer.mozilla.org/en-US/docs/Web/API/Window/open"/> or <see cref="NewPageAsync"/>.76        /// </summary>77        public event EventHandler<TargetChangedArgs> TargetCreated;78        /// <summary>79        /// Raised when a target is destroyed, for example when a page is closed80        /// </summary>81        public event EventHandler<TargetChangedArgs> TargetDestroyed;82        /// <summary>83        /// Gets the Browser websocket url84        /// </summary>85        /// <remarks>86        /// Browser websocket endpoint which can be used as an argument to <see cref="Puppeteer.ConnectAsync(ConnectOptions, ILoggerFactory)"/>.87        /// The format is <c>ws://${host}:${port}/devtools/browser/[id]</c>88        /// You can find the <c>webSocketDebuggerUrl</c> from <c>http://${host}:${port}/json/version</c>.89        /// Learn more about the devtools protocol <see href="https://chromedevtools.github.io/devtools-protocol"/> 90        /// and the browser endpoint <see href="https://chromedevtools.github.io/devtools-protocol/#how-do-i-access-the-browser-target"/>91        /// </remarks>92        public string WebSocketEndpoint => Connection.Url;93        /// <summary>94        /// Gets the spawned browser process. Returns <c>null</c> if the browser instance was created with <see cref="Puppeteer.ConnectAsync(ConnectOptions, ILoggerFactory)"/> method.95        /// </summary>96        public Process Process { get; }97        /// <summary>98        /// Gets or Sets whether to ignore HTTPS errors during navigation99        /// </summary>100        public bool IgnoreHTTPSErrors { get; set; }101        /// <summary>102        /// Gets or Sets whether to use appMode or not103        /// </summary>104        public bool AppMode { get; set; }105        /// <summary>106        /// Gets a value indicating if the browser is closed107        /// </summary>108        public bool IsClosed { get; internal set; }109        internal TaskQueue ScreenshotTaskQueue { get; set; }110        internal Connection Connection { get; }111        #endregion112        #region Public Methods113        /// <summary>114        /// Creates a new page115        /// </summary>116        /// <returns>Task which resolves to a new <see cref="Page"/> object</returns>117        public async Task<Page> NewPageAsync()118        {119            string targetId = (await Connection.SendAsync("Target.createTarget", new Dictionary<string, object>(){120                {"url", "about:blank"}121              })).targetId.ToString();122            var target = _targets[targetId];123            await target.InitializedTask;...

Full Screen

Full Screen

Connection.cs

Source:Connection.cs Github

copy

Full Screen

...15    /// A connection handles the communication with a Chromium browser16    /// </summary>17    public class Connection : IDisposable18    {19        private TaskQueue _callbackQueue = new TaskQueue();20        internal Connection(string url, int delay, IConnectionTransport transport)21        {22            Url = url;23            Delay = delay;24            Transport = transport;25            Transport.MessageReceived += Transport_MessageReceived;26            Transport.Closed += Transport_Closed;27            _callbacks = new ConcurrentDictionary<int, MessageTask>();28            _sessions = new ConcurrentDictionary<string, CDPSession>();29            _asyncSessions = new AsyncDictionaryHelper<string, CDPSession>(_sessions, "Session {0} not found");30        }31        #region Private Members32        private int _lastId;33        private readonly ConcurrentDictionary<int, MessageTask> _callbacks;...

Full Screen

Full Screen

WebSocketTransport.cs

Source:WebSocketTransport.cs Github

copy

Full Screen

...12    public class WebSocketTransport : IConnectionTransport13    {14        private readonly WebSocket _client;15        private readonly bool _queueRequests;16        private readonly TaskQueue _socketQueue;17        private CancellationTokenSource _readerCancellationSource { get; }18        /// <summary>19        /// Gets a value indicating whether this <see cref="PuppeteerSharp.Transport.IConnectionTransport"/> is closed.20        /// </summary>21        public bool IsClosed { get; private set; }22        /// <summary>23        /// Occurs when the transport is closed.24        /// </summary>25        public event EventHandler Closed;26        /// <summary>27        /// Occurs when a message is received.28        /// </summary>29        public event EventHandler<MessageReceivedEventArgs> MessageReceived;30        /// <summary>31        /// Initializes a new instance of the <see cref="PuppeteerSharp.Transport.WebSocketTransport"/> class.32        /// </summary>33        /// <param name="wsClient">WebSocket client.</param>34        /// <param name="queueRequests">If set to <c>true</c> to queue requests.</param>35        public WebSocketTransport(WebSocket wsClient, bool queueRequests = true)36        {37            _client = wsClient;38            _queueRequests = queueRequests;39            _socketQueue = new TaskQueue();40            _readerCancellationSource = new CancellationTokenSource();41            Task.Factory.StartNew(GetResponseAsync);42        }43        /// <summary>44        /// Sends a message using the transport.45        /// </summary>46        /// <returns>The task.</returns>47        /// <param name="message">Message to send.</param>48        public Task SendAsync(string message)49        {50            var encoded = Encoding.UTF8.GetBytes(message);51            var buffer = new ArraySegment<byte>(encoded, 0, encoded.Length);52            Task sendTask() => _client.SendAsync(buffer, WebSocketMessageType.Text, true, default);53            return _queueRequests ? _socketQueue.Enqueue(sendTask) : sendTask();...

Full Screen

Full Screen

TaskQueue.cs

Source:TaskQueue.cs Github

copy

Full Screen

2using System.Threading;3using System.Threading.Tasks;4namespace PuppeteerSharp.Helpers5{6    internal class TaskQueue7    {8        private SemaphoreSlim _semaphore;9        internal TaskQueue()10        {11            _semaphore = new SemaphoreSlim(1);12        }13        internal async Task<T> Enqueue<T>(Func<Task<T>> taskGenerator)14        {15            await _semaphore.WaitAsync();16            try17            {18                return await taskGenerator();19            }20            finally21            {22                _semaphore.Release();23            }...

Full Screen

Full Screen

TaskQueue

Using AI Code Generation

copy

Full Screen

1var browser = await Puppeteer.LaunchAsync(new LaunchOptions2{3    Args = new string[] { "--start-maximized" },4});5var page = await browser.NewPageAsync();6await page.TypeAsync("input[name='q']", "PuppeteerSharp");7await page.Keyboard.PressAsync("Enter");8await page.WaitForNavigationAsync();9await page.ScreenshotAsync("google.png");10await browser.CloseAsync();11var browser = await Puppeteer.LaunchAsync(new LaunchOptions12{13    Args = new string[] { "--start-maximized" },14});15var page = await browser.NewPageAsync();16await page.TypeAsync("input[name='q']", "PuppeteerSharp");17await page.Keyboard.PressAsync("Enter");18await page.WaitForNavigationAsync();19await page.ScreenshotAsync("google.png");20await browser.CloseAsync();21error CS0234: The type or namespace name 'Helpers' does not exist in the namespace 'PuppeteerSharp' (are you missing an assembly reference?)22error CS0234: The type or namespace name 'Helpers' does not exist in the namespace 'PuppeteerSharp' (are you missing an assembly reference?)23error CS0234: The type or namespace name 'Helpers' does not exist in the namespace 'PuppeteerSharp' (are you

Full Screen

Full Screen

TaskQueue

Using AI Code Generation

copy

Full Screen

1using PuppeteerSharp.Extra;2using PuppeteerSharp.Extra.Tasks;3Error CS0246 The type or namespace name 'Puppeteer' could not be found (are you missing a using directive or an assembly reference?)4using PuppeteerSharp;5Error CS0246 The type or namespace name 'PuppeteerSharp' could not be found (are you missing a using directive or an assembly reference?)6using PuppeteerSharp.Contrib;7Error CS0246 The type or namespace name 'PuppeteerSharp' could not be found (are you missing a using directive or an assembly reference?)

Full Screen

Full Screen

TaskQueue

Using AI Code Generation

copy

Full Screen

1var taskQueue = new TaskQueue();2await taskQueue.Enqueue(async () =>3{4});5await taskQueue.Enqueue(async () =>6{7});8var taskQueue = new TaskQueue();9await taskQueue.Enqueue(async () =>10{11});12await taskQueue.Enqueue(async () =>13{14});15var taskQueue = new TaskQueue();16await taskQueue.Enqueue(async () =>17{18});19await taskQueue.Enqueue(async () =>20{21});22var taskQueue = new TaskQueue();23await taskQueue.Enqueue(async () =>24{25});26await taskQueue.Enqueue(async () =>27{28});29var taskQueue = new TaskQueue();30await taskQueue.Enqueue(async () =>31{32});33await taskQueue.Enqueue(async () =>34{35});36var taskQueue = new TaskQueue();37await taskQueue.Enqueue(async () =>38{39});40await taskQueue.Enqueue(async () =>41{42});43var taskQueue = new TaskQueue();44await taskQueue.Enqueue(async () =>45{46});47await taskQueue.Enqueue(async () =>48{49});50var taskQueue = new TaskQueue();51await taskQueue.Enqueue(async () =>52{53});54await taskQueue.Enqueue(async () =>55{56});57var taskQueue = new TaskQueue();58await taskQueue.Enqueue(async () =>59{60});61await taskQueue.Enqueue(async () =>62{63});

Full Screen

Full Screen

TaskQueue

Using AI Code Generation

copy

Full Screen

1using PuppeteerSharp.Helpers;2var taskQueue = new TaskQueue();3await taskQueue.Enqueue(async () => {4    await page.ScreenshotAsync("google.png");5});6using PuppeteerSharp.Helpers;7var taskQueue = new TaskQueue();8await taskQueue.Enqueue(async () => {9    await page.ScreenshotAsync("bing.png");10});11using PuppeteerSharp.Helpers;12var taskQueue = new TaskQueue();13await taskQueue.Enqueue(async () => {14    await page.ScreenshotAsync("yahoo.png");15});16using PuppeteerSharp.Helpers;17using System;18using System.Threading.Tasks;19{20    {21        static async Task Main(string[] args)22        {23            var taskQueue = new TaskQueue();24            await taskQueue.Enqueue(async () => {25                await Task.Delay(5000);26                Console.WriteLine("Hello 1");27            });28            await taskQueue.Enqueue(async () => {29                await Task.Delay(5000);30                Console.WriteLine("Hello 2");31            });32            await taskQueue.Enqueue(async () => {33                await Task.Delay(5000);34                Console.WriteLine("Hello 3");35            });36        }37    }38}

Full Screen

Full Screen

TaskQueue

Using AI Code Generation

copy

Full Screen

1await new TaskQueue().RunAsync(async () => 2{3});4await new TaskQueue().RunAsync(async () => 5{6});7await new TaskQueue().RunAsync(async () => 8{9});10await new TaskQueue().RunAsync(async () => 11{12});13await new TaskQueue().RunAsync(async () => 14{15});16await new TaskQueue().RunAsync(async () => 17{18});19await new TaskQueue().RunAsync(async () => 20{21});22await new TaskQueue().RunAsync(async () => 23{24});25await new TaskQueue().RunAsync(async () => 26{27});28await new TaskQueue().RunAsync(async () => 29{30});31await new TaskQueue().RunAsync(async () => 32{33});34await new TaskQueue().RunAsync(async () => 35{36});37await new TaskQueue().RunAsync(async () => 38{

Full Screen

Full Screen

TaskQueue

Using AI Code Generation

copy

Full Screen

1using PuppeteerSharp.Helpers;2using System;3using System.Threading.Tasks;4{5    {6        static async Task Main(string[] args)7        {8            var queue = new TaskQueue();9            var browser = await Puppeteer.LaunchAsync(new LaunchOptions10            {11            });12            var page = await browser.NewPageAsync();13            await page.EvaluateExpressionAsync("document.body.style.backgroundColor = 'red'");14            await page.EvaluateExpressionAsync("document.body.style.backgroundColor = 'blue'");15            await page.EvaluateExpressionAsync("document.body.style.backgroundColor = 'green'");16            await page.EvaluateExpressionAsync("document.body.style.backgroundColor = 'yellow'");17            await page.EvaluateExpressionAsync("document.body.style.backgroundColor = 'orange'");18            await page.EvaluateExpressionAsync("document.body.style.backgroundColor = 'purple'");19            await page.EvaluateExpressionAsync("document.body.style.backgroundColor = 'black'");20            await page.EvaluateExpressionAsync("document.body.style.backgroundColor = 'white'");21            await page.EvaluateExpressionAsync("document.body.style.backgroundColor = 'gray'");22            await page.EvaluateExpressionAsync("document.body.style.backgroundColor = 'brown'");23            await page.EvaluateExpressionAsync("document.body.style.backgroundColor = 'pink'");24            await page.EvaluateExpressionAsync("document.body.style.backgroundColor = 'aqua'");25            await page.EvaluateExpressionAsync("document.body.style.backgroundColor = 'silver'");26            await page.EvaluateExpressionAsync("document.body.style.backgroundColor = 'maroon'");27            await page.EvaluateExpressionAsync("document.body.style.backgroundColor = 'olive'");28            await page.EvaluateExpressionAsync("document.body.style.backgroundColor = 'teal'");29            await page.EvaluateExpressionAsync("document.body.style.backgroundColor = 'navy'");30            await page.EvaluateExpressionAsync("document.body.style.backgroundColor = 'fuchsia'");31            await page.EvaluateExpressionAsync("document.body.style.backgroundColor = 'lime'");32            await page.EvaluateExpressionAsync("document.body.style.backgroundColor = 'red'");33            await page.EvaluateExpressionAsync("document.body.style.backgroundColor = 'blue'");34            await page.EvaluateExpressionAsync("document.body.style.backgroundColor = 'green'");35            await page.EvaluateExpressionAsync("document.body.style.backgroundColor = 'yellow'");36            await page.EvaluateExpressionAsync("document.body.style.backgroundColor = 'orange'");37            await page.EvaluateExpressionAsync("document.body.style.backgroundColor = 'purple'");38            await page.EvaluateExpressionAsync("document.body.style

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run Puppeteer-sharp automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Most used methods in TaskQueue

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful