How to use ShouldInterceptMainResourceDuringCrossProcessNavigation method of Microsoft.Playwright.Tests.PageRouteTests class

Best Playwright-dotnet code snippet using Microsoft.Playwright.Tests.PageRouteTests.ShouldInterceptMainResourceDuringCrossProcessNavigation

Run Playwright-dotnet automation tests on LambdaTest cloud grid

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

PageRouteTests.cs

Source: PageRouteTests.cs Github

copy
1/*
2 * MIT License
3 *
4 * Copyright (c) Microsoft Corporation.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25using System;
26using System.Collections.Generic;
27using System.Linq;
28using System.Net;
29using System.Net.Http;
30using System.Text.RegularExpressions;
31using System.Threading.Tasks;
32using Microsoft.AspNetCore.Http;
33using Microsoft.Extensions.Primitives;
34using Microsoft.Playwright.NUnit;
35using NUnit.Framework;
36
37namespace Microsoft.Playwright.Tests
38{
39    public class PageRouteTests : PageTestEx
40    {
41        [PlaywrightTest("page-route.spec.ts", "should intercept")]
42        public async Task ShouldIntercept()
43        {
44            bool intercepted = false;
45            await Page.RouteAsync("**/empty.html", (route) =>
46            {
47                StringAssert.Contains("empty.html", route.Request.Url);
48#pragma warning disable 0612
49                Assert.False(string.IsNullOrEmpty(route.Request.Headers["user-agent"]));
50#pragma warning restore 0612
51                Assert.AreEqual(HttpMethod.Get.Method, route.Request.Method);
52                Assert.Null(route.Request.PostData);
53                Assert.True(route.Request.IsNavigationRequest);
54                Assert.AreEqual("document", route.Request.ResourceType);
55                Assert.AreEqual(route.Request.Frame, Page.MainFrame);
56                Assert.AreEqual("about:blank", route.Request.Frame.Url);
57                route.ContinueAsync();
58                intercepted = true;
59            });
60
61            var response = await Page.GotoAsync(Server.EmptyPage);
62            Assert.True(response.Ok);
63            Assert.True(intercepted);
64        }
65
66        [PlaywrightTest("page-route.spec.ts", "should unroute")]
67        public async Task ShouldUnroute()
68        {
69            var intercepted = new List<int>();
70
71            await Page.RouteAsync("**/*", (route) =>
72            {
73                intercepted.Add(1);
74                route.ContinueAsync();
75            });
76
77            await Page.RouteAsync("**/empty.html", (route) =>
78            {
79                intercepted.Add(2);
80                route.ContinueAsync();
81            });
82
83            await Page.RouteAsync("**/empty.html", (route) =>
84            {
85                intercepted.Add(3);
86                route.ContinueAsync();
87            });
88
89
90            Action<IRoute> handler4 = (route) =>
91            {
92                intercepted.Add(4);
93                route.ContinueAsync();
94            };
95
96            await Page.RouteAsync("**/empty.html", handler4);
97            await Page.GotoAsync(Server.EmptyPage);
98            Assert.AreEqual(new[] { 4 }, intercepted.ToArray());
99
100            intercepted.Clear();
101            await Page.UnrouteAsync("**/empty.html", handler4);
102            await Page.GotoAsync(Server.EmptyPage);
103            Assert.AreEqual(new[] { 3 }, intercepted.ToArray());
104
105            intercepted.Clear();
106            await Page.UnrouteAsync("**/empty.html");
107            await Page.GotoAsync(Server.EmptyPage);
108            Assert.AreEqual(new[] { 1 }, intercepted.ToArray());
109        }
110
111        [PlaywrightTest("page-route.spec.ts", "should work when POST is redirected with 302")]
112        public async Task ShouldWorkWhenPostIsRedirectedWith302()
113        {
114            Server.SetRedirect("/rredirect", "/empty.html");
115            await Page.GotoAsync(Server.EmptyPage);
116            await Page.RouteAsync("**/*", (route) => route.ContinueAsync());
117            await Page.SetContentAsync(@"
118                <form action='/rredirect' method='post'>
119                    <input type=""hidden"" id=""foo"" name=""foo"" value=""FOOBAR"">
120                </form>");
121            await TaskUtils.WhenAll(
122                Page.EvalOnSelectorAsync("form", "form => form.submit()"),
123                Page.WaitForNavigationAsync()
124            );
125        }
126
127        [PlaywrightTest("page-route.spec.ts", "should work when header manipulation headers with redirect")]
128        public async Task ShouldWorkWhenHeaderManipulationHeadersWithRedirect()
129        {
130            Server.SetRedirect("/rrredirect", "/empty.html");
131            await Page.RouteAsync("**/*", (route) =>
132            {
133#pragma warning disable 0612
134                var headers = new Dictionary<string, string>(route.Request.Headers.ToDictionary(x => x.Key, x => x.Value)) { ["foo"] = "bar" };
135#pragma warning restore 0612
136                route.ContinueAsync(new() { Headers = headers });
137            });
138            await Page.GotoAsync(Server.Prefix + "/rrredirect");
139        }
140
141        [PlaywrightTest("page-route.spec.ts", "should be able to remove headers")]
142        public async Task ShouldBeAbleToRemoveHeaders()
143        {
144            await Page.RouteAsync("**/*", (route) =>
145            {
146#pragma warning disable 0612
147                var headers = new Dictionary<string, string>(route.Request.Headers.ToDictionary(x => x.Key, x => x.Value)) { ["foo"] = "bar" };
148#pragma warning restore 0612
149                headers.Remove("origin");
150                route.ContinueAsync(new() { Headers = headers });
151            });
152
153            var originRequestHeader = Server.WaitForRequest("/empty.html", request => request.Headers["origin"]);
154            await TaskUtils.WhenAll(
155                originRequestHeader,
156                Page.GotoAsync(Server.EmptyPage)
157            );
158            Assert.AreEqual(StringValues.Empty, originRequestHeader.Result);
159        }
160
161        [PlaywrightTest("page-route.spec.ts", "should contain referer header")]
162        public async Task ShouldContainRefererHeader()
163        {
164            var requests = new List<IRequest>();
165            await Page.RouteAsync("**/*", (route) =>
166            {
167                requests.Add(route.Request);
168                route.ContinueAsync();
169            });
170            await Page.GotoAsync(Server.Prefix + "/one-style.html");
171            StringAssert.Contains("/one-style.css", requests[1].Url);
172#pragma warning disable 0612
173            StringAssert.Contains("/one-style.html", requests[1].Headers["referer"]);
174#pragma warning restore 0612
175        }
176
177        [PlaywrightTest("page-route.spec.ts", "should properly return navigation response when URL has cookies")]
178        public async Task ShouldProperlyReturnNavigationResponseWhenURLHasCookies()
179        {
180            // Setup cookie.
181            await Page.GotoAsync(Server.EmptyPage);
182            await Context.AddCookiesAsync(new[]
183            {
184                new Cookie
185                {
186                    Url = Server.EmptyPage,
187                    Name = "foo",
188                    Value = "bar"
189                }
190            });
191
192            // Setup request interception.
193            await Page.RouteAsync("**/*", (route) => route.ContinueAsync());
194            var response = await Page.ReloadAsync();
195            Assert.AreEqual((int)HttpStatusCode.OK, response.Status);
196        }
197
198        [PlaywrightTest("page-route.spec.ts", "should show custom HTTP headers")]
199        public async Task ShouldShowCustomHTTPHeaders()
200        {
201            await Page.SetExtraHTTPHeadersAsync(new Dictionary<string, string>
202            {
203                ["foo"] = "bar"
204            });
205            await Page.RouteAsync("**/*", (route) =>
206            {
207#pragma warning disable 0612
208                Assert.AreEqual("bar", route.Request.Headers["foo"]);
209#pragma warning restore 0612
210                route.ContinueAsync();
211            });
212            var response = await Page.GotoAsync(Server.EmptyPage);
213            Assert.True(response.Ok);
214        }
215
216        [PlaywrightTest("page-route.spec.ts", "should work with redirect inside sync XHR")]
217        public async Task ShouldWorkWithRedirectInsideSyncXHR()
218        {
219            await Page.GotoAsync(Server.EmptyPage);
220            Server.SetRedirect("/logo.png", "/pptr.png");
221            await Page.RouteAsync("**/*", (route) => route.ContinueAsync());
222            int status = await Page.EvaluateAsync<int>(@"async () => {
223                var request = new XMLHttpRequest();
224                request.open('GET', '/logo.png', false);  // `false` makes the request synchronous
225                request.send(null);
226                return request.status;
227            }");
228            Assert.AreEqual(200, status);
229        }
230
231        [PlaywrightTest("page-route.spec.ts", "should work with custom referer headers")]
232        public async Task ShouldWorkWithCustomRefererHeaders()
233        {
234            await Page.SetExtraHTTPHeadersAsync(new Dictionary<string, string> { ["referer"] = Server.EmptyPage });
235            await Page.RouteAsync("**/*", (route) =>
236            {
237                if (TestConstants.IsChromium)
238                {
239#pragma warning disable 0612
240                    Assert.AreEqual(Server.EmptyPage + ", " + Server.EmptyPage, route.Request.Headers["referer"]);
241#pragma warning restore 0612
242                }
243                else
244                {
245#pragma warning disable 0612
246                    Assert.AreEqual(Server.EmptyPage, route.Request.Headers["referer"]);
247#pragma warning restore 0612
248                }
249                route.ContinueAsync();
250            });
251            var response = await Page.GotoAsync(Server.EmptyPage);
252            Assert.True(response.Ok);
253        }
254
255        [PlaywrightTest("page-route.spec.ts", "should be abortable")]
256        public async Task ShouldBeAbortable()
257        {
258            await Page.RouteAsync(new Regex("\\.css"), (route) => route.AbortAsync());
259
260            int failedRequests = 0;
261            Page.RequestFailed += (_, _) => ++failedRequests;
262            var response = await Page.GotoAsync(Server.Prefix + "/one-style.html");
263            Assert.True(response.Ok);
264            Assert.Null(response.Request.Failure);
265            Assert.AreEqual(1, failedRequests);
266        }
267
268        [PlaywrightTest("page-route.spec.ts", "should be abortable with custom error codes")]
269        public async Task ShouldBeAbortableWithCustomErrorCodes()
270        {
271            await Page.RouteAsync("**/*", (route) =>
272            {
273                route.AbortAsync(RequestAbortErrorCode.InternetDisconnected);
274            });
275
276            IRequest failedRequest = null;
277            Page.RequestFailed += (_, e) => failedRequest = e;
278            var exception = await PlaywrightAssert.ThrowsAsync<PlaywrightException>(() => Page.GotoAsync(Server.EmptyPage));
279            Assert.NotNull(failedRequest);
280            StringAssert.StartsWith(failedRequest.Failure, exception.Message);
281            if (TestConstants.IsWebKit)
282            {
283                Assert.AreEqual("Request intercepted", failedRequest.Failure);
284            }
285            else if (TestConstants.IsFirefox)
286            {
287                Assert.AreEqual("NS_ERROR_OFFLINE", failedRequest.Failure);
288            }
289            else
290            {
291                Assert.AreEqual("net::ERR_INTERNET_DISCONNECTED", failedRequest.Failure);
292            }
293        }
294
295        [PlaywrightTest("page-route.spec.ts", "should send referer")]
296        public async Task ShouldSendReferer()
297        {
298            await Page.SetExtraHTTPHeadersAsync(new Dictionary<string, string> { ["referer"] = "http://google.com/" });
299            await Page.RouteAsync("**/*", (route) => route.ContinueAsync());
300#pragma warning disable 0612
301            var requestTask = Server.WaitForRequest("/grid.html", request => request.Headers["referer"]);
302#pragma warning restore 0612
303            await TaskUtils.WhenAll(
304                requestTask,
305                Page.GotoAsync(Server.Prefix + "/grid.html")
306            );
307            Assert.AreEqual("http://google.com/", requestTask.Result);
308        }
309
310        [PlaywrightTest("page-route.spec.ts", "should fail navigation when aborting main resource")]
311        public async Task ShouldFailNavigationWhenAbortingMainResource()
312        {
313            await Page.RouteAsync("**/*", (route) => route.AbortAsync());
314            var exception = await PlaywrightAssert.ThrowsAsync<PlaywrightException>(() => Page.GotoAsync(Server.EmptyPage));
315            Assert.NotNull(exception);
316            if (TestConstants.IsWebKit)
317            {
318                StringAssert.Contains("Request intercepted", exception.Message);
319            }
320            else if (TestConstants.IsFirefox)
321            {
322                StringAssert.Contains("NS_ERROR_FAILURE", exception.Message);
323            }
324            else
325            {
326                StringAssert.Contains("net::ERR_FAILED", exception.Message);
327            }
328        }
329
330        [PlaywrightTest("page-route.spec.ts", "should not work with redirects")]
331        public async Task ShouldNotWorkWithRedirects()
332        {
333            var requests = new List<IRequest>();
334            await Page.RouteAsync("**/*", (route) =>
335            {
336                route.ContinueAsync();
337                requests.Add(route.Request);
338            });
339            Server.SetRedirect("/non-existing-page.html", "/non-existing-page-2.html");
340            Server.SetRedirect("/non-existing-page-2.html", "/non-existing-page-3.html");
341            Server.SetRedirect("/non-existing-page-3.html", "/non-existing-page-4.html");
342            Server.SetRedirect("/non-existing-page-4.html", "/empty.html");
343            var response = await Page.GotoAsync(Server.Prefix + "/non-existing-page.html");
344
345            StringAssert.Contains("non-existing-page.html", requests[0].Url);
346            Assert.That(requests, Has.Count.EqualTo(1));
347            Assert.AreEqual("document", requests[0].ResourceType);
348            Assert.True(requests[0].IsNavigationRequest);
349
350            var chain = new List<IRequest>();
351
352            for (var request = response.Request; request != null; request = request.RedirectedFrom)
353            {
354                chain.Add(request);
355                Assert.True(request.IsNavigationRequest);
356            }
357
358            Assert.AreEqual(5, chain.Count);
359            StringAssert.Contains("/empty.html", chain[0].Url);
360            StringAssert.Contains("/non-existing-page-4.html", chain[1].Url);
361            StringAssert.Contains("/non-existing-page-3.html", chain[2].Url);
362            StringAssert.Contains("/non-existing-page-2.html", chain[3].Url);
363            StringAssert.Contains("/non-existing-page.html", chain[4].Url);
364
365            for (int i = 0; i < chain.Count; ++i)
366            {
367                var request = chain[i];
368                Assert.True(request.IsNavigationRequest);
369                Assert.AreEqual(i > 0 ? chain[i - 1] : null, chain[i].RedirectedTo);
370            }
371        }
372
373        [PlaywrightTest("page-route.spec.ts", "should work with redirects for subresources")]
374        public async Task ShouldWorkWithRedirectsForSubresources()
375        {
376            var requests = new List<IRequest>();
377            await Page.RouteAsync("**/*", (route) =>
378            {
379                route.ContinueAsync();
380                requests.Add(route.Request);
381            });
382            Server.SetRedirect("/one-style.css", "/two-style.css");
383            Server.SetRedirect("/two-style.css", "/three-style.css");
384            Server.SetRedirect("/three-style.css", "/four-style.css");
385            Server.SetRoute("/four-style.css", context => context.Response.WriteAsync("body {box-sizing: border-box; }"));
386
387            var response = await Page.GotoAsync(Server.Prefix + "/one-style.html");
388            Assert.AreEqual((int)HttpStatusCode.OK, response.Status);
389            StringAssert.Contains("one-style.html", response.Url);
390
391            Assert.AreEqual(2, requests.Count);
392            Assert.AreEqual("document", requests[0].ResourceType);
393            StringAssert.Contains("one-style.html", requests[0].Url);
394
395            var request = requests[1];
396            foreach (string url in new[] { "/one-style.css", "/two-style.css", "/three-style.css", "/four-style.css" })
397            {
398                Assert.AreEqual("stylesheet", request.ResourceType);
399                StringAssert.Contains(url, request.Url);
400                request = request.RedirectedTo;
401            }
402
403            Assert.Null(request);
404        }
405
406        [PlaywrightTest("page-route.spec.ts", "should work with equal requests")]
407        public async Task ShouldWorkWithEqualRequests()
408        {
409            await Page.GotoAsync(Server.EmptyPage);
410            int responseCount = 1;
411            Server.SetRoute("/zzz", context => context.Response.WriteAsync((responseCount++ * 11).ToString()));
412
413            bool spinner = false;
414            // Cancel 2nd request.
415            await Page.RouteAsync("**/*", (route) =>
416            {
417                if (spinner)
418                {
419                    _ = route.AbortAsync();
420                }
421                else
422                {
423                    _ = route.ContinueAsync();
424                }
425                spinner = !spinner;
426            });
427
428            var results = new List<string>();
429            for (int i = 0; i < 3; ++i)
430            {
431                results.Add(await Page.EvaluateAsync<string>("fetch('/zzz').then(response => response.text()).catch (e => 'FAILED')"));
432            }
433
434            Assert.AreEqual(new[] { "11", "FAILED", "22" }, results);
435        }
436
437        [PlaywrightTest("page-route.spec.ts", "should navigate to dataURL and not fire dataURL requests")]
438        public async Task ShouldNavigateToDataURLAndNotFireDataURLRequests()
439        {
440            var requests = new List<IRequest>();
441            await Page.RouteAsync("**/*", (route) =>
442            {
443                requests.Add(route.Request);
444                route.ContinueAsync();
445            });
446            string dataURL = "data:text/html,<div>yo</div>";
447            var response = await Page.GotoAsync(dataURL);
448            Assert.Null(response);
449            Assert.IsEmpty(requests);
450        }
451
452        [PlaywrightTest("page-route.spec.ts", "should be able to fetch dataURL and not fire dataURL requests")]
453        public async Task ShouldBeAbleToFetchDataURLAndNotFireDataURLRequests()
454        {
455            await Page.GotoAsync(Server.EmptyPage);
456
457            var requests = new List<IRequest>();
458            await Page.RouteAsync("**/*", (route) =>
459            {
460                requests.Add(route.Request);
461                route.ContinueAsync();
462            });
463            string dataURL = "data:text/html,<div>yo</div>";
464            string text = await Page.EvaluateAsync<string>("url => fetch(url).then(r => r.text())", dataURL);
465            Assert.AreEqual("<div>yo</div>", text);
466            Assert.IsEmpty(requests);
467        }
468
469        [PlaywrightTest("page-route.spec.ts", "should navigate to URL with hash and and fire requests without hash")]
470        public async Task ShouldNavigateToURLWithHashAndAndFireRequestsWithoutHash()
471        {
472            var requests = new List<IRequest>();
473            await Page.RouteAsync("**/*", (route) =>
474            {
475                requests.Add(route.Request);
476                route.ContinueAsync();
477            });
478            var response = await Page.GotoAsync(Server.EmptyPage + "#hash");
479            Assert.AreEqual((int)HttpStatusCode.OK, response.Status);
480            Assert.AreEqual(Server.EmptyPage, response.Url);
481            Assert.That(requests, Has.Count.EqualTo(1));
482            Assert.AreEqual(Server.EmptyPage, requests[0].Url);
483        }
484
485        [PlaywrightTest("page-route.spec.ts", "should work with encoded server")]
486        public async Task ShouldWorkWithEncodedServer()
487        {
488            // The requestWillBeSent will report encoded URL, whereas interception will
489            // report URL as-is. @see crbug.com/759388
490            await Page.RouteAsync("**/*", (route) => route.ContinueAsync());
491            var response = await Page.GotoAsync(Server.Prefix + "/some nonexisting page");
492            Assert.AreEqual((int)HttpStatusCode.NotFound, response.Status);
493        }
494
495        [PlaywrightTest("page-route.spec.ts", "should work with badly encoded server")]
496        public async Task ShouldWorkWithBadlyEncodedServer()
497        {
498            Server.SetRoute("/malformed?rnd=%911", _ => Task.CompletedTask);
499            await Page.RouteAsync("**/*", (route) => route.ContinueAsync());
500            var response = await Page.GotoAsync(Server.Prefix + "/malformed?rnd=%911");
501            Assert.AreEqual((int)HttpStatusCode.OK, response.Status);
502        }
503
504        [PlaywrightTest("page-route.spec.ts", "should work with encoded server - 2")]
505        public async Task ShouldWorkWithEncodedServer2()
506        {
507            // The requestWillBeSent will report URL as-is, whereas interception will
508            // report encoded URL for stylesheet. @see crbug.com/759388
509            var requests = new List<IRequest>();
510            await Page.RouteAsync("**/*", (route) =>
511            {
512                route.ContinueAsync();
513                requests.Add(route.Request);
514            });
515            var response = await Page.GotoAsync($"data:text/html,<link rel=\"stylesheet\" href=\"{Server.EmptyPage}/fonts?helvetica|arial\"/>");
516            Assert.Null(response);
517            // TODO: https://github.com/microsoft/playwright/issues/12789
518            if (TestConstants.IsFirefox)
519                Assert.That(requests, Has.Count.EqualTo(2));
520            else
521                Assert.That(requests, Has.Count.EqualTo(1));
522            Assert.AreEqual((int)HttpStatusCode.NotFound, (await requests[0].ResponseAsync()).Status);
523        }
524
525        [PlaywrightTest("page-route.spec.ts", @"should not throw ""Invalid Interception Id"" if the request was cancelled")]
526        public async Task ShouldNotThrowInvalidInterceptionIdIfTheRequestWasCancelled()
527        {
528            await Page.SetContentAsync("<iframe></iframe>");
529            IRoute route = null;
530            await Page.RouteAsync("**/*", (r) => route = r);
531            _ = Page.EvalOnSelectorAsync("iframe", "(frame, url) => frame.src = url", Server.EmptyPage);
532            // Wait for request interception.
533            await Page.WaitForRequestAsync("**/*");
534            // Delete frame to cause request to be canceled.
535            await Page.EvalOnSelectorAsync("iframe", "frame => frame.remove()");
536            await route.ContinueAsync();
537        }
538
539        [PlaywrightTest("page-route.spec.ts", "should intercept main resource during cross-process navigation")]
540        public async Task ShouldInterceptMainResourceDuringCrossProcessNavigation()
541        {
542            await Page.GotoAsync(Server.EmptyPage);
543            bool intercepted = false;
544            await Page.RouteAsync(Server.CrossProcessPrefix + "/empty.html", (route) =>
545            {
546                if (route.Request.Url.Contains(Server.CrossProcessPrefix + "/empty.html"))
547                {
548                    intercepted = true;
549                }
550
551                route.ContinueAsync();
552            });
553            var response = await Page.GotoAsync(Server.CrossProcessPrefix + "/empty.html");
554            Assert.True(response.Ok);
555            Assert.True(intercepted);
556        }
557
558        [PlaywrightTest("page-route.spec.ts", "should fulfill with redirect status")]
559        [Skip(SkipAttribute.Targets.Webkit)]
560        public async Task ShouldFulfillWithRedirectStatus()
561        {
562            await Page.GotoAsync(Server.Prefix + "/title.html");
563            Server.SetRoute("/final", context => context.Response.WriteAsync("foo"));
564            await Page.RouteAsync("**/*", (route) =>
565            {
566                if (route.Request.Url != Server.Prefix + "/redirect_this")
567                {
568                    route.ContinueAsync();
569                    return;
570                }
571
572                _ = route.FulfillAsync(new()
573                {
574                    Status = (int)HttpStatusCode.MovedPermanently,
575                    Headers = new Dictionary<string, string>
576                    {
577                        ["location"] = "/final",
578                    }
579                });
580            });
581
582            string text = await Page.EvaluateAsync<string>(@"async url => {
583              const data = await fetch(url);
584              return data.text();
585            }", Server.Prefix + "/redirect_this");
586
587            Assert.AreEqual("foo", text);
588        }
589
590        [PlaywrightTest("page-route.spec.ts", "should support cors with GET")]
591        public async Task ShouldSupportCorsWithGET()
592        {
593            await Page.GotoAsync(Server.EmptyPage);
594            await Page.RouteAsync("**/cars*", (route) =>
595            {
596                var headers = new Dictionary<string, string>() { ["access-control-allow-origin"] = route.Request.Url.EndsWith("allow") ? "*" : "none" };
597
598                _ = route.FulfillAsync(new()
599                {
600                    ContentType = "application/json",
601                    Headers = headers,
602                    Status = (int)HttpStatusCode.OK,
603                    Body = "[\"electric\", \"cars\"]"
604                });
605            });
606
607            string[] resp = await Page.EvaluateAsync<string[]>(@"async () => {
608                const response = await fetch('https://example.com/cars?allow', { mode: 'cors' });
609                return response.json();
610            }");
611
612            Assert.AreEqual(new[] { "electric", "cars" }, resp);
613
614            var exception = await PlaywrightAssert.ThrowsAsync<PlaywrightException>(() => Page.EvaluateAsync<string[]>(@"async () => {
615                const response = await fetch('https://example.com/cars?reject', { mode: 'cors' });
616                return response.json();
617            }"));
618
619            if (TestConstants.IsChromium)
620                StringAssert.Contains("Failed", exception.Message);
621            else if (TestConstants.IsWebKit)
622                StringAssert.Contains("TypeError", exception.Message);
623            else if (TestConstants.IsFirefox)
624                StringAssert.Contains("NetworkError", exception.Message);
625            else
626                Assert.Fail("Unknown browser type.");
627        }
628
629        [PlaywrightTest("page-route.spec.ts", "should support cors with POST")]
630        public async Task ShouldSupportCorsWithPOST()
631        {
632            await Page.GotoAsync(Server.EmptyPage);
633            await Page.RouteAsync("**/cars*", (route) =>
634            {
635                _ = route.FulfillAsync(new()
636                {
637                    ContentType = "application/json",
638                    Headers = new Dictionary<string, string> { ["access-control-allow-origin"] = "*" },
639                    Status = (int)HttpStatusCode.OK,
640                    Body = "[\"electric\", \"cars\"]"
641                });
642            });
643
644            string[] resp = await Page.EvaluateAsync<string[]>(@"async () => {
645                const response = await fetch('https://example.com/cars', {
646                    method: 'POST',
647                    headers: { 'Content-Type': 'application/json' },
648                    mode: 'cors',
649                    body: JSON.stringify({ 'number': 1 }) 
650                });
651                return response.json();
652            }");
653
654            Assert.AreEqual(new[] { "electric", "cars" }, resp);
655        }
656
657        [PlaywrightTest("page-route.spec.ts", "should support cors with different methods")]
658        public async Task ShouldSupportCorsWithDifferentMethods()
659        {
660            await Page.GotoAsync(Server.EmptyPage);
661            await Page.RouteAsync("**/cars*", (route) =>
662            {
663                _ = route.FulfillAsync(new()
664                {
665                    ContentType = "application/json",
666                    Headers = new Dictionary<string, string> { ["access-control-allow-origin"] = "*" },
667                    Status = (int)HttpStatusCode.OK,
668                    Body = $"[\"{ route.Request.Method.ToString().ToUpper() }\", \"electric\", \"cars\"]"
669                });
670            });
671
672            string[] resp = await Page.EvaluateAsync<string[]>(@"async () => {
673                const response = await fetch('https://example.com/cars', {
674                  method: 'POST',
675                  headers: { 'Content-Type': 'application/json' },
676                  mode: 'cors',
677                  body: JSON.stringify({ 'number': 1 }) 
678                });
679                return response.json();
680            }");
681
682            Assert.AreEqual(new[] { "POST", "electric", "cars" }, resp);
683
684            resp = await Page.EvaluateAsync<string[]>(@"async () => {
685                const response = await fetch('https://example.com/cars', {
686                  method: 'DELETE',
687                  headers: { 'Content-Type': 'application/json' },
688                  mode: 'cors',
689                  body: JSON.stringify({ 'number': 1 }) 
690                });
691                return response.json();
692            }");
693
694            Assert.AreEqual(new[] { "DELETE", "electric", "cars" }, resp);
695        }
696
697        [PlaywrightTest]
698        public void ShouldThrowOnInvalidRouteUrl()
699        {
700#if NETCOREAPP3_1
701            var regexParseExceptionType = typeof(Regex).Assembly
702                .GetType("System.Text.RegularExpressions.RegexParseException", throwOnError: true);
703#else
704            var regexParseExceptionType = typeof(RegexParseException);
705#endif
706
707            Assert.Throws(regexParseExceptionType, () =>
708                Page.RouteAsync("[", route =>
709                {
710                    route.ContinueAsync();
711                })
712            );
713        }
714
715        [PlaywrightTest("page-route.spec.ts", "should support the times parameter with route matching")]
716        public async Task ShouldSupportTheTimesParameterWithRouteMatching()
717        {
718            List<int> intercepted = new();
719            await Page.RouteAsync("**/empty.html", (route) =>
720            {
721                intercepted.Add(1);
722                route.ContinueAsync();
723            }, new() { Times = 1 });
724
725            await Page.GotoAsync(Server.EmptyPage);
726            await Page.GotoAsync(Server.EmptyPage);
727            await Page.GotoAsync(Server.EmptyPage);
728            Assert.AreEqual(1, intercepted.Count);
729        }
730    }
731}
732
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)