How to use WaitForURLAsync method of Microsoft.Playwright.Core.Frame class

Best Playwright-dotnet code snippet using Microsoft.Playwright.Core.Frame.WaitForURLAsync

Run Playwright-dotnet automation tests on LambdaTest cloud grid

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

PageWaitForUrlTests.cs

Source: PageWaitForUrlTests.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.Linq;
27using System.Text.RegularExpressions;
28using System.Threading.Tasks;
29using Microsoft.AspNetCore.Http;
30using Microsoft.Playwright.NUnit;
31using NUnit.Framework;
32
33namespace Microsoft.Playwright.Tests
34{
35    public class PageWaitForUrlTests : PageTestEx
36    {
37        [PlaywrightTest("page-wait-for-url.spec.ts", "should work")]
38        public async Task ShouldWork()
39        {
40            await Page.GotoAsync(Server.EmptyPage);
41            await Page.EvaluateAsync("url => window.location.href = url", Server.Prefix + "/grid.html");
42            await Page.WaitForURLAsync("**/grid.html");
43        }
44
45        [PlaywrightTest("page-wait-for-url.spec.ts", "should respect timeout")]
46        public async Task ShouldRespectTimeout()
47        {
48            var task = Page.WaitForURLAsync("**/frame.html", new() { Timeout = 2500 });
49            await Page.GotoAsync(Server.EmptyPage);
50            var exception = await PlaywrightAssert.ThrowsAsync<TimeoutException>(() => task);
51            StringAssert.Contains("Timeout 2500ms exceeded.", exception.Message);
52        }
53
54        [PlaywrightTest("page-wait-for-url.spec.ts", "should work with both domcontentloaded and load")]
55        public async Task UrlShouldWorkWithBothDomcontentloadedAndLoad()
56        {
57            var responseTask = new TaskCompletionSource<bool>();
58            Server.SetRoute("/one-style.css", async (ctx) =>
59            {
60                if (await responseTask.Task)
61                {
62                    await ctx.Response.WriteAsync("Some css");
63                }
64            });
65
66            var waitForRequestTask = Server.WaitForRequest("/one-style.css");
67            var navigationTask = Page.GotoAsync(Server.Prefix + "/one-style.html");
68            var domContentLoadedTask = Page.WaitForURLAsync("**/one-style.html", new() { WaitUntil = WaitUntilState.DOMContentLoaded });
69            var bothFiredTask = Task.WhenAll(
70                Page.WaitForURLAsync("**/one-style.html", new() { WaitUntil = WaitUntilState.Load }),
71                domContentLoadedTask);
72
73            await waitForRequestTask;
74            await domContentLoadedTask;
75            Assert.False(bothFiredTask.IsCompleted);
76            responseTask.TrySetResult(true);
77            await bothFiredTask;
78            await navigationTask;
79        }
80
81        [PlaywrightTest("page-wait-for-url.spec.ts", "should work with clicking on anchor links")]
82        public async Task ShouldWorkWithClickingOnAnchorLinks()
83        {
84            await Page.GotoAsync(Server.EmptyPage);
85            await Page.SetContentAsync("<a href='#foobar'>foobar</a>");
86            await Page.ClickAsync("a");
87            await Page.WaitForURLAsync("**/*#foobar");
88        }
89
90        [PlaywrightTest("page-wait-for-url.spec.ts", "should work with history.pushState()")]
91        public async Task ShouldWorkWithHistoryPushState()
92        {
93            await Page.GotoAsync(Server.EmptyPage);
94            await Page.SetContentAsync(@"
95                <a onclick='javascript:replaceState()'>SPA</a>
96                <script>
97                  function replaceState() { history.replaceState({}, '', '/replaced.html') }
98                </script>
99            ");
100            await Page.ClickAsync("a");
101            await Page.WaitForURLAsync("**/replaced.html");
102            Assert.AreEqual(Server.Prefix + "/replaced.html", Page.Url);
103        }
104
105        [PlaywrightTest("page-wait-for-url.spec.ts", "should work with DOM history.back()/history.forward()")]
106        public async Task ShouldWorkWithDOMHistoryBackHistoryForward()
107        {
108            await Page.GotoAsync(Server.EmptyPage);
109            await Page.SetContentAsync(@"
110                <a id=back onclick='javascript:goBack()'>back</a>
111                <a id=forward onclick='javascript:goForward()'>forward</a>
112                <script>
113                  function goBack() { history.back(); }
114                  function goForward() { history.forward(); }
115                  history.pushState({}, '', '/first.html');
116                  history.pushState({}, '', '/second.html');
117                </script>
118            ");
119            Assert.AreEqual(Server.Prefix + "/second.html", Page.Url);
120
121            await Task.WhenAll(Page.WaitForURLAsync("**/first.html"), Page.ClickAsync("a#back"));
122            Assert.AreEqual(Server.Prefix + "/first.html", Page.Url);
123
124            await Task.WhenAll(Page.WaitForURLAsync("**/second.html"), Page.ClickAsync("a#forward"));
125            Assert.AreEqual(Server.Prefix + "/second.html", Page.Url);
126        }
127
128        [PlaywrightTest("page-wait-for-url.spec.ts", "should work with url match for same document navigations")]
129        public async Task ShouldWorkWithUrlMatchForSameDocumentNavigations()
130        {
131            await Page.GotoAsync(Server.EmptyPage);
132            var waitPromise = Page.WaitForURLAsync(new Regex("third\\.html"));
133            Assert.False(waitPromise.IsCompleted);
134
135            await Page.EvaluateAsync(@"() => {
136                history.pushState({}, '', '/first.html');
137            }");
138            Assert.False(waitPromise.IsCompleted);
139
140            await Page.EvaluateAsync(@"() => {
141                history.pushState({}, '', '/second.html');
142            }");
143            Assert.False(waitPromise.IsCompleted);
144
145            await Page.EvaluateAsync(@"() => {
146                history.pushState({}, '', '/third.html');
147            }");
148            await waitPromise;
149        }
150
151        [PlaywrightTest("page-wait-for-url.spec.ts", "should work on frame")]
152        public async Task ShouldWorkOnFrame()
153        {
154            await Page.GotoAsync(Server.Prefix + "/frames/one-frame.html");
155            var frame = Page.Frames.ElementAt(1);
156
157            await TaskUtils.WhenAll(
158                frame.WaitForURLAsync("**/grid.html"),
159                frame.EvaluateAsync("url => window.location.href = url", Server.Prefix + "/grid.html"));
160            ;
161        }
162    }
163}
164
Full Screen

Frame.cs

Source: Frame.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.IO;
29using System.Linq;
30using System.Text.Json;
31using System.Text.RegularExpressions;
32using System.Threading.Tasks;
33using Microsoft.Playwright.Helpers;
34using Microsoft.Playwright.Transport;
35using Microsoft.Playwright.Transport.Channels;
36using Microsoft.Playwright.Transport.Protocol;
37
38namespace Microsoft.Playwright.Core
39{
40    internal class Frame : ChannelOwnerBase, IChannelOwner<Frame>, IFrame
41    {
42        internal readonly FrameChannel _channel;
43        private readonly List<WaitUntilState> _loadStates = new();
44
45        internal Frame(IChannelOwner parent, string guid, FrameInitializer initializer) : base(parent, guid)
46        {
47            _channel = new(guid, parent.Connection, this);
48            Url = initializer.Url;
49            Name = initializer.Name;
50            ParentFrame = initializer.ParentFrame;
51            _loadStates = initializer.LoadStates;
52
53            _channel.LoadState += (_, e) =>
54            {
55                lock (_loadStates)
56                {
57                    if (e.Add.HasValue)
58                    {
59                        _loadStates.Add(e.Add.Value);
60                        LoadState?.Invoke(this, e.Add.Value);
61                    }
62
63                    if (e.Remove.HasValue)
64                    {
65                        _loadStates.Remove(e.Remove.Value);
66                    }
67                }
68            };
69
70            _channel.Navigated += (_, e) =>
71            {
72                Url = e.Url;
73                Name = e.Name;
74                Navigated?.Invoke(this, e);
75
76                if (string.IsNullOrEmpty(e.Error))
77                {
78                    ((Page)Page)?.OnFrameNavigated(this);
79                }
80            };
81        }
82
83        /// <summary>
84        /// Raised when a navigation is received.
85        /// </summary>
86        public event EventHandler<FrameNavigatedEventArgs> Navigated;
87
88        /// <summary>
89        /// Raised when a new LoadState was added.
90        /// </summary>
91        public event EventHandler<WaitUntilState> LoadState;
92
93        ChannelBase IChannelOwner.Channel => _channel;
94
95        IChannel<Frame> IChannelOwner<Frame>.Channel => _channel;
96
97        public IReadOnlyList<IFrame> ChildFrames => ChildFramesList;
98
99        public string Name { get; internal set; }
100
101        public string Url { get; internal set; }
102
103        IFrame IFrame.ParentFrame => ParentFrame;
104
105        public Frame ParentFrame { get; }
106
107        public IPage Page { get; internal set; }
108
109        public bool IsDetached { get; internal set; }
110
111        internal List<Frame> ChildFramesList { get; } = new();
112
113        public async Task<IElementHandle> FrameElementAsync()
114            => (await _channel.FrameElementAsync().ConfigureAwait(false)).Object;
115
116        public IFrameLocator FrameLocator(string selector)
117            => new FrameLocator(this, selector);
118
119        public Task<string> TitleAsync() => _channel.TitleAsync();
120
121        public Task WaitForTimeoutAsync(float timeout)
122            => _channel.WaitForTimeoutAsync(timeout);
123
124        public Task<IReadOnlyList<string>> SelectOptionAsync(string selector, string values, FrameSelectOptionOptions options = default)
125            => SelectOptionAsync(selector, new[] { values }, options);
126
127        public Task<IReadOnlyList<string>> SelectOptionAsync(string selector, IEnumerable<string> values, FrameSelectOptionOptions options = default)
128            => SelectOptionAsync(selector, values.Select(x => new SelectOptionValue() { Value = x }), options);
129
130        public Task<IReadOnlyList<string>> SelectOptionAsync(string selector, IElementHandle values, FrameSelectOptionOptions options = default)
131            => SelectOptionAsync(selector, new[] { values }, options);
132
133        public async Task<IReadOnlyList<string>> SelectOptionAsync(string selector, IEnumerable<IElementHandle> values, FrameSelectOptionOptions options = default)
134            => (await _channel.SelectOptionAsync(
135                selector,
136                values.Select(x => x as ElementHandle),
137                noWaitAfter: options?.NoWaitAfter,
138                strict: options?.Strict,
139                force: options?.Force,
140                timeout: options?.Timeout).ConfigureAwait(false)).ToList().AsReadOnly();
141
142        public Task<IReadOnlyList<string>> SelectOptionAsync(string selector, SelectOptionValue values, FrameSelectOptionOptions options = default)
143            => SelectOptionAsync(selector, new[] { values }, options);
144
145        public async Task<IReadOnlyList<string>> SelectOptionAsync(string selector, IEnumerable<SelectOptionValue> values, FrameSelectOptionOptions options = default)
146            => (await _channel.SelectOptionAsync(
147                selector,
148                values,
149                noWaitAfter: options?.NoWaitAfter,
150                strict: options?.Strict,
151                force: options?.Force,
152                timeout: options?.Timeout).ConfigureAwait(false)).ToList().AsReadOnly();
153
154        public async Task WaitForLoadStateAsync(LoadState? state = default, FrameWaitForLoadStateOptions options = default)
155        {
156            Task<WaitUntilState> task;
157            Waiter waiter = null;
158            WaitUntilState loadState = Microsoft.Playwright.WaitUntilState.Load;
159            switch (state)
160            {
161                case Microsoft.Playwright.LoadState.Load:
162                    loadState = Microsoft.Playwright.WaitUntilState.Load;
163                    break;
164                case Microsoft.Playwright.LoadState.DOMContentLoaded:
165                    loadState = Microsoft.Playwright.WaitUntilState.DOMContentLoaded;
166                    break;
167                case Microsoft.Playwright.LoadState.NetworkIdle:
168                    loadState = Microsoft.Playwright.WaitUntilState.NetworkIdle;
169                    break;
170            }
171            try
172            {
173                lock (_loadStates)
174                {
175                    if (_loadStates.Contains(loadState))
176                    {
177                        return;
178                    }
179
180                    waiter = SetupNavigationWaiter("frame.WaitForLoadStateAsync", options?.Timeout);
181                    task = waiter.WaitForEventAsync<WaitUntilState>(this, "LoadState", s =>
182                    {
183                        waiter.Log($"  \"{s}\" event fired");
184                        return s == loadState;
185                    });
186                }
187
188                await task.ConfigureAwait(false);
189            }
190            finally
191            {
192                waiter?.Dispose();
193            }
194        }
195
196        public async Task<IResponse> WaitForNavigationAsync(FrameWaitForNavigationOptions options = default)
197        {
198            WaitUntilState waitUntil2 = options?.WaitUntil ?? WaitUntilState.Load;
199            using var waiter = SetupNavigationWaiter("frame.WaitForNavigationAsync", options?.Timeout);
200            string toUrl = !string.IsNullOrEmpty(options?.UrlString) ? $" to \"{options?.UrlString}\"" : string.Empty;
201
202            waiter.Log($"waiting for navigation{toUrl} until \"{waitUntil2}\"");
203
204            var navigatedEventTask = waiter.WaitForEventAsync<FrameNavigatedEventArgs>(
205                this,
206                "Navigated",
207                e =>
208                {
209                    // Any failed navigation results in a rejection.
210                    if (e.Error != null)
211                    {
212                        return true;
213                    }
214
215                    waiter.Log($"  navigated to \"{e.Url}\"");
216                    return UrlMatches(e.Url, options?.UrlString, options?.UrlRegex, options?.UrlFunc);
217                });
218
219            var navigatedEvent = await navigatedEventTask.ConfigureAwait(false);
220
221            if (navigatedEvent.Error != null)
222            {
223                var ex = new PlaywrightException(navigatedEvent.Error);
224                await waiter.WaitForPromiseAsync(Task.FromException<object>(ex)).ConfigureAwait(false);
225            }
226
227            if (!_loadStates.Select(s => s.ToValueString()).Contains(waitUntil2.ToValueString()))
228            {
229                await waiter.WaitForEventAsync<WaitUntilState>(
230                    this,
231                    "LoadState",
232                    e =>
233                    {
234                        waiter.Log($"  \"{e}\" event fired");
235                        return e.ToValueString() == waitUntil2.ToValueString();
236                    }).ConfigureAwait(false);
237            }
238
239            var request = navigatedEvent.NewDocument?.Request?.Object;
240            var response = request != null
241                ? await waiter.WaitForPromiseAsync(request.FinalRequest.ResponseAsync()).ConfigureAwait(false)
242                : null;
243
244            return response;
245        }
246
247        public async Task<IResponse> RunAndWaitForNavigationAsync(Func<Task> action, FrameRunAndWaitForNavigationOptions options = default)
248        {
249            var result = WaitForNavigationAsync(new()
250            {
251                UrlString = options?.UrlString,
252                UrlRegex = options?.UrlRegex,
253                UrlFunc = options?.UrlFunc,
254                WaitUntil = options?.WaitUntil,
255                Timeout = options?.Timeout,
256            });
257            if (action != null)
258            {
259                await WrapApiBoundaryAsync(() => Task.WhenAll(result, action())).ConfigureAwait(false);
260            }
261
262            return await result.ConfigureAwait(false);
263        }
264
265        public Task TapAsync(string selector, FrameTapOptions options = default)
266            => _channel.TapAsync(
267                selector,
268                modifiers: options?.Modifiers,
269                position: options?.Position,
270                timeout: options?.Timeout,
271                force: options?.Force,
272                noWaitAfter: options?.NoWaitAfter,
273                trial: options?.Trial,
274                strict: options?.Strict);
275
276        internal Task<int> QueryCountAsync(string selector)
277            => _channel.QueryCountAsync(selector);
278
279        public Task<string> ContentAsync() => _channel.ContentAsync();
280
281        public Task FocusAsync(string selector, FrameFocusOptions options = default)
282            => _channel.FocusAsync(selector, options?.Timeout, options?.Strict);
283
284        public Task TypeAsync(string selector, string text, FrameTypeOptions options = default)
285            => _channel.TypeAsync(
286                selector,
287                text,
288                delay: options?.Delay,
289                timeout: options?.Timeout,
290                noWaitAfter: options?.NoWaitAfter,
291                strict: options?.Strict);
292
293        public Task<string> GetAttributeAsync(string selector, string name, FrameGetAttributeOptions options = default)
294            => _channel.GetAttributeAsync(selector, name, options?.Timeout, options?.Strict);
295
296        public Task<string> InnerHTMLAsync(string selector, FrameInnerHTMLOptions options = default)
297            => _channel.InnerHTMLAsync(selector, options?.Timeout, options?.Strict);
298
299        public Task<string> InnerTextAsync(string selector, FrameInnerTextOptions options = default)
300            => _channel.InnerTextAsync(selector, options?.Timeout, options?.Strict);
301
302        public Task<string> TextContentAsync(string selector, FrameTextContentOptions options = default)
303            => _channel.TextContentAsync(selector, options?.Timeout, options?.Strict);
304
305        public Task HoverAsync(string selector, FrameHoverOptions options = default)
306            => _channel.HoverAsync(
307                selector,
308                position: options?.Position,
309                modifiers: options?.Modifiers,
310                force: options?.Force,
311                timeout: options?.Timeout,
312                trial: options?.Trial,
313                strict: options?.Strict);
314
315        public Task PressAsync(string selector, string key, FramePressOptions options = default)
316            => _channel.PressAsync(
317                selector,
318                key,
319                delay: options?.Delay,
320                timeout: options?.Timeout,
321                noWaitAfter: options?.NoWaitAfter,
322                strict: options?.Strict);
323
324        public Task DispatchEventAsync(string selector, string type, object eventInit = default, FrameDispatchEventOptions options = default)
325            => _channel.DispatchEventAsync(
326                    selector,
327                    type,
328                    ScriptsHelper.SerializedArgument(eventInit),
329                    options?.Timeout,
330                    options?.Strict);
331
332        public Task FillAsync(string selector, string value, FrameFillOptions options = default)
333            => _channel.FillAsync(selector, value, force: options?.Force, timeout: options?.Timeout, noWaitAfter: options?.NoWaitAfter, options?.Strict);
334
335        public async Task<IElementHandle> AddScriptTagAsync(FrameAddScriptTagOptions options = default)
336        {
337            var content = options?.Content;
338            if (!string.IsNullOrEmpty(options?.Path))
339            {
340                content = File.ReadAllText(options.Path);
341                content += "//# sourceURL=" + options.Path.Replace("\n", string.Empty);
342            }
343
344            return (await _channel.AddScriptTagAsync(options?.Url, options?.Path, content, options?.Type).ConfigureAwait(false)).Object;
345        }
346
347        public async Task<IElementHandle> AddStyleTagAsync(FrameAddStyleTagOptions options = default)
348        {
349            var content = options?.Content;
350            if (!string.IsNullOrEmpty(options?.Path))
351            {
352                content = File.ReadAllText(options.Path);
353                content += "//# sourceURL=" + options.Path.Replace("\n", string.Empty);
354            }
355
356            return (await _channel.AddStyleTagAsync(options?.Url, options?.Path, content).ConfigureAwait(false)).Object;
357        }
358
359        public Task SetInputFilesAsync(string selector, string files, FrameSetInputFilesOptions options = default)
360            => SetInputFilesAsync(selector, new[] { files }, options);
361
362        public async Task SetInputFilesAsync(string selector, IEnumerable<string> files, FrameSetInputFilesOptions options = default)
363        {
364            var converted = await SetInputFilesHelpers.ConvertInputFilesAsync(files, (BrowserContext)Page.Context).ConfigureAwait(false);
365            if (converted.Files != null)
366            {
367                await _channel.SetInputFilesAsync(selector, converted.Files, options?.NoWaitAfter, options?.Timeout, options?.Strict).ConfigureAwait(false);
368            }
369            else
370            {
371                await _channel.SetInputFilePathsAsync(selector, converted?.LocalPaths, converted?.Streams, options?.NoWaitAfter, options?.Timeout, options?.Strict).ConfigureAwait(false);
372            }
373        }
374
375        public Task SetInputFilesAsync(string selector, FilePayload files, FrameSetInputFilesOptions options = default)
376            => SetInputFilesAsync(selector, new[] { files }, options);
377
378        public async Task SetInputFilesAsync(string selector, IEnumerable<FilePayload> files, FrameSetInputFilesOptions options = default)
379        {
380            var converted = SetInputFilesHelpers.ConvertInputFiles(files);
381            await _channel.SetInputFilesAsync(selector, converted.Files, noWaitAfter: options?.NoWaitAfter, timeout: options?.Timeout, options?.Strict).ConfigureAwait(false);
382        }
383
384        public Task ClickAsync(string selector, FrameClickOptions options = default)
385            => _channel.ClickAsync(
386                selector,
387                delay: options?.Delay,
388                button: options?.Button,
389                clickCount: options?.ClickCount,
390                modifiers: options?.Modifiers,
391                position: options?.Position,
392                timeout: options?.Timeout,
393                force: options?.Force,
394                noWaitAfter: options?.NoWaitAfter,
395                trial: options?.Trial,
396                strict: options?.Strict);
397
398        public Task DblClickAsync(string selector, FrameDblClickOptions options = default)
399            => _channel.DblClickAsync(
400                selector,
401                delay: options?.Delay,
402                button: options?.Button,
403                position: options?.Position,
404                modifiers: options?.Modifiers,
405                timeout: options?.Timeout,
406                force: options?.Force,
407                noWaitAfter: options?.NoWaitAfter,
408                trial: options?.Trial,
409                strict: options?.Strict);
410
411        public Task CheckAsync(string selector, FrameCheckOptions options = default)
412            => _channel.CheckAsync(
413                selector,
414                position: options?.Position,
415                timeout: options?.Timeout,
416                force: options?.Force,
417                noWaitAfter: options?.NoWaitAfter,
418                trial: options?.Trial,
419                strict: options?.Strict);
420
421        public Task UncheckAsync(string selector, FrameUncheckOptions options = default)
422            => _channel.UncheckAsync(
423                selector,
424                position: options?.Position,
425                timeout: options?.Timeout,
426                force: options?.Force,
427                noWaitAfter: options?.NoWaitAfter,
428                trial: options?.Trial,
429                strict: options?.Strict);
430
431        public Task SetCheckedAsync(string selector, bool checkedState, FrameSetCheckedOptions options = null)
432            => checkedState ?
433            _channel.CheckAsync(
434                selector,
435                position: options?.Position,
436                timeout: options?.Timeout,
437                force: options?.Force,
438                noWaitAfter: options?.NoWaitAfter,
439                trial: options?.Trial,
440                strict: options?.Strict)
441            : _channel.UncheckAsync(
442                selector,
443                position: options?.Position,
444                timeout: options?.Timeout,
445                force: options?.Force,
446                noWaitAfter: options?.NoWaitAfter,
447                trial: options?.Trial,
448                strict: options?.Strict);
449
450        public Task SetContentAsync(string html, FrameSetContentOptions options = default)
451            => _channel.SetContentAsync(html, timeout: options?.Timeout, waitUntil: options?.WaitUntil);
452
453        public Task<string> InputValueAsync(string selector, FrameInputValueOptions options = null)
454            => _channel.InputValueAsync(selector, options?.Timeout, options?.Strict);
455
456        public async Task<IElementHandle> QuerySelectorAsync(string selector)
457            => (await _channel.QuerySelectorAsync(selector).ConfigureAwait(false))?.Object;
458
459        public async Task<IReadOnlyList<IElementHandle>> QuerySelectorAllAsync(string selector)
460            => (await _channel.QuerySelectorAllAsync(selector).ConfigureAwait(false)).Select(c => ((ElementHandleChannel)c).Object).ToList().AsReadOnly();
461
462        public async Task<IJSHandle> WaitForFunctionAsync(string expression, object arg = default, FrameWaitForFunctionOptions options = default)
463             => (await _channel.WaitForFunctionAsync(
464                expression: expression,
465                arg: ScriptsHelper.SerializedArgument(arg),
466                timeout: options?.Timeout,
467                polling: options?.PollingInterval).ConfigureAwait(false)).Object;
468
469        public async Task<IElementHandle> WaitForSelectorAsync(string selector, FrameWaitForSelectorOptions options = default)
470            => (await _channel.WaitForSelectorAsync(
471                selector: selector,
472                state: options?.State,
473                timeout: options?.Timeout,
474                strict: options?.Strict,
475                omitReturnValue: false).ConfigureAwait(false))?.Object;
476
477        public async Task<IElementHandle> LocatorWaitForAsync(string selector, LocatorWaitForOptions options = default)
478            => (await _channel.WaitForSelectorAsync(
479                selector: selector,
480                state: options?.State,
481                timeout: options?.Timeout,
482                strict: true,
483                omitReturnValue: true).ConfigureAwait(false))?.Object;
484
485        public async Task<IJSHandle> EvaluateHandleAsync(string script, object args = null)
486            => (await _channel.EvaluateExpressionHandleAsync(
487                script,
488                arg: ScriptsHelper.SerializedArgument(args)).ConfigureAwait(false))?.Object;
489
490        public async Task<JsonElement?> EvaluateAsync(string script, object arg = null)
491            => ScriptsHelper.ParseEvaluateResult<JsonElement?>(await _channel.EvaluateExpressionAsync(
492                script,
493                arg: ScriptsHelper.SerializedArgument(arg)).ConfigureAwait(false));
494
495        public async Task<T> EvaluateAsync<T>(string script, object arg = null)
496            => ScriptsHelper.ParseEvaluateResult<T>(await _channel.EvaluateExpressionAsync(
497                script,
498                arg: ScriptsHelper.SerializedArgument(arg)).ConfigureAwait(false));
499
500        public async Task<JsonElement?> EvalOnSelectorAsync(string selector, string script, object arg = null)
501            => ScriptsHelper.ParseEvaluateResult<JsonElement?>(await _channel.EvalOnSelectorAsync(
502                selector: selector,
503                script,
504                arg: ScriptsHelper.SerializedArgument(arg),
505                strict: null).ConfigureAwait(false));
506
507        public async Task<T> EvalOnSelectorAsync<T>(string selector, string script, object arg = null)
508            => ScriptsHelper.ParseEvaluateResult<T>(await _channel.EvalOnSelectorAsync(
509                selector: selector,
510                script,
511                arg: ScriptsHelper.SerializedArgument(arg),
512                strict: null).ConfigureAwait(false));
513
514        public async Task<T> EvalOnSelectorAsync<T>(string selector, string expression, object arg = null, FrameEvalOnSelectorOptions options = null)
515            => ScriptsHelper.ParseEvaluateResult<T>(await _channel.EvalOnSelectorAsync(
516                selector: selector,
517                expression,
518                arg: ScriptsHelper.SerializedArgument(arg),
519                strict: options?.Strict).ConfigureAwait(false));
520
521        public async Task<JsonElement?> EvalOnSelectorAllAsync(string selector, string script, object arg = null)
522            => ScriptsHelper.ParseEvaluateResult<JsonElement?>(await _channel.EvalOnSelectorAllAsync(
523                selector: selector,
524                script,
525                arg: ScriptsHelper.SerializedArgument(arg)).ConfigureAwait(false));
526
527        public async Task<T> EvalOnSelectorAllAsync<T>(string selector, string script, object arg = null)
528            => ScriptsHelper.ParseEvaluateResult<T>(await _channel.EvalOnSelectorAllAsync(
529                selector: selector,
530                script,
531                arg: ScriptsHelper.SerializedArgument(arg)).ConfigureAwait(false));
532
533        public ILocator Locator(string selector, FrameLocatorOptions options = null) => new Locator(this, selector, new() { HasTextRegex = options?.HasTextRegex, HasTextString = options?.HasTextString, Has = options?.Has });
534
535        public async Task<IElementHandle> QuerySelectorAsync(string selector, FrameQuerySelectorOptions options = null)
536            => (await _channel.QuerySelectorAsync(selector, options?.Strict).ConfigureAwait(false))?.Object;
537
538        public async Task<IResponse> GotoAsync(string url, FrameGotoOptions options = default)
539            => (await _channel.GotoAsync(
540                url,
541                timeout: options?.Timeout,
542                waitUntil: options?.WaitUntil,
543                referer: options?.Referer).ConfigureAwait(false))?.Object;
544
545        public Task<bool> IsCheckedAsync(string selector, FrameIsCheckedOptions options = default)
546            => _channel.IsCheckedAsync(selector, timeout: options?.Timeout, options?.Strict);
547
548        public Task<bool> IsDisabledAsync(string selector, FrameIsDisabledOptions options = default)
549            => _channel.IsDisabledAsync(selector, timeout: options?.Timeout, options?.Strict);
550
551        public Task<bool> IsEditableAsync(string selector, FrameIsEditableOptions options = default)
552            => _channel.IsEditableAsync(selector, timeout: options?.Timeout, options?.Strict);
553
554        public Task<bool> IsEnabledAsync(string selector, FrameIsEnabledOptions options = default)
555            => _channel.IsEnabledAsync(selector, timeout: options?.Timeout, options?.Strict);
556
557#pragma warning disable CS0612 // Type or member is obsolete
558        public Task<bool> IsHiddenAsync(string selector, FrameIsHiddenOptions options = default)
559            => _channel.IsHiddenAsync(selector, timeout: options?.Timeout, options?.Strict);
560
561        public Task<bool> IsVisibleAsync(string selector, FrameIsVisibleOptions options = default)
562            => _channel.IsVisibleAsync(selector, timeout: options?.Timeout, options?.Strict);
563#pragma warning restore CS0612 // Type or member is obsolete
564
565        public Task WaitForURLAsync(string url, FrameWaitForURLOptions options = default)
566            => WaitForURLAsync(url, null, null, options);
567
568        public Task WaitForURLAsync(Regex url, FrameWaitForURLOptions options = default)
569            => WaitForURLAsync(null, url, null, options);
570
571        public Task WaitForURLAsync(Func<string, bool> url, FrameWaitForURLOptions options = default)
572            => WaitForURLAsync(null, null, url, options);
573
574        public Task DragAndDropAsync(string source, string target, FrameDragAndDropOptions options = null)
575            => _channel.DragAndDropAsync(source, target, options?.Force, options?.NoWaitAfter, options?.Timeout, options?.Trial, options?.Strict);
576
577        internal Task<FrameExpectResult> ExpectAsync(string selector, string expression, FrameExpectOptions options = null) =>
578            _channel.ExpectAsync(selector, expression, expressionArg: options?.ExpressionArg, expectedText: options?.ExpectedText, expectedNumber: options?.ExpectedNumber, expectedValue: options?.ExpectedValue, useInnerText: options?.UseInnerText, isNot: options?.IsNot, timeout: options?.Timeout);
579
580        private Task WaitForURLAsync(string urlString, Regex urlRegex, Func<string, bool> urlFunc, FrameWaitForURLOptions options = default)
581        {
582            if (UrlMatches(Url, urlString, urlRegex, urlFunc))
583            {
584                return WaitForLoadStateAsync(ToLoadState(options?.WaitUntil), new() { Timeout = options?.Timeout });
585            }
586
587            return WaitForNavigationAsync(
588                new()
589                {
590                    UrlString = urlString,
591                    UrlRegex = urlRegex,
592                    UrlFunc = urlFunc,
593                    Timeout = options?.Timeout,
594                    WaitUntil = options?.WaitUntil,
595                });
596        }
597
598        private LoadState? ToLoadState(WaitUntilState? waitUntilState)
599        {
600            if (waitUntilState == null)
601            {
602                return null;
603            }
604
605            return waitUntilState switch
606            {
607                WaitUntilState.Load => Microsoft.Playwright.LoadState.Load,
608                WaitUntilState.DOMContentLoaded => Microsoft.Playwright.LoadState.DOMContentLoaded,
609                WaitUntilState.NetworkIdle => Microsoft.Playwright.LoadState.NetworkIdle,
610                _ => null,
611            };
612        }
613
614        private Waiter SetupNavigationWaiter(string @event, float? timeout)
615        {
616            var waiter = new Waiter(this.Page as Page, @event);
617            if (this.Page.IsClosed)
618            {
619                waiter.RejectImmediately(new PlaywrightException("Navigation failed because page was closed!"));
620            }
621            waiter.RejectOnEvent<IPage>(Page, PageEvent.Close.Name, new("Navigation failed because page was closed!"));
622            waiter.RejectOnEvent<IPage>(Page, PageEvent.Crash.Name, new("Navigation failed because page was crashed!"));
623            waiter.RejectOnEvent<IFrame>(
624                Page,
625                "FrameDetached",
626                new("Navigating frame was detached!"),
627                e => e == this);
628            timeout ??= (Page as Page)?.DefaultNavigationTimeout ?? PlaywrightImpl.DefaultTimeout;
629            waiter.RejectOnTimeout(Convert.ToInt32(timeout), $"Timeout {timeout}ms exceeded.");
630
631            return waiter;
632        }
633
634        private bool UrlMatches(string url, string matchUrl, Regex regex, Func<string, bool> match)
635        {
636            matchUrl = (Page.Context as BrowserContext)?.CombineUrlWithBase(matchUrl);
637
638            if (matchUrl == null && regex == null && match == null)
639            {
640                return true;
641            }
642
643            if (!string.IsNullOrEmpty(matchUrl))
644            {
645                regex = new(matchUrl.GlobToRegex());
646            }
647
648            if (matchUrl != null && url == matchUrl)
649            {
650                return true;
651            }
652
653            if (regex != null)
654            {
655                return regex.IsMatch(url);
656            }
657
658            return match(url);
659        }
660
661        internal Task HighlightAsync(string selector)
662            => _channel.HighlightAsync(selector);
663    }
664}
665
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

Accelerate Your Automation Test Cycles With LambdaTest

Leverage LambdaTest’s cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.

Try LambdaTest
LambdaTestX

We use cookies to give you the best experience. Cookies help to provide a more personalized experience and relevant advertising for you, and web analytics for us. Learn More in our Cookies policy, Privacy & Terms of service

Allow Cookie
Sarah

I hope you find the best code examples for your project.

If you want to accelerate automated browser testing, try LambdaTest. Your first 100 automation testing minutes are FREE.

Sarah Elson (Product & Growth Lead)