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

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

Run Playwright-dotnet automation tests on LambdaTest cloud grid

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

PageAutoWaitingBasicTests.cs

Source: PageAutoWaitingBasicTests.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.Collections.Generic;
26using System.Threading.Tasks;
27using Microsoft.AspNetCore.Http;
28using Microsoft.Playwright.NUnit;
29using NUnit.Framework;
30
31namespace Microsoft.Playwright.Tests
32{
33    public class PageAutoWaitingBasicTests : PageTestEx
34    {
35        [PlaywrightTest("page-autowaiting-basic.spec.ts", "should await navigation when clicking anchor")]
36        [Ignore("Flacky")]
37        public async Task ShouldAwaitNavigationWhenClickingAnchor()
38        {
39            var messages = new List<string>();
40            Server.SetRoute("/empty.html", context =>
41            {
42                messages.Add("route");
43                context.Response.ContentType = "text/html";
44                return context.Response.WriteAsync("<link rel='stylesheet' href='./one-style.css'>");
45            });
46
47            await Page.SetContentAsync($"<a href=\"{Server.EmptyPage}\">empty.html</a>");
48            await TaskUtils.WhenAll(
49                Page.ClickAsync("a").ContinueWith(_ => messages.Add("click")),
50                Page.WaitForNavigationAsync().ContinueWith(_ => messages.Add("navigated")));
51
52            Assert.AreEqual("route|navigated|click", string.Join("|", messages));
53        }
54
55        [PlaywrightTest("page-autowaiting-basic.spec.ts", "should await cross-process navigation when clicking anchor")]
56        [Ignore("Flacky")]
57        public async Task ShouldAwaitCrossProcessNavigationWhenClickingAnchor()
58        {
59            var messages = new List<string>();
60            Server.SetRoute("/empty.html", context =>
61            {
62                messages.Add("route");
63                context.Response.ContentType = "text/html";
64                return context.Response.WriteAsync("<link rel='stylesheet' href='./one-style.css'>");
65            });
66
67            await Page.SetContentAsync($"<a href=\"{Server.CrossProcessPrefix}/empty.html\">empty.html</a>");
68            await TaskUtils.WhenAll(
69                Page.ClickAsync("a").ContinueWith(_ => messages.Add("click")),
70                Page.WaitForNavigationAsync().ContinueWith(_ => messages.Add("navigated")));
71
72            Assert.AreEqual("route|navigated|click", string.Join("|", messages));
73        }
74
75        [PlaywrightTest("page-autowaiting-basic.spec.ts", "should await form-get on click")]
76        [Ignore("Flacky")]
77        public async Task ShouldAwaitFormGetOnClick()
78        {
79            var messages = new List<string>();
80            Server.SetRoute("/empty.html?foo=bar", context =>
81            {
82                messages.Add("route");
83                context.Response.ContentType = "text/html";
84                return context.Response.WriteAsync("<link rel='stylesheet' href='./one-style.css'>");
85            });
86
87            await Page.SetContentAsync([email protected]"
88                <form action=""{Server.EmptyPage}"" method=""get"">
89                    <input name=""foo"" value=""bar"">
90                    <input type=""submit"" value=""Submit"">
91                </form>");
92
93            await TaskUtils.WhenAll(
94                Page.ClickAsync("input[type=submit]").ContinueWith(_ => messages.Add("click")),
95                Page.WaitForNavigationAsync().ContinueWith(_ => messages.Add("navigated")));
96
97            Assert.AreEqual("route|navigated|click", string.Join("|", messages));
98        }
99
100        [PlaywrightTest("page-autowaiting-basic.spec.ts", "should await form-post on click")]
101        [Ignore("Flacky")]
102        public async Task ShouldAwaitFormPostOnClick()
103        {
104            var messages = new List<string>();
105            Server.SetRoute("/empty.html", context =>
106            {
107                messages.Add("route");
108                context.Response.ContentType = "text/html";
109                return context.Response.WriteAsync("<link rel='stylesheet' href='./one-style.css'>");
110            });
111
112            await Page.SetContentAsync([email protected]"
113                <form action=""{ Server.EmptyPage}"" method=""post"">
114                    <input name=""foo"" value=""bar"">
115                    <input type=""submit"" value=""Submit"">
116                </form>");
117
118            await TaskUtils.WhenAll(
119                Page.ClickAsync("input[type=submit]").ContinueWith(_ => messages.Add("click")),
120                Page.WaitForNavigationAsync().ContinueWith(_ => messages.Add("navigated")));
121
122            Assert.AreEqual("route|navigated|click", string.Join("|", messages));
123        }
124
125        [PlaywrightTest("page-autowaiting-basic.spec.ts", "should await navigation when assigning location")]
126        [Ignore("Flacky")]
127        public async Task ShouldAwaitNavigationWhenAssigningLocation()
128        {
129            var messages = new List<string>();
130            Server.SetRoute("/empty.html", context =>
131            {
132                messages.Add("route");
133                context.Response.ContentType = "text/html";
134                return context.Response.WriteAsync("<link rel='stylesheet' href='./one-style.css'>");
135            });
136
137            await TaskUtils.WhenAll(
138                Page.EvaluateAsync($"window.location.href = '{Server.EmptyPage}'").ContinueWith(_ => messages.Add("evaluate")),
139                Page.WaitForNavigationAsync().ContinueWith(_ => messages.Add("navigated")));
140
141            Assert.AreEqual("route|navigated|evaluate", string.Join("|", messages));
142        }
143
144        [PlaywrightTest("page-autowaiting-basic.spec.ts", "should await navigation when assigning location twice")]
145        public async Task ShouldAwaitNavigationWhenAssigningLocationTwice()
146        {
147            var messages = new List<string>();
148            Server.SetRoute("/empty.html?cancel", context =>
149            {
150                return context.Response.WriteAsync("done");
151            });
152
153            Server.SetRoute("/empty.html?override", context =>
154            {
155                messages.Add("routeoverride");
156                return context.Response.WriteAsync("done");
157            });
158
159            await Page.EvaluateAsync([email protected]"
160                window.location.href = '{Server.EmptyPage}?cancel';
161                window.location.href = '{Server.EmptyPage}?override';");
162            messages.Add("evaluate");
163
164            Assert.AreEqual("routeoverride|evaluate", string.Join("|", messages));
165        }
166
167        [PlaywrightTest("page-autowaiting-basic.spec.ts", "should await navigation when evaluating reload")]
168        [Ignore("Flacky")]
169        public async Task ShouldAwaitNavigationWhenEvaluatingReload()
170        {
171            var messages = new List<string>();
172            await Page.GotoAsync(Server.EmptyPage);
173            Server.SetRoute("/empty.html", context =>
174            {
175                messages.Add("route");
176                context.Response.ContentType = "text/html";
177                return context.Response.WriteAsync("<link rel='stylesheet' href='./one-style.css'>");
178            });
179
180            await TaskUtils.WhenAll(
181                Page.EvaluateAsync($"window.location.reload();").ContinueWith(_ => messages.Add("evaluate")),
182                Page.WaitForNavigationAsync().ContinueWith(_ => messages.Add("navigated")));
183
184            Assert.AreEqual("route|navigated|evaluate", string.Join("|", messages));
185        }
186
187        [PlaywrightTest("page-autowaiting-basic.spec.ts", "should await navigating specified target")]
188        [Ignore("Flacky")]
189        public async Task ShouldAwaitNavigatingSpecifiedTarget()
190        {
191            var messages = new List<string>();
192            Server.SetRoute("/empty.html", context =>
193            {
194                messages.Add("route");
195                context.Response.ContentType = "text/html";
196                return context.Response.WriteAsync("<link rel='stylesheet' href='./one-style.css'>");
197            });
198
199            await Page.SetContentAsync([email protected]"
200                <a href=""{ Server.EmptyPage}"" target=target>empty.html</a>
201                <iframe name=target></iframe>");
202
203            var frame = Page.Frame("target");
204
205            await TaskUtils.WhenAll(
206                Page.ClickAsync("a").ContinueWith(_ => messages.Add("click")),
207                Page.WaitForNavigationAsync().ContinueWith(_ => messages.Add("navigated")));
208
209            Assert.AreEqual(Server.EmptyPage, frame.Url);
210            Assert.AreEqual("route|navigated|click", string.Join("|", messages));
211        }
212
213        [PlaywrightTest("page-autowaiting-basic.spec.ts", "should work with noWaitAfter: true")]
214        public async Task ShouldWorkWithNoWaitAfterTrue()
215        {
216            Server.SetRoute("/empty.html", _ => Task.CompletedTask);
217            await Page.SetContentAsync($"<a id=anchor href='{Server.EmptyPage}'>empty.html</a>");
218            await Page.ClickAsync("a", new() { NoWaitAfter = true });
219        }
220
221        [PlaywrightTest("page-autowaiting-basic.spec.ts", "should work with waitForLoadState(load)")]
222        [Ignore("Flacky")]
223        public async Task ShouldWorkWithWaitForLoadStateLoad()
224        {
225            var messages = new List<string>();
226            Server.SetRoute("/empty.html", context =>
227            {
228                messages.Add("route");
229                context.Response.ContentType = "text/html";
230                return context.Response.WriteAsync("<link rel='stylesheet' href='./one-style.css'>");
231            });
232
233            await Page.SetContentAsync($"<a href=\"{Server.EmptyPage}\">empty.html</a>");
234            var clickLoaded = new TaskCompletionSource<bool>();
235
236            await TaskUtils.WhenAll(
237                Page.ClickAsync("a").ContinueWith(_ => Page.WaitForLoadStateAsync(LoadState.Load).ContinueWith(_ =>
238                {
239                    messages.Add("clickload");
240                    clickLoaded.TrySetResult(true);
241                })),
242                clickLoaded.Task,
243                Page.WaitForNavigationAsync(new() { WaitUntil = WaitUntilState.DOMContentLoaded }).ContinueWith(_ => messages.Add("domcontentloaded")));
244
245            Assert.AreEqual("route|domcontentloaded|clickload", string.Join("|", messages));
246        }
247
248        [PlaywrightTest("page-autowaiting-basic.spec.ts", "should work with goto following click")]
249        public async Task ShouldWorkWithGotoFollowingClick()
250        {
251            var messages = new List<string>();
252            Server.SetRoute("/empty.html", context =>
253            {
254                messages.Add("route");
255                context.Response.ContentType = "text/html";
256                return context.Response.WriteAsync("You are logged in");
257            });
258
259            await Page.SetContentAsync([email protected]"
260                <form action=""{ Server.EmptyPage}/login.html"" method=""get"">
261                    <input type=""text"">
262                    <input type=""submit"" value=""Submit"">
263                </form>");
264
265            await Page.FillAsync("input[type=text]", "admin");
266            await Page.ClickAsync("input[type=submit]");
267            await Page.GotoAsync(Server.EmptyPage);
268        }
269    }
270}
271
Full Screen

PageNetworkIdleTests.cs

Source: PageNetworkIdleTests.cs Github

copy
1/*
2 * MIT License
3 *
4 * Copyright (c) 2020 Darío Kondratiuk
5 * Modifications copyright (c) Microsoft Corporation.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in all
15 * copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 */
25
26using System;
27using System.Collections.Concurrent;
28using System.Collections.Generic;
29using System.Diagnostics;
30using System.Net;
31using System.Threading.Tasks;
32using Microsoft.AspNetCore.Http;
33using Microsoft.Playwright.NUnit;
34using NUnit.Framework;
35
36namespace Microsoft.Playwright.Tests
37{
38    ///<playwright-file>page-network-idle.spec.ts</playwright-file>
39    public class PageNetworkIdleTests : PageTestEx
40    {
41        [PlaywrightTest("page-network-idle.spec.ts", "should navigate to empty page with networkidle")]
42        public async Task ShouldNavigateToEmptyPageWithNetworkIdle()
43        {
44            var response = await Page.GotoAsync(Server.EmptyPage, new() { WaitUntil = WaitUntilState.NetworkIdle });
45            Assert.AreEqual((int)HttpStatusCode.OK, response.Status);
46        }
47
48        [PlaywrightTest("page-network-idle.spec.ts", "should wait for networkidle to succeed navigation")]
49        public Task ShouldWaitForNetworkIdleToSucceedNavigation()
50            => NetworkIdleTestAsync(Page.MainFrame, () => Page.GotoAsync(Server.Prefix + "/networkidle.html", new() { WaitUntil = WaitUntilState.NetworkIdle }));
51
52        [PlaywrightTest("page-network-idle.spec.ts", "should wait for networkidle to succeed navigation with request from previous navigation")]
53        public async Task ShouldWaitForToSucceedNavigationWithRequestFromPreviousNavigation()
54        {
55            await Page.GotoAsync(Server.EmptyPage);
56            Server.SetRoute("/foo.js", _ => Task.CompletedTask);
57            await Page.SetContentAsync("<script>fetch('foo.js')</script>");
58            await NetworkIdleTestAsync(Page.MainFrame, () => Page.GotoAsync(Server.Prefix + "/networkidle.html", new() { WaitUntil = WaitUntilState.NetworkIdle }));
59        }
60
61        [PlaywrightTest("page-network-idle.spec.ts", "should wait for networkidle in waitForNavigation")]
62        public Task ShouldWaitForInWaitForNavigation()
63            => NetworkIdleTestAsync(
64                Page.MainFrame,
65                () =>
66                {
67                    var task = Page.WaitForNavigationAsync(new() { WaitUntil = WaitUntilState.NetworkIdle });
68                    Page.GotoAsync(Server.Prefix + "/networkidle.html");
69                    return task;
70                });
71
72        [PlaywrightTest("page-network-idle.spec.ts", "should wait for networkidle in setContent")]
73        public async Task ShouldWaitForInSetContent()
74        {
75            await Page.GotoAsync(Server.EmptyPage);
76            await NetworkIdleTestAsync(
77                Page.MainFrame,
78                () => Page.SetContentAsync("<script src='networkidle.js'></script>", new() { WaitUntil = WaitUntilState.NetworkIdle }),
79                true);
80        }
81
82        [PlaywrightTest("page-network-idle.spec.ts", "should wait for networkidle in setContent with request from previous navigation")]
83        public async Task ShouldWaitForNetworkIdleInSetContentWithRequestFromPreviousNavigation()
84        {
85            await Page.GotoAsync(Server.EmptyPage);
86            Server.SetRoute("/foo.js", _ => Task.CompletedTask);
87            await Page.SetContentAsync("<script>fetch('foo.js')</script>");
88            await NetworkIdleTestAsync(
89                Page.MainFrame,
90                () => Page.SetContentAsync("<script src='networkidle.js'></script>", new() { WaitUntil = WaitUntilState.NetworkIdle }),
91                true);
92        }
93
94        [PlaywrightTest("page-network-idle.spec.ts", "should wait for networkidle when navigating iframe")]
95        public async Task ShouldWaitForNetworkIdleWhenNavigatingIframe()
96        {
97            await Page.GotoAsync(Server.Prefix + "/frames/one-frame.html");
98            var frame = Page.FirstChildFrame();
99            await NetworkIdleTestAsync(
100                frame,
101                () => frame.GotoAsync(Server.Prefix + "/networkidle.html", new() { WaitUntil = WaitUntilState.NetworkIdle }));
102        }
103
104        [PlaywrightTest("page-network-idle.spec.ts", "should wait for networkidle in setContent from the child frame")]
105        public async Task ShouldWaitForInSetContentFromTheChildFrame()
106        {
107            await Page.GotoAsync(Server.EmptyPage);
108            await NetworkIdleTestAsync(
109                Page.MainFrame,
110                () => Page.SetContentAsync("<iframe src='networkidle.html'></iframe>", new() { WaitUntil = WaitUntilState.NetworkIdle }),
111                true);
112        }
113
114        [PlaywrightTest("page-network-idle.spec.ts", "should wait for networkidle from the child frame")]
115        public Task ShouldWaitForFromTheChildFrame()
116            => NetworkIdleTestAsync(
117                Page.MainFrame,
118                () => Page.GotoAsync(Server.Prefix + "/networkidle-frame.html", new() { WaitUntil = WaitUntilState.NetworkIdle }));
119
120        [PlaywrightTest("page-network-idle.spec.ts", "should wait for networkidle from the popup")]
121        public async Task ShouldWaitForNetworkIdleFromThePopup()
122        {
123            await Page.GotoAsync(Server.EmptyPage);
124            await Page.SetContentAsync(@"
125                <button id=box1 onclick=""window.open('./popup/popup.html')"">Button1</button>
126                <button id=box2 onclick=""window.open('./popup/popup.html')"">Button2</button>
127                <button id=box3 onclick=""window.open('./popup/popup.html')"">Button3</button>
128                <button id=box4 onclick=""window.open('./popup/popup.html')"">Button4</button>
129                <button id=box5 onclick=""window.open('./popup/popup.html')"">Button5</button>
130            ");
131
132            for (int i = 1; i < 6; i++)
133            {
134                var popupTask = Page.WaitForPopupAsync();
135                await Task.WhenAll(
136                    Page.WaitForPopupAsync(),
137                    Page.ClickAsync("#box" + i));
138
139                await popupTask.Result.WaitForLoadStateAsync(LoadState.NetworkIdle);
140            }
141        }
142
143        private async Task NetworkIdleTestAsync(IFrame frame, Func<Task> action = default, bool isSetContent = false)
144        {
145            var lastResponseFinished = new Stopwatch();
146            var responses = new ConcurrentDictionary<string, TaskCompletionSource<bool>>();
147            var fetches = new Dictionary<string, TaskCompletionSource<bool>>();
148
149            async Task RequestDelegate(HttpContext context)
150            {
151                var taskCompletion = new TaskCompletionSource<bool>();
152                responses[context.Request.Path] = taskCompletion;
153                fetches[context.Request.Path].TrySetResult(true);
154                await taskCompletion.Task;
155                lastResponseFinished.Restart();
156                context.Response.StatusCode = 404;
157                await context.Response.WriteAsync("File not found");
158            }
159
160            fetches["/fetch-request-a.js"] = new();
161            Server.SetRoute("/fetch-request-a.js", RequestDelegate);
162
163            var firstFetchResourceRequested = Server.WaitForRequest("/fetch-request-a.js");
164
165            fetches["/fetch-request-b.js"] = new();
166            Server.SetRoute("/fetch-request-b.js", RequestDelegate);
167            var secondFetchResourceRequested = Server.WaitForRequest("/fetch-request-b.js");
168
169            var waitForLoadTask = isSetContent ? Task.CompletedTask : frame.WaitForNavigationAsync(new() { WaitUntil = WaitUntilState.Load });
170
171            var actionTask = action();
172
173            await waitForLoadTask;
174            Assert.False(actionTask.IsCompleted);
175
176            await firstFetchResourceRequested;
177            Assert.False(actionTask.IsCompleted);
178
179            await fetches["/fetch-request-a.js"].Task;
180            await frame.Page.EvaluateAsync("() => window['fetchSecond']()");
181
182            // Finishing first response should leave 2 requests alive and trigger networkidle2.
183            responses["/fetch-request-a.js"].TrySetResult(true);
184
185            // Wait for the second round to be requested.
186            await secondFetchResourceRequested;
187            Assert.False(actionTask.IsCompleted);
188
189            await fetches["/fetch-request-b.js"].Task;
190            responses["/fetch-request-b.js"].TrySetResult(true);
191
192            IResponse navigationResponse = null;
193            if (!isSetContent)
194            {
195                navigationResponse = await (Task<IResponse>)actionTask;
196            }
197            else
198            {
199                await actionTask;
200            }
201
202            lastResponseFinished.Stop();
203            if (!isSetContent)
204            {
205                Assert.AreEqual((int)HttpStatusCode.OK, navigationResponse.Status);
206            }
207        }
208    }
209}
210
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

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)