How to use PageWaitForPopupOptions class of Microsoft.Playwright package

Best Playwright-dotnet code snippet using Microsoft.Playwright.PageWaitForPopupOptions

Run Playwright-dotnet automation tests on LambdaTest cloud grid

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

PageWaitForPopupOptions.cs

Source: PageWaitForPopupOptions.cs Github

copy
1/*
2 * MIT License
3 *
4 * Copyright (c) Microsoft Corporation.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25using System;
26using System.Collections.Generic;
27using System.ComponentModel.DataAnnotations;
28using System.Drawing;
29using System.Globalization;
30using System.IO;
31using System.Runtime.Serialization;
32using System.Text.Json;
33using System.Text.Json.Serialization;
34using System.Text.RegularExpressions;
35using System.Threading;
36using System.Threading.Tasks;
37
38#nullable enable
39
40namespace Microsoft.Playwright
41{
42    public class PageWaitForPopupOptions
43    {
44        public PageWaitForPopupOptions() { }
45
46        public PageWaitForPopupOptions(PageWaitForPopupOptions clone)
47        {
48            if (clone == null)
49            {
50                return;
51            }
52
53            Predicate = clone.Predicate;
54            Timeout = clone.Timeout;
55        }
56
57        /// <summary>
58        /// <para>
59        /// Receives the <see cref="IPage"/> object and resolves to truthy value when the waiting
60        /// should resolve.
61        /// </para>
62        /// </summary>
63        [JsonPropertyName("predicate")]
64        public Func<IPage, bool>? Predicate { get; set; }
65
66        /// <summary>
67        /// <para>
68        /// Maximum time to wait for in milliseconds. Defaults to <c>30000</c> (30 seconds).
69        /// Pass <c>0</c> to disable timeout. The default value can be changed by using the
70        /// <see cref="IBrowserContext.SetDefaultTimeout"/>.
71        /// </para>
72        /// </summary>
73        [JsonPropertyName("timeout")]
74        public float? Timeout { get; set; }
75    }
76}
77
78#nullable disable
79
Full Screen

Page.cs

Source: Page.cs Github

copy
1/*
2 * MIT License
3 *
4 * Copyright (c) 2020 Darío Kondratiuk
5 * Copyright (c) 2020 Meir Blachman
6 * Modifications copyright (c) Microsoft Corporation.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in all
16 * copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * SOFTWARE.
25 */
26using System;
27using System.Collections.Generic;
28using System.Data.SqlTypes;
29using System.IO;
30using System.Linq;
31using System.Text.Json;
32using System.Text.RegularExpressions;
33using System.Threading.Tasks;
34using Microsoft.Playwright.Helpers;
35using Microsoft.Playwright.Transport;
36using Microsoft.Playwright.Transport.Channels;
37using Microsoft.Playwright.Transport.Protocol;
38
39namespace Microsoft.Playwright.Core
40{
41    internal partial class Page : ChannelOwnerBase, IChannelOwner<Page>, IPage
42    {
43        private readonly PageChannel _channel;
44        private readonly List<Frame> _frames = new();
45        private readonly List<(IEvent PageEvent, TaskCompletionSource<bool> WaitTcs)> _waitForCancellationTcs = new();
46        private readonly object _fileChooserEventLock = new();
47        private readonly IAccessibility _accessibility;
48        private readonly IMouse _mouse;
49        private readonly IKeyboard _keyboard;
50        private readonly ITouchscreen _touchscreen;
51        private readonly PageInitializer _initializer;
52
53        private List<RouteSetting> _routes = new();
54        private EventHandler<IFileChooser> _fileChooserEventHandler;
55        private bool _fileChooserIntercepted;
56        private Video _video;
57        private float _defaultNavigationTimeout;
58        private float _defaultTimeout;
59
60        internal Page(IChannelOwner parent, string guid, PageInitializer initializer) : base(parent, guid)
61        {
62            Context = (BrowserContext)parent;
63
64            _channel = new(guid, parent.Connection, this);
65
66            MainFrame = initializer.MainFrame;
67            MainFrame.Page = this;
68            _frames.Add(MainFrame);
69            if (initializer.ViewportSize != null)
70            {
71                ViewportSize = new() { Width = initializer.ViewportSize.Width, Height = initializer.ViewportSize.Height };
72            }
73
74            IsClosed = initializer.IsClosed;
75            _accessibility = new Accessibility(_channel);
76            _keyboard = new Keyboard(_channel);
77            _touchscreen = new Touchscreen(_channel);
78            _mouse = new Mouse(_channel);
79            _channel.Closed += (_, _) => OnClose();
80            _channel.Crashed += Channel_Crashed;
81            _channel.Popup += (_, e) => Popup?.Invoke(this, e.Page);
82            _channel.WebSocket += (_, e) => WebSocket?.Invoke(this, e);
83            _channel.BindingCall += Channel_BindingCall;
84            _channel.Route += (_, e) => OnRoute(e.Route, e.Request);
85            _channel.FrameAttached += Channel_FrameAttached;
86            _channel.FrameDetached += Channel_FrameDetached;
87            _channel.Dialog += (_, e) =>
88            {
89                if (Dialog == null)
90                {
91                    if ("beforeunload".Equals(e.Type, StringComparison.Ordinal))
92                    {
93                        e.AcceptAsync(null).IgnoreException();
94                    }
95                    else
96                    {
97                        e.DismissAsync().IgnoreException();
98                    }
99                }
100                else
101                {
102                    Dialog?.Invoke(this, e);
103                }
104            };
105            _channel.Console += (_, e) => Console?.Invoke(this, e);
106            _channel.DOMContentLoaded += (_, _) => DOMContentLoaded?.Invoke(this, this);
107            _channel.Download += (_, e) => Download?.Invoke(this, new Download(this, e.Url, e.SuggestedFilename, e.Artifact.Object));
108            _channel.PageError += (_, e) => PageError?.Invoke(this, e.ToString());
109            _channel.Load += (_, _) => Load?.Invoke(this, this);
110            _channel.Video += (_, e) => ForceVideo().ArtifactReady(e.Artifact);
111
112            _channel.FileChooser += (_, e) => _fileChooserEventHandler?.Invoke(this, new FileChooser(this, e.Element.Object, e.IsMultiple));
113            _channel.Worker += (_, e) =>
114            {
115                WorkersList.Add(e.WorkerChannel.Object);
116                e.WorkerChannel.Object.Page = this;
117                Worker?.Invoke(this, e.WorkerChannel.Object);
118            };
119
120            _defaultNavigationTimeout = Context.DefaultNavigationTimeout;
121            _defaultTimeout = Context.DefaultTimeout;
122            _initializer = initializer;
123
124            Close += (_, _) => ClosedOrCrashedTcs.TrySetResult(true);
125            Crash += (_, _) => ClosedOrCrashedTcs.TrySetResult(true);
126        }
127
128        public event EventHandler<IConsoleMessage> Console;
129
130        public event EventHandler<IPage> Popup;
131
132        public event EventHandler<IRequest> Request;
133
134        public event EventHandler<IWebSocket> WebSocket;
135
136        public event EventHandler<IResponse> Response;
137
138        public event EventHandler<IRequest> RequestFinished;
139
140        public event EventHandler<IRequest> RequestFailed;
141
142        public event EventHandler<IDialog> Dialog;
143
144        public event EventHandler<IFrame> FrameAttached;
145
146        public event EventHandler<IFrame> FrameDetached;
147
148        public event EventHandler<IFrame> FrameNavigated;
149
150        public event EventHandler<IFileChooser> FileChooser
151        {
152            add
153            {
154                lock (_fileChooserEventLock)
155                {
156                    _fileChooserEventHandler += value;
157                    _fileChooserIntercepted = true;
158                    _channel.SetFileChooserInterceptedNoReplyAsync(true).IgnoreException();
159                }
160            }
161
162            remove
163            {
164                lock (_fileChooserEventLock)
165                {
166                    _fileChooserEventHandler -= value;
167
168                    if (_fileChooserIntercepted)
169                    {
170                        _fileChooserIntercepted = false;
171                        _channel.SetFileChooserInterceptedNoReplyAsync(false).IgnoreException();
172                    }
173                }
174            }
175        }
176
177        public event EventHandler<IPage> Load;
178
179        public event EventHandler<IPage> DOMContentLoaded;
180
181        public event EventHandler<IPage> Close;
182
183        public event EventHandler<IPage> Crash;
184
185        public event EventHandler<string> PageError;
186
187        public event EventHandler<IWorker> Worker;
188
189        public event EventHandler<IDownload> Download;
190
191        ChannelBase IChannelOwner.Channel => _channel;
192
193        IChannel<Page> IChannelOwner<Page>.Channel => _channel;
194
195        public bool IsClosed { get; private set; }
196
197        IFrame IPage.MainFrame => MainFrame;
198
199        public Frame MainFrame { get; }
200
201        IBrowserContext IPage.Context => Context;
202
203        public BrowserContext Context { get; set; }
204
205        public PageViewportSizeResult ViewportSize { get; private set; }
206
207        public IAccessibility Accessibility
208        {
209            get => _accessibility;
210            set => throw new NotSupportedException();
211        }
212
213        public IMouse Mouse
214        {
215            get => _mouse;
216            set => throw new NotSupportedException();
217        }
218
219        public string Url => MainFrame.Url;
220
221        public IReadOnlyList<IFrame> Frames => _frames.AsReadOnly();
222
223        public IKeyboard Keyboard
224        {
225            get => _keyboard;
226        }
227
228        public ITouchscreen Touchscreen
229        {
230            get => _touchscreen;
231        }
232
233        public IReadOnlyList<IWorker> Workers => WorkersList;
234
235        public IVideo Video
236        {
237            get
238            {
239                if (Context.Options.RecordVideoDir == null)
240                {
241                    return null;
242                }
243
244                return ForceVideo();
245            }
246            set => _video = value as Video;
247        }
248
249        internal BrowserContext OwnedContext { get; set; }
250
251        internal Dictionary<string, Delegate> Bindings { get; } = new();
252
253        internal List<Worker> WorkersList { get; } = new();
254
255        internal Page Opener => _initializer.Opener;
256
257        internal PageChannel Channel => _channel;
258
259        internal float DefaultTimeout
260        {
261            get => _defaultTimeout;
262            set
263            {
264                _defaultTimeout = value;
265                _channel.SetDefaultTimeoutNoReplyAsync(value).IgnoreException();
266            }
267        }
268
269        internal float DefaultNavigationTimeout
270        {
271            get => _defaultNavigationTimeout;
272            set
273            {
274                _defaultNavigationTimeout = value;
275                _channel.SetDefaultNavigationTimeoutNoReplyAsync(value).IgnoreException();
276            }
277        }
278
279        internal TaskCompletionSource<bool> ClosedOrCrashedTcs { get; } = new();
280
281        public IFrame Frame(string name)
282            => Frames.FirstOrDefault(f => f.Name == name);
283
284        public IFrame FrameByUrl(string urlString) => Frames.FirstOrDefault(f => Context.UrlMatches(urlString, f.Url));
285
286        public IFrame FrameByUrl(Regex urlRegex) => Frames.FirstOrDefault(f => urlRegex.IsMatch(f.Url));
287
288        public IFrame FrameByUrl(Func<string, bool> urlFunc) => Frames.FirstOrDefault(f => urlFunc(f.Url));
289
290        IFrameLocator IPage.FrameLocator(string selector) => MainFrame.FrameLocator(selector);
291
292        public Task<string> TitleAsync() => MainFrame.TitleAsync();
293
294        public Task BringToFrontAsync() => _channel.BringToFrontAsync();
295
296        public Task<IPage> OpenerAsync() => Task.FromResult<IPage>(Opener?.IsClosed == false ? Opener : null);
297
298        public Task EmulateMediaAsync(PageEmulateMediaOptions options = default)
299        {
300            var args = new Dictionary<string, object>
301            {
302                ["media"] = options?.Media,
303                ["colorScheme"] = options?.ColorScheme,
304                ["reducedMotion"] = options?.ReducedMotion,
305                ["forcedColors"] = options?.ForcedColors,
306            };
307            return _channel.EmulateMediaAsync(args);
308        }
309
310        public Task<IResponse> GotoAsync(string url, PageGotoOptions options = default)
311            => MainFrame.GotoAsync(url, new() { WaitUntil = options?.WaitUntil, Timeout = options?.Timeout, Referer = options?.Referer });
312
313        public Task WaitForURLAsync(string url, PageWaitForURLOptions options = default)
314            => MainFrame.WaitForURLAsync(url, new() { WaitUntil = options?.WaitUntil, Timeout = options?.Timeout });
315
316        public Task WaitForURLAsync(Regex url, PageWaitForURLOptions options = default)
317            => MainFrame.WaitForURLAsync(url, new() { WaitUntil = options?.WaitUntil, Timeout = options?.Timeout });
318
319        public Task WaitForURLAsync(Func<string, bool> url, PageWaitForURLOptions options = default)
320            => MainFrame.WaitForURLAsync(url, new() { WaitUntil = options?.WaitUntil, Timeout = options?.Timeout });
321
322        public Task<IConsoleMessage> WaitForConsoleMessageAsync(PageWaitForConsoleMessageOptions options = default)
323            => InnerWaitForEventAsync(PageEvent.Console, null, options?.Predicate, options?.Timeout);
324
325        public Task<IFileChooser> WaitForFileChooserAsync(PageWaitForFileChooserOptions options = default)
326            => InnerWaitForEventAsync(PageEvent.FileChooser, null, options?.Predicate, options?.Timeout);
327
328        public Task<IPage> WaitForPopupAsync(PageWaitForPopupOptions options = default)
329            => InnerWaitForEventAsync(PageEvent.Popup, null, options?.Predicate, options?.Timeout);
330
331        public Task<IWebSocket> WaitForWebSocketAsync(PageWaitForWebSocketOptions options = default)
332            => InnerWaitForEventAsync(PageEvent.WebSocket, null, options?.Predicate, options?.Timeout);
333
334        public Task<IWorker> WaitForWorkerAsync(PageWaitForWorkerOptions options = default)
335            => InnerWaitForEventAsync(PageEvent.Worker, null, options?.Predicate, options?.Timeout);
336
337        public Task<IResponse> WaitForNavigationAsync(PageWaitForNavigationOptions options = default)
338            => MainFrame.WaitForNavigationAsync(new()
339            {
340                UrlString = options?.UrlString,
341                UrlRegex = options?.UrlRegex,
342                UrlFunc = options?.UrlFunc,
343                WaitUntil = options?.WaitUntil,
344                Timeout = options?.Timeout,
345            });
346
347        public Task<IResponse> RunAndWaitForNavigationAsync(Func<Task> action, PageRunAndWaitForNavigationOptions options = default)
348            => MainFrame.RunAndWaitForNavigationAsync(action, new()
349            {
350                UrlString = options?.UrlString,
351                UrlRegex = options?.UrlRegex,
352                UrlFunc = options?.UrlFunc,
353                WaitUntil = options?.WaitUntil,
354                Timeout = options?.Timeout,
355            });
356
357        public Task<IRequest> WaitForRequestAsync(string urlOrPredicate, PageWaitForRequestOptions options = default)
358            => InnerWaitForEventAsync(PageEvent.Request, null, e => Context.UrlMatches(e.Url, urlOrPredicate), options?.Timeout);
359
360        public Task<IRequest> WaitForRequestAsync(Regex urlOrPredicate, PageWaitForRequestOptions options = default)
361            => InnerWaitForEventAsync(PageEvent.Request, null, e => urlOrPredicate.IsMatch(e.Url), options?.Timeout);
362
363        public Task<IRequest> WaitForRequestAsync(Func<IRequest, bool> urlOrPredicate, PageWaitForRequestOptions options = default)
364            => InnerWaitForEventAsync(PageEvent.Request, null, e => urlOrPredicate(e), options?.Timeout);
365
366        public Task<IRequest> WaitForRequestFinishedAsync(PageWaitForRequestFinishedOptions options = default)
367            => InnerWaitForEventAsync(PageEvent.RequestFinished, null, options?.Predicate, options?.Timeout);
368
369        public Task<IResponse> WaitForResponseAsync(string urlOrPredicate, PageWaitForResponseOptions options = default)
370            => InnerWaitForEventAsync(PageEvent.Response, null, e => Context.UrlMatches(e.Url, urlOrPredicate), options?.Timeout);
371
372        public Task<IResponse> WaitForResponseAsync(Regex urlOrPredicate, PageWaitForResponseOptions options = default)
373            => InnerWaitForEventAsync(PageEvent.Response, null, e => urlOrPredicate.IsMatch(e.Url), options?.Timeout);
374
375        public Task<IResponse> WaitForResponseAsync(Func<IResponse, bool> urlOrPredicate, PageWaitForResponseOptions options = default)
376            => InnerWaitForEventAsync(PageEvent.Response, null, e => urlOrPredicate(e), options?.Timeout);
377
378        public Task<IConsoleMessage> RunAndWaitForConsoleMessageAsync(Func<Task> action, PageRunAndWaitForConsoleMessageOptions options = default)
379            => InnerWaitForEventAsync(PageEvent.Console, action, options?.Predicate, options?.Timeout);
380
381        public Task<IDownload> WaitForDownloadAsync(PageWaitForDownloadOptions options = default)
382            => InnerWaitForEventAsync(PageEvent.Download, null, options?.Predicate, options?.Timeout);
383
384        public Task<IDownload> RunAndWaitForDownloadAsync(Func<Task> action, PageRunAndWaitForDownloadOptions options = default)
385            => InnerWaitForEventAsync(PageEvent.Download, action, options?.Predicate, options?.Timeout);
386
387        public Task<IFileChooser> RunAndWaitForFileChooserAsync(Func<Task> action, PageRunAndWaitForFileChooserOptions options = default)
388            => InnerWaitForEventAsync(PageEvent.FileChooser, action, options?.Predicate, options?.Timeout);
389
390        public Task<IPage> RunAndWaitForPopupAsync(Func<Task> action, PageRunAndWaitForPopupOptions options = default)
391            => InnerWaitForEventAsync(PageEvent.Popup, action, options?.Predicate, options?.Timeout);
392
393        public Task<IRequest> RunAndWaitForRequestFinishedAsync(Func<Task> action, PageRunAndWaitForRequestFinishedOptions options = default)
394            => InnerWaitForEventAsync(PageEvent.RequestFinished, action, options?.Predicate, options?.Timeout);
395
396        public Task<IWebSocket> RunAndWaitForWebSocketAsync(Func<Task> action, PageRunAndWaitForWebSocketOptions options = default)
397            => InnerWaitForEventAsync(PageEvent.WebSocket, action, options?.Predicate, options?.Timeout);
398
399        public Task<IWorker> RunAndWaitForWorkerAsync(Func<Task> action, PageRunAndWaitForWorkerOptions options = default)
400            => InnerWaitForEventAsync(PageEvent.Worker, action, options?.Predicate, options?.Timeout);
401
402        public Task<IRequest> RunAndWaitForRequestAsync(Func<Task> action, string urlOrPredicate, PageRunAndWaitForRequestOptions options = default)
403            => InnerWaitForEventAsync(PageEvent.Request, action, e => Context.UrlMatches(e.Url, urlOrPredicate), options?.Timeout);
404
405        public Task<IRequest> RunAndWaitForRequestAsync(Func<Task> action, Regex urlOrPredicate, PageRunAndWaitForRequestOptions options = default)
406            => InnerWaitForEventAsync(PageEvent.Request, action, e => urlOrPredicate.IsMatch(e.Url), options?.Timeout);
407
408        public Task<IRequest> RunAndWaitForRequestAsync(Func<Task> action, Func<IRequest, bool> urlOrPredicate, PageRunAndWaitForRequestOptions options = default)
409            => InnerWaitForEventAsync(PageEvent.Request, action, e => urlOrPredicate(e), options?.Timeout);
410
411        public Task<IResponse> RunAndWaitForResponseAsync(Func<Task> action, string urlOrPredicate, PageRunAndWaitForResponseOptions options = default)
412            => InnerWaitForEventAsync(PageEvent.Response, action, e => Context.UrlMatches(e.Url, urlOrPredicate), options?.Timeout);
413
414        public Task<IResponse> RunAndWaitForResponseAsync(Func<Task> action, Regex urlOrPredicate, PageRunAndWaitForResponseOptions options = default)
415            => InnerWaitForEventAsync(PageEvent.Response, action, e => urlOrPredicate.IsMatch(e.Url), options?.Timeout);
416
417        public Task<IResponse> RunAndWaitForResponseAsync(Func<Task> action, Func<IResponse, bool> urlOrPredicate, PageRunAndWaitForResponseOptions options = default)
418            => InnerWaitForEventAsync(PageEvent.Response, action, e => urlOrPredicate(e), options?.Timeout);
419
420        public Task<IJSHandle> WaitForFunctionAsync(string expression, object arg = default, PageWaitForFunctionOptions options = default)
421            => MainFrame.WaitForFunctionAsync(expression, arg, new() { PollingInterval = options?.PollingInterval, Timeout = options?.Timeout });
422
423        public async Task<T> InnerWaitForEventAsync<T>(PlaywrightEvent<T> pageEvent, Func<Task> action = default, Func<T, bool> predicate = default, float? timeout = default)
424        {
425            if (pageEvent == null)
426            {
427                throw new ArgumentException("Page event is required", nameof(pageEvent));
428            }
429
430            timeout ??= _defaultTimeout;
431            using var waiter = new Waiter(this, $"page.WaitForEventAsync(\"{typeof(T)}\")");
432            waiter.RejectOnTimeout(Convert.ToInt32(timeout), $"Timeout {timeout}ms exceeded while waiting for event \"{pageEvent.Name}\"");
433
434            if (pageEvent.Name != PageEvent.Crash.Name)
435            {
436                waiter.RejectOnEvent<IPage>(this, PageEvent.Crash.Name, new("Page crashed"));
437            }
438
439            if (pageEvent.Name != PageEvent.Close.Name)
440            {
441                waiter.RejectOnEvent<IPage>(this, PageEvent.Close.Name, new("Page closed"));
442            }
443
444            var result = waiter.WaitForEventAsync(this, pageEvent.Name, predicate);
445            if (action != null)
446            {
447                await WrapApiBoundaryAsync(() => Task.WhenAll(result, action())).ConfigureAwait(false);
448            }
449
450            return await result.ConfigureAwait(false);
451        }
452
453        public async Task CloseAsync(PageCloseOptions options = default)
454        {
455            try
456            {
457                await _channel.CloseAsync(options?.RunBeforeUnload ?? false).ConfigureAwait(false);
458                if (OwnedContext != null)
459                {
460                    await OwnedContext.CloseAsync().ConfigureAwait(false);
461                }
462            }
463            catch (Exception e) when (DriverMessages.IsSafeCloseError(e))
464            {
465                // Swallow exception
466            }
467        }
468
469        public Task<T> EvaluateAsync<T>(string expression, object arg) => MainFrame.EvaluateAsync<T>(expression, arg);
470
471        public Task<JsonElement?> EvalOnSelectorAsync(string selector, string expression, object arg) => MainFrame.EvalOnSelectorAsync(selector, expression, arg);
472
473        public Task<T> EvalOnSelectorAsync<T>(string selector, string expression, object arg = null, PageEvalOnSelectorOptions options = null)
474            => MainFrame.EvalOnSelectorAsync<T>(selector, expression, arg, new() { Strict = options?.Strict });
475
476        public ILocator Locator(string selector, PageLocatorOptions options = default)
477            => MainFrame.Locator(selector, new() { HasTextString = options?.HasTextString, HasTextRegex = options?.HasTextRegex, Has = options?.Has });
478
479        public Task<IElementHandle> QuerySelectorAsync(string selector, PageQuerySelectorOptions options = null)
480            => MainFrame.QuerySelectorAsync(selector, new() { Strict = options?.Strict });
481
482        public Task<T> EvalOnSelectorAsync<T>(string selector, string expression, object arg) => MainFrame.EvalOnSelectorAsync<T>(selector, expression, arg);
483
484        public Task<JsonElement?> EvalOnSelectorAllAsync(string selector, string expression, object arg) => MainFrame.EvalOnSelectorAllAsync(selector, expression, arg);
485
486        public Task<T> EvalOnSelectorAllAsync<T>(string selector, string expression, object arg) => MainFrame.EvalOnSelectorAllAsync<T>(selector, expression, arg);
487
488        public Task FillAsync(string selector, string value, PageFillOptions options = default)
489            => MainFrame.FillAsync(selector, value, new() { NoWaitAfter = options?.NoWaitAfter, Timeout = options?.Timeout, Force = options?.Force, Strict = options?.Strict });
490
491        public Task SetInputFilesAsync(string selector, string files, PageSetInputFilesOptions options = default)
492            => MainFrame.SetInputFilesAsync(selector, files, Map(options));
493
494        public Task SetInputFilesAsync(string selector, IEnumerable<string> files, PageSetInputFilesOptions options = default)
495            => MainFrame.SetInputFilesAsync(selector, files, Map(options));
496
497        public Task SetInputFilesAsync(string selector, FilePayload files, PageSetInputFilesOptions options = default)
498            => MainFrame.SetInputFilesAsync(selector, files, Map(options));
499
500        public Task SetInputFilesAsync(string selector, IEnumerable<FilePayload> files, PageSetInputFilesOptions options = default)
501            => MainFrame.SetInputFilesAsync(selector, files, Map(options));
502
503        public Task TypeAsync(string selector, string text, PageTypeOptions options = default)
504            => MainFrame.TypeAsync(selector, text, new()
505            {
506                Delay = options?.Delay,
507                NoWaitAfter = options?.NoWaitAfter,
508                Timeout = options?.Timeout,
509                Strict = options?.Strict,
510            });
511
512        public Task FocusAsync(string selector, PageFocusOptions options = default)
513            => MainFrame.FocusAsync(selector, new()
514            {
515                Timeout = options?.Timeout,
516                Strict = options?.Strict,
517            });
518
519        public Task HoverAsync(string selector, PageHoverOptions options = default)
520            => MainFrame.HoverAsync(
521                selector,
522                new()
523                {
524                    Position = options?.Position,
525                    Modifiers = options?.Modifiers,
526                    Force = options?.Force,
527                    Timeout = options?.Timeout,
528                    Trial = options?.Trial,
529                    Strict = options?.Strict,
530                });
531
532        public Task PressAsync(string selector, string key, PagePressOptions options = default)
533            => MainFrame.PressAsync(selector, key, new()
534            {
535                Delay = options?.Delay,
536                NoWaitAfter = options?.NoWaitAfter,
537                Timeout = options?.Timeout,
538                Strict = options?.Strict,
539            });
540
541        public Task<IReadOnlyList<string>> SelectOptionAsync(string selector, string values, PageSelectOptionOptions options = default)
542            => SelectOptionAsync(selector, new[] { values }, options);
543
544        public Task<IReadOnlyList<string>> SelectOptionAsync(string selector, IEnumerable<string> values, PageSelectOptionOptions options = default)
545            => SelectOptionAsync(selector, values.Select(x => new SelectOptionValue() { Value = x }), options);
546
547        public Task<IReadOnlyList<string>> SelectOptionAsync(string selector, IElementHandle values, PageSelectOptionOptions options = default)
548            => SelectOptionAsync(selector, new[] { values }, options);
549
550        public Task<IReadOnlyList<string>> SelectOptionAsync(string selector, IEnumerable<IElementHandle> values, PageSelectOptionOptions options = default)
551            => MainFrame.SelectOptionAsync(selector, values, new()
552            {
553                NoWaitAfter = options?.NoWaitAfter,
554                Timeout = options?.Timeout,
555                Force = options?.Force,
556                Strict = options?.Strict,
557            });
558
559        public Task<IReadOnlyList<string>> SelectOptionAsync(string selector, SelectOptionValue values, PageSelectOptionOptions options = default)
560            => SelectOptionAsync(selector, new[] { values }, options);
561
562        public Task<IReadOnlyList<string>> SelectOptionAsync(string selector, IEnumerable<SelectOptionValue> values, PageSelectOptionOptions options = default)
563            => MainFrame.SelectOptionAsync(selector, values, new()
564            {
565                NoWaitAfter = options?.NoWaitAfter,
566                Timeout = options?.Timeout,
567                Force = options?.Force,
568                Strict = options?.Strict,
569            });
570
571        public Task WaitForTimeoutAsync(float timeout) => MainFrame.WaitForTimeoutAsync(timeout);
572
573        public Task<IElementHandle> WaitForSelectorAsync(string selector, PageWaitForSelectorOptions options = default)
574            => MainFrame.WaitForSelectorAsync(selector, new()
575            {
576                State = options?.State,
577                Timeout = options?.Timeout,
578                Strict = options?.Strict,
579            });
580
581        public Task<JsonElement?> EvaluateAsync(string expression, object arg) => MainFrame.EvaluateAsync(expression, arg);
582
583        public async Task<byte[]> ScreenshotAsync(PageScreenshotOptions options = default)
584        {
585            options ??= new PageScreenshotOptions();
586            if (options.Type == null && !string.IsNullOrEmpty(options.Path))
587            {
588                options.Type = ElementHandle.DetermineScreenshotType(options.Path);
589            }
590
591            byte[] result = await _channel.ScreenshotAsync(
592                path: options.Path,
593                fullPage: options.FullPage,
594                clip: options.Clip,
595                omitBackground: options.OmitBackground,
596                type: options.Type,
597                quality: options.Quality,
598                mask: options.Mask,
599                animations: options.Animations,
600                caret: options.Caret,
601                scale: options.Scale,
602                timeout: options.Timeout).ConfigureAwait(false);
603
604            if (!string.IsNullOrEmpty(options.Path))
605            {
606                Directory.CreateDirectory(new FileInfo(options.Path).Directory.FullName);
607                File.WriteAllBytes(options.Path, result);
608            }
609
610            return result;
611        }
612
613        public Task SetContentAsync(string html, PageSetContentOptions options = default)
614            => MainFrame.SetContentAsync(html, new() { WaitUntil = options?.WaitUntil, Timeout = options?.Timeout });
615
616        public Task<string> ContentAsync() => MainFrame.ContentAsync();
617
618        public Task SetExtraHTTPHeadersAsync(IEnumerable<KeyValuePair<string, string>> headers)
619            => _channel.SetExtraHTTPHeadersAsync(headers);
620
621        public Task<IElementHandle> QuerySelectorAsync(string selector) => MainFrame.QuerySelectorAsync(selector);
622
623        public Task<IReadOnlyList<IElementHandle>> QuerySelectorAllAsync(string selector)
624            => MainFrame.QuerySelectorAllAsync(selector);
625
626        public Task<IJSHandle> EvaluateHandleAsync(string expression, object arg) => MainFrame.EvaluateHandleAsync(expression, arg);
627
628        public Task<IElementHandle> AddScriptTagAsync(PageAddScriptTagOptions options = default)
629            => MainFrame.AddScriptTagAsync(new()
630            {
631                Url = options?.Url,
632                Path = options?.Path,
633                Content = options?.Content,
634                Type = options?.Type,
635            });
636
637        public Task<IElementHandle> AddStyleTagAsync(PageAddStyleTagOptions options = default)
638            => MainFrame.AddStyleTagAsync(new()
639            {
640                Url = options?.Url,
641                Path = options?.Path,
642                Content = options?.Content,
643            });
644
645        public Task ClickAsync(string selector, PageClickOptions options = default)
646            => MainFrame.ClickAsync(
647                selector,
648                new()
649                {
650                    Button = options?.Button,
651                    ClickCount = options?.ClickCount,
652                    Delay = options?.Delay,
653                    Position = options?.Position,
654                    Modifiers = options?.Modifiers,
655                    Force = options?.Force,
656                    NoWaitAfter = options?.NoWaitAfter,
657                    Timeout = options?.Timeout,
658                    Trial = options?.Trial,
659                    Strict = options?.Strict,
660                });
661
662        public Task DblClickAsync(string selector, PageDblClickOptions options = default)
663            => MainFrame.DblClickAsync(selector, new()
664            {
665                Delay = options?.Delay,
666                Button = options?.Button,
667                Position = options?.Position,
668                Modifiers = options?.Modifiers,
669                Timeout = options?.Timeout,
670                Force = options?.Force,
671                NoWaitAfter = options?.NoWaitAfter,
672                Trial = options?.Trial,
673                Strict = options?.Strict,
674            });
675
676        public async Task<IResponse> GoBackAsync(PageGoBackOptions options = default)
677            => (await _channel.GoBackAsync(options?.Timeout, options?.WaitUntil).ConfigureAwait(false))?.Object;
678
679        public async Task<IResponse> GoForwardAsync(PageGoForwardOptions options = default)
680            => (await _channel.GoForwardAsync(options?.Timeout, options?.WaitUntil).ConfigureAwait(false))?.Object;
681
682        public async Task<IResponse> ReloadAsync(PageReloadOptions options = default)
683            => (await _channel.ReloadAsync(options?.Timeout, options?.WaitUntil).ConfigureAwait(false))?.Object;
684
685        public Task ExposeBindingAsync(string name, Action callback, PageExposeBindingOptions options = default)
686            => InnerExposeBindingAsync(name, (Delegate)callback, options?.Handle ?? false);
687
688        public Task ExposeBindingAsync(string name, Action<BindingSource> callback)
689            => InnerExposeBindingAsync(name, (Delegate)callback);
690
691        public Task ExposeBindingAsync<T>(string name, Action<BindingSource, T> callback)
692            => InnerExposeBindingAsync(name, (Delegate)callback);
693
694        public Task ExposeBindingAsync<TResult>(string name, Func<BindingSource, TResult> callback)
695            => InnerExposeBindingAsync(name, (Delegate)callback);
696
697        public Task ExposeBindingAsync<TResult>(string name, Func<BindingSource, IJSHandle, TResult> callback)
698            => InnerExposeBindingAsync(name, (Delegate)callback, true);
699
700        public Task ExposeBindingAsync<T, TResult>(string name, Func<BindingSource, T, TResult> callback)
701            => InnerExposeBindingAsync(name, (Delegate)callback);
702
703        public Task ExposeBindingAsync<T1, T2, TResult>(string name, Func<BindingSource, T1, T2, TResult> callback)
704            => InnerExposeBindingAsync(name, (Delegate)callback);
705
706        public Task ExposeBindingAsync<T1, T2, T3, TResult>(string name, Func<BindingSource, T1, T2, T3, TResult> callback)
707            => InnerExposeBindingAsync(name, (Delegate)callback);
708
709        public Task ExposeBindingAsync<T1, T2, T3, T4, TResult>(string name, Func<BindingSource, T1, T2, T3, T4, TResult> callback)
710            => InnerExposeBindingAsync(name, (Delegate)callback);
711
712        public Task ExposeFunctionAsync(string name, Action callback)
713            => ExposeBindingAsync(name, (BindingSource _) => callback());
714
715        public Task ExposeFunctionAsync<T>(string name, Action<T> callback)
716            => ExposeBindingAsync(name, (BindingSource _, T t) => callback(t));
717
718        public Task ExposeFunctionAsync<TResult>(string name, Func<TResult> callback)
719            => ExposeBindingAsync(name, (BindingSource _) => callback());
720
721        public Task ExposeFunctionAsync<T, TResult>(string name, Func<T, TResult> callback)
722            => ExposeBindingAsync(name, (BindingSource _, T t) => callback(t));
723
724        public Task ExposeFunctionAsync<T1, T2, TResult>(string name, Func<T1, T2, TResult> callback)
725            => ExposeBindingAsync(name, (BindingSource _, T1 t1, T2 t2) => callback(t1, t2));
726
727        public Task ExposeFunctionAsync<T1, T2, T3, TResult>(string name, Func<T1, T2, T3, TResult> callback)
728            => ExposeBindingAsync(name, (BindingSource _, T1 t1, T2 t2, T3 t3) => callback(t1, t2, t3));
729
730        public Task ExposeFunctionAsync<T1, T2, T3, T4, TResult>(string name, Func<T1, T2, T3, T4, TResult> callback)
731            => ExposeBindingAsync(name, (BindingSource _, T1 t1, T2 t2, T3 t3, T4 t4) => callback(t1, t2, t3, t4));
732
733        public async Task<byte[]> PdfAsync(PagePdfOptions options = default)
734        {
735            if (!Context.IsChromium)
736            {
737                throw new NotSupportedException("This browser doesn't support this action.");
738            }
739
740            byte[] result = await _channel.PdfAsync(
741                scale: options?.Scale,
742                displayHeaderFooter: options?.DisplayHeaderFooter,
743                headerTemplate: options?.HeaderTemplate,
744                footerTemplate: options?.FooterTemplate,
745                printBackground: options?.PrintBackground,
746                landscape: options?.Landscape,
747                pageRanges: options?.PageRanges,
748                format: options?.Format,
749                width: options?.Width,
750                height: options?.Height,
751                margin: options?.Margin,
752                preferCSSPageSize: options?.PreferCSSPageSize).ConfigureAwait(false);
753
754            if (!string.IsNullOrEmpty(options?.Path))
755            {
756                Directory.CreateDirectory(new FileInfo(options.Path).Directory.FullName);
757                File.WriteAllBytes(options.Path, result);
758            }
759
760            return result;
761        }
762
763        public Task AddInitScriptAsync(string script, string scriptPath)
764            => _channel.AddInitScriptAsync(ScriptsHelper.EvaluationScript(script, scriptPath));
765
766        public Task RouteAsync(string url, Action<IRoute> handler, PageRouteOptions options = null)
767            => RouteAsync(new Regex(Context.CombineUrlWithBase(url).GlobToRegex()), null, handler, options);
768
769        public Task RouteAsync(Regex url, Action<IRoute> handler, PageRouteOptions options = null)
770             => RouteAsync(url, null, handler, options);
771
772        public Task RouteAsync(Func<string, bool> url, Action<IRoute> handler, PageRouteOptions options = null)
773            => RouteAsync(null, url, handler, options);
774
775        public Task UnrouteAsync(string urlString, Action<IRoute> handler)
776            => UnrouteAsync(new Regex(Context.CombineUrlWithBase(urlString).GlobToRegex()), null, handler);
777
778        public Task UnrouteAsync(Regex urlString, Action<IRoute> handler)
779            => UnrouteAsync(urlString, null, handler);
780
781        public Task UnrouteAsync(Func<string, bool> urlFunc, Action<IRoute> handler)
782            => UnrouteAsync(null, urlFunc, handler);
783
784        public Task WaitForLoadStateAsync(LoadState? state = default, PageWaitForLoadStateOptions options = default)
785            => MainFrame.WaitForLoadStateAsync(state, new() { Timeout = options?.Timeout });
786
787        public Task SetViewportSizeAsync(int width, int height)
788        {
789            ViewportSize = new() { Width = width, Height = height };
790            return _channel.SetViewportSizeAsync(ViewportSize);
791        }
792
793        public Task SetCheckedAsync(string selector, bool checkedState, PageSetCheckedOptions options = null)
794            => checkedState ?
795            MainFrame.CheckAsync(selector, new()
796            {
797                Position = options?.Position,
798                Force = options?.Force,
799                NoWaitAfter = options?.NoWaitAfter,
800                Strict = options?.Strict,
801                Timeout = options?.Timeout,
802                Trial = options?.Trial,
803            })
804            : MainFrame.UncheckAsync(selector, new()
805            {
806                Position = options?.Position,
807                Force = options?.Force,
808                NoWaitAfter = options?.NoWaitAfter,
809                Timeout = options?.Timeout,
810                Trial = options?.Trial,
811                Strict = options?.Strict,
812            });
813
814        public Task CheckAsync(string selector, PageCheckOptions options = default)
815            => MainFrame.CheckAsync(selector, new()
816            {
817                Position = options?.Position,
818                Force = options?.Force,
819                NoWaitAfter = options?.NoWaitAfter,
820                Strict = options?.Strict,
821                Timeout = options?.Timeout,
822                Trial = options?.Trial,
823            });
824
825        public Task UncheckAsync(string selector, PageUncheckOptions options = default)
826            => MainFrame.UncheckAsync(selector, new()
827            {
828                Position = options?.Position,
829                Force = options?.Force,
830                NoWaitAfter = options?.NoWaitAfter,
831                Timeout = options?.Timeout,
832                Trial = options?.Trial,
833                Strict = options?.Strict,
834            });
835
836        public Task DispatchEventAsync(string selector, string type, object eventInit = default, PageDispatchEventOptions options = default)
837             => MainFrame.DispatchEventAsync(selector, type, eventInit, new() { Timeout = options?.Timeout, Strict = options?.Strict });
838
839        public Task<string> GetAttributeAsync(string selector, string name, PageGetAttributeOptions options = default)
840             => MainFrame.GetAttributeAsync(selector, name, new()
841             {
842                 Timeout = options?.Timeout,
843                 Strict = options?.Strict,
844             });
845
846        public Task<string> InnerHTMLAsync(string selector, PageInnerHTMLOptions options = default)
847             => MainFrame.InnerHTMLAsync(selector, new()
848             {
849                 Timeout = options?.Timeout,
850                 Strict = options?.Strict,
851             });
852
853        public Task<string> InnerTextAsync(string selector, PageInnerTextOptions options = default)
854             => MainFrame.InnerTextAsync(selector, new()
855             {
856                 Timeout = options?.Timeout,
857                 Strict = options?.Strict,
858             });
859
860        public Task<string> TextContentAsync(string selector, PageTextContentOptions options = default)
861             => MainFrame.TextContentAsync(selector, new()
862             {
863                 Timeout = options?.Timeout,
864                 Strict = options?.Strict,
865             });
866
867        public Task TapAsync(string selector, PageTapOptions options = default)
868            => MainFrame.TapAsync(
869                selector,
870                new()
871                {
872                    Modifiers = options?.Modifiers,
873                    Position = options?.Position,
874                    Force = options?.Force,
875                    NoWaitAfter = options?.NoWaitAfter,
876                    Timeout = options?.Timeout,
877                    Trial = options?.Trial,
878                    Strict = options?.Strict,
879                });
880
881        public Task<bool> IsCheckedAsync(string selector, PageIsCheckedOptions options = default)
882            => MainFrame.IsCheckedAsync(selector, new()
883            {
884                Timeout = options?.Timeout,
885                Strict = options?.Strict,
886            });
887
888        public Task<bool> IsDisabledAsync(string selector, PageIsDisabledOptions options = default)
889            => MainFrame.IsDisabledAsync(selector, new()
890            {
891                Timeout = options?.Timeout,
892                Strict = options?.Strict,
893            });
894
895        public Task<bool> IsEditableAsync(string selector, PageIsEditableOptions options = default)
896            => MainFrame.IsEditableAsync(selector, new()
897            {
898                Timeout = options?.Timeout,
899                Strict = options?.Strict,
900            });
901
902        public Task<bool> IsEnabledAsync(string selector, PageIsEnabledOptions options = default)
903            => MainFrame.IsEnabledAsync(selector, new()
904            {
905                Timeout = options?.Timeout,
906                Strict = options?.Strict,
907            });
908
909#pragma warning disable CS0612 // Type or member is obsolete
910        public Task<bool> IsHiddenAsync(string selector, PageIsHiddenOptions options = default)
911            => MainFrame.IsHiddenAsync(selector, new()
912            {
913                Timeout = options?.Timeout,
914                Strict = options?.Strict,
915            });
916
917        public Task<bool> IsVisibleAsync(string selector, PageIsVisibleOptions options = default)
918            => MainFrame.IsVisibleAsync(selector, new()
919            {
920                Timeout = options?.Timeout,
921                Strict = options?.Strict,
922            });
923#pragma warning restore CS0612 // Type or member is obsolete
924
925        public Task PauseAsync() => Context.Channel.PauseAsync();
926
927        public void SetDefaultNavigationTimeout(float timeout) => DefaultNavigationTimeout = timeout;
928
929        public void SetDefaultTimeout(float timeout) => DefaultTimeout = timeout;
930
931        public Task<string> InputValueAsync(string selector, PageInputValueOptions options = null)
932            => MainFrame.InputValueAsync(selector, new()
933            {
934                Timeout = options?.Timeout,
935                Strict = options?.Strict,
936            });
937
938        public Task DragAndDropAsync(string source, string target, PageDragAndDropOptions options = null)
939            => MainFrame.DragAndDropAsync(source, target, new()
940            {
941                Force = options?.Force,
942                NoWaitAfter = options?.NoWaitAfter,
943                Timeout = options?.Timeout,
944                Trial = options?.Trial,
945                Strict = options?.Strict,
946            });
947
948        internal void NotifyPopup(Page page) => Popup?.Invoke(this, page);
949
950        internal void OnFrameNavigated(Frame frame)
951            => FrameNavigated?.Invoke(this, frame);
952
953        internal void FireRequest(IRequest request) => Request?.Invoke(this, request);
954
955        internal void FireRequestFailed(IRequest request) => RequestFailed?.Invoke(this, request);
956
957        internal void FireRequestFinished(IRequest request) => RequestFinished?.Invoke(this, request);
958
959        internal void FireResponse(IResponse response) => Response?.Invoke(this, response);
960
961        private Task RouteAsync(Regex urlRegex, Func<string, bool> urlFunc, Action<IRoute> handler, PageRouteOptions options)
962            => RouteAsync(new()
963            {
964                Regex = urlRegex,
965                Function = urlFunc,
966                Handler = handler,
967                Times = options?.Times,
968            });
969
970        private Task RouteAsync(RouteSetting setting)
971        {
972            _routes.Insert(0, setting);
973
974            if (_routes.Count == 1)
975            {
976                return _channel.SetNetworkInterceptionEnabledAsync(true);
977            }
978
979            return Task.CompletedTask;
980        }
981
982        private Task UnrouteAsync(Regex urlRegex, Func<string, bool> urlFunc, Action<IRoute> handler = null)
983            => UnrouteAsync(new()
984            {
985                Function = urlFunc,
986                Regex = urlRegex,
987                Handler = handler,
988            });
989
990        private Task UnrouteAsync(RouteSetting setting)
991        {
992            var newRoutesList = new List<RouteSetting>();
993            newRoutesList.AddRange(_routes.Where(r =>
994                (setting.Regex != null && !(r.Regex == setting.Regex || (r.Regex.ToString() == setting.Regex.ToString() && r.Regex.Options == setting.Regex.Options))) ||
995                (setting.Function != null && r.Function != setting.Function) ||
996                (setting.Handler != null && r.Handler != setting.Handler)));
997            _routes = newRoutesList;
998
999            if (_routes.Count == 0)
1000            {
1001                return DisableInterceptionAsync();
1002            }
1003
1004            return Task.CompletedTask;
1005        }
1006
1007        internal void OnClose()
1008        {
1009            IsClosed = true;
1010            Context?.PagesList.Remove(this);
1011            RejectPendingOperations(false);
1012            Close?.Invoke(this, this);
1013        }
1014
1015        private void Channel_Crashed(object sender, EventArgs e)
1016        {
1017            RejectPendingOperations(true);
1018            Crash?.Invoke(this, this);
1019        }
1020
1021        private void Channel_BindingCall(object sender, BindingCallEventArgs e)
1022        {
1023            if (Bindings.TryGetValue(e.BindingCall.Name, out var binding))
1024            {
1025                _ = e.BindingCall.CallAsync(binding);
1026            }
1027        }
1028
1029        private void OnRoute(Route route, IRequest request)
1030        {
1031            foreach (var routeHandler in _routes.ToList())
1032            {
1033                if ((routeHandler.Regex?.IsMatch(request.Url) == true) ||
1034                    (routeHandler.Function?.Invoke(request.Url) == true))
1035                {
1036                    try
1037                    {
1038                        routeHandler.Handle(route);
1039                    }
1040                    finally
1041                    {
1042                        if (!routeHandler.IsActive())
1043                        {
1044                            _routes.Remove(routeHandler);
1045                            if (_routes.Count == 0)
1046                            {
1047                                DisableInterceptionAsync().ConfigureAwait(false);
1048                            }
1049                        }
1050                    }
1051                    return;
1052                }
1053            }
1054
1055            Context.OnRoute(route, request);
1056        }
1057
1058        internal async Task DisableInterceptionAsync()
1059        {
1060            await Channel.SetNetworkInterceptionEnabledAsync(false).ConfigureAwait(false);
1061        }
1062
1063        private void Channel_FrameDetached(object sender, IFrame args)
1064        {
1065            var frame = (Frame)args;
1066            _frames.Remove(frame);
1067            frame.IsDetached = true;
1068            frame.ParentFrame?.ChildFramesList?.Remove(frame);
1069            FrameDetached?.Invoke(this, args);
1070        }
1071
1072        private void Channel_FrameAttached(object sender, IFrame args)
1073        {
1074            var frame = (Frame)args;
1075            frame.Page = this;
1076            _frames.Add(frame);
1077            frame.ParentFrame?.ChildFramesList?.Add(frame);
1078            FrameAttached?.Invoke(this, args);
1079        }
1080
1081        private void RejectPendingOperations(bool isCrash)
1082        {
1083            foreach (var (_, waitTcs) in _waitForCancellationTcs.Where(e => e.PageEvent != (isCrash ? PageEvent.Crash : PageEvent.Close)))
1084            {
1085                waitTcs.TrySetException(new PlaywrightException(isCrash ? "Page crashed" : "Page closed"));
1086            }
1087
1088            _waitForCancellationTcs.Clear();
1089        }
1090
1091        private Task InnerExposeBindingAsync(string name, Delegate callback, bool handle = false)
1092        {
1093            if (Bindings.ContainsKey(name))
1094            {
1095                throw new PlaywrightException($"Function \"{name}\" has been already registered");
1096            }
1097
1098            Bindings.Add(name, callback);
1099
1100            return _channel.ExposeBindingAsync(name, handle);
1101        }
1102
1103        private Video ForceVideo() => _video ??= new(this, _channel.Connection);
1104
1105        private FrameSetInputFilesOptions Map(PageSetInputFilesOptions options)
1106        {
1107            if (options == null)
1108            {
1109                return null;
1110            }
1111
1112            return new()
1113            {
1114                NoWaitAfter = options.NoWaitAfter,
1115                Timeout = options.Timeout,
1116                Strict = options.Strict,
1117            };
1118        }
1119    }
1120}
1121
Full Screen

IPage.cs

Source: IPage.cs Github

copy
1/*
2 * MIT License
3 *
4 * Copyright (c) Microsoft Corporation.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25using System;
26using System.Collections.Generic;
27using System.ComponentModel.DataAnnotations;
28using System.Drawing;
29using System.Globalization;
30using System.IO;
31using System.Runtime.Serialization;
32using System.Text.Json;
33using System.Text.Json.Serialization;
34using System.Text.RegularExpressions;
35using System.Threading;
36using System.Threading.Tasks;
37
38#nullable enable
39
40namespace Microsoft.Playwright
41{
42    /// <summary>
43    /// <para>
44    /// Page provides methods to interact with a single tab in a <see cref="IBrowser"/>,
45    /// or an <a href="https://developer.chrome.com/extensions/background_pages">extension
46    /// background page</a> in Chromium. One <see cref="IBrowser"/> instance might have
47    /// multiple <see cref="IPage"/> instances.
48    /// </para>
49    /// <para>This example creates a page, navigates it to a URL, and then saves a screenshot:</para>
50    /// <code>
51    /// using Microsoft.Playwright;<br/>
52    /// using System.Threading.Tasks;<br/>
53    /// <br/>
54    /// class PageExamples<br/>
55    /// {<br/>
56    ///     public static async Task Run()<br/>
57    ///     {<br/>
58    ///         using var playwright = await Playwright.CreateAsync();<br/>
59    ///         await using var browser = await playwright.Webkit.LaunchAsync();<br/>
60    ///         var page = await browser.NewPageAsync();<br/>
61    ///         await page.GotoAsync("https://www.theverge.com");<br/>
62    ///         await page.ScreenshotAsync(new PageScreenshotOptions { Path = "theverge.png" });<br/>
63    ///     }<br/>
64    /// }
65    /// </code>
66    /// <para>
67    /// The Page class emits various events (described below) which can be handled using
68    /// any of Node's native <a href="https://nodejs.org/api/events.html#events_class_eventemitter"><c>EventEmitter</c></a>
69    /// methods, such as <c>on</c>, <c>once</c> or <c>removeListener</c>.
70    /// </para>
71    /// <para>This example logs a message for a single page <c>load</c> event:</para>
72    /// <code>page.Load += (_, _) =&gt; Console.WriteLine("Page loaded!");</code>
73    /// <para>To unsubscribe from events use the <c>removeListener</c> method:</para>
74    /// <code>
75    /// void PageLoadHandler(object _, IPage p) {<br/>
76    ///     Console.WriteLine("Page loaded!");<br/>
77    /// };<br/>
78    /// <br/>
79    /// page.Load += PageLoadHandler;<br/>
80    /// // Do some work...<br/>
81    /// page.Load -= PageLoadHandler;
82    /// </code>
83    /// </summary>
84    public partial interface IPage
85    {
86        /// <summary><para>Emitted when the page closes.</para></summary>
87        event EventHandler<IPage> Close;
88
89        /// <summary>
90        /// <para>
91        /// Emitted when JavaScript within the page calls one of console API methods, e.g. <c>console.log</c>
92        /// or <c>console.dir</c>. Also emitted if the page throws an error or a warning.
93        /// </para>
94        /// <para>The arguments passed into <c>console.log</c> appear as arguments on the event handler.</para>
95        /// <para>An example of handling <c>console</c> event:</para>
96        /// <code>
97        /// page.Console += async (_, msg) =&gt;<br/>
98        /// {<br/>
99        ///     foreach (var arg in msg.Args)<br/>
100        ///         Console.WriteLine(await arg.JsonValueAsync&lt;object&gt;());<br/>
101        /// };<br/>
102        /// <br/>
103        /// await page.EvaluateAsync("console.log('hello', 5, { foo: 'bar' })");
104        /// </code>
105        /// </summary>
106        event EventHandler<IConsoleMessage> Console;
107
108        /// <summary>
109        /// <para>
110        /// Emitted when the page crashes. Browser pages might crash if they try to allocate
111        /// too much memory. When the page crashes, ongoing and subsequent operations will throw.
112        /// </para>
113        /// <para>The most common way to deal with crashes is to catch an exception:</para>
114        /// <code>
115        /// try {<br/>
116        ///   // Crash might happen during a click.<br/>
117        ///   await page.ClickAsync("button");<br/>
118        ///   // Or while waiting for an event.<br/>
119        ///   await page.WaitForPopup();<br/>
120        /// } catch (PlaywrightException e) {<br/>
121        ///   // When the page crashes, exception message contains "crash".<br/>
122        /// }
123        /// </code>
124        /// </summary>
125        event EventHandler<IPage> Crash;
126
127        /// <summary>
128        /// <para>
129        /// Emitted when a JavaScript dialog appears, such as <c>alert</c>, <c>prompt</c>, <c>confirm</c>
130        /// or <c>beforeunload</c>. Listener **must** either <see cref="IDialog.AcceptAsync"/>
131        /// or <see cref="IDialog.DismissAsync"/> the dialog - otherwise the page will <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop#never_blocking">freeze</a>
132        /// waiting for the dialog, and actions like click will never finish.
133        /// </para>
134        /// <code>
135        /// page.RequestFailed += (_, request) =&gt;<br/>
136        /// {<br/>
137        ///     Console.WriteLine(request.Url + " " + request.Failure);<br/>
138        /// };
139        /// </code>
140        /// </summary>
141        /// <remarks>
142        /// <para>
143        /// When no <see cref="IPage.Dialog"/> listeners are present, all dialogs are automatically
144        /// dismissed.
145        /// </para>
146        /// </remarks>
147        event EventHandler<IDialog> Dialog;
148
149        /// <summary>
150        /// <para>
151        /// Emitted when the JavaScript <a href="https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded"><c>DOMContentLoaded</c></a>
152        /// event is dispatched.
153        /// </para>
154        /// </summary>
155        event EventHandler<IPage> DOMContentLoaded;
156
157        /// <summary>
158        /// <para>
159        /// Emitted when attachment download started. User can access basic file operations
160        /// on downloaded content via the passed <see cref="IDownload"/> instance.
161        /// </para>
162        /// </summary>
163        event EventHandler<IDownload> Download;
164
165        /// <summary>
166        /// <para>
167        /// Emitted when a file chooser is supposed to appear, such as after clicking the  <c>&lt;input
168        /// type=file&gt;</c>. Playwright can respond to it via setting the input files using
169        /// <see cref="IFileChooser.SetFilesAsync"/> that can be uploaded after that.
170        /// </para>
171        /// <code>
172        /// page.FileChooser += (_, fileChooser) =&gt;<br/>
173        /// {<br/>
174        ///     fileChooser.SetFilesAsync(@"C:\temp\myfile.pdf");<br/>
175        /// };
176        /// </code>
177        /// </summary>
178        event EventHandler<IFileChooser> FileChooser;
179
180        /// <summary><para>Emitted when a frame is attached.</para></summary>
181        event EventHandler<IFrame> FrameAttached;
182
183        /// <summary><para>Emitted when a frame is detached.</para></summary>
184        event EventHandler<IFrame> FrameDetached;
185
186        /// <summary><para>Emitted when a frame is navigated to a new url.</para></summary>
187        event EventHandler<IFrame> FrameNavigated;
188
189        /// <summary>
190        /// <para>
191        /// Emitted when the JavaScript <a href="https://developer.mozilla.org/en-US/docs/Web/Events/load"><c>load</c></a>
192        /// event is dispatched.
193        /// </para>
194        /// </summary>
195        event EventHandler<IPage> Load;
196
197        /// <summary>
198        /// <para>Emitted when an uncaught exception happens within the page.</para>
199        /// <code>
200        /// // Log all uncaught errors to the terminal<br/>
201        /// page.PageError += (_, exception) =&gt;<br/>
202        /// {<br/>
203        ///   Console.WriteLine("Uncaught exception: " + exception);<br/>
204        /// };
205        /// </code>
206        /// </summary>
207        event EventHandler<string> PageError;
208
209        /// <summary>
210        /// <para>
211        /// Emitted when the page opens a new tab or window. This event is emitted in addition
212        /// to the <see cref="IBrowserContext.Page"/>, but only for popups relevant to this
213        /// page.
214        /// </para>
215        /// <para>
216        /// The earliest moment that page is available is when it has navigated to the initial
217        /// url. For example, when opening a popup with <c>window.open('http://example.com')</c>,
218        /// this event will fire when the network request to "http://example.com" is done and
219        /// its response has started loading in the popup.
220        /// </para>
221        /// <code>
222        /// var popup = await page.RunAndWaitForPopupAsync(async () =&gt;<br/>
223        /// {<br/>
224        ///     await page.EvaluateAsync("() =&gt; window.open('https://microsoft.com')");<br/>
225        /// });<br/>
226        /// Console.WriteLine(await popup.EvaluateAsync&lt;string&gt;("location.href"));
227        /// </code>
228        /// </summary>
229        /// <remarks>
230        /// <para>
231        /// Use <see cref="IPage.WaitForLoadStateAsync"/> to wait until the page gets to a particular
232        /// state (you should not need it in most cases).
233        /// </para>
234        /// </remarks>
235        event EventHandler<IPage> Popup;
236
237        /// <summary>
238        /// <para>
239        /// Emitted when a page issues a request. The <see cref="request"/> object is read-only.
240        /// In order to intercept and mutate requests, see <see cref="IPage.RouteAsync"/> or
241        /// <see cref="IBrowserContext.RouteAsync"/>.
242        /// </para>
243        /// </summary>
244        event EventHandler<IRequest> Request;
245
246        /// <summary><para>Emitted when a request fails, for example by timing out.</para></summary>
247        /// <remarks>
248        /// <para>
249        /// HTTP Error responses, such as 404 or 503, are still successful responses from HTTP
250        /// standpoint, so request will complete with <see cref="IPage.RequestFinished"/> event
251        /// and not with <see cref="IPage.RequestFailed"/>. A request will only be considered
252        /// failed when the client cannot get an HTTP response from the server, e.g. due to
253        /// network error net::ERR_FAILED.
254        /// </para>
255        /// </remarks>
256        event EventHandler<IRequest> RequestFailed;
257
258        /// <summary>
259        /// <para>
260        /// Emitted when a request finishes successfully after downloading the response body.
261        /// For a successful response, the sequence of events is <c>request</c>, <c>response</c>
262        /// and <c>requestfinished</c>.
263        /// </para>
264        /// </summary>
265        event EventHandler<IRequest> RequestFinished;
266
267        /// <summary>
268        /// <para>
269        /// Emitted when <see cref="response"/> status and headers are received for a request.
270        /// For a successful response, the sequence of events is <c>request</c>, <c>response</c>
271        /// and <c>requestfinished</c>.
272        /// </para>
273        /// </summary>
274        event EventHandler<IResponse> Response;
275
276        /// <summary><para>Emitted when <see cref="IWebSocket"/> request is sent.</para></summary>
277        event EventHandler<IWebSocket> WebSocket;
278
279        /// <summary>
280        /// <para>
281        /// Emitted when a dedicated <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API">WebWorker</a>
282        /// is spawned by the page.
283        /// </para>
284        /// </summary>
285        event EventHandler<IWorker> Worker;
286
287        public IAccessibility Accessibility { get; }
288
289        /// <summary>
290        /// <para>Adds a script which would be evaluated in one of the following scenarios:</para>
291        /// <list type="bullet">
292        /// <item><description>Whenever the page is navigated.</description></item>
293        /// <item><description>
294        /// Whenever the child frame is attached or navigated. In this case, the script is evaluated
295        /// in the context of the newly attached frame.
296        /// </description></item>
297        /// </list>
298        /// <para>
299        /// The script is evaluated after the document was created but before any of its scripts
300        /// were run. This is useful to amend the JavaScript environment, e.g. to seed <c>Math.random</c>.
301        /// </para>
302        /// <para>An example of overriding <c>Math.random</c> before the page loads:</para>
303        /// <code>await page.AddInitScriptAsync(new PageAddInitScriptOption { ScriptPath = "./preload.js" });</code>
304        /// </summary>
305        /// <remarks>
306        /// <para>
307        /// The order of evaluation of multiple scripts installed via <see cref="IBrowserContext.AddInitScriptAsync"/>
308        /// and <see cref="IPage.AddInitScriptAsync"/> is not defined.
309        /// </para>
310        /// </remarks>
311        /// <param name="script">Script to be evaluated in all pages in the browser context.</param>
312        /// <param name="scriptPath">Instead of specifying <paramref name="script"/>, gives the file name to load from.</param>
313        Task AddInitScriptAsync(string? script = default, string? scriptPath = default);
314
315        /// <summary>
316        /// <para>
317        /// Adds a <c>&lt;script&gt;</c> tag into the page with the desired url or content.
318        /// Returns the added tag when the script's onload fires or when the script content
319        /// was injected into frame.
320        /// </para>
321        /// <para>Shortcut for main frame's <see cref="IFrame.AddScriptTagAsync"/>.</para>
322        /// </summary>
323        /// <param name="options">Call options</param>
324        Task<IElementHandle> AddScriptTagAsync(PageAddScriptTagOptions? options = default);
325
326        /// <summary>
327        /// <para>
328        /// Adds a <c>&lt;link rel="stylesheet"&gt;</c> tag into the page with the desired url
329        /// or a <c>&lt;style type="text/css"&gt;</c> tag with the content. Returns the added
330        /// tag when the stylesheet's onload fires or when the CSS content was injected into
331        /// frame.
332        /// </para>
333        /// <para>Shortcut for main frame's <see cref="IFrame.AddStyleTagAsync"/>.</para>
334        /// </summary>
335        /// <param name="options">Call options</param>
336        Task<IElementHandle> AddStyleTagAsync(PageAddStyleTagOptions? options = default);
337
338        /// <summary><para>Brings page to front (activates tab).</para></summary>
339        Task BringToFrontAsync();
340
341        /// <summary>
342        /// <para>
343        /// This method checks an element matching <paramref name="selector"/> by performing
344        /// the following steps:
345        /// </para>
346        /// <list type="ordinal">
347        /// <item><description>
348        /// Find an element matching <paramref name="selector"/>. If there is none, wait until
349        /// a matching element is attached to the DOM.
350        /// </description></item>
351        /// <item><description>
352        /// Ensure that matched element is a checkbox or a radio input. If not, this method
353        /// throws. If the element is already checked, this method returns immediately.
354        /// </description></item>
355        /// <item><description>
356        /// Wait for <a href="https://playwright.dev/dotnet/docs/actionability">actionability</a>
357        /// checks on the matched element, unless <paramref name="force"/> option is set. If
358        /// the element is detached during the checks, the whole action is retried.
359        /// </description></item>
360        /// <item><description>Scroll the element into view if needed.</description></item>
361        /// <item><description>Use <see cref="IPage.Mouse"/> to click in the center of the element.</description></item>
362        /// <item><description>
363        /// Wait for initiated navigations to either succeed or fail, unless <paramref name="noWaitAfter"/>
364        /// option is set.
365        /// </description></item>
366        /// <item><description>Ensure that the element is now checked. If not, this method throws.</description></item>
367        /// </list>
368        /// <para>
369        /// When all steps combined have not finished during the specified <paramref name="timeout"/>,
370        /// this method throws a <see cref="TimeoutException"/>. Passing zero timeout disables
371        /// this.
372        /// </para>
373        /// <para>Shortcut for main frame's <see cref="IFrame.CheckAsync"/>.</para>
374        /// </summary>
375        /// <param name="selector">
376        /// A selector to search for an element. If there are multiple elements satisfying the
377        /// selector, the first will be used. See <a href="https://playwright.dev/dotnet/docs/selectors">working
378        /// with selectors</a> for more details.
379        /// </param>
380        /// <param name="options">Call options</param>
381        Task CheckAsync(string selector, PageCheckOptions? options = default);
382
383        /// <summary>
384        /// <para>
385        /// This method clicks an element matching <paramref name="selector"/> by performing
386        /// the following steps:
387        /// </para>
388        /// <list type="ordinal">
389        /// <item><description>
390        /// Find an element matching <paramref name="selector"/>. If there is none, wait until
391        /// a matching element is attached to the DOM.
392        /// </description></item>
393        /// <item><description>
394        /// Wait for <a href="https://playwright.dev/dotnet/docs/actionability">actionability</a>
395        /// checks on the matched element, unless <paramref name="force"/> option is set. If
396        /// the element is detached during the checks, the whole action is retried.
397        /// </description></item>
398        /// <item><description>Scroll the element into view if needed.</description></item>
399        /// <item><description>
400        /// Use <see cref="IPage.Mouse"/> to click in the center of the element, or the specified
401        /// <paramref name="position"/>.
402        /// </description></item>
403        /// <item><description>
404        /// Wait for initiated navigations to either succeed or fail, unless <paramref name="noWaitAfter"/>
405        /// option is set.
406        /// </description></item>
407        /// </list>
408        /// <para>
409        /// When all steps combined have not finished during the specified <paramref name="timeout"/>,
410        /// this method throws a <see cref="TimeoutException"/>. Passing zero timeout disables
411        /// this.
412        /// </para>
413        /// <para>Shortcut for main frame's <see cref="IFrame.ClickAsync"/>.</para>
414        /// </summary>
415        /// <param name="selector">
416        /// A selector to search for an element. If there are multiple elements satisfying the
417        /// selector, the first will be used. See <a href="https://playwright.dev/dotnet/docs/selectors">working
418        /// with selectors</a> for more details.
419        /// </param>
420        /// <param name="options">Call options</param>
421        Task ClickAsync(string selector, PageClickOptions? options = default);
422
423        /// <summary>
424        /// <para>
425        /// If <paramref name="runBeforeUnload"/> is <c>false</c>, does not run any unload handlers
426        /// and waits for the page to be closed. If <paramref name="runBeforeUnload"/> is <c>true</c>
427        /// the method will run unload handlers, but will **not** wait for the page to close.
428        /// </para>
429        /// <para>By default, <c>page.close()</c> **does not** run <c>beforeunload</c> handlers.</para>
430        /// </summary>
431        /// <remarks>
432        /// <para>
433        /// if <paramref name="runBeforeUnload"/> is passed as true, a <c>beforeunload</c> dialog
434        /// might be summoned and should be handled manually via <see cref="IPage.Dialog"/>
435        /// event.
436        /// </para>
437        /// </remarks>
438        /// <param name="options">Call options</param>
439        Task CloseAsync(PageCloseOptions? options = default);
440
441        /// <summary><para>Gets the full HTML contents of the page, including the doctype.</para></summary>
442        Task<string> ContentAsync();
443
444        /// <summary><para>Get the browser context that the page belongs to.</para></summary>
445        IBrowserContext Context { get; }
446
447        /// <summary>
448        /// <para>
449        /// This method double clicks an element matching <paramref name="selector"/> by performing
450        /// the following steps:
451        /// </para>
452        /// <list type="ordinal">
453        /// <item><description>
454        /// Find an element matching <paramref name="selector"/>. If there is none, wait until
455        /// a matching element is attached to the DOM.
456        /// </description></item>
457        /// <item><description>
458        /// Wait for <a href="https://playwright.dev/dotnet/docs/actionability">actionability</a>
459        /// checks on the matched element, unless <paramref name="force"/> option is set. If
460        /// the element is detached during the checks, the whole action is retried.
461        /// </description></item>
462        /// <item><description>Scroll the element into view if needed.</description></item>
463        /// <item><description>
464        /// Use <see cref="IPage.Mouse"/> to double click in the center of the element, or the
465        /// specified <paramref name="position"/>.
466        /// </description></item>
467        /// <item><description>
468        /// Wait for initiated navigations to either succeed or fail, unless <paramref name="noWaitAfter"/>
469        /// option is set. Note that if the first click of the <c>dblclick()</c> triggers a
470        /// navigation event, this method will throw.
471        /// </description></item>
472        /// </list>
473        /// <para>
474        /// When all steps combined have not finished during the specified <paramref name="timeout"/>,
475        /// this method throws a <see cref="TimeoutException"/>. Passing zero timeout disables
476        /// this.
477        /// </para>
478        /// <para>Shortcut for main frame's <see cref="IFrame.DblClickAsync"/>.</para>
479        /// </summary>
480        /// <remarks>
481        /// <para>
482        /// <c>page.dblclick()</c> dispatches two <c>click</c> events and a single <c>dblclick</c>
483        /// event.
484        /// </para>
485        /// </remarks>
486        /// <param name="selector">
487        /// A selector to search for an element. If there are multiple elements satisfying the
488        /// selector, the first will be used. See <a href="https://playwright.dev/dotnet/docs/selectors">working
489        /// with selectors</a> for more details.
490        /// </param>
491        /// <param name="options">Call options</param>
492        Task DblClickAsync(string selector, PageDblClickOptions? options = default);
493
494        /// <summary>
495        /// <para>
496        /// The snippet below dispatches the <c>click</c> event on the element. Regardless of
497        /// the visibility state of the element, <c>click</c> is dispatched. This is equivalent
498        /// to calling <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click">element.click()</a>.
499        /// </para>
500        /// <code>await page.DispatchEventAsync("button#submit", "click");</code>
501        /// <para>
502        /// Under the hood, it creates an instance of an event based on the given <paramref
503        /// name="type"/>, initializes it with <paramref name="eventInit"/> properties and dispatches
504        /// it on the element. Events are <c>composed</c>, <c>cancelable</c> and bubble by default.
505        /// </para>
506        /// <para>
507        /// Since <paramref name="eventInit"/> is event-specific, please refer to the events
508        /// documentation for the lists of initial properties:
509        /// </para>
510        /// <list type="bullet">
511        /// <item><description><a href="https://developer.mozilla.org/en-US/docs/Web/API/DragEvent/DragEvent">DragEvent</a></description></item>
512        /// <item><description><a href="https://developer.mozilla.org/en-US/docs/Web/API/FocusEvent/FocusEvent">FocusEvent</a></description></item>
513        /// <item><description><a href="https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/KeyboardEvent">KeyboardEvent</a></description></item>
514        /// <item><description><a href="https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/MouseEvent">MouseEvent</a></description></item>
515        /// <item><description><a href="https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/PointerEvent">PointerEvent</a></description></item>
516        /// <item><description><a href="https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent/TouchEvent">TouchEvent</a></description></item>
517        /// <item><description><a href="https://developer.mozilla.org/en-US/docs/Web/API/Event/Event">Event</a></description></item>
518        /// </list>
519        /// <para>
520        /// You can also specify <c>JSHandle</c> as the property value if you want live objects
521        /// to be passed into the event:
522        /// </para>
523        /// <code>
524        /// var dataTransfer = await page.EvaluateHandleAsync("() =&gt; new DataTransfer()");<br/>
525        /// await page.DispatchEventAsync("#source", "dragstart", new { dataTransfer });
526        /// </code>
527        /// </summary>
528        /// <param name="selector">
529        /// A selector to search for an element. If there are multiple elements satisfying the
530        /// selector, the first will be used. See <a href="https://playwright.dev/dotnet/docs/selectors">working
531        /// with selectors</a> for more details.
532        /// </param>
533        /// <param name="type">DOM event type: <c>"click"</c>, <c>"dragstart"</c>, etc.</param>
534        /// <param name="eventInit">Optional event-specific initialization properties.</param>
535        /// <param name="options">Call options</param>
536        Task DispatchEventAsync(string selector, string type, object? eventInit = default, PageDispatchEventOptions? options = default);
537
538        /// <param name="source">
539        /// </param>
540        /// <param name="target">
541        /// </param>
542        /// <param name="options">Call options</param>
543        Task DragAndDropAsync(string source, string target, PageDragAndDropOptions? options = default);
544
545        /// <summary>
546        /// <para>
547        /// This method changes the <c>CSS media type</c> through the <c>media</c> argument,
548        /// and/or the <c>'prefers-colors-scheme'</c> media feature, using the <c>colorScheme</c>
549        /// argument.
550        /// </para>
551        /// <code>
552        /// await page.EvaluateAsync("() =&gt; matchMedia('screen').matches");<br/>
553        /// // → true<br/>
554        /// await page.EvaluateAsync("() =&gt; matchMedia('print').matches");<br/>
555        /// // → false<br/>
556        /// <br/>
557        /// await page.EmulateMediaAsync(new PageEmulateMediaOptions { Media = Media.Print });<br/>
558        /// await page.EvaluateAsync("() =&gt; matchMedia('screen').matches");<br/>
559        /// // → false<br/>
560        /// await page.EvaluateAsync("() =&gt; matchMedia('print').matches");<br/>
561        /// // → true<br/>
562        /// <br/>
563        /// await page.EmulateMediaAsync(new PageEmulateMediaOptions { Media = Media.Screen });<br/>
564        /// await page.EvaluateAsync("() =&gt; matchMedia('screen').matches");<br/>
565        /// // → true<br/>
566        /// await page.EvaluateAsync("() =&gt; matchMedia('print').matches");<br/>
567        /// // → false
568        /// </code>
569        /// <code>
570        /// await page.EmulateMediaAsync(new PageEmulateMediaOptions { ColorScheme = ColorScheme.Dark });<br/>
571        /// await page.EvaluateAsync("matchMedia('(prefers-color-scheme: dark)').matches");<br/>
572        /// // → true<br/>
573        /// await page.EvaluateAsync("matchMedia('(prefers-color-scheme: light)').matches");<br/>
574        /// // → false<br/>
575        /// await page.EvaluateAsync("matchMedia('(prefers-color-scheme: no-preference)').matches");<br/>
576        /// // → false
577        /// </code>
578        /// </summary>
579        /// <param name="options">Call options</param>
580        Task EmulateMediaAsync(PageEmulateMediaOptions? options = default);
581
582        /// <summary>
583        /// <para>
584        /// The method finds an element matching the specified selector within the page and
585        /// passes it as a first argument to <paramref name="expression"/>. If no elements match
586        /// the selector, the method throws an error. Returns the value of <paramref name="expression"/>.
587        /// </para>
588        /// <para>
589        /// If <paramref name="expression"/> returns a <see cref="Task"/>, then <see cref="IPage.EvalOnSelectorAsync"/>
590        /// would wait for the promise to resolve and return its value.
591        /// </para>
592        /// <para>Examples:</para>
593        /// <code>
594        /// var searchValue = await page.EvalOnSelectorAsync&lt;string&gt;("#search", "el =&gt; el.value");<br/>
595        /// var preloadHref = await page.EvalOnSelectorAsync&lt;string&gt;("link[rel=preload]", "el =&gt; el.href");<br/>
596        /// var html = await page.EvalOnSelectorAsync(".main-container", "(e, suffix) =&gt; e.outerHTML + suffix", "hello");
597        /// </code>
598        /// <para>Shortcut for main frame's <see cref="IFrame.EvalOnSelectorAsync"/>.</para>
599        /// </summary>
600        /// <remarks>
601        /// <para>
602        /// This method does not wait for the element to pass actionability checks and therefore
603        /// can lead to the flaky tests. Use <see cref="ILocator.EvaluateAsync"/>, other <see
604        /// cref="ILocator"/> helper methods or web-first assertions instead.
605        /// </para>
606        /// </remarks>
607        /// <param name="selector">
608        /// A selector to query for. See <a href="https://playwright.dev/dotnet/docs/selectors">working
609        /// with selectors</a> for more details.
610        /// </param>
611        /// <param name="expression">
612        /// JavaScript expression to be evaluated in the browser context. If it looks like a
613        /// function declaration, it is interpreted as a function. Otherwise, evaluated as an
614        /// expression.
615        /// </param>
616        /// <param name="arg">Optional argument to pass to <paramref name="expression"/>.</param>
617        /// <param name="options">Call options</param>
618        Task<T> EvalOnSelectorAsync<T>(string selector, string expression, object? arg = default, PageEvalOnSelectorOptions? options = default);
619
620        /// <summary>
621        /// <para>
622        /// The method finds all elements matching the specified selector within the page and
623        /// passes an array of matched elements as a first argument to <paramref name="expression"/>.
624        /// Returns the result of <paramref name="expression"/> invocation.
625        /// </para>
626        /// <para>
627        /// If <paramref name="expression"/> returns a <see cref="Task"/>, then <see cref="IPage.EvalOnSelectorAllAsync"/>
628        /// would wait for the promise to resolve and return its value.
629        /// </para>
630        /// <para>Examples:</para>
631        /// <code>var divsCount = await page.EvalOnSelectorAllAsync&lt;bool&gt;("div", "(divs, min) =&gt; divs.length &gt;= min", 10);</code>
632        /// </summary>
633        /// <remarks>
634        /// <para>
635        /// In most cases, <see cref="ILocator.EvaluateAllAsync"/>, other <see cref="ILocator"/>
636        /// helper methods and web-first assertions do a better job.
637        /// </para>
638        /// </remarks>
639        /// <param name="selector">
640        /// A selector to query for. See <a href="https://playwright.dev/dotnet/docs/selectors">working
641        /// with selectors</a> for more details.
642        /// </param>
643        /// <param name="expression">
644        /// JavaScript expression to be evaluated in the browser context. If it looks like a
645        /// function declaration, it is interpreted as a function. Otherwise, evaluated as an
646        /// expression.
647        /// </param>
648        /// <param name="arg">Optional argument to pass to <paramref name="expression"/>.</param>
649        Task<T> EvalOnSelectorAllAsync<T>(string selector, string expression, object? arg = default);
650
651        /// <summary>
652        /// <para>Returns the value of the <paramref name="expression"/> invocation.</para>
653        /// <para>
654        /// If the function passed to the <see cref="IPage.EvaluateAsync"/> returns a <see cref="Task"/>,
655        /// then <see cref="IPage.EvaluateAsync"/> would wait for the promise to resolve and
656        /// return its value.
657        /// </para>
658        /// <para>
659        /// If the function passed to the <see cref="IPage.EvaluateAsync"/> returns a non-<see
660        /// cref="Serializable"/> value, then <see cref="IPage.EvaluateAsync"/> resolves to
661        /// <c>undefined</c>. Playwright also supports transferring some additional values that
662        /// are not serializable by <c>JSON</c>: <c>-0</c>, <c>NaN</c>, <c>Infinity</c>, <c>-Infinity</c>.
663        /// </para>
664        /// <para>Passing argument to <paramref name="expression"/>:</para>
665        /// <code>
666        /// var result = await page.EvaluateAsync&lt;int&gt;("([x, y]) =&gt; Promise.resolve(x * y)", new[] { 7, 8 });<br/>
667        /// Console.WriteLine(result);
668        /// </code>
669        /// <para>A string can also be passed in instead of a function:</para>
670        /// <code>Console.WriteLine(await page.EvaluateAsync&lt;int&gt;("1 + 2")); // prints "3"</code>
671        /// <para>
672        /// <see cref="IElementHandle"/> instances can be passed as an argument to the <see
673        /// cref="IPage.EvaluateAsync"/>:
674        /// </para>
675        /// <code>
676        /// var bodyHandle = await page.EvaluateAsync("document.body");<br/>
677        /// var html = await page.EvaluateAsync&lt;string&gt;("([body, suffix]) =&gt; body.innerHTML + suffix", new object [] { bodyHandle, "hello" });<br/>
678        /// await bodyHandle.DisposeAsync();
679        /// </code>
680        /// <para>Shortcut for main frame's <see cref="IFrame.EvaluateAsync"/>.</para>
681        /// </summary>
682        /// <param name="expression">
683        /// JavaScript expression to be evaluated in the browser context. If it looks like a
684        /// function declaration, it is interpreted as a function. Otherwise, evaluated as an
685        /// expression.
686        /// </param>
687        /// <param name="arg">Optional argument to pass to <paramref name="expression"/>.</param>
688        Task<T> EvaluateAsync<T>(string expression, object? arg = default);
689
690        /// <summary>
691        /// <para>Returns the value of the <paramref name="expression"/> invocation as a <see cref="IJSHandle"/>.</para>
692        /// <para>
693        /// The only difference between <see cref="IPage.EvaluateAsync"/> and <see cref="IPage.EvaluateHandleAsync"/>
694        /// is that <see cref="IPage.EvaluateHandleAsync"/> returns <see cref="IJSHandle"/>.
695        /// </para>
696        /// <para>
697        /// If the function passed to the <see cref="IPage.EvaluateHandleAsync"/> returns a
698        /// <see cref="Task"/>, then <see cref="IPage.EvaluateHandleAsync"/> would wait for
699        /// the promise to resolve and return its value.
700        /// </para>
701        /// <code>
702        /// // Handle for the window object.<br/>
703        /// var aWindowHandle = await page.EvaluateHandleAsync("() =&gt; Promise.resolve(window)");
704        /// </code>
705        /// <para>A string can also be passed in instead of a function:</para>
706        /// <code>var docHandle = await page.EvaluateHandleAsync("document"); // Handle for the `document`</code>
707        /// <para><see cref="IJSHandle"/> instances can be passed as an argument to the <see cref="IPage.EvaluateHandleAsync"/>:</para>
708        /// <code>
709        /// var handle = await page.EvaluateHandleAsync("() =&gt; document.body");<br/>
710        /// var resultHandle = await page.EvaluateHandleAsync("([body, suffix]) =&gt; body.innerHTML + suffix", new object[] { handle, "hello" });<br/>
711        /// Console.WriteLine(await resultHandle.JsonValueAsync&lt;string&gt;());<br/>
712        /// await resultHandle.DisposeAsync();
713        /// </code>
714        /// </summary>
715        /// <param name="expression">
716        /// JavaScript expression to be evaluated in the browser context. If it looks like a
717        /// function declaration, it is interpreted as a function. Otherwise, evaluated as an
718        /// expression.
719        /// </param>
720        /// <param name="arg">Optional argument to pass to <paramref name="expression"/>.</param>
721        Task<IJSHandle> EvaluateHandleAsync(string expression, object? arg = default);
722
723        /// <summary>
724        /// <para>
725        /// The method adds a function called <paramref name="name"/> on the <c>window</c> object
726        /// of every frame in this page. When called, the function executes <paramref name="callback"/>
727        /// and returns a <see cref="Task"/> which resolves to the return value of <paramref
728        /// name="callback"/>. If the <paramref name="callback"/> returns a <see cref="Promise"/>,
729        /// it will be awaited.
730        /// </para>
731        /// <para>
732        /// The first argument of the <paramref name="callback"/> function contains information
733        /// about the caller: <c>{ browserContext: BrowserContext, page: Page, frame: Frame
734        /// }</c>.
735        /// </para>
736        /// <para>See <see cref="IBrowserContext.ExposeBindingAsync"/> for the context-wide version.</para>
737        /// <para>An example of exposing page URL to all frames in a page:</para>
738        /// <code>
739        /// using Microsoft.Playwright;<br/>
740        /// using System.Threading.Tasks;<br/>
741        /// <br/>
742        /// class PageExamples<br/>
743        /// {<br/>
744        ///     public static async Task Main()<br/>
745        ///     {<br/>
746        ///         using var playwright = await Playwright.CreateAsync();<br/>
747        ///         await using var browser = await playwright.Webkit.LaunchAsync(new BrowserTypeLaunchOptions<br/>
748        ///         {<br/>
749        ///             Headless: false<br/>
750        ///         });<br/>
751        ///         var page = await browser.NewPageAsync();<br/>
752        /// <br/>
753        ///         await page.ExposeBindingAsync("pageUrl", (source) =&gt; source.Page.Url);<br/>
754        ///         await page.SetContentAsync("&lt;script&gt;\n" +<br/>
755        ///         "  async function onClick() {\n" +<br/>
756        ///         "    document.querySelector('div').textContent = await window.pageURL();\n" +<br/>
757        ///         "  }\n" +<br/>
758        ///         "&lt;/script&gt;\n" +<br/>
759        ///         "&lt;button onclick=\"onClick()\"&gt;Click me&lt;/button&gt;\n" +<br/>
760        ///         "&lt;div&gt;&lt;/div&gt;");<br/>
761        /// <br/>
762        ///         await page.ClickAsync("button");<br/>
763        ///     }<br/>
764        /// }
765        /// </code>
766        /// <para>An example of passing an element handle:</para>
767        /// <code>
768        /// var result = new TaskCompletionSource&lt;string&gt;();<br/>
769        /// await page.ExposeBindingAsync("clicked", async (BindingSource _, IJSHandle t) =&gt;<br/>
770        /// {<br/>
771        ///     return result.TrySetResult(await t.AsElement().TextContentAsync());<br/>
772        /// });<br/>
773        /// <br/>
774        /// await page.SetContentAsync("&lt;script&gt;\n" +<br/>
775        ///   "  document.addEventListener('click', event =&gt; window.clicked(event.target));\n" +<br/>
776        ///   "&lt;/script&gt;\n" +<br/>
777        ///   "&lt;div&gt;Click me&lt;/div&gt;\n" +<br/>
778        ///   "&lt;div&gt;Or click me&lt;/div&gt;\n");<br/>
779        /// <br/>
780        /// await page.ClickAsync("div");<br/>
781        /// Console.WriteLine(await result.Task);
782        /// </code>
783        /// </summary>
784        /// <remarks><para>Functions installed via <see cref="IPage.ExposeBindingAsync"/> survive navigations.</para></remarks>
785        /// <param name="name">Name of the function on the window object.</param>
786        /// <param name="callback">Callback function that will be called in the Playwright's context.</param>
787        /// <param name="options">Call options</param>
788        Task ExposeBindingAsync(string name, Action callback, PageExposeBindingOptions? options = default);
789
790        /// <summary>
791        /// <para>
792        /// The method adds a function called <paramref name="name"/> on the <c>window</c> object
793        /// of every frame in the page. When called, the function executes <paramref name="callback"/>
794        /// and returns a <see cref="Task"/> which resolves to the return value of <paramref
795        /// name="callback"/>.
796        /// </para>
797        /// <para>If the <paramref name="callback"/> returns a <see cref="Task"/>, it will be awaited.</para>
798        /// <para>See <see cref="IBrowserContext.ExposeFunctionAsync"/> for context-wide exposed function.</para>
799        /// <para>An example of adding a <c>sha256</c> function to the page:</para>
800        /// <code>
801        /// using Microsoft.Playwright;<br/>
802        /// using System;<br/>
803        /// using System.Security.Cryptography;<br/>
804        /// using System.Threading.Tasks;<br/>
805        /// <br/>
806        /// class PageExamples<br/>
807        /// {<br/>
808        ///     public static async Task Main()<br/>
809        ///     {<br/>
810        ///         using var playwright = await Playwright.CreateAsync();<br/>
811        ///         await using var browser = await playwright.Webkit.LaunchAsync(new BrowserTypeLaunchOptions<br/>
812        ///         {<br/>
813        ///             Headless: false<br/>
814        ///         });<br/>
815        ///         var page = await browser.NewPageAsync();<br/>
816        /// <br/>
817        ///         await page.ExposeFunctionAsync("sha256", (string input) =&gt;<br/>
818        ///         {<br/>
819        ///             return Convert.ToBase64String(<br/>
820        ///                 SHA256.Create().ComputeHash(System.Text.Encoding.UTF8.GetBytes(input)));<br/>
821        ///         });<br/>
822        /// <br/>
823        ///         await page.SetContentAsync("&lt;script&gt;\n" +<br/>
824        ///         "  async function onClick() {\n" +<br/>
825        ///         "    document.querySelector('div').textContent = await window.sha256('PLAYWRIGHT');\n" +<br/>
826        ///         "  }\n" +<br/>
827        ///         "&lt;/script&gt;\n" +<br/>
828        ///         "&lt;button onclick=\"onClick()\"&gt;Click me&lt;/button&gt;\n" +<br/>
829        ///         "&lt;div&gt;&lt;/div&gt;");<br/>
830        /// <br/>
831        ///         await page.ClickAsync("button");<br/>
832        ///         Console.WriteLine(await page.TextContentAsync("div"));<br/>
833        ///     }<br/>
834        /// }
835        /// </code>
836        /// </summary>
837        /// <remarks><para>Functions installed via <see cref="IPage.ExposeFunctionAsync"/> survive navigations.</para></remarks>
838        /// <param name="name">Name of the function on the window object</param>
839        /// <param name="callback">Callback function which will be called in Playwright's context.</param>
840        Task ExposeFunctionAsync(string name, Action callback);
841
842        /// <summary>
843        /// <para>
844        /// This method waits for an element matching <paramref name="selector"/>, waits for
845        /// <a href="https://playwright.dev/dotnet/docs/actionability">actionability</a> checks,
846        /// focuses the element, fills it and triggers an <c>input</c> event after filling.
847        /// Note that you can pass an empty string to clear the input field.
848        /// </para>
849        /// <para>
850        /// If the target element is not an <c>&lt;input&gt;</c>, <c>&lt;textarea&gt;</c> or
851        /// <c>[contenteditable]</c> element, this method throws an error. However, if the element
852        /// is inside the <c>&lt;label&gt;</c> element that has an associated <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/control">control</a>,
853        /// the control will be filled instead.
854        /// </para>
855        /// <para>To send fine-grained keyboard events, use <see cref="IPage.TypeAsync"/>.</para>
856        /// <para>Shortcut for main frame's <see cref="IFrame.FillAsync"/>.</para>
857        /// </summary>
858        /// <param name="selector">
859        /// A selector to search for an element. If there are multiple elements satisfying the
860        /// selector, the first will be used. See <a href="https://playwright.dev/dotnet/docs/selectors">working
861        /// with selectors</a> for more details.
862        /// </param>
863        /// <param name="value">
864        /// Value to fill for the <c>&lt;input&gt;</c>, <c>&lt;textarea&gt;</c> or <c>[contenteditable]</c>
865        /// element.
866        /// </param>
867        /// <param name="options">Call options</param>
868        Task FillAsync(string selector, string value, PageFillOptions? options = default);
869
870        /// <summary>
871        /// <para>
872        /// This method fetches an element with <paramref name="selector"/> and focuses it.
873        /// If there's no element matching <paramref name="selector"/>, the method waits until
874        /// a matching element appears in the DOM.
875        /// </para>
876        /// <para>Shortcut for main frame's <see cref="IFrame.FocusAsync"/>.</para>
877        /// </summary>
878        /// <param name="selector">
879        /// A selector to search for an element. If there are multiple elements satisfying the
880        /// selector, the first will be used. See <a href="https://playwright.dev/dotnet/docs/selectors">working
881        /// with selectors</a> for more details.
882        /// </param>
883        /// <param name="options">Call options</param>
884        Task FocusAsync(string selector, PageFocusOptions? options = default);
885
886        /// <summary>
887        /// <para>
888        /// Returns frame matching the specified criteria. Either <c>name</c> or <c>url</c>
889        /// must be specified.
890        /// </para>
891        /// <code>var frame = page.Frame("frame-name");</code>
892        /// <code>var frame = page.FrameByUrl(".*domain.*");</code>
893        /// </summary>
894        /// <param name="name">Frame name specified in the <c>iframe</c>'s <c>name</c> attribute.</param>
895        IFrame? Frame(string name);
896
897        /// <summary><para>Returns frame with matching URL.</para></summary>
898        /// <param name="url">
899        /// A glob pattern, regex pattern or predicate receiving frame's <c>url</c> as a <see
900        /// cref="URL"/> object.
901        /// </param>
902        IFrame? FrameByUrl(string url);
903
904        /// <summary><para>Returns frame with matching URL.</para></summary>
905        /// <param name="url">
906        /// A glob pattern, regex pattern or predicate receiving frame's <c>url</c> as a <see
907        /// cref="URL"/> object.
908        /// </param>
909        IFrame? FrameByUrl(Regex url);
910
911        /// <summary><para>Returns frame with matching URL.</para></summary>
912        /// <param name="url">
913        /// A glob pattern, regex pattern or predicate receiving frame's <c>url</c> as a <see
914        /// cref="URL"/> object.
915        /// </param>
916        IFrame? FrameByUrl(Func<string, bool> url);
917
918        /// <summary>
919        /// <para>
920        /// When working with iframes, you can create a frame locator that will enter the iframe
921        /// and allow selecting elements in that iframe. Following snippet locates element with
922        /// text "Submit" in the iframe with id <c>my-frame</c>, like <c>&lt;iframe id="my-frame"&gt;</c>:
923        /// </para>
924        /// <code>
925        /// var locator = page.FrameLocator("#my-iframe").Locator("text=Submit");<br/>
926        /// await locator.ClickAsync();
927        /// </code>
928        /// </summary>
929        /// <param name="selector">
930        /// A selector to use when resolving DOM element. See <a href="https://playwright.dev/dotnet/docs/selectors">working
931        /// with selectors</a> for more details.
932        /// </param>
933        IFrameLocator FrameLocator(string selector);
934
935        /// <summary><para>An array of all frames attached to the page.</para></summary>
936        IReadOnlyList<IFrame> Frames { get; }
937
938        /// <summary><para>Returns element attribute value.</para></summary>
939        /// <param name="selector">
940        /// A selector to search for an element. If there are multiple elements satisfying the
941        /// selector, the first will be used. See <a href="https://playwright.dev/dotnet/docs/selectors">working
942        /// with selectors</a> for more details.
943        /// </param>
944        /// <param name="name">Attribute name to get the value for.</param>
945        /// <param name="options">Call options</param>
946        Task<string?> GetAttributeAsync(string selector, string name, PageGetAttributeOptions? options = default);
947
948        /// <summary>
949        /// <para>
950        /// Returns the main resource response. In case of multiple redirects, the navigation
951        /// will resolve with the response of the last redirect. If can not go back, returns
952        /// <c>null</c>.
953        /// </para>
954        /// <para>Navigate to the previous page in history.</para>
955        /// </summary>
956        /// <param name="options">Call options</param>
957        Task<IResponse?> GoBackAsync(PageGoBackOptions? options = default);
958
959        /// <summary>
960        /// <para>
961        /// Returns the main resource response. In case of multiple redirects, the navigation
962        /// will resolve with the response of the last redirect. If can not go forward, returns
963        /// <c>null</c>.
964        /// </para>
965        /// <para>Navigate to the next page in history.</para>
966        /// </summary>
967        /// <param name="options">Call options</param>
968        Task<IResponse?> GoForwardAsync(PageGoForwardOptions? options = default);
969
970        /// <summary>
971        /// <para>
972        /// Returns the main resource response. In case of multiple redirects, the navigation
973        /// will resolve with the response of the last redirect.
974        /// </para>
975        /// <para>The method will throw an error if:</para>
976        /// <list type="bullet">
977        /// <item><description>there's an SSL error (e.g. in case of self-signed certificates).</description></item>
978        /// <item><description>target URL is invalid.</description></item>
979        /// <item><description>the <paramref name="timeout"/> is exceeded during navigation.</description></item>
980        /// <item><description>the remote server does not respond or is unreachable.</description></item>
981        /// <item><description>the main resource failed to load.</description></item>
982        /// </list>
983        /// <para>
984        /// The method will not throw an error when any valid HTTP status code is returned by
985        /// the remote server, including 404 "Not Found" and 500 "Internal Server Error".  The
986        /// status code for such responses can be retrieved by calling <see cref="IResponse.Status"/>.
987        /// </para>
988        /// <para>Shortcut for main frame's <see cref="IFrame.GotoAsync"/></para>
989        /// </summary>
990        /// <remarks>
991        /// <para>
992        /// The method either throws an error or returns a main resource response. The only
993        /// exceptions are navigation to <c>about:blank</c> or navigation to the same URL with
994        /// a different hash, which would succeed and return <c>null</c>.
995        /// </para>
996        /// <para>
997        /// Headless mode doesn't support navigation to a PDF document. See the <a href="https://bugs.chromium.org/p/chromium/issues/detail?id=761295">upstream
998        /// issue</a>.
999        /// </para>
1000        /// </remarks>
1001        /// <param name="url">
1002        /// URL to navigate page to. The url should include scheme, e.g. <c>https://</c>. When
1003        /// a <paramref name="baseURL"/> via the context options was provided and the passed
1004        /// URL is a path, it gets merged via the <a href="https://developer.mozilla.org/en-US/docs/Web/API/URL/URL"><c>new
1005        /// URL()</c></a> constructor.
1006        /// </param>
1007        /// <param name="options">Call options</param>
1008        Task<IResponse?> GotoAsync(string url, PageGotoOptions? options = default);
1009
1010        /// <summary>
1011        /// <para>
1012        /// This method hovers over an element matching <paramref name="selector"/> by performing
1013        /// the following steps:
1014        /// </para>
1015        /// <list type="ordinal">
1016        /// <item><description>
1017        /// Find an element matching <paramref name="selector"/>. If there is none, wait until
1018        /// a matching element is attached to the DOM.
1019        /// </description></item>
1020        /// <item><description>
1021        /// Wait for <a href="https://playwright.dev/dotnet/docs/actionability">actionability</a>
1022        /// checks on the matched element, unless <paramref name="force"/> option is set. If
1023        /// the element is detached during the checks, the whole action is retried.
1024        /// </description></item>
1025        /// <item><description>Scroll the element into view if needed.</description></item>
1026        /// <item><description>
1027        /// Use <see cref="IPage.Mouse"/> to hover over the center of the element, or the specified
1028        /// <paramref name="position"/>.
1029        /// </description></item>
1030        /// <item><description>
1031        /// Wait for initiated navigations to either succeed or fail, unless <c>noWaitAfter</c>
1032        /// option is set.
1033        /// </description></item>
1034        /// </list>
1035        /// <para>
1036        /// When all steps combined have not finished during the specified <paramref name="timeout"/>,
1037        /// this method throws a <see cref="TimeoutException"/>. Passing zero timeout disables
1038        /// this.
1039        /// </para>
1040        /// <para>Shortcut for main frame's <see cref="IFrame.HoverAsync"/>.</para>
1041        /// </summary>
1042        /// <param name="selector">
1043        /// A selector to search for an element. If there are multiple elements satisfying the
1044        /// selector, the first will be used. See <a href="https://playwright.dev/dotnet/docs/selectors">working
1045        /// with selectors</a> for more details.
1046        /// </param>
1047        /// <param name="options">Call options</param>
1048        Task HoverAsync(string selector, PageHoverOptions? options = default);
1049
1050        /// <summary><para>Returns <c>element.innerHTML</c>.</para></summary>
1051        /// <param name="selector">
1052        /// A selector to search for an element. If there are multiple elements satisfying the
1053        /// selector, the first will be used. See <a href="https://playwright.dev/dotnet/docs/selectors">working
1054        /// with selectors</a> for more details.
1055        /// </param>
1056        /// <param name="options">Call options</param>
1057        Task<string> InnerHTMLAsync(string selector, PageInnerHTMLOptions? options = default);
1058
1059        /// <summary><para>Returns <c>element.innerText</c>.</para></summary>
1060        /// <param name="selector">
1061        /// A selector to search for an element. If there are multiple elements satisfying the
1062        /// selector, the first will be used. See <a href="https://playwright.dev/dotnet/docs/selectors">working
1063        /// with selectors</a> for more details.
1064        /// </param>
1065        /// <param name="options">Call options</param>
1066        Task<string> InnerTextAsync(string selector, PageInnerTextOptions? options = default);
1067
1068        /// <summary>
1069        /// <para>
1070        /// Returns <c>input.value</c> for the selected <c>&lt;input&gt;</c> or <c>&lt;textarea&gt;</c>
1071        /// or <c>&lt;select&gt;</c> element. Throws for non-input elements.
1072        /// </para>
1073        /// </summary>
1074        /// <param name="selector">
1075        /// A selector to search for an element. If there are multiple elements satisfying the
1076        /// selector, the first will be used. See <a href="https://playwright.dev/dotnet/docs/selectors">working
1077        /// with selectors</a> for more details.
1078        /// </param>
1079        /// <param name="options">Call options</param>
1080        Task<string> InputValueAsync(string selector, PageInputValueOptions? options = default);
1081
1082        /// <summary>
1083        /// <para>
1084        /// Returns whether the element is checked. Throws if the element is not a checkbox
1085        /// or radio input.
1086        /// </para>
1087        /// </summary>
1088        /// <param name="selector">
1089        /// A selector to search for an element. If there are multiple elements satisfying the
1090        /// selector, the first will be used. See <a href="https://playwright.dev/dotnet/docs/selectors">working
1091        /// with selectors</a> for more details.
1092        /// </param>
1093        /// <param name="options">Call options</param>
1094        Task<bool> IsCheckedAsync(string selector, PageIsCheckedOptions? options = default);
1095
1096        /// <summary><para>Indicates that the page has been closed.</para></summary>
1097        bool IsClosed { get; }
1098
1099        /// <summary><para>Returns whether the element is disabled, the opposite of <a href="https://playwright.dev/dotnet/docs/actionability#enabled">enabled</a>.</para></summary>
1100        /// <param name="selector">
1101        /// A selector to search for an element. If there are multiple elements satisfying the
1102        /// selector, the first will be used. See <a href="https://playwright.dev/dotnet/docs/selectors">working
1103        /// with selectors</a> for more details.
1104        /// </param>
1105        /// <param name="options">Call options</param>
1106        Task<bool> IsDisabledAsync(string selector, PageIsDisabledOptions? options = default);
1107
1108        /// <summary><para>Returns whether the element is <a href="https://playwright.dev/dotnet/docs/actionability#editable">editable</a>.</para></summary>
1109        /// <param name="selector">
1110        /// A selector to search for an element. If there are multiple elements satisfying the
1111        /// selector, the first will be used. See <a href="https://playwright.dev/dotnet/docs/selectors">working
1112        /// with selectors</a> for more details.
1113        /// </param>
1114        /// <param name="options">Call options</param>
1115        Task<bool> IsEditableAsync(string selector, PageIsEditableOptions? options = default);
1116
1117        /// <summary><para>Returns whether the element is <a href="https://playwright.dev/dotnet/docs/actionability#enabled">enabled</a>.</para></summary>
1118        /// <param name="selector">
1119        /// A selector to search for an element. If there are multiple elements satisfying the
1120        /// selector, the first will be used. See <a href="https://playwright.dev/dotnet/docs/selectors">working
1121        /// with selectors</a> for more details.
1122        /// </param>
1123        /// <param name="options">Call options</param>
1124        Task<bool> IsEnabledAsync(string selector, PageIsEnabledOptions? options = default);
1125
1126        /// <summary>
1127        /// <para>
1128        /// Returns whether the element is hidden, the opposite of <a href="https://playwright.dev/dotnet/docs/actionability#visible">visible</a>.
1129        /// <paramref name="selector"/> that does not match any elements is considered hidden.
1130        /// </para>
1131        /// </summary>
1132        /// <param name="selector">
1133        /// A selector to search for an element. If there are multiple elements satisfying the
1134        /// selector, the first will be used. See <a href="https://playwright.dev/dotnet/docs/selectors">working
1135        /// with selectors</a> for more details.
1136        /// </param>
1137        /// <param name="options">Call options</param>
1138        Task<bool> IsHiddenAsync(string selector, PageIsHiddenOptions? options = default);
1139
1140        /// <summary>
1141        /// <para>
1142        /// Returns whether the element is <a href="https://playwright.dev/dotnet/docs/actionability#visible">visible</a>.
1143        /// <paramref name="selector"/> that does not match any elements is considered not visible.
1144        /// </para>
1145        /// </summary>
1146        /// <param name="selector">
1147        /// A selector to search for an element. If there are multiple elements satisfying the
1148        /// selector, the first will be used. See <a href="https://playwright.dev/dotnet/docs/selectors">working
1149        /// with selectors</a> for more details.
1150        /// </param>
1151        /// <param name="options">Call options</param>
1152        Task<bool> IsVisibleAsync(string selector, PageIsVisibleOptions? options = default);
1153
1154        public IKeyboard Keyboard { get; }
1155
1156        /// <summary>
1157        /// <para>
1158        /// The method returns an element locator that can be used to perform actions on the
1159        /// page. Locator is resolved to the element immediately before performing an action,
1160        /// so a series of actions on the same locator can in fact be performed on different
1161        /// DOM elements. That would happen if the DOM structure between those actions has changed.
1162        /// </para>
1163        /// <para>Shortcut for main frame's <see cref="IFrame.Locator"/>.</para>
1164        /// </summary>
1165        /// <param name="selector">
1166        /// A selector to use when resolving DOM element. See <a href="https://playwright.dev/dotnet/docs/selectors">working
1167        /// with selectors</a> for more details.
1168        /// </param>
1169        /// <param name="options">Call options</param>
1170        ILocator Locator(string selector, PageLocatorOptions? options = default);
1171
1172        /// <summary>
1173        /// <para>
1174        /// The page's main frame. Page is guaranteed to have a main frame which persists during
1175        /// navigations.
1176        /// </para>
1177        /// </summary>
1178        IFrame MainFrame { get; }
1179
1180        public IMouse Mouse { get; }
1181
1182        /// <summary>
1183        /// <para>
1184        /// Returns the opener for popup pages and <c>null</c> for others. If the opener has
1185        /// been closed already the returns <c>null</c>.
1186        /// </para>
1187        /// </summary>
1188        Task<IPage?> OpenerAsync();
1189
1190        /// <summary>
1191        /// <para>
1192        /// Pauses script execution. Playwright will stop executing the script and wait for
1193        /// the user to either press 'Resume' button in the page overlay or to call <c>playwright.resume()</c>
1194        /// in the DevTools console.
1195        /// </para>
1196        /// <para>
1197        /// User can inspect selectors or perform manual steps while paused. Resume will continue
1198        /// running the original script from the place it was paused.
1199        /// </para>
1200        /// </summary>
1201        /// <remarks>
1202        /// <para>
1203        /// This method requires Playwright to be started in a headed mode, with a falsy <paramref
1204        /// name="headless"/> value in the <see cref="IBrowserType.LaunchAsync"/>.
1205        /// </para>
1206        /// </remarks>
1207        Task PauseAsync();
1208
1209        /// <summary>
1210        /// <para>Returns the PDF buffer.</para>
1211        /// <para>
1212        /// <c>page.pdf()</c> generates a pdf of the page with <c>print</c> css media. To generate
1213        /// a pdf with <c>screen</c> media, call <see cref="IPage.EmulateMediaAsync"/> before
1214        /// calling <c>page.pdf()</c>:
1215        /// </para>
1216        /// <code>
1217        /// // Generates a PDF with 'screen' media type<br/>
1218        /// await page.EmulateMediaAsync(new PageEmulateMediaOptions { Media = Media.Screen });<br/>
1219        /// await page.PdfAsync(new PagePdfOptions { Path = "page.pdf" });
1220        /// </code>
1221        /// <para>
1222        /// The <paramref name="width"/>, <paramref name="height"/>, and <paramref name="margin"/>
1223        /// options accept values labeled with units. Unlabeled values are treated as pixels.
1224        /// </para>
1225        /// <para>A few examples:</para>
1226        /// <list type="bullet">
1227        /// <item><description><c>page.pdf({width: 100})</c> - prints with width set to 100 pixels</description></item>
1228        /// <item><description><c>page.pdf({width: '100px'})</c> - prints with width set to 100 pixels</description></item>
1229        /// <item><description><c>page.pdf({width: '10cm'})</c> - prints with width set to 10 centimeters.</description></item>
1230        /// </list>
1231        /// <para>All possible units are:</para>
1232        /// <list type="bullet">
1233        /// <item><description><c>px</c> - pixel</description></item>
1234        /// <item><description><c>in</c> - inch</description></item>
1235        /// <item><description><c>cm</c> - centimeter</description></item>
1236        /// <item><description><c>mm</c> - millimeter</description></item>
1237        /// </list>
1238        /// <para>The <paramref name="format"/> options are:</para>
1239        /// <list type="bullet">
1240        /// <item><description><c>Letter</c>: 8.5in x 11in</description></item>
1241        /// <item><description><c>Legal</c>: 8.5in x 14in</description></item>
1242        /// <item><description><c>Tabloid</c>: 11in x 17in</description></item>
1243        /// <item><description><c>Ledger</c>: 17in x 11in</description></item>
1244        /// <item><description><c>A0</c>: 33.1in x 46.8in</description></item>
1245        /// <item><description><c>A1</c>: 23.4in x 33.1in</description></item>
1246        /// <item><description><c>A2</c>: 16.54in x 23.4in</description></item>
1247        /// <item><description><c>A3</c>: 11.7in x 16.54in</description></item>
1248        /// <item><description><c>A4</c>: 8.27in x 11.7in</description></item>
1249        /// <item><description><c>A5</c>: 5.83in x 8.27in</description></item>
1250        /// <item><description><c>A6</c>: 4.13in x 5.83in</description></item>
1251        /// </list>
1252        /// </summary>
1253        /// <remarks>
1254        /// <para>Generating a pdf is currently only supported in Chromium headless.</para>
1255        /// <para>
1256        /// By default, <c>page.pdf()</c> generates a pdf with modified colors for printing.
1257        /// Use the <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-print-color-adjust"><c>-webkit-print-color-adjust</c></a>
1258        /// property to force rendering of exact colors.
1259        /// </para>
1260        /// <para>
1261        /// <paramref name="headerTemplate"/> and <paramref name="footerTemplate"/> markup have
1262        /// the following limitations: > 1. Script tags inside templates are not evaluated.
1263        /// > 2. Page styles are not visible inside templates.
1264        /// </para>
1265        /// </remarks>
1266        /// <param name="options">Call options</param>
1267        Task<byte[]> PdfAsync(PagePdfOptions? options = default);
1268
1269        /// <summary>
1270        /// <para>Focuses the element, and then uses <see cref="IKeyboard.DownAsync"/> and <see cref="IKeyboard.UpAsync"/>.</para>
1271        /// <para>
1272        /// <paramref name="key"/> can specify the intended <a href="https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key">keyboardEvent.key</a>
1273        /// value or a single character to generate the text for. A superset of the <paramref
1274        /// name="key"/> values can be found <a href="https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values">here</a>.
1275        /// Examples of the keys are:
1276        /// </para>
1277        /// <para>
1278        /// <c>F1</c> - <c>F12</c>, <c>Digit0</c>- <c>Digit9</c>, <c>KeyA</c>- <c>KeyZ</c>,
1279        /// <c>Backquote</c>, <c>Minus</c>, <c>Equal</c>, <c>Backslash</c>, <c>Backspace</c>,
1280        /// <c>Tab</c>, <c>Delete</c>, <c>Escape</c>, <c>ArrowDown</c>, <c>End</c>, <c>Enter</c>,
1281        /// <c>Home</c>, <c>Insert</c>, <c>PageDown</c>, <c>PageUp</c>, <c>ArrowRight</c>, <c>ArrowUp</c>,
1282        /// etc.
1283        /// </para>
1284        /// <para>
1285        /// Following modification shortcuts are also supported: <c>Shift</c>, <c>Control</c>,
1286        /// <c>Alt</c>, <c>Meta</c>, <c>ShiftLeft</c>.
1287        /// </para>
1288        /// <para>
1289        /// Holding down <c>Shift</c> will type the text that corresponds to the <paramref name="key"/>
1290        /// in the upper case.
1291        /// </para>
1292        /// <para>
1293        /// If <paramref name="key"/> is a single character, it is case-sensitive, so the values
1294        /// <c>a</c> and <c>A</c> will generate different respective texts.
1295        /// </para>
1296        /// <para>
1297        /// Shortcuts such as <c>key: "Control+o"</c> or <c>key: "Control+Shift+T"</c> are supported
1298        /// as well. When specified with the modifier, modifier is pressed and being held while
1299        /// the subsequent key is being pressed.
1300        /// </para>
1301        /// <code>
1302        /// var page = await browser.NewPageAsync();<br/>
1303        /// await page.GotoAsync("https://keycode.info");<br/>
1304        /// await page.PressAsync("body", "A");<br/>
1305        /// await page.ScreenshotAsync(new PageScreenshotOptions { Path = "A.png" });<br/>
1306        /// await page.PressAsync("body", "ArrowLeft");<br/>
1307        /// await page.ScreenshotAsync(new PageScreenshotOptions { Path = "ArrowLeft.png" });<br/>
1308        /// await page.PressAsync("body", "Shift+O");<br/>
1309        /// await page.ScreenshotAsync(new PageScreenshotOptions { Path = "O.png" });
1310        /// </code>
1311        /// </summary>
1312        /// <param name="selector">
1313        /// A selector to search for an element. If there are multiple elements satisfying the
1314        /// selector, the first will be used. See <a href="https://playwright.dev/dotnet/docs/selectors">working
1315        /// with selectors</a> for more details.
1316        /// </param>
1317        /// <param name="key">
1318        /// Name of the key to press or a character to generate, such as <c>ArrowLeft</c> or
1319        /// <c>a</c>.
1320        /// </param>
1321        /// <param name="options">Call options</param>
1322        Task PressAsync(string selector, string key, PagePressOptions? options = default);
1323
1324        /// <summary>
1325        /// <para>
1326        /// The method finds an element matching the specified selector within the page. If
1327        /// no elements match the selector, the return value resolves to <c>null</c>. To wait
1328        /// for an element on the page, use <see cref="ILocator.WaitForAsync"/>.
1329        /// </para>
1330        /// <para>Shortcut for main frame's <see cref="IFrame.QuerySelectorAsync"/>.</para>
1331        /// </summary>
1332        /// <remarks>
1333        /// <para>
1334        /// The use of <see cref="IElementHandle"/> is discouraged, use <see cref="ILocator"/>
1335        /// objects and web-first assertions instead.
1336        /// </para>
1337        /// </remarks>
1338        /// <param name="selector">
1339        /// A selector to query for. See <a href="https://playwright.dev/dotnet/docs/selectors">working
1340        /// with selectors</a> for more details.
1341        /// </param>
1342        /// <param name="options">Call options</param>
1343        Task<IElementHandle?> QuerySelectorAsync(string selector, PageQuerySelectorOptions? options = default);
1344
1345        /// <summary>
1346        /// <para>
1347        /// The method finds all elements matching the specified selector within the page. If
1348        /// no elements match the selector, the return value resolves to <c>[]</c>.
1349        /// </para>
1350        /// <para>Shortcut for main frame's <see cref="IFrame.QuerySelectorAllAsync"/>.</para>
1351        /// </summary>
1352        /// <remarks>
1353        /// <para>
1354        /// The use of <see cref="IElementHandle"/> is discouraged, use <see cref="ILocator"/>
1355        /// objects and web-first assertions instead.
1356        /// </para>
1357        /// </remarks>
1358        /// <param name="selector">
1359        /// A selector to query for. See <a href="https://playwright.dev/dotnet/docs/selectors">working
1360        /// with selectors</a> for more details.
1361        /// </param>
1362        Task<IReadOnlyList<IElementHandle>> QuerySelectorAllAsync(string selector);
1363
1364        /// <summary>
1365        /// <para>
1366        /// This method reloads the current page, in the same way as if the user had triggered
1367        /// a browser refresh. Returns the main resource response. In case of multiple redirects,
1368        /// the navigation will resolve with the response of the last redirect.
1369        /// </para>
1370        /// </summary>
1371        /// <param name="options">Call options</param>
1372        Task<IResponse?> ReloadAsync(PageReloadOptions? options = default);
1373
1374        /// <summary>
1375        /// <para>Routing provides the capability to modify network requests that are made by a page.</para>
1376        /// <para>
1377        /// Once routing is enabled, every request matching the url pattern will stall unless
1378        /// it's continued, fulfilled or aborted.
1379        /// </para>
1380        /// <para>An example of a naive handler that aborts all image requests:</para>
1381        /// <code>
1382        /// var page = await browser.NewPageAsync();<br/>
1383        /// await page.RouteAsync("**/*.{png,jpg,jpeg}", async r =&gt; await r.AbortAsync());<br/>
1384        /// await page.GotoAsync("https://www.microsoft.com");
1385        /// </code>
1386        /// <para>or the same snippet using a regex pattern instead:</para>
1387        /// <code>
1388        /// var page = await browser.NewPageAsync();<br/>
1389        /// await page.RouteAsync(new Regex("(\\.png$)|(\\.jpg$)"), async r =&gt; await r.AbortAsync());<br/>
1390        /// await page.GotoAsync("https://www.microsoft.com");
1391        /// </code>
1392        /// <para>
1393        /// It is possible to examine the request to decide the route action. For example, mocking
1394        /// all requests that contain some post data, and leaving all other requests as is:
1395        /// </para>
1396        /// <code>
1397        /// await page.RouteAsync("/api/**", async r =&gt;<br/>
1398        /// {<br/>
1399        ///   if (r.Request.PostData.Contains("my-string"))<br/>
1400        ///       await r.FulfillAsync(new RouteFulfillOptions { Body = "mocked-data" });<br/>
1401        ///   else<br/>
1402        ///       await r.ContinueAsync();<br/>
1403        /// });
1404        /// </code>
1405        /// <para>
1406        /// Page routes take precedence over browser context routes (set up with <see cref="IBrowserContext.RouteAsync"/>)
1407        /// when request matches both handlers.
1408        /// </para>
1409        /// <para>To remove a route with its handler you can use <see cref="IPage.UnrouteAsync"/>.</para>
1410        /// </summary>
1411        /// <remarks>
1412        /// <para>The handler will only be called for the first url if the response is a redirect.</para>
1413        /// <para>
1414        /// <see cref="IPage.RouteAsync"/> will not intercept requests intercepted by Service
1415        /// Worker. See <a href="https://github.com/microsoft/playwright/issues/1090">this</a>
1416        /// issue. We recommend disabling Service Workers when using request interception. Via
1417        /// <c>await context.addInitScript(() =&gt; delete window.navigator.serviceWorker);</c>
1418        /// </para>
1419        /// <para>Enabling routing disables http cache.</para>
1420        /// </remarks>
1421        /// <param name="url">
1422        /// A glob pattern, regex pattern or predicate receiving <see cref="URL"/> to match
1423        /// while routing. When a <paramref name="baseURL"/> via the context options was provided
1424        /// and the passed URL is a path, it gets merged via the <a href="https://developer.mozilla.org/en-US/docs/Web/API/URL/URL"><c>new
1425        /// URL()</c></a> constructor.
1426        /// </param>
1427        /// <param name="handler">handler function to route the request.</param>
1428        /// <param name="options">Call options</param>
1429        Task RouteAsync(string url, Action<IRoute> handler, PageRouteOptions? options = default);
1430
1431        /// <summary>
1432        /// <para>Routing provides the capability to modify network requests that are made by a page.</para>
1433        /// <para>
1434        /// Once routing is enabled, every request matching the url pattern will stall unless
1435        /// it's continued, fulfilled or aborted.
1436        /// </para>
1437        /// <para>An example of a naive handler that aborts all image requests:</para>
1438        /// <code>
1439        /// var page = await browser.NewPageAsync();<br/>
1440        /// await page.RouteAsync("**/*.{png,jpg,jpeg}", async r =&gt; await r.AbortAsync());<br/>
1441        /// await page.GotoAsync("https://www.microsoft.com");
1442        /// </code>
1443        /// <para>or the same snippet using a regex pattern instead:</para>
1444        /// <code>
1445        /// var page = await browser.NewPageAsync();<br/>
1446        /// await page.RouteAsync(new Regex("(\\.png$)|(\\.jpg$)"), async r =&gt; await r.AbortAsync());<br/>
1447        /// await page.GotoAsync("https://www.microsoft.com");
1448        /// </code>
1449        /// <para>
1450        /// It is possible to examine the request to decide the route action. For example, mocking
1451        /// all requests that contain some post data, and leaving all other requests as is:
1452        /// </para>
1453        /// <code>
1454        /// await page.RouteAsync("/api/**", async r =&gt;<br/>
1455        /// {<br/>
1456        ///   if (r.Request.PostData.Contains("my-string"))<br/>
1457        ///       await r.FulfillAsync(new RouteFulfillOptions { Body = "mocked-data" });<br/>
1458        ///   else<br/>
1459        ///       await r.ContinueAsync();<br/>
1460        /// });
1461        /// </code>
1462        /// <para>
1463        /// Page routes take precedence over browser context routes (set up with <see cref="IBrowserContext.RouteAsync"/>)
1464        /// when request matches both handlers.
1465        /// </para>
1466        /// <para>To remove a route with its handler you can use <see cref="IPage.UnrouteAsync"/>.</para>
1467        /// </summary>
1468        /// <remarks>
1469        /// <para>The handler will only be called for the first url if the response is a redirect.</para>
1470        /// <para>
1471        /// <see cref="IPage.RouteAsync"/> will not intercept requests intercepted by Service
1472        /// Worker. See <a href="https://github.com/microsoft/playwright/issues/1090">this</a>
1473        /// issue. We recommend disabling Service Workers when using request interception. Via
1474        /// <c>await context.addInitScript(() =&gt; delete window.navigator.serviceWorker);</c>
1475        /// </para>
1476        /// <para>Enabling routing disables http cache.</para>
1477        /// </remarks>
1478        /// <param name="url">
1479        /// A glob pattern, regex pattern or predicate receiving <see cref="URL"/> to match
1480        /// while routing. When a <paramref name="baseURL"/> via the context options was provided
1481        /// and the passed URL is a path, it gets merged via the <a href="https://developer.mozilla.org/en-US/docs/Web/API/URL/URL"><c>new
1482        /// URL()</c></a> constructor.
1483        /// </param>
1484        /// <param name="handler">handler function to route the request.</param>
1485        /// <param name="options">Call options</param>
1486        Task RouteAsync(Regex url, Action<IRoute> handler, PageRouteOptions? options = default);
1487
1488        /// <summary>
1489        /// <para>Routing provides the capability to modify network requests that are made by a page.</para>
1490        /// <para>
1491        /// Once routing is enabled, every request matching the url pattern will stall unless
1492        /// it's continued, fulfilled or aborted.
1493        /// </para>
1494        /// <para>An example of a naive handler that aborts all image requests:</para>
1495        /// <code>
1496        /// var page = await browser.NewPageAsync();<br/>
1497        /// await page.RouteAsync("**/*.{png,jpg,jpeg}", async r =&gt; await r.AbortAsync());<br/>
1498        /// await page.GotoAsync("https://www.microsoft.com");
1499        /// </code>
1500        /// <para>or the same snippet using a regex pattern instead:</para>
1501        /// <code>
1502        /// var page = await browser.NewPageAsync();<br/>
1503        /// await page.RouteAsync(new Regex("(\\.png$)|(\\.jpg$)"), async r =&gt; await r.AbortAsync());<br/>
1504        /// await page.GotoAsync("https://www.microsoft.com");
1505        /// </code>
1506        /// <para>
1507        /// It is possible to examine the request to decide the route action. For example, mocking
1508        /// all requests that contain some post data, and leaving all other requests as is:
1509        /// </para>
1510        /// <code>
1511        /// await page.RouteAsync("/api/**", async r =&gt;<br/>
1512        /// {<br/>
1513        ///   if (r.Request.PostData.Contains("my-string"))<br/>
1514        ///       await r.FulfillAsync(new RouteFulfillOptions { Body = "mocked-data" });<br/>
1515        ///   else<br/>
1516        ///       await r.ContinueAsync();<br/>
1517        /// });
1518        /// </code>
1519        /// <para>
1520        /// Page routes take precedence over browser context routes (set up with <see cref="IBrowserContext.RouteAsync"/>)
1521        /// when request matches both handlers.
1522        /// </para>
1523        /// <para>To remove a route with its handler you can use <see cref="IPage.UnrouteAsync"/>.</para>
1524        /// </summary>
1525        /// <remarks>
1526        /// <para>The handler will only be called for the first url if the response is a redirect.</para>
1527        /// <para>
1528        /// <see cref="IPage.RouteAsync"/> will not intercept requests intercepted by Service
1529        /// Worker. See <a href="https://github.com/microsoft/playwright/issues/1090">this</a>
1530        /// issue. We recommend disabling Service Workers when using request interception. Via
1531        /// <c>await context.addInitScript(() =&gt; delete window.navigator.serviceWorker);</c>
1532        /// </para>
1533        /// <para>Enabling routing disables http cache.</para>
1534        /// </remarks>
1535        /// <param name="url">
1536        /// A glob pattern, regex pattern or predicate receiving <see cref="URL"/> to match
1537        /// while routing. When a <paramref name="baseURL"/> via the context options was provided
1538        /// and the passed URL is a path, it gets merged via the <a href="https://developer.mozilla.org/en-US/docs/Web/API/URL/URL"><c>new
1539        /// URL()</c></a> constructor.
1540        /// </param>
1541        /// <param name="handler">handler function to route the request.</param>
1542        /// <param name="options">Call options</param>
1543        Task RouteAsync(Func<string, bool> url, Action<IRoute> handler, PageRouteOptions? options = default);
1544
1545        /// <summary><para>Returns the buffer with the captured screenshot.</para></summary>
1546        /// <param name="options">Call options</param>
1547        Task<byte[]> ScreenshotAsync(PageScreenshotOptions? options = default);
1548
1549        /// <summary>
1550        /// <para>
1551        /// This method waits for an element matching <paramref name="selector"/>, waits for
1552        /// <a href="https://playwright.dev/dotnet/docs/actionability">actionability</a> checks,
1553        /// waits until all specified options are present in the <c>&lt;select&gt;</c> element
1554        /// and selects these options.
1555        /// </para>
1556        /// <para>
1557        /// If the target element is not a <c>&lt;select&gt;</c> element, this method throws
1558        /// an error. However, if the element is inside the <c>&lt;label&gt;</c> element that
1559        /// has an associated <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/control">control</a>,
1560        /// the control will be used instead.
1561        /// </para>
1562        /// <para>Returns the array of option values that have been successfully selected.</para>
1563        /// <para>
1564        /// Triggers a <c>change</c> and <c>input</c> event once all the provided options have
1565        /// been selected.
1566        /// </para>
1567        /// <code>
1568        /// // single selection matching the value<br/>
1569        /// await page.SelectOptionAsync("select#colors", new[] { "blue" });<br/>
1570        /// // single selection matching both the value and the label<br/>
1571        /// await page.SelectOptionAsync("select#colors", new[] { new SelectOptionValue() { Label = "blue" } });<br/>
1572        /// // multiple<br/>
1573        /// await page.SelectOptionAsync("select#colors", new[] { "red", "green", "blue" });
1574        /// </code>
1575        /// <para>Shortcut for main frame's <see cref="IFrame.SelectOptionAsync"/>.</para>
1576        /// </summary>
1577        /// <param name="selector">
1578        /// A selector to search for an element. If there are multiple elements satisfying the
1579        /// selector, the first will be used. See <a href="https://playwright.dev/dotnet/docs/selectors">working
1580        /// with selectors</a> for more details.
1581        /// </param>
1582        /// <param name="values">
1583        /// Options to select. If the <c>&lt;select&gt;</c> has the <c>multiple</c> attribute,
1584        /// all matching options are selected, otherwise only the first option matching one
1585        /// of the passed options is selected. String values are equivalent to <c>{value:'string'}</c>.
1586        /// Option is considered matching if all specified properties match.
1587        /// </param>
1588        /// <param name="options">Call options</param>
1589        Task<IReadOnlyList<string>> SelectOptionAsync(string selector, string values, PageSelectOptionOptions? options = default);
1590
1591        /// <summary>
1592        /// <para>
1593        /// This method waits for an element matching <paramref name="selector"/>, waits for
1594        /// <a href="https://playwright.dev/dotnet/docs/actionability">actionability</a> checks,
1595        /// waits until all specified options are present in the <c>&lt;select&gt;</c> element
1596        /// and selects these options.
1597        /// </para>
1598        /// <para>
1599        /// If the target element is not a <c>&lt;select&gt;</c> element, this method throws
1600        /// an error. However, if the element is inside the <c>&lt;label&gt;</c> element that
1601        /// has an associated <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/control">control</a>,
1602        /// the control will be used instead.
1603        /// </para>
1604        /// <para>Returns the array of option values that have been successfully selected.</para>
1605        /// <para>
1606        /// Triggers a <c>change</c> and <c>input</c> event once all the provided options have
1607        /// been selected.
1608        /// </para>
1609        /// <code>
1610        /// // single selection matching the value<br/>
1611        /// await page.SelectOptionAsync("select#colors", new[] { "blue" });<br/>
1612        /// // single selection matching both the value and the label<br/>
1613        /// await page.SelectOptionAsync("select#colors", new[] { new SelectOptionValue() { Label = "blue" } });<br/>
1614        /// // multiple<br/>
1615        /// await page.SelectOptionAsync("select#colors", new[] { "red", "green", "blue" });
1616        /// </code>
1617        /// <para>Shortcut for main frame's <see cref="IFrame.SelectOptionAsync"/>.</para>
1618        /// </summary>
1619        /// <param name="selector">
1620        /// A selector to search for an element. If there are multiple elements satisfying the
1621        /// selector, the first will be used. See <a href="https://playwright.dev/dotnet/docs/selectors">working
1622        /// with selectors</a> for more details.
1623        /// </param>
1624        /// <param name="values">
1625        /// Options to select. If the <c>&lt;select&gt;</c> has the <c>multiple</c> attribute,
1626        /// all matching options are selected, otherwise only the first option matching one
1627        /// of the passed options is selected. String values are equivalent to <c>{value:'string'}</c>.
1628        /// Option is considered matching if all specified properties match.
1629        /// </param>
1630        /// <param name="options">Call options</param>
1631        Task<IReadOnlyList<string>> SelectOptionAsync(string selector, IElementHandle values, PageSelectOptionOptions? options = default);
1632
1633        /// <summary>
1634        /// <para>
1635        /// This method waits for an element matching <paramref name="selector"/>, waits for
1636        /// <a href="https://playwright.dev/dotnet/docs/actionability">actionability</a> checks,
1637        /// waits until all specified options are present in the <c>&lt;select&gt;</c> element
1638        /// and selects these options.
1639        /// </para>
1640        /// <para>
1641        /// If the target element is not a <c>&lt;select&gt;</c> element, this method throws
1642        /// an error. However, if the element is inside the <c>&lt;label&gt;</c> element that
1643        /// has an associated <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/control">control</a>,
1644        /// the control will be used instead.
1645        /// </para>
1646        /// <para>Returns the array of option values that have been successfully selected.</para>
1647        /// <para>
1648        /// Triggers a <c>change</c> and <c>input</c> event once all the provided options have
1649        /// been selected.
1650        /// </para>
1651        /// <code>
1652        /// // single selection matching the value<br/>
1653        /// await page.SelectOptionAsync("select#colors", new[] { "blue" });<br/>
1654        /// // single selection matching both the value and the label<br/>
1655        /// await page.SelectOptionAsync("select#colors", new[] { new SelectOptionValue() { Label = "blue" } });<br/>
1656        /// // multiple<br/>
1657        /// await page.SelectOptionAsync("select#colors", new[] { "red", "green", "blue" });
1658        /// </code>
1659        /// <para>Shortcut for main frame's <see cref="IFrame.SelectOptionAsync"/>.</para>
1660        /// </summary>
1661        /// <param name="selector">
1662        /// A selector to search for an element. If there are multiple elements satisfying the
1663        /// selector, the first will be used. See <a href="https://playwright.dev/dotnet/docs/selectors">working
1664        /// with selectors</a> for more details.
1665        /// </param>
1666        /// <param name="values">
1667        /// Options to select. If the <c>&lt;select&gt;</c> has the <c>multiple</c> attribute,
1668        /// all matching options are selected, otherwise only the first option matching one
1669        /// of the passed options is selected. String values are equivalent to <c>{value:'string'}</c>.
1670        /// Option is considered matching if all specified properties match.
1671        /// </param>
1672        /// <param name="options">Call options</param>
1673        Task<IReadOnlyList<string>> SelectOptionAsync(string selector, IEnumerable<string> values, PageSelectOptionOptions? options = default);
1674
1675        /// <summary>
1676        /// <para>
1677        /// This method waits for an element matching <paramref name="selector"/>, waits for
1678        /// <a href="https://playwright.dev/dotnet/docs/actionability">actionability</a> checks,
1679        /// waits until all specified options are present in the <c>&lt;select&gt;</c> element
1680        /// and selects these options.
1681        /// </para>
1682        /// <para>
1683        /// If the target element is not a <c>&lt;select&gt;</c> element, this method throws
1684        /// an error. However, if the element is inside the <c>&lt;label&gt;</c> element that
1685        /// has an associated <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/control">control</a>,
1686        /// the control will be used instead.
1687        /// </para>
1688        /// <para>Returns the array of option values that have been successfully selected.</para>
1689        /// <para>
1690        /// Triggers a <c>change</c> and <c>input</c> event once all the provided options have
1691        /// been selected.
1692        /// </para>
1693        /// <code>
1694        /// // single selection matching the value<br/>
1695        /// await page.SelectOptionAsync("select#colors", new[] { "blue" });<br/>
1696        /// // single selection matching both the value and the label<br/>
1697        /// await page.SelectOptionAsync("select#colors", new[] { new SelectOptionValue() { Label = "blue" } });<br/>
1698        /// // multiple<br/>
1699        /// await page.SelectOptionAsync("select#colors", new[] { "red", "green", "blue" });
1700        /// </code>
1701        /// <para>Shortcut for main frame's <see cref="IFrame.SelectOptionAsync"/>.</para>
1702        /// </summary>
1703        /// <param name="selector">
1704        /// A selector to search for an element. If there are multiple elements satisfying the
1705        /// selector, the first will be used. See <a href="https://playwright.dev/dotnet/docs/selectors">working
1706        /// with selectors</a> for more details.
1707        /// </param>
1708        /// <param name="values">
1709        /// Options to select. If the <c>&lt;select&gt;</c> has the <c>multiple</c> attribute,
1710        /// all matching options are selected, otherwise only the first option matching one
1711        /// of the passed options is selected. String values are equivalent to <c>{value:'string'}</c>.
1712        /// Option is considered matching if all specified properties match.
1713        /// </param>
1714        /// <param name="options">Call options</param>
1715        Task<IReadOnlyList<string>> SelectOptionAsync(string selector, SelectOptionValue values, PageSelectOptionOptions? options = default);
1716
1717        /// <summary>
1718        /// <para>
1719        /// This method waits for an element matching <paramref name="selector"/>, waits for
1720        /// <a href="https://playwright.dev/dotnet/docs/actionability">actionability</a> checks,
1721        /// waits until all specified options are present in the <c>&lt;select&gt;</c> element
1722        /// and selects these options.
1723