How to use FileChooser class of PuppeteerSharp package

Best Puppeteer-sharp code snippet using PuppeteerSharp.FileChooser

Page.cs

Source:Page.cs Github

copy

Full Screen

...45        private readonly IDictionary<string, Worker> _workers;46        private readonly ILogger _logger;47        private readonly TaskCompletionSource<bool> _closeCompletedTcs = new(TaskCreationOptions.RunContinuationsAsynchronously);48        private readonly TimeoutSettings _timeoutSettings;49        private readonly ConcurrentDictionary<Guid, TaskCompletionSource<FileChooser>> _fileChooserInterceptors;50        private PageGetLayoutMetricsResponse _burstModeMetrics;51        private bool _screenshotBurstModeOn;52        private ScreenshotOptions _screenshotBurstModeOptions;53        private TaskCompletionSource<bool> _sessionClosedTcs;54        private static readonly Dictionary<string, decimal> _unitToPixels = new()55        {56            { "px", 1 },57            { "in", 96 },58            { "cm", 37.8m },59            { "mm", 3.78m }60        };61        /// <summary>62        /// List of supported metrics provided by the <see cref="Metrics"/> event.63        /// </summary>64        public static readonly IEnumerable<string> SupportedMetrics = new List<string>65        {66            "Timestamp",67            "Documents",68            "Frames",69            "JSEventListeners",70            "Nodes",71            "LayoutCount",72            "RecalcStyleCount",73            "LayoutDuration",74            "RecalcStyleDuration",75            "ScriptDuration",76            "TaskDuration",77            "JSHeapUsedSize",78            "JSHeapTotalSize"79        };80        private Page(81            CDPSession client,82            Target target,83            TaskQueue screenshotTaskQueue)84        {85            Client = client;86            Target = target;87            Keyboard = new Keyboard(client);88            Mouse = new Mouse(client, Keyboard);89            Touchscreen = new Touchscreen(client, Keyboard);90            Tracing = new Tracing(client);91            Coverage = new Coverage(client);92            _fileChooserInterceptors = new ConcurrentDictionary<Guid, TaskCompletionSource<FileChooser>>();93            _timeoutSettings = new TimeoutSettings();94            _emulationManager = new EmulationManager(client);95            _pageBindings = new Dictionary<string, Delegate>();96            _workers = new ConcurrentDictionary<string, Worker>();97            _logger = Client.Connection.LoggerFactory.CreateLogger<Page>();98            Accessibility = new Accessibility(client);99            _screenshotTaskQueue = screenshotTaskQueue;100            _ = target.CloseTask.ContinueWith(101                _ =>102                {103                    try104                    {105                        Close?.Invoke(this, EventArgs.Empty);106                    }107                    finally108                    {109                        IsClosed = true;110                        _closeCompletedTcs.TrySetResult(true);111                    }112                },113                TaskScheduler.Default);114        }115        /// <summary>116        /// Raised when the JavaScript <c>load</c> <see href="https://developer.mozilla.org/en-US/docs/Web/Events/load"/> event is dispatched.117        /// </summary>118        public event EventHandler Load;119        /// <summary>120        /// Raised when the page crashes121        /// </summary>122        public event EventHandler<ErrorEventArgs> Error;123        /// <summary>124        /// Raised when the JavaScript code makes a call to <c>console.timeStamp</c>. For the list of metrics see <see cref="MetricsAsync"/>.125        /// </summary>126        public event EventHandler<MetricEventArgs> Metrics;127        /// <summary>128        /// Raised when a JavaScript dialog appears, such as <c>alert</c>, <c>prompt</c>, <c>confirm</c> or <c>beforeunload</c>. Puppeteer can respond to the dialog via <see cref="Dialog"/>'s <see cref="PuppeteerSharp.Dialog.Accept(string)"/> or <see cref="PuppeteerSharp.Dialog.Dismiss"/> methods.129        /// </summary>130        public event EventHandler<DialogEventArgs> Dialog;131        /// <summary>132        /// Raised when the JavaScript <c>DOMContentLoaded</c> <see href="https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded"/> event is dispatched.133        /// </summary>134        public event EventHandler DOMContentLoaded;135        /// <summary>136        /// 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.137        /// The arguments passed into <c>console.log</c> appear as arguments on the event handler.138        /// </summary>139        /// <example>140        /// An example of handling <see cref="Console"/> event:141        /// <code>142        /// <![CDATA[143        /// page.Console += (sender, e) =>144        /// {145        ///     for (var i = 0; i < e.Message.Args.Count; ++i)146        ///     {147        ///         System.Console.WriteLine($"{i}: {e.Message.Args[i]}");148        ///     }149        /// }150        /// ]]>151        /// </code>152        /// </example>153        public event EventHandler<ConsoleEventArgs> Console;154        /// <summary>155        /// Raised when a frame is attached.156        /// </summary>157        public event EventHandler<FrameEventArgs> FrameAttached;158        /// <summary>159        /// Raised when a frame is detached.160        /// </summary>161        public event EventHandler<FrameEventArgs> FrameDetached;162        /// <summary>163        /// Raised when a frame is navigated to a new url.164        /// </summary>165        public event EventHandler<FrameEventArgs> FrameNavigated;166        /// <summary>167        /// Raised when a <see cref="Response"/> is received.168        /// </summary>169        /// <example>170        /// An example of handling <see cref="Response"/> event:171        /// <code>172        /// <![CDATA[173        /// var tcs = new TaskCompletionSource<string>(TaskCreationOptions.RunContinuationsAsynchronously);174        /// page.Response += async(sender, e) =>175        /// {176        ///     if (e.Response.Url.Contains("script.js"))177        ///     {178        ///         tcs.TrySetResult(await e.Response.TextAsync());179        ///     }180        /// };181        ///182        /// await Task.WhenAll(183        ///     page.GoToAsync(TestConstants.ServerUrl + "/grid.html"),184        ///     tcs.Task);185        /// Console.WriteLine(await tcs.Task);186        /// ]]>187        /// </code>188        /// </example>189        public event EventHandler<ResponseCreatedEventArgs> Response;190        /// <summary>191        /// Raised when a page issues a request. The <see cref="Request"/> object is read-only.192        /// In order to intercept and mutate requests, see <see cref="SetRequestInterceptionAsync(bool)"/>193        /// </summary>194        public event EventHandler<RequestEventArgs> Request;195        /// <summary>196        /// Raised when a request finishes successfully.197        /// </summary>198        public event EventHandler<RequestEventArgs> RequestFinished;199        /// <summary>200        /// Raised when a request fails, for example by timing out.201        /// </summary>202        public event EventHandler<RequestEventArgs> RequestFailed;203        /// <summary>204        /// Raised when a request ended up loading from cache.205        /// </summary>206        public event EventHandler<RequestEventArgs> RequestServedFromCache;207        /// <summary>208        /// Raised when an uncaught exception happens within the page.209        /// </summary>210        public event EventHandler<PageErrorEventArgs> PageError;211        /// <summary>212        /// Emitted when a dedicated WebWorker (<see href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API"/>) is spawned by the page.213        /// </summary>214        public event EventHandler<WorkerEventArgs> WorkerCreated;215        /// <summary>216        /// Emitted when a dedicated WebWorker (<see href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API"/>) is terminated.217        /// </summary>218        public event EventHandler<WorkerEventArgs> WorkerDestroyed;219        /// <summary>220        /// Raised when the page closes.221        /// </summary>222        public event EventHandler Close;223        /// <summary>224        /// Raised when the page opens a new tab or window.225        /// </summary>226        public event EventHandler<PopupEventArgs> Popup;227        /// <summary>228        /// Chrome DevTools Protocol session.229        /// </summary>230        public CDPSession Client { get; }231        /// <summary>232        /// This setting will change the default maximum time for the following methods:233        /// - <see cref="GoToAsync(string, NavigationOptions)"/>234        /// - <see cref="GoBackAsync(NavigationOptions)"/>235        /// - <see cref="GoForwardAsync(NavigationOptions)"/>236        /// - <see cref="ReloadAsync(NavigationOptions)"/>237        /// - <see cref="SetContentAsync(string, NavigationOptions)"/>238        /// - <see cref="WaitForNavigationAsync(NavigationOptions)"/>239        /// **NOTE** <see cref="DefaultNavigationTimeout"/> takes priority over <seealso cref="DefaultTimeout"/>240        /// </summary>241        public int DefaultNavigationTimeout242        {243            get => _timeoutSettings.NavigationTimeout;244            set => _timeoutSettings.NavigationTimeout = value;245        }246        /// <summary>247        /// This setting will change the default maximum times for the following methods:248        /// - <see cref="GoBackAsync(NavigationOptions)"/>249        /// - <see cref="GoForwardAsync(NavigationOptions)"/>250        /// - <see cref="GoToAsync(string, NavigationOptions)"/>251        /// - <see cref="ReloadAsync(NavigationOptions)"/>252        /// - <see cref="SetContentAsync(string, NavigationOptions)"/>253        /// - <see cref="WaitForFunctionAsync(string, object[])"/>254        /// - <see cref="WaitForNavigationAsync(NavigationOptions)"/>255        /// - <see cref="WaitForRequestAsync(string, WaitForOptions)"/>256        /// - <see cref="WaitForResponseAsync(string, WaitForOptions)"/>257        /// - <see cref="WaitForXPathAsync(string, WaitForSelectorOptions)"/>258        /// - <see cref="WaitForSelectorAsync(string, WaitForSelectorOptions)"/>259        /// - <see cref="WaitForExpressionAsync(string, WaitForFunctionOptions)"/>260        /// </summary>261        public int DefaultTimeout262        {263            get => _timeoutSettings.Timeout;264            set => _timeoutSettings.Timeout = value;265        }266        /// <summary>267        /// Gets page's main frame268        /// </summary>269        /// <remarks>270        /// Page is guaranteed to have a main frame which persists during navigations.271        /// </remarks>272        public Frame MainFrame => FrameManager.MainFrame;273        /// <summary>274        /// Gets all frames attached to the page.275        /// </summary>276        /// <value>An array of all frames attached to the page.</value>277        public Frame[] Frames => FrameManager.GetFrames();278        /// <summary>279        /// Gets all workers in the page.280        /// </summary>281        public Worker[] Workers => _workers.Values.ToArray();282        /// <summary>283        /// Shortcut for <c>page.MainFrame.Url</c>284        /// </summary>285        public string Url => MainFrame.Url;286        /// <summary>287        /// Gets that target this page was created from.288        /// </summary>289        public Target Target { get; }290        /// <summary>291        /// Gets this page's keyboard292        /// </summary>293        public Keyboard Keyboard { get; }294        /// <summary>295        /// Gets this page's touchscreen296        /// </summary>297        public Touchscreen Touchscreen { get; }298        /// <summary>299        /// Gets this page's coverage300        /// </summary>301        public Coverage Coverage { get; }302        /// <summary>303        /// Gets this page's tracing304        /// </summary>305        public Tracing Tracing { get; }306        /// <summary>307        /// Gets this page's mouse308        /// </summary>309        public Mouse Mouse { get; }310        /// <summary>311        /// Gets this page's viewport312        /// </summary>313        public ViewPortOptions Viewport { get; private set; }314        /// <summary>315        /// Get the browser the page belongs to.316        /// </summary>317        public Browser Browser => Target.Browser;318        /// <summary>319        /// Get the browser context that the page belongs to.320        /// </summary>321        public BrowserContext BrowserContext => Target.BrowserContext;322        /// <summary>323        /// Get an indication that the page has been closed.324        /// </summary>325        public bool IsClosed { get; private set; }326        /// <summary>327        /// Gets the accessibility.328        /// </summary>329        public Accessibility Accessibility { get; }330        /// <summary>331        /// `true` if drag events are being intercepted, `false` otherwise.332        /// </summary>333        public bool IsDragInterceptionEnabled { get; private set; }334        internal bool JavascriptEnabled { get; set; } = true;335        internal bool HasPopupEventListeners => Popup?.GetInvocationList().Any() == true;336        internal FrameManager FrameManager { get; private set; }337        private Task SessionClosedTask338        {339            get340            {341                if (_sessionClosedTcs == null)342                {343                    _sessionClosedTcs = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);344                    Client.Disconnected += clientDisconnected;345                    void clientDisconnected(object sender, EventArgs e)346                    {347                        _sessionClosedTcs.TrySetException(new TargetClosedException("Target closed", "Session closed"));348                        Client.Disconnected -= clientDisconnected;349                    }350                }351                return _sessionClosedTcs.Task;352            }353        }354        /// <summary>355        /// Sets the page's geolocation.356        /// </summary>357        /// <returns>The task.</returns>358        /// <param name="options">Geolocation options.</param>359        /// <remarks>360        /// Consider using <seealso cref="PuppeteerSharp.BrowserContext.OverridePermissionsAsync(string, IEnumerable{OverridePermission})"/> to grant permissions for the page to read its geolocation.361        /// </remarks>362        public Task SetGeolocationAsync(GeolocationOption options)363        {364            if (options == null)365            {366                throw new ArgumentNullException(nameof(options));367            }368            if (options.Longitude < -180 || options.Longitude > 180)369            {370                throw new ArgumentException($"Invalid longitude '{options.Longitude}': precondition - 180 <= LONGITUDE <= 180 failed.");371            }372            if (options.Latitude < -90 || options.Latitude > 90)373            {374                throw new ArgumentException($"Invalid latitude '{options.Latitude}': precondition - 90 <= LATITUDE <= 90 failed.");375            }376            if (options.Accuracy < 0)377            {378                throw new ArgumentException($"Invalid accuracy '{options.Accuracy}': precondition 0 <= ACCURACY failed.");379            }380            return Client.SendAsync("Emulation.setGeolocationOverride", options);381        }382        /// <summary>383        /// Whether to enable drag interception.384        /// </summary>385        /// <remarks>386        /// Activating drag interception enables the `Input.drag`,387        /// methods This provides the capability to capture drag events emitted388        /// on the page, which can then be used to simulate drag-and-drop.389        /// </remarks>390        /// <param name="enabled">Interception enabled</param>391        /// <returns>A Task that resolves when the message was confirmed by the browser</returns>392        public Task SetDragInterceptionAsync(bool enabled)393        {394            IsDragInterceptionEnabled = enabled;395            return Client.SendAsync("Input.setInterceptDrags", new InputSetInterceptDragsRequest { Enabled = enabled });396        }397        /// <summary>398        /// Returns metrics399        /// </summary>400        /// <returns>Task which resolves into a list of metrics</returns>401        /// <remarks>402        /// All timestamps are in monotonic time: monotonically increasing time in seconds since an arbitrary point in the past.403        /// </remarks>404        public async Task<Dictionary<string, decimal>> MetricsAsync()405        {406            var response = await Client.SendAsync<PerformanceGetMetricsResponse>("Performance.getMetrics").ConfigureAwait(false);407            return BuildMetricsObject(response.Metrics);408        }409        /// <summary>410        /// Fetches an element with <paramref name="selector"/>, scrolls it into view if needed, and then uses <see cref="Touchscreen"/> to tap in the center of the element.411        /// </summary>412        /// <param name="selector">A selector to search for element to tap. If there are multiple elements satisfying the selector, the first will be clicked.</param>413        /// <exception cref="SelectorException">If there's no element matching <paramref name="selector"/></exception>414        /// <returns>Task which resolves when the element matching <paramref name="selector"/> is successfully tapped</returns>415        public async Task TapAsync(string selector)416        {417            var handle = await QuerySelectorAsync(selector).ConfigureAwait(false);418            if (handle == null)419            {420                throw new SelectorException($"No node found for selector: {selector}", selector);421            }422            await handle.TapAsync().ConfigureAwait(false);423            await handle.DisposeAsync().ConfigureAwait(false);424        }425        /// <summary>426        /// The method runs <c>document.querySelector</c> within the page. If no element matches the selector, the return value resolve to <c>null</c>.427        /// </summary>428        /// <param name="selector">A selector to query page for</param>429        /// <returns>Task which resolves to <see cref="ElementHandle"/> pointing to the frame element</returns>430        /// <remarks>431        /// Shortcut for <c>page.MainFrame.QuerySelectorAsync(selector)</c>432        /// </remarks>433        /// <seealso cref="Frame.QuerySelectorAsync(string)"/>434        public Task<ElementHandle> QuerySelectorAsync(string selector)435            => MainFrame.QuerySelectorAsync(selector);436        /// <summary>437        /// Runs <c>document.querySelectorAll</c> within the page. If no elements match the selector, the return value resolve to <see cref="Array.Empty{T}"/>.438        /// </summary>439        /// <param name="selector">A selector to query page for</param>440        /// <returns>Task which resolves to ElementHandles pointing to the frame elements</returns>441        /// <seealso cref="Frame.QuerySelectorAllAsync(string)"/>442        public Task<ElementHandle[]> QuerySelectorAllAsync(string selector)443            => MainFrame.QuerySelectorAllAsync(selector);444        /// <summary>445        /// A utility function to be used with <see cref="PuppeteerHandleExtensions.EvaluateFunctionAsync{T}(Task{JSHandle}, string, object[])"/>446        /// </summary>447        /// <param name="selector">A selector to query page for</param>448        /// <returns>Task which resolves to a <see cref="JSHandle"/> of <c>document.querySelectorAll</c> result</returns>449        public Task<JSHandle> QuerySelectorAllHandleAsync(string selector)450            => EvaluateFunctionHandleAsync("selector => Array.from(document.querySelectorAll(selector))", selector);451        /// <summary>452        /// Evaluates the XPath expression453        /// </summary>454        /// <param name="expression">Expression to evaluate <see href="https://developer.mozilla.org/en-US/docs/Web/API/Document/evaluate"/></param>455        /// <returns>Task which resolves to an array of <see cref="ElementHandle"/></returns>456        /// <remarks>457        /// Shortcut for <c>page.MainFrame.XPathAsync(expression)</c>458        /// </remarks>459        /// <seealso cref="Frame.XPathAsync(string)"/>460        public Task<ElementHandle[]> XPathAsync(string expression) => MainFrame.XPathAsync(expression);461        /// <summary>462        /// Executes a script in browser context463        /// </summary>464        /// <param name="script">Script to be evaluated in browser context</param>465        /// <remarks>466        /// If the script, returns a Promise, then the method would wait for the promise to resolve and return its value.467        /// </remarks>468        /// <returns>Task which resolves to script return value</returns>469        public async Task<JSHandle> EvaluateExpressionHandleAsync(string script)470        {471            var context = await MainFrame.GetExecutionContextAsync().ConfigureAwait(false);472            return await context.EvaluateExpressionHandleAsync(script).ConfigureAwait(false);473        }474        /// <summary>475        /// Executes a script in browser context476        /// </summary>477        /// <param name="pageFunction">Script to be evaluated in browser context</param>478        /// <param name="args">Function arguments</param>479        /// <remarks>480        /// If the script, returns a Promise, then the method would wait for the promise to resolve and return its value.481        /// <see cref="JSHandle"/> instances can be passed as arguments482        /// </remarks>483        /// <returns>Task which resolves to script return value</returns>484        public async Task<JSHandle> EvaluateFunctionHandleAsync(string pageFunction, params object[] args)485        {486            var context = await MainFrame.GetExecutionContextAsync().ConfigureAwait(false);487            return await context.EvaluateFunctionHandleAsync(pageFunction, args).ConfigureAwait(false);488        }489        /// <summary>490        /// Adds a function which would be invoked in one of the following scenarios:491        /// - whenever the page is navigated492        /// - whenever the child frame is attached or navigated. In this case, the function is invoked in the context of the newly attached frame493        /// </summary>494        /// <param name="pageFunction">Function to be evaluated in browser context</param>495        /// <param name="args">Arguments to pass to <c>pageFunction</c></param>496        /// <remarks>497        /// The function is invoked after the document was created but before any of its scripts were run. This is useful to amend JavaScript environment, e.g. to seed <c>Math.random</c>.498        /// </remarks>499        /// <example>500        /// An example of overriding the navigator.languages property before the page loads:501        /// <code>502        /// await page.EvaluateOnNewDocumentAsync("() => window.__example = true");503        /// </code>504        /// </example>505        /// <returns>Task</returns>506        [Obsolete("User EvaluateFunctionOnNewDocumentAsync instead")]507        public Task EvaluateOnNewDocumentAsync(string pageFunction, params object[] args)508            => EvaluateFunctionOnNewDocumentAsync(pageFunction, args);509        /// <summary>510        /// Adds a function which would be invoked in one of the following scenarios:511        /// - whenever the page is navigated512        /// - whenever the child frame is attached or navigated. In this case, the function is invoked in the context of the newly attached frame513        /// </summary>514        /// <param name="pageFunction">Function to be evaluated in browser context</param>515        /// <param name="args">Arguments to pass to <c>pageFunction</c></param>516        /// <remarks>517        /// The function is invoked after the document was created but before any of its scripts were run. This is useful to amend JavaScript environment, e.g. to seed <c>Math.random</c>.518        /// </remarks>519        /// <example>520        /// An example of overriding the navigator.languages property before the page loads:521        /// <code>522        /// await page.EvaluateFunctionOnNewDocumentAsync("() => window.__example = true");523        /// </code>524        /// </example>525        /// <returns>Task</returns>526        public Task EvaluateFunctionOnNewDocumentAsync(string pageFunction, params object[] args)527        {528            var source = EvaluationString(pageFunction, args);529            return Client.SendAsync("Page.addScriptToEvaluateOnNewDocument", new PageAddScriptToEvaluateOnNewDocumentRequest530            {531                Source = source532            });533        }534        /// <summary>535        /// Adds a function which would be invoked in one of the following scenarios:536        /// - whenever the page is navigated537        /// - whenever the child frame is attached or navigated. In this case, the function is invoked in the context of the newly attached frame538        /// </summary>539        /// <param name="expression">Javascript expression to be evaluated in browser context</param>540        /// <remarks>541        /// The function is invoked after the document was created but before any of its scripts were run. This is useful to amend JavaScript environment, e.g. to seed <c>Math.random</c>.542        /// </remarks>543        /// <example>544        /// An example of overriding the navigator.languages property before the page loads:545        /// <code>546        /// await page.EvaluateExpressionOnNewDocumentAsync("window.__example = true;");547        /// </code>548        /// </example>549        /// <returns>Task</returns>550        public Task EvaluateExpressionOnNewDocumentAsync(string expression)551            => Client.SendAsync("Page.addScriptToEvaluateOnNewDocument", new PageAddScriptToEvaluateOnNewDocumentRequest552            {553                Source = expression554            });555        /// <summary>556        /// The method iterates JavaScript heap and finds all the objects with the given prototype.557        /// Shortcut for <c>page.MainFrame.GetExecutionContextAsync().QueryObjectsAsync(prototypeHandle)</c>.558        /// </summary>559        /// <returns>A task which resolves to a handle to an array of objects with this prototype.</returns>560        /// <param name="prototypeHandle">A handle to the object prototype.</param>561        public async Task<JSHandle> QueryObjectsAsync(JSHandle prototypeHandle)562        {563            var context = await MainFrame.GetExecutionContextAsync().ConfigureAwait(false);564            return await context.QueryObjectsAsync(prototypeHandle).ConfigureAwait(false);565        }566        /// <summary>567        /// Activating request interception enables <see cref="PuppeteerSharp.Request.AbortAsync(RequestAbortErrorCode)">request.AbortAsync</see>,568        /// <see cref="PuppeteerSharp.Request.ContinueAsync(Payload)">request.ContinueAsync</see> and <see cref="PuppeteerSharp.Request.RespondAsync(ResponseData)">request.RespondAsync</see> methods.569        /// </summary>570        /// <returns>The request interception task.</returns>571        /// <param name="value">Whether to enable request interception..</param>572        public Task SetRequestInterceptionAsync(bool value)573            => FrameManager.NetworkManager.SetRequestInterceptionAsync(value);574        /// <summary>575        /// Set offline mode for the page.576        /// </summary>577        /// <returns>Result task</returns>578        /// <param name="value">When <c>true</c> enables offline mode for the page.</param>579        public Task SetOfflineModeAsync(bool value) => FrameManager.NetworkManager.SetOfflineModeAsync(value);580        /// <summary>581        /// Emulates network conditions582        /// </summary>583        /// <param name="networkConditions">Passing <c>null</c> disables network condition emulation.</param>584        /// <returns>Result task</returns>585        /// <remarks>586        /// **NOTE** This does not affect WebSockets and WebRTC PeerConnections (see https://crbug.com/563644)587        /// </remarks>588        public Task EmulateNetworkConditionsAsync(NetworkConditions networkConditions) => FrameManager.NetworkManager.EmulateNetworkConditionsAsync(networkConditions);589        /// <summary>590        /// Returns the page's cookies591        /// </summary>592        /// <param name="urls">Url's to return cookies for</param>593        /// <returns>Array of cookies</returns>594        /// <remarks>595        /// If no URLs are specified, this method returns cookies for the current page URL.596        /// If URLs are specified, only cookies for those URLs are returned.597        /// </remarks>598        public async Task<CookieParam[]> GetCookiesAsync(params string[] urls)599            => (await Client.SendAsync<NetworkGetCookiesResponse>("Network.getCookies", new NetworkGetCookiesRequest600            {601                Urls = urls.Length > 0 ? urls : new string[] { Url }602            }).ConfigureAwait(false)).Cookies;603        /// <summary>604        /// Clears all of the current cookies and then sets the cookies for the page605        /// </summary>606        /// <param name="cookies">Cookies to set</param>607        /// <returns>Task</returns>608        public async Task SetCookieAsync(params CookieParam[] cookies)609        {610            foreach (var cookie in cookies)611            {612                if (string.IsNullOrEmpty(cookie.Url) && Url.StartsWith("http", StringComparison.Ordinal))613                {614                    cookie.Url = Url;615                }616                if (cookie.Url == "about:blank")617                {618                    throw new PuppeteerException($"Blank page can not have cookie \"{cookie.Name}\"");619                }620            }621            await DeleteCookieAsync(cookies).ConfigureAwait(false);622            if (cookies.Length > 0)623            {624                await Client.SendAsync("Network.setCookies", new NetworkSetCookiesRequest625                {626                    Cookies = cookies627                }).ConfigureAwait(false);628            }629        }630        /// <summary>631        /// Deletes cookies from the page632        /// </summary>633        /// <param name="cookies">Cookies to delete</param>634        /// <returns>Task</returns>635        public async Task DeleteCookieAsync(params CookieParam[] cookies)636        {637            var pageURL = Url;638            foreach (var cookie in cookies)639            {640                if (string.IsNullOrEmpty(cookie.Url) && pageURL.StartsWith("http", StringComparison.Ordinal))641                {642                    cookie.Url = pageURL;643                }644                await Client.SendAsync("Network.deleteCookies", cookie).ConfigureAwait(false);645            }646        }647        /// <summary>648        /// Adds a <c><![CDATA[<script>]]></c> tag into the page with the desired url or content649        /// </summary>650        /// <param name="options">add script tag options</param>651        /// <remarks>652        /// Shortcut for <c>page.MainFrame.AddScriptTagAsync(options)</c>653        /// </remarks>654        /// <returns>Task which resolves to the added tag when the script's onload fires or when the script content was injected into frame</returns>655        /// <seealso cref="Frame.AddScriptTagAsync(AddTagOptions)"/>656        public Task<ElementHandle> AddScriptTagAsync(AddTagOptions options) => MainFrame.AddScriptTagAsync(options);657        /// <summary>658        /// Adds a <c><![CDATA[<script>]]></c> tag into the page with the desired url or content659        /// </summary>660        /// <param name="url">script url</param>661        /// <remarks>662        /// Shortcut for <c>page.MainFrame.AddScriptTagAsync(new AddTagOptions { Url = url })</c>663        /// </remarks>664        /// <returns>Task which resolves to the added tag when the script's onload fires or when the script content was injected into frame</returns>665        public Task<ElementHandle> AddScriptTagAsync(string url) => AddScriptTagAsync(new AddTagOptions { Url = url });666        /// <summary>667        /// 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 content668        /// </summary>669        /// <param name="options">add style tag options</param>670        /// <remarks>671        /// Shortcut for <c>page.MainFrame.AddStyleTagAsync(options)</c>672        /// </remarks>673        /// <returns>Task which resolves to the added tag when the stylesheet's onload fires or when the CSS content was injected into frame</returns>674        /// <seealso cref="Frame.AddStyleTag(AddTagOptions)"/>675        public Task<ElementHandle> AddStyleTagAsync(AddTagOptions options) => MainFrame.AddStyleTagAsync(options);676        /// <summary>677        /// 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 content678        /// </summary>679        /// <param name="url">stylesheel url</param>680        /// <remarks>681        /// Shortcut for <c>page.MainFrame.AddStyleTagAsync(new AddTagOptions { Url = url })</c>682        /// </remarks>683        /// <returns>Task which resolves to the added tag when the stylesheet's onload fires or when the CSS content was injected into frame</returns>684        public Task<ElementHandle> AddStyleTagAsync(string url) => AddStyleTagAsync(new AddTagOptions { Url = url });685        /// <summary>686        /// Adds a function called <c>name</c> on the page's <c>window</c> object.687        /// When called, the function executes <paramref name="puppeteerFunction"/> in C# and returns a <see cref="Task"/> which resolves when <paramref name="puppeteerFunction"/> completes.688        /// </summary>689        /// <param name="name">Name of the function on the window object</param>690        /// <param name="puppeteerFunction">Callback function which will be called in Puppeteer's context.</param>691        /// <remarks>692        /// If the <paramref name="puppeteerFunction"/> returns a <see cref="Task"/>, it will be awaited.693        /// Functions installed via <see cref="ExposeFunctionAsync(string, Action)"/> survive navigations694        /// </remarks>695        /// <returns>Task</returns>696        public Task ExposeFunctionAsync(string name, Action puppeteerFunction)697            => ExposeFunctionAsync(name, (Delegate)puppeteerFunction);698        /// <summary>699        /// Adds a function called <c>name</c> on the page's <c>window</c> object.700        /// 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"/>.701        /// </summary>702        /// <typeparam name="TResult">The result of <paramref name="puppeteerFunction"/></typeparam>703        /// <param name="name">Name of the function on the window object</param>704        /// <param name="puppeteerFunction">Callback function which will be called in Puppeteer's context.</param>705        /// <remarks>706        /// If the <paramref name="puppeteerFunction"/> returns a <see cref="Task"/>, it will be awaited.707        /// Functions installed via <see cref="ExposeFunctionAsync{TResult}(string, Func{TResult})"/> survive navigations708        /// </remarks>709        /// <returns>Task</returns>710        public Task ExposeFunctionAsync<TResult>(string name, Func<TResult> puppeteerFunction)711            => ExposeFunctionAsync(name, (Delegate)puppeteerFunction);712        /// <summary>713        /// Adds a function called <c>name</c> on the page's <c>window</c> object.714        /// 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"/>.715        /// </summary>716        /// <typeparam name="T">The parameter of <paramref name="puppeteerFunction"/></typeparam>717        /// <typeparam name="TResult">The result of <paramref name="puppeteerFunction"/></typeparam>718        /// <param name="name">Name of the function on the window object</param>719        /// <param name="puppeteerFunction">Callback function which will be called in Puppeteer's context.</param>720        /// <remarks>721        /// If the <paramref name="puppeteerFunction"/> returns a <see cref="Task"/>, it will be awaited.722        /// Functions installed via <see cref="ExposeFunctionAsync{T, TResult}(string, Func{T, TResult})"/> survive navigations723        /// </remarks>724        /// <returns>Task</returns>725        public Task ExposeFunctionAsync<T, TResult>(string name, Func<T, TResult> puppeteerFunction)726            => ExposeFunctionAsync(name, (Delegate)puppeteerFunction);727        /// <summary>728        /// Adds a function called <c>name</c> on the page's <c>window</c> object.729        /// 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"/>.730        /// </summary>731        /// <typeparam name="T1">The first parameter of <paramref name="puppeteerFunction"/></typeparam>732        /// <typeparam name="T2">The second parameter of <paramref name="puppeteerFunction"/></typeparam>733        /// <typeparam name="TResult">The result of <paramref name="puppeteerFunction"/></typeparam>734        /// <param name="name">Name of the function on the window object</param>735        /// <param name="puppeteerFunction">Callback function which will be called in Puppeteer's context.</param>736        /// <remarks>737        /// If the <paramref name="puppeteerFunction"/> returns a <see cref="Task"/>, it will be awaited.738        /// Functions installed via <see cref="ExposeFunctionAsync{T1, T2, TResult}(string, Func{T1, T2, TResult})"/> survive navigations739        /// </remarks>740        /// <returns>Task</returns>741        public Task ExposeFunctionAsync<T1, T2, TResult>(string name, Func<T1, T2, TResult> puppeteerFunction)742            => ExposeFunctionAsync(name, (Delegate)puppeteerFunction);743        /// <summary>744        /// Adds a function called <c>name</c> on the page's <c>window</c> object.745        /// 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"/>.746        /// </summary>747        /// <typeparam name="T1">The first parameter of <paramref name="puppeteerFunction"/></typeparam>748        /// <typeparam name="T2">The second parameter of <paramref name="puppeteerFunction"/></typeparam>749        /// <typeparam name="T3">The third parameter of <paramref name="puppeteerFunction"/></typeparam>750        /// <typeparam name="TResult">The result of <paramref name="puppeteerFunction"/></typeparam>751        /// <param name="name">Name of the function on the window object</param>752        /// <param name="puppeteerFunction">Callback function which will be called in Puppeteer's context.</param>753        /// <remarks>754        /// If the <paramref name="puppeteerFunction"/> returns a <see cref="Task"/>, it will be awaited.755        /// Functions installed via <see cref="ExposeFunctionAsync{T1, T2, T3, TResult}(string, Func{T1, T2, T3, TResult})"/> survive navigations756        /// </remarks>757        /// <returns>Task</returns>758        public Task ExposeFunctionAsync<T1, T2, T3, TResult>(string name, Func<T1, T2, T3, TResult> puppeteerFunction)759            => ExposeFunctionAsync(name, (Delegate)puppeteerFunction);760        /// <summary>761        /// Adds a function called <c>name</c> on the page's <c>window</c> object.762        /// 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"/>.763        /// </summary>764        /// <typeparam name="T1">The first parameter of <paramref name="puppeteerFunction"/></typeparam>765        /// <typeparam name="T2">The second parameter of <paramref name="puppeteerFunction"/></typeparam>766        /// <typeparam name="T3">The third parameter of <paramref name="puppeteerFunction"/></typeparam>767        /// <typeparam name="T4">The fourth parameter of <paramref name="puppeteerFunction"/></typeparam>768        /// <typeparam name="TResult">The result of <paramref name="puppeteerFunction"/></typeparam>769        /// <param name="name">Name of the function on the window object</param>770        /// <param name="puppeteerFunction">Callback function which will be called in Puppeteer's context.</param>771        /// <remarks>772        /// If the <paramref name="puppeteerFunction"/> returns a <see cref="Task"/>, it will be awaited.773        /// Functions installed via <see cref="ExposeFunctionAsync{T1, T2, T3, T4, TResult}(string, Func{T1, T2, T3, T4, TResult})"/> survive navigations774        /// </remarks>775        /// <returns>Task</returns>776        public Task ExposeFunctionAsync<T1, T2, T3, T4, TResult>(string name, Func<T1, T2, T3, T4, TResult> puppeteerFunction)777            => ExposeFunctionAsync(name, (Delegate)puppeteerFunction);778        /// <summary>779        /// Gets the full HTML contents of the page, including the doctype.780        /// </summary>781        /// <returns>Task which resolves to the HTML content.</returns>782        /// <seealso cref="Frame.GetContentAsync"/>783        public Task<string> GetContentAsync() => FrameManager.MainFrame.GetContentAsync();784        /// <summary>785        /// Sets the HTML markup to the page786        /// </summary>787        /// <param name="html">HTML markup to assign to the page.</param>788        /// <param name="options">The navigations options</param>789        /// <returns>Task.</returns>790        /// <seealso cref="Frame.SetContentAsync(string, NavigationOptions)"/>791        public Task SetContentAsync(string html, NavigationOptions options = null) => FrameManager.MainFrame.SetContentAsync(html, options);792        /// <summary>793        /// Navigates to an url794        /// </summary>795        /// <remarks>796        /// <see cref="GoToAsync(string, int?, WaitUntilNavigation[])"/> will throw an error if:797        /// - there's an SSL error (e.g. in case of self-signed certificates).798        /// - target URL is invalid.799        /// - the `timeout` is exceeded during navigation.800        /// - the remote server does not respond or is unreachable.801        /// - the main resource failed to load.802        ///803        /// <see cref="GoToAsync(string, int?, WaitUntilNavigation[])"/> will not throw an error when any valid HTTP status code is returned by the remote server,804        /// including 404 "Not Found" and 500 "Internal Server Error".  The status code for such responses can be retrieved by calling <see cref="PuppeteerSharp.Response.Status"/>805        ///806        /// > **NOTE** <see cref="GoToAsync(string, int?, WaitUntilNavigation[])"/> either throws an error or returns a main resource response.807        /// The only exceptions are navigation to `about:blank` or navigation to the same URL with a different hash, which would succeed and return `null`.808        ///809        /// > **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>.810        ///811        /// Shortcut for <seealso cref="Frame.GoToAsync(string, int?, WaitUntilNavigation[])"/>812        /// </remarks>813        /// <param name="url">URL to navigate page to. The url should include scheme, e.g. https://.</param>814        /// <param name="options">Navigation parameters.</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="GoToAsync(string, int?, WaitUntilNavigation[])"/>817        public Task<Response> GoToAsync(string url, NavigationOptions options) => FrameManager.MainFrame.GoToAsync(url, options);818        /// <summary>819        /// Navigates to an url820        /// </summary>821        /// <param name="url">URL to navigate page to. The url should include scheme, e.g. https://.</param>822        /// <param name="timeout">Maximum navigation time in milliseconds, defaults to 30 seconds, pass <c>0</c> to disable timeout. </param>823        /// <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>824        /// <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>825        /// <seealso cref="GoToAsync(string, NavigationOptions)"/>826        public Task<Response> GoToAsync(string url, int? timeout = null, WaitUntilNavigation[] waitUntil = null)827            => GoToAsync(url, new NavigationOptions { Timeout = timeout, WaitUntil = waitUntil });828        /// <summary>829        /// Navigates to an url830        /// </summary>831        /// <param name="url">URL to navigate page to. The url should include scheme, e.g. https://.</param>832        /// <param name="waitUntil">When to consider navigation succeeded.</param>833        /// <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>834        /// <seealso cref="GoToAsync(string, NavigationOptions)"/>835        public Task<Response> GoToAsync(string url, WaitUntilNavigation waitUntil)836            => GoToAsync(url, new NavigationOptions { WaitUntil = new[] { waitUntil } });837        /// <summary>838        /// 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"/>839        /// </summary>840        /// <param name="file">The file path to save the PDF to. paths are resolved using <see cref="Path.GetFullPath(string)"/></param>841        /// <returns></returns>842        /// <remarks>843        /// Generating a pdf is currently only supported in Chrome headless844        /// </remarks>845        public Task PdfAsync(string file) => PdfAsync(file, new PdfOptions());846        /// <summary>847        ///  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"/>848        /// </summary>849        /// <param name="file">The file path to save the PDF to. paths are resolved using <see cref="Path.GetFullPath(string)"/></param>850        /// <param name="options">pdf options</param>851        /// <returns></returns>852        /// <remarks>853        /// Generating a pdf is currently only supported in Chrome headless854        /// </remarks>855        public async Task PdfAsync(string file, PdfOptions options)856        {857            if (options == null)858            {859                throw new ArgumentNullException(nameof(options));860            }861            await PdfInternalAsync(file, options).ConfigureAwait(false);862        }863        /// <summary>864        /// 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"/>865        /// </summary>866        /// <returns>Task which resolves to a <see cref="Stream"/> containing the PDF data.</returns>867        /// <remarks>868        /// Generating a pdf is currently only supported in Chrome headless869        /// </remarks>870        public Task<Stream> PdfStreamAsync() => PdfStreamAsync(new PdfOptions());871        /// <summary>872        /// 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"/>873        /// </summary>874        /// <param name="options">pdf options</param>875        /// <returns>Task which resolves to a <see cref="Stream"/> containing the PDF data.</returns>876        /// <remarks>877        /// Generating a pdf is currently only supported in Chrome headless878        /// </remarks>879        public async Task<Stream> PdfStreamAsync(PdfOptions options)880            => new MemoryStream(await PdfDataAsync(options).ConfigureAwait(false));881        /// <summary>882        /// 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"/>883        /// </summary>884        /// <returns>Task which resolves to a <see cref="byte"/>[] containing the PDF data.</returns>885        /// <remarks>886        /// Generating a pdf is currently only supported in Chrome headless887        /// </remarks>888        public Task<byte[]> PdfDataAsync() => PdfDataAsync(new PdfOptions());889        /// <summary>890        /// 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"/>891        /// </summary>892        /// <param name="options">pdf options</param>893        /// <returns>Task which resolves to a <see cref="byte"/>[] containing the PDF data.</returns>894        /// <remarks>895        /// Generating a pdf is currently only supported in Chrome headless896        /// </remarks>897        public Task<byte[]> PdfDataAsync(PdfOptions options)898        {899            if (options == null)900            {901                throw new ArgumentNullException(nameof(options));902            }903            return PdfInternalAsync(null, options);904        }905        internal async Task<byte[]> PdfInternalAsync(string file, PdfOptions options)906        {907            var paperWidth = PaperFormat.Letter.Width;908            var paperHeight = PaperFormat.Letter.Height;909            if (options.Format != null)910            {911                paperWidth = options.Format.Width;912                paperHeight = options.Format.Height;913            }914            else915            {916                if (options.Width != null)917                {918                    paperWidth = ConvertPrintParameterToInches(options.Width);919                }920                if (options.Height != null)921                {922                    paperHeight = ConvertPrintParameterToInches(options.Height);923                }924            }925            var marginTop = ConvertPrintParameterToInches(options.MarginOptions.Top);926            var marginLeft = ConvertPrintParameterToInches(options.MarginOptions.Left);927            var marginBottom = ConvertPrintParameterToInches(options.MarginOptions.Bottom);928            var marginRight = ConvertPrintParameterToInches(options.MarginOptions.Right);929            if (options.OmitBackground)930            {931                await SetTransparentBackgroundColorAsync().ConfigureAwait(false);932            }933            var result = await Client.SendAsync<PagePrintToPDFResponse>("Page.printToPDF", new PagePrintToPDFRequest934            {935                TransferMode = "ReturnAsStream",936                Landscape = options.Landscape,937                DisplayHeaderFooter = options.DisplayHeaderFooter,938                HeaderTemplate = options.HeaderTemplate,939                FooterTemplate = options.FooterTemplate,940                PrintBackground = options.PrintBackground,941                Scale = options.Scale,942                PaperWidth = paperWidth,943                PaperHeight = paperHeight,944                MarginTop = marginTop,945                MarginBottom = marginBottom,946                MarginLeft = marginLeft,947                MarginRight = marginRight,948                PageRanges = options.PageRanges,949                PreferCSSPageSize = options.PreferCSSPageSize950            }).ConfigureAwait(false);951            if (options.OmitBackground)952            {953                await ResetDefaultBackgroundColorAsync().ConfigureAwait(false);954            }955            return await ProtocolStreamReader.ReadProtocolStreamByteAsync(Client, result.Stream, file).ConfigureAwait(false);956        }957        /// <summary>958        /// Enables/Disables Javascript on the page959        /// </summary>960        /// <returns>Task.</returns>961        /// <param name="enabled">Whether or not to enable JavaScript on the page.</param>962        public Task SetJavaScriptEnabledAsync(bool enabled)963        {964            if (enabled == JavascriptEnabled)965            {966                return Task.CompletedTask;967            }968            JavascriptEnabled = enabled;969            return Client.SendAsync("Emulation.setScriptExecutionDisabled", new EmulationSetScriptExecutionDisabledRequest970            {971                Value = !enabled972            });973        }974        /// <summary>975        /// Toggles bypassing page's Content-Security-Policy.976        /// </summary>977        /// <param name="enabled">sets bypassing of page's Content-Security-Policy.</param>978        /// <returns></returns>979        /// <remarks>980        /// CSP bypassing happens at the moment of CSP initialization rather then evaluation.981        /// Usually this means that <see cref="SetBypassCSPAsync(bool)"/> should be called before navigating to the domain.982        /// </remarks>983        public Task SetBypassCSPAsync(bool enabled) => Client.SendAsync("Page.setBypassCSP", new PageSetBypassCSPRequest984        {985            Enabled = enabled986        });987        /// <summary>988        /// Emulates a media such as screen or print.989        /// </summary>990        /// <returns>Task.</returns>991        /// <param name="media">Media to set.</param>992        [Obsolete("User EmulateMediaTypeAsync instead")]993        public Task EmulateMediaAsync(MediaType media) => EmulateMediaTypeAsync(media);994        /// <summary>995        /// Emulates a media such as screen or print.996        /// </summary>997        /// <param name="type">Media to set.</param>998        /// <example>999        /// <code>1000        /// <![CDATA[1001        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('screen').matches)");1002        /// // → true1003        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('print').matches)");1004        /// // → true1005        /// await page.EmulateMediaTypeAsync(MediaType.Print);1006        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('screen').matches)");1007        /// // → false1008        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('print').matches)");1009        /// // → true1010        /// await page.EmulateMediaTypeAsync(MediaType.None);1011        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('screen').matches)");1012        /// // → true1013        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('print').matches)");1014        /// // → true1015        /// ]]>1016        /// </code>1017        /// </example>1018        /// <returns>Emulate media type task.</returns>1019        public Task EmulateMediaTypeAsync(MediaType type)1020            => Client.SendAsync("Emulation.setEmulatedMedia", new EmulationSetEmulatedMediaTypeRequest { Media = type });1021        /// <summary>1022        /// Given an array of media feature objects, emulates CSS media features on the page.1023        /// </summary>1024        /// <param name="features">Features to apply</param>1025        /// <example>1026        /// <code>1027        /// <![CDATA[1028        /// await page.EmulateMediaFeaturesAsync(new MediaFeature[]{ new MediaFeature { MediaFeature =  MediaFeature.PrefersColorScheme, Value = "dark" }});1029        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('(prefers-color-scheme: dark)').matches)");1030        /// // → true1031        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('(prefers-color-scheme: light)').matches)");1032        /// // → false1033        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('(prefers-color-scheme: no-preference)').matches)");1034        /// // → false1035        /// await page.EmulateMediaFeaturesAsync(new MediaFeature[]{ new MediaFeature { MediaFeature = MediaFeature.PrefersReducedMotion, Value = "reduce" }});1036        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('(prefers-reduced-motion: reduce)').matches)");1037        /// // → true1038        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('(prefers-color-scheme: no-preference)').matches)");1039        /// // → false1040        /// await page.EmulateMediaFeaturesAsync(new MediaFeature[]1041        /// {1042        ///   new MediaFeature { MediaFeature = MediaFeature.PrefersColorScheme, Value = "dark" },1043        ///   new MediaFeature { MediaFeature = MediaFeature.PrefersReducedMotion, Value = "reduce" },1044        /// });1045        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('(prefers-color-scheme: dark)').matches)");1046        /// // → true1047        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('(prefers-color-scheme: light)').matches)");1048        /// // → false1049        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('(prefers-color-scheme: no-preference)').matches)");1050        /// // → false1051        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('(prefers-reduced-motion: reduce)').matches)");1052        /// // → true1053        /// await page.EvaluateFunctionAsync<bool>("() => matchMedia('(prefers-color-scheme: no-preference)').matches)");1054        /// // → false1055        /// ]]>1056        /// </code>1057        /// </example>1058        /// <returns>Emulate features task</returns>1059        public Task EmulateMediaFeaturesAsync(IEnumerable<MediaFeatureValue> features)1060            => Client.SendAsync("Emulation.setEmulatedMedia", new EmulationSetEmulatedMediaFeatureRequest { Features = features });1061        /// <summary>1062        /// Sets the viewport.1063        /// In the case of multiple pages in a single browser, each page can have its own viewport size.1064        /// <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.1065        /// </summary>1066        /// <example>1067        ///<![CDATA[1068        /// using(var page = await browser.NewPageAsync())1069        /// {1070        ///     await page.SetViewPortAsync(new ViewPortOptions1071        ///     {1072        ///         Width = 640,1073        ///         Height = 480,1074        ///         DeviceScaleFactor = 11075        ///     });1076        ///     await page.goto('https://www.example.com');1077        /// }1078        /// ]]>1079        /// </example>1080        /// <returns>The viewport task.</returns>1081        /// <param name="viewport">Viewport options.</param>1082        public async Task SetViewportAsync(ViewPortOptions viewport)1083        {1084            if (viewport == null)1085            {1086                throw new ArgumentNullException(nameof(viewport));1087            }1088            var needsReload = await _emulationManager.EmulateViewport(viewport).ConfigureAwait(false);1089            Viewport = viewport;1090            if (needsReload)1091            {1092                await ReloadAsync().ConfigureAwait(false);1093            }1094        }1095        /// <summary>1096        /// Emulates given device metrics and user agent.1097        /// </summary>1098        /// <remarks>1099        /// This method is a shortcut for calling two methods:1100        /// <see cref="SetViewportAsync(ViewPortOptions)"/>1101        /// <see cref="SetUserAgentAsync(string)"/>1102        /// To aid emulation, puppeteer provides a list of device descriptors which can be obtained via the <see cref="Puppeteer.Devices"/>.1103        /// <see cref="EmulateAsync(DeviceDescriptor)"/> will resize the page. A lot of websites don't expect phones to change size, so you should emulate before navigating to the page.1104        /// </remarks>1105        /// <example>1106        ///<![CDATA[1107        /// var iPhone = Puppeteer.Devices[DeviceDescriptorName.IPhone6];1108        /// using(var page = await browser.NewPageAsync())1109        /// {1110        ///     await page.EmulateAsync(iPhone);1111        ///     await page.goto('https://www.google.com');1112        /// }1113        /// ]]>1114        /// </example>1115        /// <returns>Task.</returns>1116        /// <param name="options">Emulation options.</param>1117        public Task EmulateAsync(DeviceDescriptor options)1118        {1119            if (options == null)1120            {1121                throw new ArgumentNullException(nameof(options));1122            }1123            return Task.WhenAll(1124                SetViewportAsync(options.ViewPort),1125                SetUserAgentAsync(options.UserAgent));1126        }1127        /// <summary>1128        /// Takes a screenshot of the page1129        /// </summary>1130        /// <returns>The screenshot task.</returns>1131        /// <param name="file">The file path to save the image to. The screenshot type will be inferred from file extension.1132        /// If path is a relative path, then it is resolved relative to current working directory. If no path is provided,1133        /// the image won't be saved to the disk.</param>1134        public Task ScreenshotAsync(string file) => ScreenshotAsync(file, new ScreenshotOptions());1135        /// <summary>1136        /// Takes a screenshot of the page1137        /// </summary>1138        /// <returns>The screenshot task.</returns>1139        /// <param name="file">The file path to save the image to. The screenshot type will be inferred from file extension.1140        /// If path is a relative path, then it is resolved relative to current working directory. If no path is provided,1141        /// the image won't be saved to the disk.</param>1142        /// <param name="options">Screenshot options.</param>1143        public async Task ScreenshotAsync(string file, ScreenshotOptions options)1144        {1145            if (options == null)1146            {1147                throw new ArgumentNullException(nameof(options));1148            }1149            if (!options.Type.HasValue)1150            {1151                options.Type = ScreenshotOptions.GetScreenshotTypeFromFile(file);1152                if (options.Type == ScreenshotType.Jpeg && !options.Quality.HasValue)1153                {1154                    options.Quality = 90;1155                }1156            }1157            var data = await ScreenshotDataAsync(options).ConfigureAwait(false);1158            using (var fs = AsyncFileHelper.CreateStream(file, FileMode.Create))1159            {1160                await fs.WriteAsync(data, 0, data.Length).ConfigureAwait(false);1161            }1162        }1163        /// <summary>1164        /// Takes a screenshot of the page1165        /// </summary>1166        /// <returns>Task which resolves to a <see cref="Stream"/> containing the image data.</returns>1167        public Task<Stream> ScreenshotStreamAsync() => ScreenshotStreamAsync(new ScreenshotOptions());1168        /// <summary>1169        /// Takes a screenshot of the page1170        /// </summary>1171        /// <returns>Task which resolves to a <see cref="Stream"/> containing the image data.</returns>1172        /// <param name="options">Screenshot options.</param>1173        public async Task<Stream> ScreenshotStreamAsync(ScreenshotOptions options)1174            => new MemoryStream(await ScreenshotDataAsync(options).ConfigureAwait(false));1175        /// <summary>1176        /// Takes a screenshot of the page1177        /// </summary>1178        /// <returns>Task which resolves to a <see cref="string"/> containing the image data as base64.</returns>1179        public Task<string> ScreenshotBase64Async() => ScreenshotBase64Async(new ScreenshotOptions());1180        /// <summary>1181        /// Takes a screenshot of the page1182        /// </summary>1183        /// <returns>Task which resolves to a <see cref="string"/> containing the image data as base64.</returns>1184        /// <param name="options">Screenshot options.</param>1185        public Task<string> ScreenshotBase64Async(ScreenshotOptions options)1186        {1187            if (options == null)1188            {1189                throw new ArgumentNullException(nameof(options));1190            }1191            var screenshotType = options.Type;1192            if (!screenshotType.HasValue)1193            {1194                screenshotType = ScreenshotType.Png;1195            }1196            if (options.Quality.HasValue)1197            {1198                if (screenshotType != ScreenshotType.Jpeg)1199                {1200                    throw new ArgumentException($"options.Quality is unsupported for the {screenshotType} screenshots");1201                }1202                if (options.Quality < 0 || options.Quality > 100)1203                {1204                    throw new ArgumentException($"Expected options.quality to be between 0 and 100 (inclusive), got {options.Quality}");1205                }1206            }1207            if (options?.Clip?.Width == 0)1208            {1209                throw new PuppeteerException("Expected options.Clip.Width not to be 0.");1210            }1211            if (options?.Clip?.Height == 0)1212            {1213                throw new PuppeteerException("Expected options.Clip.Height not to be 0.");1214            }1215            if (options.Clip != null && options.FullPage)1216            {1217                throw new ArgumentException("options.clip and options.fullPage are exclusive");1218            }1219            return _screenshotTaskQueue.Enqueue(() => PerformScreenshot(screenshotType.Value, options));1220        }1221        /// <summary>1222        /// Takes a screenshot of the page1223        /// </summary>1224        /// <returns>Task which resolves to a <see cref="byte"/>[] containing the image data.</returns>1225        public Task<byte[]> ScreenshotDataAsync() => ScreenshotDataAsync(new ScreenshotOptions());1226        /// <summary>1227        /// Takes a screenshot of the page1228        /// </summary>1229        /// <returns>Task which resolves to a <see cref="byte"/>[] containing the image data.</returns>1230        /// <param name="options">Screenshot options.</param>1231        public async Task<byte[]> ScreenshotDataAsync(ScreenshotOptions options)1232            => Convert.FromBase64String(await ScreenshotBase64Async(options).ConfigureAwait(false));1233        /// <summary>1234        /// Returns page's title1235        /// </summary>1236        /// <returns>page's title</returns>1237        /// <see cref="Frame.GetTitleAsync"/>1238        public Task<string> GetTitleAsync() => MainFrame.GetTitleAsync();1239        /// <summary>1240        /// Closes the page.1241        /// </summary>1242        /// <param name="options">Close options.</param>1243        /// <returns>Task.</returns>1244        public Task CloseAsync(PageCloseOptions options = null)1245        {1246            if (!(Client?.Connection?.IsClosed ?? true))1247            {1248                var runBeforeUnload = options?.RunBeforeUnload ?? false;1249                if (runBeforeUnload)1250                {1251                    return Client.SendAsync("Page.close");1252                }1253                return Client.Connection.SendAsync("Target.closeTarget", new TargetCloseTargetRequest1254                {1255                    TargetId = Target.TargetId1256                }).ContinueWith(task => Target.CloseTask, TaskScheduler.Default);1257            }1258            _logger.LogWarning("Protocol error: Connection closed. Most likely the page has been closed.");1259            return _closeCompletedTcs.Task;1260        }1261        /// <summary>1262        /// Toggles ignoring cache for each request based on the enabled state. By default, caching is enabled.1263        /// </summary>1264        /// <param name="enabled">sets the <c>enabled</c> state of the cache</param>1265        /// <returns>Task</returns>1266        public Task SetCacheEnabledAsync(bool enabled = true)1267            => FrameManager.NetworkManager.SetCacheEnabledAsync(enabled);1268        /// <summary>1269        /// Fetches an element with <paramref name="selector"/>, scrolls it into view if needed, and then uses <see cref="Mouse"/> to click in the center of the element.1270        /// </summary>1271        /// <param name="selector">A selector to search for element to click. If there are multiple elements satisfying the selector, the first will be clicked.</param>1272        /// <param name="options">click options</param>1273        /// <exception cref="SelectorException">If there's no element matching <paramref name="selector"/></exception>1274        /// <returns>Task which resolves when the element matching <paramref name="selector"/> is successfully clicked</returns>1275        public Task ClickAsync(string selector, ClickOptions options = null) => FrameManager.MainFrame.ClickAsync(selector, options);1276        /// <summary>1277        /// Fetches an element with <paramref name="selector"/>, scrolls it into view if needed, and then uses <see cref="Mouse"/> to hover over the center of the element.1278        /// </summary>1279        /// <param name="selector">A selector to search for element to hover. If there are multiple elements satisfying the selector, the first will be hovered.</param>1280        /// <exception cref="SelectorException">If there's no element matching <paramref name="selector"/></exception>1281        /// <returns>Task which resolves when the element matching <paramref name="selector"/> is successfully hovered</returns>1282        public Task HoverAsync(string selector) => FrameManager.MainFrame.HoverAsync(selector);1283        /// <summary>1284        /// Fetches an element with <paramref name="selector"/> and focuses it1285        /// </summary>1286        /// <param name="selector">A selector to search for element to focus. If there are multiple elements satisfying the selector, the first will be focused.</param>1287        /// <exception cref="SelectorException">If there's no element matching <paramref name="selector"/></exception>1288        /// <returns>Task which resolves when the element matching <paramref name="selector"/> is successfully focused</returns>1289        public Task FocusAsync(string selector) => FrameManager.MainFrame.FocusAsync(selector);1290        /// <summary>1291        /// Sends a <c>keydown</c>, <c>keypress</c>/<c>input</c>, and <c>keyup</c> event for each character in the text.1292        /// </summary>1293        /// <param name="selector">A selector of an element to type into. If there are multiple elements satisfying the selector, the first will be used.</param>1294        /// <param name="text">A text to type into a focused element</param>1295        /// <param name="options">The options to apply to the type operation.</param>1296        /// <exception cref="SelectorException">If there's no element matching <paramref name="selector"/></exception>1297        /// <remarks>1298        /// To press a special key, like <c>Control</c> or <c>ArrowDown</c> use <see cref="PuppeteerSharp.Input.Keyboard.PressAsync(string, PressOptions)"/>1299        /// </remarks>1300        /// <example>1301        /// <code>1302        /// await page.TypeAsync("#mytextarea", "Hello"); // Types instantly1303        /// await page.TypeAsync("#mytextarea", "World", new TypeOptions { Delay = 100 }); // Types slower, like a user1304        /// </code>1305        /// </example>1306        /// <returns>Task</returns>1307        public Task TypeAsync(string selector, string text, TypeOptions options = null)1308            => FrameManager.MainFrame.TypeAsync(selector, text, options);1309        /// <summary>1310        /// Executes a script in browser context1311        /// </summary>1312        /// <param name="script">Script to be evaluated in browser context</param>1313        /// <remarks>1314        /// If the script, returns a Promise, then the method would wait for the promise to resolve and return its value.1315        /// </remarks>1316        /// <example>1317        /// An example of scraping information from all hyperlinks on the page.1318        /// <code>1319        /// var hyperlinkInfo = await page.EvaluateExpressionAsync(@"1320        ///     Array1321        ///        .from(document.querySelectorAll('a'))1322        ///        .map(n => ({1323        ///            text: n.innerText,1324        ///            href: n.getAttribute('href'),1325        ///            target: n.getAttribute('target')1326        ///         }))1327        /// ");1328        /// Console.WriteLine(hyperlinkInfo.ToString()); // Displays JSON array of hyperlinkInfo objects1329        /// </code>1330        /// </example>1331        /// <seealso href="https://www.newtonsoft.com/json/help/html/t_newtonsoft_json_linq_jtoken.htm"/>1332        /// <seealso cref="EvaluateFunctionAsync{T}(string, object[])"/>1333        /// <returns>Task which resolves to script return value</returns>1334        public Task<JToken> EvaluateExpressionAsync(string script)1335            => FrameManager.MainFrame.EvaluateExpressionAsync<JToken>(script);1336        /// <summary>1337        /// Executes a script in browser context1338        /// </summary>1339        /// <typeparam name="T">The type to deserialize the result to</typeparam>1340        /// <param name="script">Script to be evaluated in browser context</param>1341        /// <remarks>1342        /// If the script, returns a Promise, then the method would wait for the promise to resolve and return its value.1343        /// </remarks>1344        /// <seealso cref="EvaluateFunctionAsync{T}(string, object[])"/>1345        /// <returns>Task which resolves to script return value</returns>1346        public Task<T> EvaluateExpressionAsync<T>(string script)1347            => FrameManager.MainFrame.EvaluateExpressionAsync<T>(script);1348        /// <summary>1349        /// Executes a function in browser context1350        /// </summary>1351        /// <param name="script">Script to be evaluated in browser context</param>1352        /// <param name="args">Arguments to pass to script</param>1353        /// <remarks>1354        /// If the script, returns a Promise, then the method would wait for the promise to resolve and return its value.1355        /// <see cref="JSHandle"/> instances can be passed as arguments1356        /// </remarks>1357        /// <seealso cref="EvaluateExpressionAsync{T}(string)"/>1358        /// <returns>Task which resolves to script return value</returns>1359        public Task<JToken> EvaluateFunctionAsync(string script, params object[] args)1360            => FrameManager.MainFrame.EvaluateFunctionAsync<JToken>(script, args);1361        /// <summary>1362        /// Executes a function in browser context1363        /// </summary>1364        /// <typeparam name="T">The type to deserialize the result to</typeparam>1365        /// <param name="script">Script to be evaluated in browser context</param>1366        /// <param name="args">Arguments to pass to script</param>1367        /// <remarks>1368        /// If the script, returns a Promise, then the method would wait for the promise to resolve and return its value.1369        /// <see cref="JSHandle"/> instances can be passed as arguments1370        /// </remarks>1371        /// <seealso cref="EvaluateExpressionAsync{T}(string)"/>1372        /// <returns>Task which resolves to script return value</returns>1373        public Task<T> EvaluateFunctionAsync<T>(string script, params object[] args)1374            => FrameManager.MainFrame.EvaluateFunctionAsync<T>(script, args);1375        /// <summary>1376        /// Sets the user agent to be used in this page1377        /// </summary>1378        /// <param name="userAgent">Specific user agent to use in this page</param>1379        /// <returns>Task</returns>1380        public Task SetUserAgentAsync(string userAgent)1381            => FrameManager.NetworkManager.SetUserAgentAsync(userAgent);1382        /// <summary>1383        /// Sets extra HTTP headers that will be sent with every request the page initiates1384        /// </summary>1385        /// <param name="headers">Additional http headers to be sent with every request</param>1386        /// <returns>Task</returns>1387        public Task SetExtraHttpHeadersAsync(Dictionary<string, string> headers)1388        {1389            if (headers == null)1390            {1391                throw new ArgumentNullException(nameof(headers));1392            }1393            return FrameManager.NetworkManager.SetExtraHTTPHeadersAsync(headers);1394        }1395        /// <summary>1396        /// Provide credentials for http authentication <see href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication"/>1397        /// </summary>1398        /// <param name="credentials">The credentials</param>1399        /// <returns></returns>1400        /// <remarks>1401        /// To disable authentication, pass <c>null</c>1402        /// </remarks>1403        public Task AuthenticateAsync(Credentials credentials) => FrameManager.NetworkManager.AuthenticateAsync(credentials);1404        /// <summary>1405        /// Reloads the page1406        /// </summary>1407        /// <param name="options">Navigation options</param>1408        /// <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>1409        /// <seealso cref="ReloadAsync(int?, WaitUntilNavigation[])"/>1410        public async Task<Response> ReloadAsync(NavigationOptions options)1411        {1412            var navigationTask = WaitForNavigationAsync(options);1413            await Task.WhenAll(1414              navigationTask,1415              Client.SendAsync("Page.reload", new PageReloadRequest { FrameId = MainFrame.Id })).ConfigureAwait(false);1416            return navigationTask.Result;1417        }1418        /// <summary>1419        /// Reloads the page1420        /// </summary>1421        /// <param name="timeout">Maximum navigation time in milliseconds, defaults to 30 seconds, pass <c>0</c> to disable timeout. </param>1422        /// <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>1423        /// <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>1424        /// <seealso cref="ReloadAsync(NavigationOptions)"/>1425        public Task<Response> ReloadAsync(int? timeout = null, WaitUntilNavigation[] waitUntil = null)1426            => ReloadAsync(new NavigationOptions { Timeout = timeout, WaitUntil = waitUntil });1427        /// <summary>1428        /// Triggers a change and input event once all the provided options have been selected.1429        /// If there's no <![CDATA[<select>]]> element matching selector, the method throws an error.1430        /// </summary>1431        /// <exception cref="SelectorException">If there's no element matching <paramref name="selector"/></exception>1432        /// <param name="selector">A selector to query page for</param>1433        /// <param name="values">Values of options to select. If the <![CDATA[<select>]]> has the multiple attribute,1434        /// all values are considered, otherwise only the first one is taken into account.</param>1435        /// <returns>Returns an array of option values that have been successfully selected.</returns>1436        /// <seealso cref="Frame.SelectAsync(string, string[])"/>1437        public Task<string[]> SelectAsync(string selector, params string[] values)1438            => MainFrame.SelectAsync(selector, values);1439        /// <summary>1440        /// Waits for a timeout1441        /// </summary>1442        /// <param name="milliseconds">The amount of time to wait.</param>1443        /// <returns>A task that resolves when after the timeout</returns>1444        /// <seealso cref="Frame.WaitForTimeoutAsync(int)"/>1445        public Task WaitForTimeoutAsync(int milliseconds)1446            => MainFrame.WaitForTimeoutAsync(milliseconds);1447        /// <summary>1448        /// Waits for a function to be evaluated to a truthy value1449        /// </summary>1450        /// <param name="script">Function to be evaluated in browser context</param>1451        /// <param name="options">Optional waiting parameters</param>1452        /// <param name="args">Arguments to pass to <c>script</c></param>1453        /// <returns>A task that resolves when the <c>script</c> returns a truthy value</returns>1454        /// <seealso cref="Frame.WaitForFunctionAsync(string, WaitForFunctionOptions, object[])"/>1455        public Task<JSHandle> WaitForFunctionAsync(string script, WaitForFunctionOptions options = null, params object[] args)1456            => MainFrame.WaitForFunctionAsync(script, options ?? new WaitForFunctionOptions(), args);1457        /// <summary>1458        /// Waits for a function to be evaluated to a truthy value1459        /// </summary>1460        /// <param name="script">Function to be evaluated in browser context</param>1461        /// <param name="args">Arguments to pass to <c>script</c></param>1462        /// <returns>A task that resolves when the <c>script</c> returns a truthy value</returns>1463        public Task<JSHandle> WaitForFunctionAsync(string script, params object[] args) => WaitForFunctionAsync(script, null, args);1464        /// <summary>1465        /// Waits for an expression to be evaluated to a truthy value1466        /// </summary>1467        /// <param name="script">Expression to be evaluated in browser context</param>1468        /// <param name="options">Optional waiting parameters</param>1469        /// <returns>A task that resolves when the <c>script</c> returns a truthy value</returns>1470        /// <seealso cref="Frame.WaitForExpressionAsync(string, WaitForFunctionOptions)"/>1471        public Task<JSHandle> WaitForExpressionAsync(string script, WaitForFunctionOptions options = null)1472            => MainFrame.WaitForExpressionAsync(script, options ?? new WaitForFunctionOptions());1473        /// <summary>1474        /// Waits for a selector to be added to the DOM1475        /// </summary>1476        /// <param name="selector">A selector of an element to wait for</param>1477        /// <param name="options">Optional waiting parameters</param>1478        /// <returns>A task that resolves when element specified by selector string is added to DOM.1479        /// Resolves to `null` if waiting for `hidden: true` and selector is not found in DOM.</returns>1480        /// <seealso cref="WaitForXPathAsync(string, WaitForSelectorOptions)"/>1481        /// <seealso cref="Frame.WaitForSelectorAsync(string, WaitForSelectorOptions)"/>1482        public Task<ElementHandle> WaitForSelectorAsync(string selector, WaitForSelectorOptions options = null)1483            => MainFrame.WaitForSelectorAsync(selector, options ?? new WaitForSelectorOptions());1484        /// <summary>1485        /// Waits for a xpath selector to be added to the DOM1486        /// </summary>1487        /// <param name="xpath">A xpath selector of an element to wait for</param>1488        /// <param name="options">Optional waiting parameters</param>1489        /// <returns>A task which resolves when element specified by xpath string is added to DOM.1490        /// Resolves to `null` if waiting for `hidden: true` and xpath is not found in DOM.</returns>1491        /// <example>1492        /// <code>1493        /// <![CDATA[1494        /// var browser = await Puppeteer.LaunchAsync(new LaunchOptions());1495        /// var page = await browser.NewPageAsync();1496        /// string currentURL = null;1497        /// page1498        ///     .WaitForXPathAsync("//img")1499        ///     .ContinueWith(_ => Console.WriteLine("First URL with image: " + currentURL));1500        /// foreach (var current in new[] { "https://example.com", "https://google.com", "https://bbc.com" })1501        /// {1502        ///     currentURL = current;1503        ///     await page.GoToAsync(currentURL);1504        /// }1505        /// await browser.CloseAsync();1506        /// ]]>1507        /// </code>1508        /// </example>1509        /// <seealso cref="WaitForSelectorAsync(string, WaitForSelectorOptions)"/>1510        /// <seealso cref="Frame.WaitForXPathAsync(string, WaitForSelectorOptions)"/>1511        public Task<ElementHandle> WaitForXPathAsync(string xpath, WaitForSelectorOptions options = null)1512            => MainFrame.WaitForXPathAsync(xpath, options ?? new WaitForSelectorOptions());1513        /// <summary>1514        /// This resolves when the page navigates to a new URL or reloads.1515        /// It is useful for when you run code which will indirectly cause the page to navigate.1516        /// </summary>1517        /// <param name="options">navigation options</param>1518        /// <returns>Task which resolves to the main resource response.1519        /// In case of multiple redirects, the navigation will resolve with the response of the last redirect.1520        /// In case of navigation to a different anchor or navigation due to History API usage, the navigation will resolve with `null`.1521        /// </returns>1522        /// <remarks>1523        /// 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 navigation1524        /// </remarks>1525        /// <example>1526        /// <code>1527        /// <![CDATA[1528        /// var navigationTask = page.WaitForNavigationAsync();1529        /// await page.ClickAsync("a.my-link");1530        /// await navigationTask;1531        /// ]]>1532        /// </code>1533        /// </example>1534        public Task<Response> WaitForNavigationAsync(NavigationOptions options = null) => FrameManager.WaitForFrameNavigationAsync(FrameManager.MainFrame, options);1535        /// <summary>1536        /// Waits for Network Idle1537        /// </summary>1538        /// <param name="options">Optional waiting parameters</param>1539        /// <returns>returns Task which resolves when network is idle</returns>1540        /// <example>1541        /// <code>1542        /// <![CDATA[1543        /// page.EvaluateFunctionAsync("() => fetch('some-url')");1544        /// await page.WaitForNetworkIdle(); // The Task resolves after fetch above finishes1545        /// ]]>1546        /// </code>1547        /// </example>1548        public async Task WaitForNetworkIdleAsync(WaitForNetworkIdleOptions options = null)1549        {1550            var timeout = options?.Timeout ?? DefaultTimeout;1551            var idleTime = options?.IdleTime ?? 500;1552            var networkIdleTcs = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);1553            var idleTimer = new Timer1554            {1555                Interval = idleTime1556            };1557            idleTimer.Elapsed += (sender, args) =>1558            {1559                networkIdleTcs.TrySetResult(true);1560            };1561            var networkManager = FrameManager.NetworkManager;1562            void Evaluate()1563            {1564                idleTimer.Stop();1565                if (networkManager.NumRequestsInProgress == 0)1566                {1567                    idleTimer.Start();1568                }1569            }1570            void RequestEventListener(object sender, RequestEventArgs e) => Evaluate();1571            void ResponseEventListener(object sender, ResponseCreatedEventArgs e) => Evaluate();1572            void Cleanup()1573            {1574                idleTimer.Stop();1575                idleTimer.Dispose();1576                networkManager.Request -= RequestEventListener;1577                networkManager.Response -= ResponseEventListener;1578            }1579            networkManager.Request += RequestEventListener;1580            networkManager.Response += ResponseEventListener;1581            Evaluate();1582            await Task.WhenAny(networkIdleTcs.Task, SessionClosedTask).WithTimeout(timeout, t =>1583            {1584                Cleanup();1585                return new TimeoutException($"Timeout of {t.TotalMilliseconds} ms exceeded");1586            }).ConfigureAwait(false);1587            Cleanup();1588            if (SessionClosedTask.IsFaulted)1589            {1590                await SessionClosedTask.ConfigureAwait(false);1591            }1592        }1593        /// <summary>1594        /// Waits for a request.1595        /// </summary>1596        /// <example>1597        /// <code>1598        /// <![CDATA[1599        /// var firstRequest = await page.WaitForRequestAsync("http://example.com/resource");1600        /// return firstRequest.Url;1601        /// ]]>1602        /// </code>1603        /// </example>1604        /// <returns>A task which resolves when a matching request was made.</returns>1605        /// <param name="url">URL to wait for.</param>1606        /// <param name="options">Options.</param>1607        public Task<Request> WaitForRequestAsync(string url, WaitForOptions options = null)1608            => WaitForRequestAsync(request => request.Url == url, options);1609        /// <summary>1610        /// Waits for a request.1611        /// </summary>1612        /// <example>1613        /// <code>1614        /// <![CDATA[1615        /// var request = await page.WaitForRequestAsync(request => request.Url === "http://example.com" && request.Method === HttpMethod.Get;1616        /// return request.Url;1617        /// ]]>1618        /// </code>1619        /// </example>1620        /// <returns>A task which resolves when a matching request was made.</returns>1621        /// <param name="predicate">Function which looks for a matching request.</param>1622        /// <param name="options">Options.</param>1623        public async Task<Request> WaitForRequestAsync(Func<Request, bool> predicate, WaitForOptions options = null)1624        {1625            var timeout = options?.Timeout ?? DefaultTimeout;1626            var requestTcs = new TaskCompletionSource<Request>(TaskCreationOptions.RunContinuationsAsynchronously);1627            void requestEventListener(object sender, RequestEventArgs e)1628            {1629                if (predicate(e.Request))1630                {1631                    requestTcs.TrySetResult(e.Request);1632                    FrameManager.NetworkManager.Request -= requestEventListener;1633                }1634            }1635            FrameManager.NetworkManager.Request += requestEventListener;1636            await Task.WhenAny(requestTcs.Task, SessionClosedTask).WithTimeout(timeout, t =>1637            {1638                FrameManager.NetworkManager.Request -= requestEventListener;1639                return new TimeoutException($"Timeout of {t.TotalMilliseconds} ms exceeded");1640            }).ConfigureAwait(false);1641            if (SessionClosedTask.IsFaulted)1642            {1643                await SessionClosedTask.ConfigureAwait(false);1644            }1645            return await requestTcs.Task.ConfigureAwait(false);1646        }1647        /// <summary>1648        /// Waits for a response.1649        /// </summary>1650        /// <example>1651        /// <code>1652        /// <![CDATA[1653        /// var firstResponse = await page.WaitForResponseAsync("http://example.com/resource");1654        /// return firstResponse.Url;1655        /// ]]>1656        /// </code>1657        /// </example>1658        /// <returns>A task which resolves when a matching response is received.</returns>1659        /// <param name="url">URL to wait for.</param>1660        /// <param name="options">Options.</param>1661        public Task<Response> WaitForResponseAsync(string url, WaitForOptions options = null)1662            => WaitForResponseAsync(response => response.Url == url, options);1663        /// <summary>1664        /// Waits for a response.1665        /// </summary>1666        /// <example>1667        /// <code>1668        /// <![CDATA[1669        /// var response = await page.WaitForResponseAsync(response => response.Url === "http://example.com" && response.Status === HttpStatus.Ok;1670        /// return response.Url;1671        /// ]]>1672        /// </code>1673        /// </example>1674        /// <returns>A task which resolves when a matching response is received.</returns>1675        /// <param name="predicate">Function which looks for a matching response.</param>1676        /// <param name="options">Options.</param>1677        public async Task<Response> WaitForResponseAsync(Func<Response, bool> predicate, WaitForOptions options = null)1678        {1679            var timeout = options?.Timeout ?? DefaultTimeout;1680            var responseTcs = new TaskCompletionSource<Response>(TaskCreationOptions.RunContinuationsAsynchronously);1681            void responseEventListener(object sender, ResponseCreatedEventArgs e)1682            {1683                if (predicate(e.Response))1684                {1685                    responseTcs.TrySetResult(e.Response);1686                    FrameManager.NetworkManager.Response -= responseEventListener;1687                }1688            }1689            FrameManager.NetworkManager.Response += responseEventListener;1690            await Task.WhenAny(responseTcs.Task, SessionClosedTask).WithTimeout(timeout).ConfigureAwait(false);1691            if (SessionClosedTask.IsFaulted)1692            {1693                await SessionClosedTask.ConfigureAwait(false);1694            }1695            return await responseTcs.Task.ConfigureAwait(false);1696        }1697        /// <summary>1698        /// Waits for a page to open a file picker1699        /// </summary>1700        /// <remarks>1701        /// In non-headless Chromium, this method results in the native file picker dialog **not showing up** for the user.1702        /// </remarks>1703        /// <example>1704        /// This method is typically coupled with an action that triggers file choosing.1705        /// The following example clicks a button that issues a file chooser, and then1706        /// responds with `/tmp/myfile.pdf` as if a user has selected this file.1707        /// <code>1708        /// <![CDATA[1709        /// var waitTask = page.WaitForFileChooserAsync();1710        /// await Task.WhenAll(1711        ///     waitTask,1712        ///     page.ClickAsync("#upload-file-button")); // some button that triggers file selection1713        ///1714        /// await waitTask.Result.AcceptAsync('/tmp/myfile.pdf');1715        /// ]]>1716        /// </code>1717        ///1718        /// This must be called *before* the file chooser is launched. It will not return a currently active file chooser.1719        /// </example>1720        /// <param name="options">Optional waiting parameters.</param>1721        /// <returns>A task that resolves after a page requests a file picker.</returns>1722        public async Task<FileChooser> WaitForFileChooserAsync(WaitForFileChooserOptions options = null)1723        {1724            if (!_fileChooserInterceptors.Any())1725            {1726                await Client.SendAsync("Page.setInterceptFileChooserDialog", new PageSetInterceptFileChooserDialog1727                {1728                    Enabled = true1729                }).ConfigureAwait(false);1730            }1731            var timeout = options?.Timeout ?? _timeoutSettings.Timeout;1732            var tcs = new TaskCompletionSource<FileChooser>(TaskCreationOptions.RunContinuationsAsynchronously);1733            var guid = Guid.NewGuid();1734            _fileChooserInterceptors.TryAdd(guid, tcs);1735            try1736            {1737                return await tcs.Task.WithTimeout(timeout).ConfigureAwait(false);1738            }1739            catch (Exception)1740            {1741                _fileChooserInterceptors.TryRemove(guid, out _);1742                throw;1743            }1744        }1745        /// <summary>1746        /// Navigate to the previous page in history.1747        /// </summary>1748        /// <returns>Task that resolves to the main resource response. In case of multiple redirects,1749        /// the navigation will resolve with the response of the last redirect. If can not go back, resolves to null.</returns>1750        /// <param name="options">Navigation parameters.</param>1751        public Task<Response> GoBackAsync(NavigationOptions options = null) => GoAsync(-1, options);1752        /// <summary>1753        /// Navigate to the next page in history.1754        /// </summary>1755        /// <returns>Task that resolves to the main resource response. In case of multiple redirects,1756        /// the navigation will resolve with the response of the last redirect. If can not go forward, resolves to null.</returns>1757        /// <param name="options">Navigation parameters.</param>1758        public Task<Response> GoForwardAsync(NavigationOptions options = null) => GoAsync(1, options);1759        /// <summary>1760        /// Resets the background color and Viewport after taking Screenshots using BurstMode.1761        /// </summary>1762        /// <returns>The burst mode off.</returns>1763        public Task SetBurstModeOffAsync()1764        {1765            _screenshotBurstModeOn = false;1766            if (_screenshotBurstModeOptions != null)1767            {1768                ResetBackgroundColorAndViewportAsync(_screenshotBurstModeOptions);1769            }1770            return Task.CompletedTask;1771        }1772        /// <summary>1773        /// Brings page to front (activates tab).1774        /// </summary>1775        /// <returns>A task that resolves when the message has been sent to Chromium.</returns>1776        public Task BringToFrontAsync() => Client.SendAsync("Page.bringToFront");1777        /// <summary>1778        /// Simulates the given vision deficiency on the page.1779        /// </summary>1780        /// <example>1781        /// await Page.EmulateVisionDeficiencyAsync(VisionDeficiency.Achromatopsia);1782        /// await Page.ScreenshotAsync("Achromatopsia.png");1783        /// </example>1784        /// <param name="type">The type of deficiency to simulate, or <see cref="VisionDeficiency.None"/> to reset.</param>1785        /// <returns>A task that resolves when the message has been sent to the browser.</returns>1786        public Task EmulateVisionDeficiencyAsync(VisionDeficiency type)1787            => Client.SendAsync("Emulation.setEmulatedVisionDeficiency", new EmulationSetEmulatedVisionDeficiencyRequest1788            {1789                Type = type,1790            });1791        /// <summary>1792        /// Changes the timezone of the page.1793        /// </summary>1794        /// <param name="timezoneId">Timezone to set. See <seealso href="https://cs.chromium.org/chromium/src/third_party/icu/source/data/misc/metaZones.txt?rcl=faee8bc70570192d82d2978a71e2a615788597d1" >ICU’s `metaZones.txt`</seealso>1795        /// for a list of supported timezone IDs. Passing `null` disables timezone emulation.</param>1796        /// <returns>The viewport task.</returns>1797        public async Task EmulateTimezoneAsync(string timezoneId)1798        {1799            try1800            {1801                await Client.SendAsync("Emulation.setTimezoneOverride", new EmulateTimezoneRequest1802                {1803                    TimezoneId = timezoneId ?? string.Empty1804                }).ConfigureAwait(false);1805            }1806            catch (Exception ex) when (ex.Message.Contains("Invalid timezone"))1807            {1808                throw new PuppeteerException($"Invalid timezone ID: {timezoneId}");1809            }1810        }1811        /// <summary>1812        /// Emulates the idle state.1813        /// If no arguments set, clears idle state emulation.1814        /// </summary>1815        /// <example>1816        /// <code>1817        /// // set idle emulation1818        /// await page.EmulateIdleStateAsync(new EmulateIdleOverrides() {IsUserActive = true, IsScreenUnlocked = false});1819        /// // do some checks here1820        /// ...1821        /// // clear idle emulation1822        /// await page.EmulateIdleStateAsync();1823        /// </code>1824        /// </example>1825        /// <param name="overrides">Overrides</param>1826        /// <returns>A task that resolves when the message has been sent to the browser.</returns>1827        public async Task EmulateIdleStateAsync(EmulateIdleOverrides overrides = null)1828        {1829            if (overrides != null)1830            {1831                await Client.SendAsync(1832                    "Emulation.setIdleOverride",1833                    new EmulationSetIdleOverrideRequest1834                    {1835                        IsUserActive = overrides.IsUserActive,1836                        IsScreenUnlocked = overrides.IsScreenUnlocked,1837                    }).ConfigureAwait(false);1838            }1839            else1840            {1841                await Client.SendAsync("Emulation.clearIdleOverride").ConfigureAwait(false);1842            }1843        }1844        /// <summary>1845        /// Enables CPU throttling to emulate slow CPUs.1846        /// </summary>1847        /// <param name="factor">Throttling rate as a slowdown factor (1 is no throttle, 2 is 2x slowdown, etc).</param>1848        /// <returns>A task that resolves when the message has been sent to the browser.</returns>1849        public Task EmulateCPUThrottlingAsync(decimal? factor = null)1850        {1851            if (factor != null && factor < 1)1852            {1853                throw new ArgumentException("Throttling rate should be greater or equal to 1", nameof(factor));1854            }1855            return Client.SendAsync("Emulation.setCPUThrottlingRate", new EmulationSetCPUThrottlingRateRequest1856            {1857                Rate = factor ?? 11858            });1859        }1860        internal void OnPopup(Page popupPage) => Popup?.Invoke(this, new PopupEventArgs { PopupPage = popupPage });1861        internal static async Task<Page> CreateAsync(1862            CDPSession client,1863            Target target,1864            bool ignoreHTTPSErrors,1865            ViewPortOptions defaultViewPort,1866            TaskQueue screenshotTaskQueue)1867        {1868            var page = new Page(client, target, screenshotTaskQueue);1869            await page.InitializeAsync(ignoreHTTPSErrors).ConfigureAwait(false);1870            if (defaultViewPort != null)1871            {1872                await page.SetViewportAsync(defaultViewPort).ConfigureAwait(false);1873            }1874            return page;1875        }1876        private async Task InitializeAsync(bool ignoreHTTPSErrors)1877        {1878            FrameManager = await FrameManager.CreateFrameManagerAsync(Client, this, ignoreHTTPSErrors, _timeoutSettings).ConfigureAwait(false);1879            var networkManager = FrameManager.NetworkManager;1880            Client.MessageReceived += Client_MessageReceived;1881            FrameManager.FrameAttached += (_, e) => FrameAttached?.Invoke(this, e);1882            FrameManager.FrameDetached += (_, e) => FrameDetached?.Invoke(this, e);1883            FrameManager.FrameNavigated += (_, e) => FrameNavigated?.Invoke(this, e);1884            networkManager.Request += (_, e) => Request?.Invoke(this, e);1885            networkManager.RequestFailed += (_, e) => RequestFailed?.Invoke(this, e);1886            networkManager.Response += (_, e) => Response?.Invoke(this, e);1887            networkManager.RequestFinished += (_, e) => RequestFinished?.Invoke(this, e);1888            networkManager.RequestServedFromCache += (_, e) => RequestServedFromCache?.Invoke(this, e);1889            await Task.WhenAll(1890               Client.SendAsync("Target.setAutoAttach", new TargetSetAutoAttachRequest1891               {1892                   AutoAttach = true,1893                   WaitForDebuggerOnStart = false,1894                   Flatten = true1895               }),1896               Client.SendAsync("Performance.enable", null),1897               Client.SendAsync("Log.enable", null)).ConfigureAwait(false);1898        }1899        private async Task<Response> GoAsync(int delta, NavigationOptions options)1900        {1901            var history = await Client.SendAsync<PageGetNavigationHistoryResponse>("Page.getNavigationHistory").ConfigureAwait(false);1902            if (history.Entries.Count <= history.CurrentIndex + delta || history.CurrentIndex + delta < 0)1903            {1904                return null;1905            }1906            var entry = history.Entries[history.CurrentIndex + delta];1907            var waitTask = WaitForNavigationAsync(options);1908            await Task.WhenAll(1909                waitTask,1910                Client.SendAsync("Page.navigateToHistoryEntry", new PageNavigateToHistoryEntryRequest1911                {1912                    EntryId = entry.Id1913                })).ConfigureAwait(false);1914            return waitTask.Result;1915        }1916        private Dictionary<string, decimal> BuildMetricsObject(List<Metric> metrics)1917        {1918            var result = new Dictionary<string, decimal>();1919            foreach (var item in metrics)1920            {1921                if (SupportedMetrics.Contains(item.Name))1922                {1923                    result.Add(item.Name, item.Value);1924                }1925            }1926            return result;1927        }1928        private async Task<string> PerformScreenshot(ScreenshotType type, ScreenshotOptions options)1929        {1930            if (!_screenshotBurstModeOn)1931            {1932                await Client.SendAsync("Target.activateTarget", new TargetActivateTargetRequest1933                {1934                    TargetId = Target.TargetId1935                }).ConfigureAwait(false);1936            }1937            var clip = options.Clip != null ? ProcessClip(options.Clip) : null;1938            if (!_screenshotBurstModeOn)1939            {1940                if (options != null && options.FullPage)1941                {1942                    var metrics = _screenshotBurstModeOn1943                        ? _burstModeMetrics :1944                        await Client.SendAsync<PageGetLayoutMetricsResponse>("Page.getLayoutMetrics").ConfigureAwait(false);1945                    if (options.BurstMode)1946                    {1947                        _burstModeMetrics = metrics;1948                    }1949                    var contentSize = metrics.ContentSize;1950                    var width = Convert.ToInt32(Math.Ceiling(contentSize.Width));1951                    var height = Convert.ToInt32(Math.Ceiling(contentSize.Height));1952                    // Overwrite clip for full page at all times.1953                    clip = new Clip1954                    {1955                        X = 0,1956                        Y = 0,1957                        Width = width,1958                        Height = height,1959                        Scale = 11960                    };1961                    var isMobile = Viewport?.IsMobile ?? false;1962                    var deviceScaleFactor = Viewport?.DeviceScaleFactor ?? 1;1963                    var isLandscape = Viewport?.IsLandscape ?? false;1964                    var screenOrientation = isLandscape ?1965                        new ScreenOrientation1966                        {1967                            Angle = 90,1968                            Type = ScreenOrientationType.LandscapePrimary1969                        } :1970                        new ScreenOrientation1971                        {1972                            Angle = 0,1973                            Type = ScreenOrientationType.PortraitPrimary1974                        };1975                    await Client.SendAsync("Emulation.setDeviceMetricsOverride", new EmulationSetDeviceMetricsOverrideRequest1976                    {1977                        Mobile = isMobile,1978                        Width = width,1979                        Height = height,1980                        DeviceScaleFactor = deviceScaleFactor,1981                        ScreenOrientation = screenOrientation1982                    }).ConfigureAwait(false);1983                }1984                if (options?.OmitBackground == true && type == ScreenshotType.Png)1985                {1986                    await SetTransparentBackgroundColorAsync().ConfigureAwait(false);1987                }1988            }1989            var screenMessage = new PageCaptureScreenshotRequest1990            {1991                Format = type.ToString().ToLower(CultureInfo.CurrentCulture)1992            };1993            if (options.Quality.HasValue)1994            {1995                screenMessage.Quality = options.Quality.Value;1996            }1997            if (clip != null)1998            {1999                screenMessage.Clip = clip;2000            }2001            var result = await Client.SendAsync<PageCaptureScreenshotResponse>("Page.captureScreenshot", screenMessage).ConfigureAwait(false);2002            if (options.BurstMode)2003            {2004                _screenshotBurstModeOptions = options;2005                _screenshotBurstModeOn = true;2006            }2007            else2008            {2009                await ResetBackgroundColorAndViewportAsync(options).ConfigureAwait(false);2010            }2011            return result.Data;2012        }2013        private Clip ProcessClip(Clip clip)2014        {2015            var x = Math.Round(clip.X);2016            var y = Math.Round(clip.Y);2017            return new Clip2018            {2019                X = x,2020                Y = y,2021                Width = Math.Round(clip.Width + clip.X - x, MidpointRounding.AwayFromZero),2022                Height = Math.Round(clip.Height + clip.Y - y, MidpointRounding.AwayFromZero),2023                Scale = clip.Scale2024            };2025        }2026        private Task ResetBackgroundColorAndViewportAsync(ScreenshotOptions options)2027        {2028            var omitBackgroundTask = options?.OmitBackground == true && options.Type == ScreenshotType.Png ?2029                ResetDefaultBackgroundColorAsync() : Task.CompletedTask;2030            var setViewPortTask = (options?.FullPage == true && Viewport != null) ?2031                SetViewportAsync(Viewport) : Task.CompletedTask;2032            return Task.WhenAll(omitBackgroundTask, setViewPortTask);2033        }2034        private Task ResetDefaultBackgroundColorAsync()2035            => Client.SendAsync("Emulation.setDefaultBackgroundColorOverride");2036        private Task SetTransparentBackgroundColorAsync()2037            => Client.SendAsync("Emulation.setDefaultBackgroundColorOverride", new EmulationSetDefaultBackgroundColorOverrideRequest2038            {2039                Color = new EmulationSetDefaultBackgroundColorOverrideColor2040                {2041                    R = 0,2042                    G = 0,2043                    B = 0,2044                    A = 02045                }2046            });2047        private decimal ConvertPrintParameterToInches(object parameter)2048        {2049            if (parameter == null)2050            {2051                return 0;2052            }2053            decimal pixels;2054            if (parameter is decimal || parameter is int)2055            {2056                pixels = Convert.ToDecimal(parameter, CultureInfo.CurrentCulture);2057            }2058            else2059            {2060                var text = parameter.ToString();2061                var unit = text.Substring(text.Length - 2).ToLower(CultureInfo.CurrentCulture);2062                string valueText;2063                if (_unitToPixels.ContainsKey(unit))2064                {2065                    valueText = text.Substring(0, text.Length - 2);2066                }2067                else2068                {2069                    // In case of unknown unit try to parse the whole parameter as number of pixels.2070                    // This is consistent with phantom's paperSize behavior.2071                    unit = "px";2072                    valueText = text;2073                }2074                if (decimal.TryParse(valueText, NumberStyles.Any, CultureInfo.InvariantCulture.NumberFormat, out var number))2075                {2076                    pixels = number * _unitToPixels[unit];2077                }2078                else2079                {2080                    throw new ArgumentException($"Failed to parse parameter value: '{text}'", nameof(parameter));2081                }2082            }2083            return pixels / 96;2084        }2085        private async void Client_MessageReceived(object sender, MessageEventArgs e)2086        {2087            try2088            {2089                switch (e.MessageID)2090                {2091                    case "Page.domContentEventFired":2092                        DOMContentLoaded?.Invoke(this, EventArgs.Empty);2093                        break;2094                    case "Page.loadEventFired":2095                        Load?.Invoke(this, EventArgs.Empty);2096                        break;2097                    case "Runtime.consoleAPICalled":2098                        await OnConsoleAPIAsync(e.MessageData.ToObject<PageConsoleResponse>(true)).ConfigureAwait(false);2099                        break;2100                    case "Page.javascriptDialogOpening":2101                        OnDialog(e.MessageData.ToObject<PageJavascriptDialogOpeningResponse>(true));2102                        break;2103                    case "Runtime.exceptionThrown":2104                        HandleException(e.MessageData.ToObject<RuntimeExceptionThrownResponse>(true).ExceptionDetails);2105                        break;2106                    case "Inspector.targetCrashed":2107                        OnTargetCrashed();2108                        break;2109                    case "Performance.metrics":2110                        EmitMetrics(e.MessageData.ToObject<PerformanceMetricsResponse>(true));2111                        break;2112                    case "Target.attachedToTarget":2113                        await OnAttachedToTargetAsync(e.MessageData.ToObject<TargetAttachedToTargetResponse>(true)).ConfigureAwait(false);2114                        break;2115                    case "Target.detachedFromTarget":2116                        OnDetachedFromTarget(e.MessageData.ToObject<TargetDetachedFromTargetResponse>(true));2117                        break;2118                    case "Log.entryAdded":2119                        await OnLogEntryAddedAsync(e.MessageData.ToObject<LogEntryAddedResponse>(true)).ConfigureAwait(false);2120                        break;2121                    case "Runtime.bindingCalled":2122                        await OnBindingCalled(e.MessageData.ToObject<BindingCalledResponse>(true)).ConfigureAwait(false);2123                        break;2124                    case "Page.fileChooserOpened":2125                        await OnFileChooserAsync(e.MessageData.ToObject<PageFileChooserOpenedResponse>(true)).ConfigureAwait(false);2126                        break;2127                }2128            }2129            catch (Exception ex)2130            {2131                var message = $"Page failed to process {e.MessageID}. {ex.Message}. {ex.StackTrace}";2132                _logger.LogError(ex, message);2133                Client.Close(message);2134            }2135        }2136        private async Task OnFileChooserAsync(PageFileChooserOpenedResponse e)2137        {2138            if (_fileChooserInterceptors.Count == 0)2139            {2140                try2141                {2142                    await Client.SendAsync("Page.handleFileChooser", new PageHandleFileChooserRequest2143                    {2144                        Action = FileChooserAction.Fallback2145                    }).ConfigureAwait(false);2146                    return;2147                }2148                catch (Exception ex)2149                {2150                    _logger.LogError(ex, ex.ToString());2151                }2152            }2153            var frame = await FrameManager.GetFrameAsync(e.FrameId).ConfigureAwait(false);2154            var context = await frame.GetExecutionContextAsync().ConfigureAwait(false);2155            var element = await context.AdoptBackendNodeAsync(e.BackendNodeId).ConfigureAwait(false);2156            var fileChooser = new FileChooser(element, e);2157            while (_fileChooserInterceptors.Count > 0)2158            {2159                var key = _fileChooserInterceptors.FirstOrDefault().Key;2160                if (_fileChooserInterceptors.TryRemove(key, out var tcs))2161                {2162                    tcs.TrySetResult(fileChooser);2163                }2164            }2165        }2166        private async Task OnBindingCalled(BindingCalledResponse e)2167        {2168            string expression;2169            try2170            {...

Full Screen

Full Screen

ScheduleController.cs

Source:ScheduleController.cs Github

copy

Full Screen

...384                                var html2 = await page.GetContentAsync();385                                if (html2.Contains("Welcome to Instagram"))386                                {387                                    page.EvaluateExpressionAsync(@"document.querySelector(""header button"").click()");388                                    var fileChooser = await page.WaitForFileChooserAsync();389                                    await fileChooser.AcceptAsync(new string[] { HostingEnvironment.MapPath(schedule.ImagePath) });390                                    await PageNavigation(page);391                                }392                                else393                                {394                                    try395                                    {396                                        page.EvaluateExpressionAsync(ClickButton("Your Story"));397                                        var fileChooser = await page.WaitForFileChooserAsync();398                                        await fileChooser.AcceptAsync(new string[] { HostingEnvironment.MapPath(schedule.ImagePath) });399                                        await PageNavigation(page);400                                    }401                                    catch (Exception ex)402                                    {403                                        page.EvaluateExpressionAsync(ClickButton("Not Now"));404                                        var fileChooser = await page.WaitForFileChooserAsync();405                                        await fileChooser.AcceptAsync(new string[] { HostingEnvironment.MapPath(schedule.ImagePath) });406                                        await PageNavigation(page);407                                    }408                                }409                                try410                                {411                                    System.Threading.Thread.Sleep(5000);412                                    await page.EvaluateExpressionAsync(ClickButton("Add to your story"));413                                    System.Threading.Thread.Sleep(500);414                                    await PageNavigation(page);415                                    System.Threading.Thread.Sleep(5000);416                                    schedule.PostedStatus = true;417                                    schedule.LastTryDate = DateTime.Now;418                                    schedule.Exception = "";419                                }420                                catch (Exception ex)421                                {422                                    schedule.PostedStatus = true;423                                    schedule.LastTryDate = DateTime.Now;424                                    schedule.Exception = "Story Already Posted";425                                }426                            }427                            else428                            {429                                page.EvaluateExpressionAsync(@"document.querySelector(""div[data-testid=new-post-button]"").click()");430                                var fileChooser = await page.WaitForFileChooserAsync();431                                await fileChooser.AcceptAsync(new string[] { HostingEnvironment.MapPath(schedule.ImagePath) });432                                await PageNavigation(page);433                                System.Threading.Thread.Sleep(5000);434                                await page.EvaluateExpressionAsync(ClickButton("Next"));435                                await PageNavigation(page);436                                System.Threading.Thread.Sleep(5000);437                                for (int i = 0; i < 4; i++)438                                {439                                    await page.Keyboard.DownAsync(key: "Tab");440                                    System.Threading.Thread.Sleep(500);441                                }442                                await page.Keyboard.TypeAsync(schedule.Caption, new TypeOptions { Delay = 200 });443                                await page.EvaluateExpressionAsync(ClickButton("Share"));444                                System.Threading.Thread.Sleep(500);...

Full Screen

Full Screen

LicenseActivator.cs

Source:LicenseActivator.cs Github

copy

Full Screen

...78                        await AcceptTosIfRequired(page);79                        //Upload file80                        await page.WaitForSelectorAsync("#licenseFile");81                        Console.WriteLine("Uploading file...");82                        var fileChooserTask = page.WaitForFileChooserAsync();83                        await page.ClickAsync("#licenseFile");84                        var fileChooser = await fileChooserTask;85                        await fileChooser.AcceptAsync(cliOptions.LicenseFile);86                        await page.ClickAsync("input[value='Next']");87                        //Activate your license88                        var unityPersonalEditionButton = await page.WaitForSelectorAsync("label[for='type_personal']");89                        Console.WriteLine("Selecting edition...");90                        await unityPersonalEditionButton.ClickAsync();91                        var notUseUnityInProfessionalCapacity = await page.WaitForSelectorAsync("label[for='option3']");92                        await notUseUnityInProfessionalCapacity.ClickAsync();93                        var nextButton = await page.WaitForSelectorAsync(".selected input[value='Next']");94                        await nextButton.ClickAsync();95                        //Download license file96                        await page.WaitForSelectorAsync("input[value='Download license file']");...

Full Screen

Full Screen

HomeController.cs

Source:HomeController.cs Github

copy

Full Screen

...84                    System.Threading.Thread.Sleep(5000);85                    //Dont add await for this86                    page.EvaluateExpressionAsync(87                        @"document.querySelector(""div[data-testid=new-post-button]"").click()");88                    var fileChooser = await page.WaitForFileChooserAsync();89                    await fileChooser.AcceptAsync(new string[] { "C:\\Users\\Zawar\\Desktop\\New folder (4)\\cover6.jpg" });90                    System.Threading.Thread.Sleep(5000);91                    await page.EvaluateExpressionAsync(ClickButton("Next"));92                    System.Threading.Thread.Sleep(5000);93                    for (int i = 0; i < 4; i++)94                    {95                        await page.Keyboard.DownAsync(key: "Tab");96                        System.Threading.Thread.Sleep(500);97                    }98                    await page.Keyboard.TypeAsync("Automated caption", new TypeOptions { Delay = 200 });99                    await page.EvaluateExpressionAsync(ClickButton("Share"));100                    System.Threading.Thread.Sleep(1600000);101                }102                catch (Exception ex)...

Full Screen

Full Screen

FileChooserAcceptTests.cs

Source:FileChooserAcceptTests.cs Github

copy

Full Screen

...7using Xunit.Abstractions;8namespace PuppeteerSharp.Tests.InputTests9{10    [Collection(TestConstants.TestFixtureCollectionName)]11    public class FileChooserAcceptTests : PuppeteerPageBaseTest12    {13        public FileChooserAcceptTests(ITestOutputHelper output) : base(output)14        {15        }16        [PuppeteerTest("input.spec.ts", "FileChooser.accept", "should accept single file")]17        [SkipBrowserFact(skipFirefox: true)]18        public async Task ShouldAcceptSingleFile()19        {20            await Page.SetContentAsync("<input type=file oninput='javascript:console.timeStamp()'>");21            var waitForTask = Page.WaitForFileChooserAsync();22            var metricsTcs = new TaskCompletionSource<bool>();23            await Task.WhenAll(24                waitForTask,25                Page.ClickAsync("input"));26            Page.Metrics += (_, _) => metricsTcs.TrySetResult(true);27            await Task.WhenAll(28                waitForTask.Result.AcceptAsync(TestConstants.FileToUpload),29                metricsTcs.Task);30            Assert.Equal(1, await Page.QuerySelectorAsync("input").EvaluateFunctionAsync<int>("input => input.files.length"));31            Assert.Equal(32                "file-to-upload.txt",33                await Page.QuerySelectorAsync("input").EvaluateFunctionAsync<string>("input => input.files[0].name"));34        }35        [PuppeteerTest("input.spec.ts", "FileChooser.accept", "should be able to read selected file")]36        [SkipBrowserFact(skipFirefox: true)]37        public async Task ShouldBeAbleToReadSelectedFile()38        {39            await Page.SetContentAsync("<input type=file>");40            _ = Page.WaitForFileChooserAsync().ContinueWith(t => t.Result.AcceptAsync(TestConstants.FileToUpload));41            Assert.Equal(42                "contents of the file",43                await Page.QuerySelectorAsync("input").EvaluateFunctionAsync<string>(@"async picker =>44                {45                    picker.click();46                    await new Promise(x => picker.oninput = x);47                    const reader = new FileReader();48                    const promise = new Promise(fulfill => reader.onload = fulfill);49                    reader.readAsText(picker.files[0]);50                    return promise.then(() => reader.result);51                }"));52        }53        [PuppeteerTest("input.spec.ts", "FileChooser.accept", "should be able to reset selected files with empty file list")]54        [SkipBrowserFact(skipFirefox: true)]55        public async Task ShouldBeAbleToResetSelectedFilesWithEmptyFileList()56        {57            await Page.SetContentAsync("<input type=file>");58            _ = Page.WaitForFileChooserAsync().ContinueWith(t => t.Result.AcceptAsync(TestConstants.FileToUpload));59            Assert.Equal(60                1,61                await Page.QuerySelectorAsync("input").EvaluateFunctionAsync<int>(@"async picker =>62                {63                picker.click();64                await new Promise(x => picker.oninput = x);65                return picker.files.length;66            }"));67            _ = Page.WaitForFileChooserAsync().ContinueWith(t => t.Result.AcceptAsync());68            Assert.Equal(69                0,70                await Page.QuerySelectorAsync("input").EvaluateFunctionAsync<int>(@"async picker =>71                {72                picker.click();73                await new Promise(x => picker.oninput = x);74                return picker.files.length;75            }"));76        }77        [PuppeteerTest("input.spec.ts", "FileChooser.accept", "should not accept multiple files for single-file input")]78        [SkipBrowserFact(skipFirefox: true)]79        public async Task ShouldNotAcceptMultipleFilesForSingleFileInput()80        {81            await Page.SetContentAsync("<input type=file>");82            var waitForTask = Page.WaitForFileChooserAsync();83            await Task.WhenAll(84                waitForTask,85                Page.ClickAsync("input"));86            await Assert.ThrowsAsync<PuppeteerException>(() => waitForTask.Result.AcceptAsync(87                "./assets/file-to-upload.txt",88                "./assets/pptr.png"));89        }90        [PuppeteerTest("input.spec.ts", "FileChooser.accept", "should fail for non-existent files")]91        [SkipBrowserFact(skipFirefox: true)]92        public async Task ShouldFailForNonExistentFiles()93        {94            await Page.SetContentAsync("<input type=file>");95            var waitForTask = Page.WaitForFileChooserAsync();96            await Task.WhenAll(97                waitForTask,98                Page.ClickAsync("input"));99            await Assert.ThrowsAsync<PuppeteerException>(() => waitForTask.Result.AcceptAsync("file-does-not-exist.txt"));100        }101        [PuppeteerTest("input.spec.ts", "FileChooser.accept", "should fail when accepting file chooser twice")]102        [SkipBrowserFact(skipFirefox: true)]103        public async Task ShouldFailWhenAcceptingFileChooserTwice()104        {105            await Page.SetContentAsync("<input type=file>");106            var waitForTask = Page.WaitForFileChooserAsync();107            await Task.WhenAll(108                waitForTask,109                Page.ClickAsync("input"));110            var fileChooser = waitForTask.Result;111            await fileChooser.AcceptAsync();112            var ex = await Assert.ThrowsAsync<PuppeteerException>(() => waitForTask.Result.AcceptAsync());113            Assert.Equal("Cannot accept FileChooser which is already handled!", ex.Message);114        }115    }116}...

Full Screen

Full Screen

FileChooser.cs

Source:FileChooser.cs Github

copy

Full Screen

...5using PuppeteerSharp.Messaging;6namespace PuppeteerSharp7{8    /// <summary>9    /// <see cref="FileChooser"/> objects are returned via the <seealso cref="Page.WaitForFileChooserAsync(WaitForFileChooserOptions)"/> method.10    /// File choosers let you react to the page requesting for a file.11    /// </summary>12    /// <example>13    /// <code>14    /// <![CDATA[15    /// var waitTask = page.WaitForFileChooserAsync();16    /// await Task.WhenAll(17    ///     waitTask,18    ///     page.ClickAsync("#upload-file-button")); // some button that triggers file selection19    /// 20    /// await waitTask.Result.AcceptAsync('/tmp/myfile.pdf');21    /// ]]>22    /// </code>23    /// </example>24    /// <remarks>25    /// In browsers, only one file chooser can be opened at a time.26    /// All file choosers must be accepted or canceled. Not doing so will prevent subsequent file choosers from appearing.27    /// </remarks>28    public class FileChooser29    {30        private CDPSession _client;31        private bool _handled;32        internal FileChooser(CDPSession client, PageFileChooserOpenedResponse e)33        {34            _client = client;35            IsMultiple = e.Mode != "selectSingle";36            _handled = false;37        }38        /// <summary>39        /// Whether file chooser allow for <see href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#attr-multiple">multiple</see> file selection.40        /// </summary>41        public bool IsMultiple { get; }42        /// <summary>43        /// Accept the file chooser request with given paths. 44        /// If some of the filePaths are relative paths, then they are resolved relative to the current working directory.45        /// </summary>46        /// <param name="filePaths">File paths to send to the file chooser</param>47        /// <returns>A task that resolves after the accept message is processed by the browser</returns>48        public Task AcceptAsync(params string[] filePaths)49        {50            if (_handled)51            {52                throw new PuppeteerException("Cannot accept FileChooser which is already handled!");53            }54            _handled = true;55            var files = filePaths.Select(Path.GetFullPath);56            return _client.SendAsync("Page.handleFileChooser", new PageHandleFileChooserRequest57            {58                Action = FileChooserAction.Accept,59                Files = files,60            });61        }62        /// <summary>63        /// Closes the file chooser without selecting any files.64        /// </summary>65        /// <returns>A task that resolves after the cancel message is processed by the browser</returns>66        public Task CancelAsync()67        {68            if (_handled)69            {70                throw new PuppeteerException("Cannot accept FileChooser which is already handled!");71            }72            _handled = true;73            return _client.SendAsync("Page.handleFileChooser", new PageHandleFileChooserRequest74            {75                Action = FileChooserAction.Cancel76            });77        }78    }79}...

Full Screen

Full Screen

FileChooserIsMultipleTests.cs

Source:FileChooserIsMultipleTests.cs Github

copy

Full Screen

...7using Xunit.Abstractions;8namespace PuppeteerSharp.Tests.InputTests9{10    [Collection(TestConstants.TestFixtureCollectionName)]11    public class FileChooserIsMultipleTests : PuppeteerPageBaseTest12    {13        public FileChooserIsMultipleTests(ITestOutputHelper output) : base(output)14        {15        }16        [PuppeteerTest("input.spec.ts", "FileChooser.isMultiple", "should work for single file pick")]17        [SkipBrowserFact(skipFirefox: true)]18        public async Task ShouldWorkForSingleFilePick()19        {20            await Page.SetContentAsync("<input type=file>");21            var waitForTask = Page.WaitForFileChooserAsync();22            await Task.WhenAll(23                waitForTask,24                Page.ClickAsync("input"));25            Assert.False(waitForTask.Result.IsMultiple);26        }27        [PuppeteerTest("input.spec.ts", "FileChooser.isMultiple", "should work for \"multiple\"")]28        [SkipBrowserFact(skipFirefox: true)]29        public async Task ShouldWorkForMultiple()30        {31            await Page.SetContentAsync("<input type=file multiple>");32            var waitForTask = Page.WaitForFileChooserAsync();33            await Task.WhenAll(34                waitForTask,35                Page.ClickAsync("input"));36            Assert.True(waitForTask.Result.IsMultiple);37        }38        [PuppeteerTest("input.spec.ts", "FileChooser.isMultiple", "should work for \"webkitdirectory\"")]39        [SkipBrowserFact(skipFirefox: true)]40        public async Task ShouldWorkForWebkitDirectory()41        {42            await Page.SetContentAsync("<input type=file multiple webkitdirectory>");43            var waitForTask = Page.WaitForFileChooserAsync();44            await Task.WhenAll(45                waitForTask,46                Page.ClickAsync("input"));47            Assert.True(waitForTask.Result.IsMultiple);48        }49    }50}...

Full Screen

Full Screen

FileChooserCancelTests.cs

Source:FileChooserCancelTests.cs Github

copy

Full Screen

...5using Xunit.Abstractions;6namespace PuppeteerSharp.Tests.InputTests7{8    [Collection(TestConstants.TestFixtureCollectionName)]9    public class FileChooserCancelTests : PuppeteerPageBaseTest10    {11        public FileChooserCancelTests(ITestOutputHelper output) : base(output)12        {13        }14        [Fact]15        public async Task ShouldCancelDialog()16        {17            // Consider file chooser canceled if we can summon another one.18            // There's no reliable way in WebPlatform to see that FileChooser was19            // canceled.20            await Page.SetContentAsync("<input type=file>");21            var waitForTask = Page.WaitForFileChooserAsync();22            await Task.WhenAll(23                waitForTask,24                Page.ClickAsync("input"));25            var fileChooser = waitForTask.Result;26            await fileChooser.CancelAsync();27            await Task.WhenAll(28                Page.WaitForFileChooserAsync(),29                Page.ClickAsync("input"));30        }31        [Fact]32        public async Task ShouldFailWhenCancelingFileChooserTwice()33        {34            await Page.SetContentAsync("<input type=file>");35            var waitForTask = Page.WaitForFileChooserAsync();36            await Task.WhenAll(37                waitForTask,38                Page.ClickAsync("input"));39            var fileChooser = waitForTask.Result;40            await fileChooser.CancelAsync();41            var ex = await Assert.ThrowsAsync<PuppeteerException>(() => fileChooser.CancelAsync());42            Assert.Equal("Cannot accept FileChooser which is already handled!", ex.Message);43        }44    }45}...

Full Screen

Full Screen

FileChooser

Using AI Code Generation

copy

Full Screen

1using System;2using System.Threading.Tasks;3using PuppeteerSharp;4{5    {6        static void Main(string[] args)7        {8            MainAsync().GetAwaiter().GetResult();9        }10        static async Task MainAsync()11        {12            await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);13            using (var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true }))14            using (var page = await browser.NewPageAsync())15            {16                var fileChooser = await page.WaitForFileChooserAsync();17                await fileChooser.SetFilesAsync(@"C:\Users\user\Desktop\1.txt");18            }19        }20    }21}22const puppeteer = require('puppeteer');23(async () => {24  const browser = await puppeteer.launch();25  const page = await browser.newPage();26  const [fileChooser] = await Promise.all([27    page.waitForFileChooser(),28  ]);29  await fileChooser.accept(['C:\\Users\\user\\Desktop\\1.txt']);30  await browser.close();31})();

Full Screen

Full Screen

FileChooser

Using AI Code Generation

copy

Full Screen

1using PuppeteerSharp;2using System;3using System.IO;4using System.Threading.Tasks;5{6    {7        static async Task Main(string[] args)8        {9            {10                Args = new string[] { "--no-sandbox", "--disable-setuid-sandbox" }11            };12            var browser = await Puppeteer.LaunchAsync(options);13            var page = await browser.NewPageAsync();14            await page.ScreenshotAsync("google.png");15            await page.ClickAsync("a[href='/search?q=google+drive']");16            await page.ScreenshotAsync("googleDrive.png");17            await page.ClickAsync("a[href='/search?q=google+docs']");18            await page.ScreenshotAsync("googleDocs.png");19            await browser.CloseAsync();20            Console.WriteLine("done");21        }22    }23}24using PuppeteerSharp;25using System;26using System.IO;27using System.Threading.Tasks;28{29    {30        static async Task Main(string[] args)31        {32            {33                Args = new string[] { "--no-sandbox", "--disable-setuid-sandbox" }34            };35            var browser = await Puppeteer.LaunchAsync(options);36            var page = await browser.NewPageAsync();37            await page.ScreenshotAsync("google.png");38            await page.ClickAsync("a[href='/search?q=google+drive']");39            await page.ScreenshotAsync("googleDrive.png");40            await page.ClickAsync("a[href='/search?q=google+docs']");41            await page.ScreenshotAsync("googleDocs.png");42            await browser.CloseAsync();43            Console.WriteLine("done");44        }45    }46}47using PuppeteerSharp;48using System;49using System.IO;50using System.Threading.Tasks;51{52    {53        static async Task Main(string[] args)54        {55            {56                Args = new string[] { "--no-sandbox

Full Screen

Full Screen

FileChooser

Using AI Code Generation

copy

Full Screen

1using System.Threading.Tasks;2using PuppeteerSharp;3{4    {5        static async Task Main(string[] args)6        {7            {8            };9            using (var browser = await Puppeteer.LaunchAsync(options))10            {11                using (var page = await browser.NewPageAsync())12                {13                    var fileChooser = await page.WaitForFileChooserAsync();14                    await fileChooser.SetFilesAsync("C:/Users/username/Desktop/file.txt");15                }16            }17        }18    }19}

Full Screen

Full Screen

FileChooser

Using AI Code Generation

copy

Full Screen

1var fileChooser = await page.WaitForFileChooserAsync();2await fileChooser.SetFilesAsync("C:\\Users\\username\\Desktop\\1.txt");3await page.ClickAsync("#buttonId");4var fileChooser = await page.WaitForFileChooserAsync();5await fileChooser.SetFilesAsync("C:\\Users\\username\\Desktop\\1.txt");6await page.ClickAsync("#buttonId");7var fileChooser = await page.WaitForFileChooserAsync();8await fileChooser.SetFilesAsync("C:\\Users\\username\\Desktop\\1.txt");9await page.ClickAsync("#buttonId");10var fileChooser = await page.WaitForFileChooserAsync();

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 FileChooser

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful