diff --git a/src/PlaywrightSharp.Tests/BrowserContextBasicTests.cs b/src/PlaywrightSharp.Tests/BrowserContextBasicTests.cs index 78b8c0ea9d..3db8f01ea4 100644 --- a/src/PlaywrightSharp.Tests/BrowserContextBasicTests.cs +++ b/src/PlaywrightSharp.Tests/BrowserContextBasicTests.cs @@ -294,7 +294,7 @@ public async Task ShouldWorkWithOfflineOption() await Assert.ThrowsAsync(() => page.GoToAsync(TestConstants.EmptyPage)); await context.SetOfflineAsync(false); var response = await page.GoToAsync(TestConstants.EmptyPage); - Assert.Equal(HttpStatusCode.OK, response.Status); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); } [PlaywrightTest("browsercontext-basic.spec.ts", "should emulate navigator.onLine")] diff --git a/src/PlaywrightSharp.Tests/BrowserContextHttpCredentialsTests.cs b/src/PlaywrightSharp.Tests/BrowserContextHttpCredentialsTests.cs index cc1d1ed197..26cb1a7412 100644 --- a/src/PlaywrightSharp.Tests/BrowserContextHttpCredentialsTests.cs +++ b/src/PlaywrightSharp.Tests/BrowserContextHttpCredentialsTests.cs @@ -23,7 +23,7 @@ public async Task ShouldFailWithoutCredentials() await using var context = await Browser.NewContextAsync(); var page = await context.NewPageAsync(); var response = await page.GoToAsync(TestConstants.EmptyPage); - Assert.Equal(HttpStatusCode.Unauthorized, response.Status); + Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); } [PlaywrightTest("browsercontext-credentials.spec.ts", "should work with setHTTPCredentials")] @@ -34,14 +34,14 @@ public async Task ShouldWorkWithSetHTTPCredentials() await using var context = await Browser.NewContextAsync(); var page = await context.NewPageAsync(); var response = await page.GoToAsync(TestConstants.EmptyPage); - Assert.Equal(HttpStatusCode.Unauthorized, response.Status); + Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); await context.SetHttpCredentialsAsync(new Credentials { Username = "user", Password = "pass" }); response = await page.ReloadAsync(); - Assert.Equal(HttpStatusCode.OK, response.Status); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); } [PlaywrightTest("browsercontext-credentials.spec.ts", "should work with correct credentials")] @@ -61,7 +61,7 @@ public async Task ShouldWorkWithCorrectCredentials() var page = await context.NewPageAsync(); var response = await page.GoToAsync(TestConstants.EmptyPage); - Assert.Equal(HttpStatusCode.OK, response.Status); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); } [PlaywrightTest("browsercontext-credentials.spec.ts", "should fail if wrong credentials")] @@ -81,7 +81,7 @@ public async Task ShouldFailIfWrongCredentials() var page = await context.NewPageAsync(); var response = await page.GoToAsync(TestConstants.EmptyPage); - Assert.Equal(HttpStatusCode.Unauthorized, response.Status); + Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); } [PlaywrightTest("browsercontext-credentials.spec.ts", "should return resource body")] @@ -100,7 +100,7 @@ public async Task ShouldReturnResourceBody() var page = await context.NewPageAsync(); var response = await page.GoToAsync(TestConstants.ServerUrl + "/playground.html"); - Assert.Equal(HttpStatusCode.OK, response.Status); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal("Playground", await page.GetTitleAsync()); Assert.Contains("Playground", await response.GetTextAsync()); } diff --git a/src/PlaywrightSharp.Tests/BrowserContextRouteTests.cs b/src/PlaywrightSharp.Tests/BrowserContextRouteTests.cs index 797a066bf1..d93f81793e 100644 --- a/src/PlaywrightSharp.Tests/BrowserContextRouteTests.cs +++ b/src/PlaywrightSharp.Tests/BrowserContextRouteTests.cs @@ -3,6 +3,7 @@ using System.Net; using System.Net.Http; using System.Threading.Tasks; +using PlaywrightSharp.Contracts.Constants; using PlaywrightSharp.Tests.BaseTests; using PlaywrightSharp.Xunit; using Xunit; @@ -32,11 +33,11 @@ await context.RouteAsync("**/empty.html", (route, _) => intercepted = true; Assert.Contains("empty.html", route.Request.Url); - Assert.False(string.IsNullOrEmpty(route.Request.Headers["user-agent"])); - Assert.Equal(HttpMethod.Get, route.Request.Method); + Assert.False(string.IsNullOrEmpty(route.Request.GetHeaderValue("user-agent"))); + Assert.Equal(HttpMethod.Get.Method, route.Request.Method); Assert.Null(route.Request.PostData); Assert.True(route.Request.IsNavigationRequest); - Assert.Equal(ResourceType.Document, route.Request.ResourceType); + Assert.Equal(ResourceTypes.Document, route.Request.ResourceType, false); Assert.Same(page.MainFrame, route.Request.Frame); Assert.Equal("about:blank", page.MainFrame.Url); diff --git a/src/PlaywrightSharp.Tests/DefaultBrowserContext1Tests.cs b/src/PlaywrightSharp.Tests/DefaultBrowserContext1Tests.cs index 3899394876..8cf5c1c52d 100644 --- a/src/PlaywrightSharp.Tests/DefaultBrowserContext1Tests.cs +++ b/src/PlaywrightSharp.Tests/DefaultBrowserContext1Tests.cs @@ -265,7 +265,7 @@ public async Task ShouldRupportHttpCredentialsOption() Server.SetAuth("/playground.html", "user", "pass"); var response = await page.GoToAsync(TestConstants.ServerUrl + "/playground.html"); - Assert.Equal(HttpStatusCode.OK, response.Status); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); tmp.Dispose(); await context.DisposeAsync(); diff --git a/src/PlaywrightSharp.Tests/FrameGoToTests.cs b/src/PlaywrightSharp.Tests/FrameGoToTests.cs index 2f38488a73..5fd0528ab1 100644 --- a/src/PlaywrightSharp.Tests/FrameGoToTests.cs +++ b/src/PlaywrightSharp.Tests/FrameGoToTests.cs @@ -27,7 +27,7 @@ public async Task ShouldNavigateSubFrames() Assert.Single(Page.Frames.Where(f => f.Url.Contains("/frames/frame.html"))); var childFrame = Page.FirstChildFrame(); var response = await childFrame.GoToAsync(TestConstants.EmptyPage); - Assert.Equal(HttpStatusCode.OK, response.Status); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Same(response.Frame, childFrame); } diff --git a/src/PlaywrightSharp.Tests/IgnoreHttpsErrorsTests.cs b/src/PlaywrightSharp.Tests/IgnoreHttpsErrorsTests.cs index 19b1de4369..2f43d9322f 100644 --- a/src/PlaywrightSharp.Tests/IgnoreHttpsErrorsTests.cs +++ b/src/PlaywrightSharp.Tests/IgnoreHttpsErrorsTests.cs @@ -36,7 +36,7 @@ await TaskUtils.WhenAll( responseTask); var response = responseTask.Result; - Assert.Equal(HttpStatusCode.OK, response.Status); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); } [PlaywrightTest("ignorehttpserrors.spec.ts", "should isolate contexts")] @@ -49,7 +49,7 @@ public async Task ShouldIsolateContexts() var page = await context.NewPageAsync(); var response = await page.GoToAsync(TestConstants.HttpsPrefix + "/empty.html"); - Assert.Equal(HttpStatusCode.OK, response.Status); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); } await using (var context = await Browser.NewContextAsync()) diff --git a/src/PlaywrightSharp.Tests/InterceptionTests.cs b/src/PlaywrightSharp.Tests/InterceptionTests.cs index 7771685cc3..7c237bfe53 100644 --- a/src/PlaywrightSharp.Tests/InterceptionTests.cs +++ b/src/PlaywrightSharp.Tests/InterceptionTests.cs @@ -54,7 +54,7 @@ public async Task ShouldWorkWitIgnoreHTTPSErrors() await page.RouteAsync("**/*", (route, _) => route.ContinueAsync()); var response = await page.GoToAsync(TestConstants.HttpsPrefix + "/empty.html"); - Assert.Equal(HttpStatusCode.OK, response.Status); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); } diff --git a/src/PlaywrightSharp.Tests/NetworkPostDataTests.cs b/src/PlaywrightSharp.Tests/NetworkPostDataTests.cs index f419a9e20d..f96d4997d4 100644 --- a/src/PlaywrightSharp.Tests/NetworkPostDataTests.cs +++ b/src/PlaywrightSharp.Tests/NetworkPostDataTests.cs @@ -47,7 +47,7 @@ public async Task ShouldReturnCorrectPostdataBufferForUtf8Body() var request = task.Result.Request; Assert.Equal(expectedJsonValue, request.PostData); - Assert.Equal(value, request.GetPostDataJson().RootElement.GetString()); + Assert.Equal(value, request.GetPayloadAsJson().RootElement.GetString()); } /// network-post-data.spec.ts @@ -70,7 +70,7 @@ public async Task ShouldReturnPostDataWOContentType() Task.WaitAll(task, actualTask); var request = task.Result.Request; - Assert.Equal(42, request.GetPostDataJson().RootElement.GetProperty("value").GetInt32()); + Assert.Equal(42, request.GetPayloadAsJson().RootElement.GetProperty("value").GetInt32()); } /// network-post-data.spec.ts @@ -92,7 +92,7 @@ public async Task ShouldThrowOnInvalidJSONInPostData() Task.WaitAll(task, actualTask); var request = task.Result.Request; - Assert.ThrowsAny(() => request.GetPostDataJson()); + Assert.ThrowsAny(() => request.GetPayloadAsJson()); } /// network-post-data.spec.ts @@ -114,7 +114,7 @@ public async Task ShouldReturnPostDataForPUTRequests() Task.WaitAll(task, actualTask); var request = task.Result.Request; - Assert.Equal(42, request.GetPostDataJson().RootElement.GetProperty("value").GetInt32()); + Assert.Equal(42, request.GetPayloadAsJson().RootElement.GetProperty("value").GetInt32()); } } } diff --git a/src/PlaywrightSharp.Tests/PageEventNetworkTests.cs b/src/PlaywrightSharp.Tests/PageEventNetworkTests.cs index 62ed236327..fdb0f75022 100644 --- a/src/PlaywrightSharp.Tests/PageEventNetworkTests.cs +++ b/src/PlaywrightSharp.Tests/PageEventNetworkTests.cs @@ -2,6 +2,7 @@ using System.Net; using System.Net.Http; using System.Threading.Tasks; +using PlaywrightSharp.Contracts.Constants; using PlaywrightSharp.Tests.BaseTests; using PlaywrightSharp.TestServer; using PlaywrightSharp.Xunit; @@ -27,8 +28,8 @@ public async Task PageEventsRequest() await Page.GoToAsync(TestConstants.EmptyPage); Assert.Single(requests); Assert.Equal(TestConstants.EmptyPage, requests[0].Url); - Assert.Equal(ResourceType.Document, requests[0].ResourceType); - Assert.Equal(HttpMethod.Get, requests[0].Method); + Assert.Equal(ResourceTypes.Document, requests[0].ResourceType, true); + Assert.Equal(HttpMethod.Get.Method, requests[0].Method); Assert.NotNull(await requests[0].GetResponseAsync()); Assert.Equal(Page.MainFrame, requests[0].Frame); Assert.Equal(TestConstants.EmptyPage, requests[0].Frame.Url); @@ -43,7 +44,7 @@ public async Task PageEventsResponse() await Page.GoToAsync(TestConstants.EmptyPage); Assert.Single(responses); Assert.Equal(TestConstants.EmptyPage, responses[0].Url); - Assert.Equal(HttpStatusCode.OK, responses[0].Status); + Assert.Equal(HttpStatusCode.OK, responses[0].StatusCode); Assert.True(responses[0].Ok); Assert.NotNull(responses[0].Request); } @@ -69,7 +70,7 @@ public async Task PageEventsRequestFailed() Assert.Single(failedRequests); Assert.Contains("one-style.css", failedRequests[0].Url); Assert.Null(await failedRequests[0].GetResponseAsync()); - Assert.Equal(ResourceType.StyleSheet, failedRequests[0].ResourceType); + Assert.Equal(ResourceTypes.Stylesheet, failedRequests[0].ResourceType, true); string error = string.Empty; @@ -89,7 +90,7 @@ public async Task PageEventsRequestFinished() var request = response.Request; Assert.Equal(TestConstants.EmptyPage, request.Url); Assert.NotNull(await request.GetResponseAsync()); - Assert.Equal(HttpMethod.Get, request.Method); + Assert.Equal(HttpMethod.Get.Method, request.Method); Assert.Equal(Page.MainFrame, request.Frame); Assert.Equal(TestConstants.EmptyPage, request.Frame.Url); } @@ -102,7 +103,7 @@ public async Task ShouldFireEventsInProperOrder() Page.Request += (_, _) => events.Add("request"); Page.Response += (_, _) => events.Add("response"); var response = await Page.GoToAsync(TestConstants.EmptyPage); - await response.FinishedAsync(); + await response.GetFinishedAsync(); events.Add("requestfinished"); Assert.Equal(new[] { "request", "response", "requestfinished" }, events); } @@ -119,7 +120,7 @@ public async Task ShouldSupportRedirects() Server.SetRedirect("/foo.html", "/empty.html"); const string FOO_URL = TestConstants.ServerUrl + "/foo.html"; var response = await Page.GoToAsync(FOO_URL); - await response.FinishedAsync(); + await response.GetFinishedAsync(); Assert.Equal(new[] { $"GET {FOO_URL}", $"302 {FOO_URL}", diff --git a/src/PlaywrightSharp.Tests/PageGoToTests.cs b/src/PlaywrightSharp.Tests/PageGoToTests.cs index 97d695f382..fff7c16d17 100644 --- a/src/PlaywrightSharp.Tests/PageGoToTests.cs +++ b/src/PlaywrightSharp.Tests/PageGoToTests.cs @@ -138,7 +138,7 @@ public async Task ShouldWorkWithRedirects() Server.SetRedirect("/redirect/2.html", "/empty.html"); var response = await Page.GoToAsync(TestConstants.ServerUrl + "/redirect/1.html"); - Assert.Equal(HttpStatusCode.OK, response.Status); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); await Page.GoToAsync(TestConstants.EmptyPage); } @@ -155,7 +155,7 @@ public async Task ShouldNavigateToAboutBlank() public async Task ShouldReturnResponseWhenPageChangesItsURLAfterLoad() { var response = await Page.GoToAsync(TestConstants.ServerUrl + "/historyapi.html"); - Assert.Equal(HttpStatusCode.OK, response.Status); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); } [PlaywrightTest("page-goto.spec.ts", "should work with subframes return 204")] @@ -201,7 +201,7 @@ public async Task ShouldFailWhenServerReturns204() public async Task ShouldNavigateToEmptyPageWithDOMContentLoaded() { var response = await Page.GoToAsync(TestConstants.EmptyPage, LifecycleEvent.DOMContentLoaded); - Assert.Equal(HttpStatusCode.OK, response.Status); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); } [PlaywrightTest("page-goto.spec.ts", "should work when page calls history API in beforeunload")] @@ -214,7 +214,7 @@ await Page.EvaluateAsync(@"() => window.addEventListener('beforeunload', () => history.replaceState(null, 'initial', window.location.href), false); }"); var response = await Page.GoToAsync(TestConstants.ServerUrl + "/grid.html"); - Assert.Equal(HttpStatusCode.OK, response.Status); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); } [PlaywrightTest("page-goto.spec.ts", "should fail when navigating to bad url")] @@ -420,7 +420,7 @@ public async Task ShouldFailWhenReplacedByAnotherNavigation() public async Task ShouldWorkWhenNavigatingToValidUrl() { var response = await Page.GoToAsync(TestConstants.EmptyPage); - Assert.Equal(HttpStatusCode.OK, response.Status); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); } [PlaywrightTest("page-goto.spec.ts", "should work when navigating to data url")] @@ -436,7 +436,7 @@ public async Task ShouldWorkWhenNavigatingToDataUrl() public async Task ShouldWorkWhenNavigatingTo404() { var response = await Page.GoToAsync(TestConstants.ServerUrl + "/not-found"); - Assert.Equal(HttpStatusCode.NotFound, response.Status); + Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); } [PlaywrightTest("page-goto.spec.ts", "should return last response in redirect chain")] @@ -448,7 +448,7 @@ public async Task ShouldReturnLastResponseInRedirectChain() Server.SetRedirect("/redirect/3.html", TestConstants.EmptyPage); var response = await Page.GoToAsync(TestConstants.ServerUrl + "/redirect/1.html"); - Assert.Equal(HttpStatusCode.OK, response.Status); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(TestConstants.EmptyPage, response.Url); } @@ -488,7 +488,7 @@ public async Task ShouldNavigateToURLWithHashAndFireRequestsWithoutHash() Page.Request += (_, e) => requests.Add(e.Request); var response = await Page.GoToAsync(TestConstants.EmptyPage + "#hash"); - Assert.Equal(HttpStatusCode.OK, response.Status); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(TestConstants.EmptyPage, response.Url); Assert.Single(requests); Assert.Equal(TestConstants.EmptyPage, requests[0].Url); @@ -499,7 +499,7 @@ public async Task ShouldNavigateToURLWithHashAndFireRequestsWithoutHash() public async Task ShouldWorkWithSelfRequestingPage() { var response = await Page.GoToAsync(TestConstants.ServerUrl + "/self-request.html"); - Assert.Equal(HttpStatusCode.OK, response.Status); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Contains("self-request.html", response.Url); } diff --git a/src/PlaywrightSharp.Tests/PageNetworkIdleTests.cs b/src/PlaywrightSharp.Tests/PageNetworkIdleTests.cs index 9c73fd0047..13933a9ed0 100644 --- a/src/PlaywrightSharp.Tests/PageNetworkIdleTests.cs +++ b/src/PlaywrightSharp.Tests/PageNetworkIdleTests.cs @@ -27,7 +27,7 @@ public PageNetworkIdleTests(ITestOutputHelper output) : base(output) public async Task ShouldNavigateToEmptyPageWithNetworkIdle() { var response = await Page.GoToAsync(TestConstants.EmptyPage, LifecycleEvent.Networkidle); - Assert.Equal(HttpStatusCode.OK, response.Status); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); } [PlaywrightTest("page-network-idle.spec.ts", "should wait for networkidle to succeed navigation")] @@ -195,7 +195,7 @@ async Task RequestDelegate(HttpContext context) lastResponseFinished.Stop(); if (!isSetContent) { - Assert.Equal(HttpStatusCode.OK, navigationResponse.Status); + Assert.Equal(HttpStatusCode.OK, navigationResponse.StatusCode); } } } diff --git a/src/PlaywrightSharp.Tests/PageNetworkRequestTest.cs b/src/PlaywrightSharp.Tests/PageNetworkRequestTest.cs index 89d22676e5..b79a6c60af 100644 --- a/src/PlaywrightSharp.Tests/PageNetworkRequestTest.cs +++ b/src/PlaywrightSharp.Tests/PageNetworkRequestTest.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; +using PlaywrightSharp.Contracts.Constants; using PlaywrightSharp.Tests.BaseTests; using PlaywrightSharp.Xunit; using Xunit; @@ -60,15 +61,16 @@ public async Task ShouldWorkForFetchRequests() public async Task ShouldReturnHeaders() { var response = await Page.GoToAsync(TestConstants.EmptyPage); - Assert.Contains( - TestConstants.Product switch - { - TestConstants.ChromiumProduct => "Chrome", - TestConstants.FirefoxProduct => "Firefox", - TestConstants.WebkitProduct => "WebKit", - _ => "None" - }, - response.Request.Headers["user-agent"]); + + string expected = TestConstants.Product switch + { + TestConstants.ChromiumProduct => "Chrome", + TestConstants.FirefoxProduct => "Firefox", + TestConstants.WebkitProduct => "WebKit", + _ => "None" + }; + + Assert.Contains(response.Request.GetHeaderValues("user-agent"), (f) => f.Contains(expected)); } [PlaywrightTest("page-network-request.spec.ts", "Request.headers", "should get the same headers as the server")] @@ -148,7 +150,7 @@ public async Task ShouldParseTheJsonPostData() Page.Request += (_, e) => request = e.Request; await Page.EvaluateHandleAsync("fetch('./post', { method: 'POST', body: JSON.stringify({ foo: 'bar'})})"); Assert.NotNull(request); - Assert.Equal("bar", request.GetPostDataJson().RootElement.GetProperty("foo").ToString()); + Assert.Equal("bar", request.GetPayloadAsJson().RootElement.GetProperty("foo").ToString()); } [PlaywrightTest("page-network-request.spec.ts", "should parse the data if content-type is application/x-www-form-urlencoded")] @@ -163,7 +165,7 @@ public async Task ShouldParseTheDataIfContentTypeIsApplicationXWwwFormUrlencoded await Page.ClickAsync("input[type=submit]"); Assert.NotNull(request); - var element = request.GetPostDataJson().RootElement; + var element = request.GetPayloadAsJson().RootElement; Assert.Equal("bar", element.GetProperty("foo").ToString()); Assert.Equal("123", element.GetProperty("baz").ToString()); } @@ -173,7 +175,7 @@ public async Task ShouldParseTheDataIfContentTypeIsApplicationXWwwFormUrlencoded public async Task ShouldBeUndefinedWhenThereIsNoPostData2() { var response = await Page.GoToAsync(TestConstants.EmptyPage); - Assert.Null(response.Request.GetPostDataJson()); + Assert.Null(response.Request.GetPayloadAsJson()); } [PlaywrightTest("page-network-request.spec.ts", "should return event source")] @@ -204,7 +206,7 @@ public async Task ShouldReturnEventSource() }); }")); - Assert.Equal(ResourceType.EventSource, requests[0].ResourceType); + Assert.Equal(ResourceTypes.EventSource, requests[0].ResourceType); } [PlaywrightTest("page-network-request.spec.ts", "should return navigation bit")] diff --git a/src/PlaywrightSharp.Tests/PageNetworkResponseTests.cs b/src/PlaywrightSharp.Tests/PageNetworkResponseTests.cs index b05317e6f0..65bd1eb086 100644 --- a/src/PlaywrightSharp.Tests/PageNetworkResponseTests.cs +++ b/src/PlaywrightSharp.Tests/PageNetworkResponseTests.cs @@ -48,7 +48,7 @@ public async Task ShouldWork() }); var response = await Page.GoToAsync(TestConstants.EmptyPage); - Assert.Contains("bar", response.Headers["foo"]); + Assert.Contains("bar", response.GetHeaderValues("foo")); } [PlaywrightTest("page-network-response.spec.ts", "should return json")] @@ -98,7 +98,7 @@ public async Task ShouldReturnUncompressedText() { Server.EnableGzip("/simple.json"); var response = await Page.GoToAsync(TestConstants.ServerUrl + "/simple.json"); - Assert.Equal("gzip", response.Headers["content-encoding"]); + Assert.Equal("gzip", response.GetHeaderValue("content-encoding")); Assert.Equal("{\"foo\": \"bar\"}", (await response.GetTextAsync()).Trim()); } @@ -111,7 +111,7 @@ public async Task ShouldThrowWhenRequestingBodyOfRedirectedResponse() var redirectedFrom = response.Request.RedirectedFrom; Assert.NotNull(redirectedFrom); var redirected = await redirectedFrom.GetResponseAsync(); - Assert.Equal(HttpStatusCode.Redirect, redirected.Status); + Assert.Equal(HttpStatusCode.Redirect, redirected.StatusCode); var exception = await Assert.ThrowsAsync(async () => await redirected.GetTextAsync()); Assert.Contains("Response body is unavailable for redirect responses", exception.Message); @@ -145,7 +145,7 @@ public async Task ShouldWaitUntilResponseCompletes() Assert.NotNull(serverResponse); Assert.NotNull(pageResponse); - Assert.Equal(HttpStatusCode.OK, pageResponse.Response.Status); + Assert.Equal(HttpStatusCode.OK, pageResponse.Response.StatusCode); Assert.False(requestFinished); var responseText = pageResponse.Response.GetTextAsync(); diff --git a/src/PlaywrightSharp.Tests/PageRequestContinueTests.cs b/src/PlaywrightSharp.Tests/PageRequestContinueTests.cs index 2664fa3fb4..1a18195f9f 100644 --- a/src/PlaywrightSharp.Tests/PageRequestContinueTests.cs +++ b/src/PlaywrightSharp.Tests/PageRequestContinueTests.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Net.Http; using System.Threading.Tasks; using PlaywrightSharp.Tests.BaseTests; @@ -32,7 +33,7 @@ public async Task ShouldAmendHTTPHeaders() { await Page.RouteAsync("**/*", (route, request) => { - var headers = new Dictionary(request.Headers) { ["FOO"] = "bar" }; + var headers = new Dictionary(request.Headers.ToDictionary(x => x.Key, x => x.Value)) { ["FOO"] = "bar" }; route.ContinueAsync(headers: headers); }); await Page.GoToAsync(TestConstants.EmptyPage); diff --git a/src/PlaywrightSharp.Tests/PageRequestFulfillTests.cs b/src/PlaywrightSharp.Tests/PageRequestFulfillTests.cs index 397ffd4991..bdc098ecdb 100644 --- a/src/PlaywrightSharp.Tests/PageRequestFulfillTests.cs +++ b/src/PlaywrightSharp.Tests/PageRequestFulfillTests.cs @@ -36,8 +36,8 @@ await Page.RouteAsync("**/*", (route, _) => body: "Yo, page!"); }); var response = await Page.GoToAsync(TestConstants.EmptyPage); - Assert.Equal(HttpStatusCode.Created, response.Status); - Assert.Equal("bar", response.Headers["foo"]); + Assert.Equal(HttpStatusCode.Created, response.StatusCode); + Assert.Equal("bar", response.GetHeaderValue("foo")); Assert.Equal("Yo, page!", await Page.EvaluateAsync("() => document.body.textContent")); } @@ -55,7 +55,7 @@ await Page.RouteAsync("**/*", (route, _) => route.FulfillAsync(HttpStatusCode.UpgradeRequired, "Yo, page!"); }); var response = await Page.GoToAsync(TestConstants.EmptyPage); - Assert.Equal(HttpStatusCode.UpgradeRequired, response.Status); + Assert.Equal(HttpStatusCode.UpgradeRequired, response.StatusCode); Assert.Equal("Upgrade Required", response.StatusText); Assert.Equal("Yo, page!", await Page.EvaluateAsync("() => document.body.textContent")); } @@ -124,8 +124,8 @@ await Page.RouteAsync("**/*", (route, _) => }); var response = await Page.GoToAsync(TestConstants.EmptyPage); - Assert.Equal(HttpStatusCode.OK, response.Status); - Assert.Equal("true", response.Headers["foo"]); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.Equal("true", response.GetHeaderValue("foo")); Assert.Equal("Yo, page!", await Page.EvaluateAsync("() => document.body.textContent")); } @@ -157,7 +157,7 @@ public async Task ShouldNotModifyTheHeadersSentToTheServer() await Page.RouteAsync(TestConstants.CrossProcessUrl + "/something", (route, request) => { playwrightRequest = request; - route.ContinueAsync(headers: request.Headers); + route.ContinueAsync(headers: request.Headers.ToDictionary(x => x.Key, x => x.Value)); }); string textAfterRoute = await Page.EvaluateAsync(@"async url => { @@ -193,7 +193,7 @@ await Page.RouteAsync(TestConstants.CrossProcessUrl + "/something", (route, requ }", TestConstants.CrossProcessUrl + "/something"); Assert.Equal("done", text); - Assert.Equal(TestConstants.ServerUrl, interceptedRequest.Headers["origin"]); + Assert.Equal(TestConstants.ServerUrl, interceptedRequest.GetHeaderValue("origin")); } } } diff --git a/src/PlaywrightSharp.Tests/PageRouteTests.cs b/src/PlaywrightSharp.Tests/PageRouteTests.cs index ec1b1f4b21..80b17b2c75 100644 --- a/src/PlaywrightSharp.Tests/PageRouteTests.cs +++ b/src/PlaywrightSharp.Tests/PageRouteTests.cs @@ -1,11 +1,13 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Net; using System.Net.Http; using System.Text.RegularExpressions; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Primitives; +using PlaywrightSharp.Contracts.Constants; using PlaywrightSharp.Tests.Attributes; using PlaywrightSharp.Tests.BaseTests; using PlaywrightSharp.Xunit; @@ -30,11 +32,11 @@ public async Task ShouldIntercept() await Page.RouteAsync("**/empty.html", (route, request) => { Assert.Contains("empty.html", request.Url); - Assert.True(request.Headers.ContainsKey("user-agent")); - Assert.Equal(HttpMethod.Get, request.Method); + Assert.Contains(request.Headers, x => string.Equals(x.Key, "user-agent", StringComparison.OrdinalIgnoreCase)); + Assert.Equal(HttpMethod.Get.Method, request.Method); Assert.Null(request.PostData); Assert.True(request.IsNavigationRequest); - Assert.Equal(ResourceType.Document, request.ResourceType); + Assert.Equal(ResourceTypes.Document, request.ResourceType, true); Assert.Same(request.Frame, Page.MainFrame); Assert.Equal("about:blank", request.Frame.Url); route.ContinueAsync(); @@ -114,7 +116,7 @@ public async Task ShouldWorkWhenHeaderManipulationHeadersWithRedirect() Server.SetRedirect("/rrredirect", "/empty.html"); await Page.RouteAsync("**/*", (route, _) => { - var headers = new Dictionary(route.Request.Headers) { ["foo"] = "bar" }; + var headers = new Dictionary(route.Request.Headers.ToDictionary(x => x.Key, x => x.Value)) { ["foo"] = "bar" }; route.ContinueAsync(headers: headers); }); await Page.GoToAsync(TestConstants.ServerUrl + "/rrredirect"); @@ -126,7 +128,7 @@ public async Task ShouldBeAbleToRemoveHeaders() { await Page.RouteAsync("**/*", (route, _) => { - var headers = new Dictionary(route.Request.Headers) { ["foo"] = "bar" }; + var headers = new Dictionary(route.Request.Headers.ToDictionary(x => x.Key, x => x.Value)) { ["foo"] = "bar" }; headers.Remove("origin"); route.ContinueAsync(headers: headers); }); @@ -151,7 +153,7 @@ await Page.RouteAsync("**/*", (route, request) => }); await Page.GoToAsync(TestConstants.ServerUrl + "/one-style.html"); Assert.Contains("/one-style.css", requests[1].Url); - Assert.Contains("/one-style.html", requests[1].Headers["referer"]); + Assert.Contains("/one-style.html", requests[1].GetHeaderValue("referer")); } [PlaywrightTest("page-route.spec.ts", "should properly return navigation response when URL has cookies")] @@ -170,7 +172,7 @@ await Context.AddCookiesAsync(new SetNetworkCookieParam // Setup request interception. await Page.RouteAsync("**/*", (route, _) => route.ContinueAsync()); var response = await Page.ReloadAsync(); - Assert.Equal(HttpStatusCode.OK, response.Status); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); } [PlaywrightTest("page-route.spec.ts", "should show custom HTTP headers")] @@ -183,7 +185,7 @@ await Page.SetExtraHTTPHeadersAsync(new Dictionary }); await Page.RouteAsync("**/*", (route, request) => { - Assert.Equal("bar", request.Headers["foo"]); + Assert.Equal("bar", request.GetHeaderValue("foo")); route.ContinueAsync(); }); var response = await Page.GoToAsync(TestConstants.EmptyPage); @@ -213,7 +215,7 @@ public async Task ShouldWorkWithCustomRefererHeaders() await Page.SetExtraHTTPHeadersAsync(new Dictionary { ["referer"] = TestConstants.EmptyPage }); await Page.RouteAsync("**/*", (route, request) => { - Assert.Equal(TestConstants.EmptyPage, request.Headers["referer"]); + Assert.Equal(TestConstants.EmptyPage, request.GetHeaderValue("referer")); route.ContinueAsync(); }); var response = await Page.GoToAsync(TestConstants.EmptyPage); @@ -314,7 +316,7 @@ await Page.RouteAsync("**/*", (route, request) => Assert.Contains("non-existing-page.html", requests[0].Url); Assert.Single(requests); - Assert.Equal(ResourceType.Document, requests[0].ResourceType); + Assert.Equal(ResourceTypes.Document, requests[0].ResourceType, true); Assert.True(requests[0].IsNavigationRequest); var chain = new List(); @@ -356,17 +358,17 @@ await Page.RouteAsync("**/*", (route, request) => Server.SetRoute("/four-style.css", context => context.Response.WriteAsync("body {box-sizing: border-box; }")); var response = await Page.GoToAsync(TestConstants.ServerUrl + "/one-style.html"); - Assert.Equal(HttpStatusCode.OK, response.Status); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Contains("one-style.html", response.Url); Assert.Equal(2, requests.Count); - Assert.Equal(ResourceType.Document, requests[0].ResourceType); + Assert.Equal(ResourceTypes.Document, requests[0].ResourceType, true); Assert.Contains("one-style.html", requests[0].Url); var request = requests[1]; foreach (string url in new[] { "/one-style.css", "/two-style.css", "/three-style.css", "/four-style.css" }) { - Assert.Equal(ResourceType.StyleSheet, request.ResourceType); + Assert.Equal(ResourceTypes.Stylesheet, request.ResourceType, true); Assert.Contains(url, request.Url); request = request.RedirectedTo; } @@ -451,7 +453,7 @@ await Page.RouteAsync("**/*", (route, request) => route.ContinueAsync(); }); var response = await Page.GoToAsync(TestConstants.EmptyPage + "#hash"); - Assert.Equal(HttpStatusCode.OK, response.Status); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(TestConstants.EmptyPage, response.Url); Assert.Single(requests); Assert.Equal(TestConstants.EmptyPage, requests[0].Url); @@ -465,7 +467,7 @@ public async Task ShouldWorkWithEncodedServer() // report URL as-is. @see crbug.com/759388 await Page.RouteAsync("**/*", (route, _) => route.ContinueAsync()); var response = await Page.GoToAsync(TestConstants.ServerUrl + "/some nonexisting page"); - Assert.Equal(HttpStatusCode.NotFound, response.Status); + Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); } [PlaywrightTest("page-route.spec.ts", "should work with badly encoded server")] @@ -475,7 +477,7 @@ public async Task ShouldWorkWithBadlyEncodedServer() Server.SetRoute("/malformed?rnd=%911", _ => Task.CompletedTask); await Page.RouteAsync("**/*", (route, _) => route.ContinueAsync()); var response = await Page.GoToAsync(TestConstants.ServerUrl + "/malformed?rnd=%911"); - Assert.Equal(HttpStatusCode.OK, response.Status); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); } [PlaywrightTest("page-route.spec.ts", "should work with encoded server - 2")] @@ -493,7 +495,7 @@ await Page.RouteAsync("**/*", (route, request) => var response = await Page.GoToAsync($"data:text/html,"); Assert.Null(response); Assert.Single(requests); - Assert.Equal(HttpStatusCode.NotFound, (await requests[0].GetResponseAsync()).Status); + Assert.Equal(HttpStatusCode.NotFound, (await requests[0].GetResponseAsync()).StatusCode); } [PlaywrightTest("page-route.spec.ts", @"should not throw ""Invalid Interception Id"" if the request was cancelled")] diff --git a/src/PlaywrightSharp.Tests/PageWaitForNavigationTests.cs b/src/PlaywrightSharp.Tests/PageWaitForNavigationTests.cs index 75483bad4d..c8d5b97819 100644 --- a/src/PlaywrightSharp.Tests/PageWaitForNavigationTests.cs +++ b/src/PlaywrightSharp.Tests/PageWaitForNavigationTests.cs @@ -30,7 +30,7 @@ await TaskUtils.WhenAll( Page.EvaluateAsync("url => window.location.href = url", TestConstants.ServerUrl + "/grid.html") ); var response = await waitForNavigationResult; - Assert.Equal(HttpStatusCode.OK, response.Status); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Contains("grid.html", response.Url); } @@ -312,7 +312,7 @@ public async Task ShouldWorkOnFrame() frame.WaitForNavigationAsync(), frame.EvaluateAsync("url => window.location.href = url", TestConstants.ServerUrl + "/grid.html") ); - Assert.Equal(HttpStatusCode.OK, response.Status); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Contains("grid.html", response.Url); Assert.Same(frame, response.Frame); Assert.Contains("/frames/one-frame.html", Page.Url); diff --git a/src/PlaywrightSharp.Tests/ResourceTimingTests.cs b/src/PlaywrightSharp.Tests/ResourceTimingTests.cs index 8d05744d2a..8032894d5c 100644 --- a/src/PlaywrightSharp.Tests/ResourceTimingTests.cs +++ b/src/PlaywrightSharp.Tests/ResourceTimingTests.cs @@ -112,7 +112,7 @@ public async Task ShouldWorkForRedirect() await Page.GoToAsync(TestConstants.ServerUrl + "/foo.html"); // This is different on purpose, promises work different in TS. - await responses[1].FinishedAsync(); + await responses[1].GetFinishedAsync(); Assert.Equal(2, responses.Count); Assert.Equal(TestConstants.ServerUrl + "/foo.html", responses[0].Url); @@ -141,6 +141,6 @@ public async Task ShouldWorkForRedirect() Assert.True(timing2.ResponseEnd < 10000); } - private bool VerifyTimingValue(decimal value, decimal previous) => value == -1 || value > 0 && value >= previous; + private bool VerifyTimingValue(float value, float previous) => value == -1 || value > 0 && value >= previous; } } diff --git a/src/PlaywrightSharp/Contracts/Constants/ResourceTypes.cs b/src/PlaywrightSharp/Contracts/Constants/ResourceTypes.cs new file mode 100644 index 0000000000..c671bb4146 --- /dev/null +++ b/src/PlaywrightSharp/Contracts/Constants/ResourceTypes.cs @@ -0,0 +1,59 @@ +/* + * MIT License + * + * Copyright (c) Microsoft Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +namespace PlaywrightSharp.Contracts.Constants +{ + /// + /// Contains the constants of resource types as returned by Playwright. + /// +#pragma warning disable CS1591, SA1600 // Missing XML comment for publicly visible type or member + public static class ResourceTypes + { + public static string Document => "document"; + + public static string Stylesheet => "stylesheet"; + + public static string Image => "image"; + + public static string Media => "media"; + + public static string Font => "font"; + + public static string Script => "script"; + + public static string TextTrack => "texttrack"; + + public static string XHR => "xhr"; + + public static string Fetch => "fetch"; + + public static string EventSource => "eventsource"; + + public static string WebSocket => "websocket"; + + public static string Manifest => "manifest"; + + public static string Other => "other"; + } +#pragma warning restore CS1591, SA1600 // Missing XML comment for publicly visible type or member +} diff --git a/src/PlaywrightSharp/Contracts/Extensions/HeaderExtensions.cs b/src/PlaywrightSharp/Contracts/Extensions/HeaderExtensions.cs new file mode 100644 index 0000000000..eb2a013c93 --- /dev/null +++ b/src/PlaywrightSharp/Contracts/Extensions/HeaderExtensions.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace PlaywrightSharp +{ + /// + /// Contains useful extensions methods. + /// + public static class HeaderExtensions + { + /// + /// Attempts to get the header value for a . + /// + /// The request for headers. + /// The name of the header. + /// Returns the first (if any) header. + public static string GetHeaderValue(this IRequest request, string name) + { + return request?.GetHeaderValues(name)?.FirstOrDefault(); + } + + /// + /// Attempts to get the header value for a . + /// + /// The request for headers. + /// The name of the header. + /// Returns the all the values for the header, or null, if none. + public static string[] GetHeaderValues(this IRequest request, string name) + { + return GetValues(request?.Headers, name); + } + + /// + /// Attempts to get the header value for a . + /// + /// The response containing the headers. + /// The name of the header. + /// Returns the first (if any) header. + public static string GetHeaderValue(this IResponse response, string name) + { + return response?.GetHeaderValues(name)?.FirstOrDefault(); + } + + /// + /// Attempts to get the header value for a . + /// + /// The response containing the headers. + /// The name of the header. + /// Returns the all the values for the header, or null, if none. + public static string[] GetHeaderValues(this IResponse response, string name) + { + return GetValues(response?.Headers, name); + } + + private static string[] GetValues(IEnumerable> collection, string name) + { + if (collection == null) + { + return null; + } + + string[] values = collection + .Where(x => x.Key.Equals(name, StringComparison.OrdinalIgnoreCase)) + .Select(x => x.Value).ToArray(); + + if (values.Length == 0) + { + return null; + } + + return values; + } + } +} diff --git a/src/PlaywrightSharp/Contracts/IRequest.generated.cs b/src/PlaywrightSharp/Contracts/IRequest.generated.cs new file mode 100644 index 0000000000..65b516b7e0 --- /dev/null +++ b/src/PlaywrightSharp/Contracts/IRequest.generated.cs @@ -0,0 +1,162 @@ +/* + * MIT License + * + * Copyright (c) Microsoft Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * + * ------------------------------------------------------------------------------ + * + * This code was generated by a tool at: + * /utils/doclint/generateDotnetApi.js + * + * Changes to this file may cause incorrect behavior and will be lost if + * the code is regenerated. + * + * ------------------------------------------------------------------------------ + */ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Globalization; +using System.IO; +using System.Runtime.Serialization; +using System.Text.Json; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; + +namespace PlaywrightSharp +{ + /// + /// + /// Whenever the page sends a request for a network resource the following sequence + /// of events are emitted by : + /// + /// + /// emitted when the request is issued by the page. + /// + /// emitted when/if the response status and headers are + /// received for the request. + /// + /// + /// emitted when the response body is downloaded + /// and the request is complete. + /// + /// + /// + /// If request fails at some point, then instead of 'requestfinished' event (and + /// possibly instead of 'response' event), the event + /// is emitted. + /// + /// + /// If request gets a 'redirect' response, the request is successfully finished with + /// the 'requestfinished' event, and a new request is issued to a redirected url. + /// + /// + /// + /// + /// HTTP Error responses, such as 404 or 503, are still successful responses from HTTP + /// standpoint, so request will complete with 'requestfinished' event. + /// + /// + public partial interface IRequest + { + /// + /// + /// The method returns null unless this request has failed, as reported by requestfailed + /// event. + /// + /// Example of logging of all the failed requests: + /// + string Failure { get; } + + /// Returns the that initiated this request. + IFrame Frame { get; } + + /// An object with HTTP headers associated with the request. All header names are lower-case. + IEnumerable> Headers { get; } + + /// Whether this request is driving frame's navigation. + bool IsNavigationRequest { get; } + + /// Request's method (GET, POST, etc.) + string Method { get; } + + /// Request's post body, if any. + string PostData { get; } + + /// Request's post body in a binary form, if any. + byte[] PostDataBuffer { get; } + + /// + /// Request that was redirected by the server to this one, if any. + /// + /// When the server responds with a redirect, Playwright creates a new + /// object. The two requests are connected by redirectedFrom() and redirectedTo() + /// methods. When multiple server redirects has happened, it is possible to construct + /// the whole redirect chain by repeatedly calling redirectedFrom(). + /// + /// For example, if the website http://example.com redirects to https://example.com: + /// If the website https://google.com has no redirects: + /// + IRequest RedirectedFrom { get; } + + /// + /// New request issued by the browser if the server responded with redirect. + /// This method is the opposite of : + /// + IRequest RedirectedTo { get; } + + /// + /// + /// Contains the request's resource type as it was perceived by the rendering engine. + /// You can use to + /// access the constants for all the values available as a result of this method. + /// + /// + string ResourceType { get; } + + /// + /// + /// Returns the matching object, or null if the response + /// was not received due to error. + /// + /// + Task GetResponseAsync(); + + /// + /// + /// Returns resource timing information for given request. Most of the timing values + /// become available upon the response, responseEnd becomes available when request + /// finishes. Find more information at Resource + /// Timing API. + /// + /// + RequestTimingResult Timing { get; } + + /// URL of the request. + string Url { get; } + + /// Returns a representation of . + /// The JSON Document Options. + JsonDocument GetPayloadAsJson(JsonDocumentOptions documentOptions = default); + } +} diff --git a/src/PlaywrightSharp/Contracts/IResponse.cs b/src/PlaywrightSharp/Contracts/IResponse.cs new file mode 100644 index 0000000000..1203d4b129 --- /dev/null +++ b/src/PlaywrightSharp/Contracts/IResponse.cs @@ -0,0 +1,18 @@ +using System.Text.Json; +using System.Threading.Tasks; + +namespace PlaywrightSharp +{ + /// + /// Partial . + /// + public partial interface IResponse + { + /// + /// . + /// + /// The Document options. + /// Returns a representation. + Task GetJsonAsync(JsonDocumentOptions options = default); + } +} diff --git a/src/PlaywrightSharp/Contracts/IResponse.generated.cs b/src/PlaywrightSharp/Contracts/IResponse.generated.cs new file mode 100644 index 0000000000..626a9f2461 --- /dev/null +++ b/src/PlaywrightSharp/Contracts/IResponse.generated.cs @@ -0,0 +1,100 @@ +/* + * MIT License + * + * Copyright (c) Microsoft Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * + * ------------------------------------------------------------------------------ + * + * This code was generated by a tool at: + * /utils/doclint/generateDotnetApi.js + * + * Changes to this file may cause incorrect behavior and will be lost if + * the code is regenerated. + * + * ------------------------------------------------------------------------------ + */ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Globalization; +using System.IO; +using System.Runtime.Serialization; +using System.Text.Json; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; + +namespace PlaywrightSharp +{ + /// class represents responses which are received by page. + public partial interface IResponse + { + /// Returns the buffer with response body. + Task GetBodyAsync(); + + /// Waits for this response to finish, returns failure error if request failed. + Task GetFinishedAsync(); + + /// Returns the that initiated this response. + IFrame Frame { get; } + + /// + /// + /// Returns the object with HTTP headers associated with the response. All header names + /// are lower-case. + /// + /// + IEnumerable> Headers { get; } + + /// + /// Returns the JSON representation of response body. + /// This method will throw if the response body is not parsable via JSON.parse. + /// + Task GetJsonAsync(); + + /// + /// + /// Contains a boolean stating whether the response was successful (status in the range + /// 200-299) or not. + /// + /// + bool Ok { get; } + + /// Returns the matching object. + IRequest Request { get; } + + /// Contains the status code of the response (e.g., 200 for a success). + int Status { get; } + + /// Contains the status text of the response (e.g. usually an "OK" for a success). + string StatusText { get; } + + /// Returns the text representation of response body. + Task GetTextAsync(); + + /// Contains the URL of the response. + string Url { get; } + + /// Gets the code of the response. + System.Net.HttpStatusCode StatusCode { get; } + } +} diff --git a/src/PlaywrightSharp/Contracts/Models/RequestTimingResult.generated.cs b/src/PlaywrightSharp/Contracts/Models/RequestTimingResult.generated.cs new file mode 100644 index 0000000000..74fabde795 --- /dev/null +++ b/src/PlaywrightSharp/Contracts/Models/RequestTimingResult.generated.cs @@ -0,0 +1,136 @@ +/* + * MIT License + * + * Copyright (c) Microsoft Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * + * ------------------------------------------------------------------------------ + * + * This code was generated by a tool at: + * /utils/doclint/generateDotnetApi.js + * + * Changes to this file may cause incorrect behavior and will be lost if + * the code is regenerated. + * + * ------------------------------------------------------------------------------ + */ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Globalization; +using System.IO; +using System.Runtime.Serialization; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; + +namespace PlaywrightSharp +{ + /// + /// Result of calling . + /// + public partial class RequestTimingResult + { + /// Request start time in milliseconds elapsed since January 1, 1970 00:00:00 UTC + [JsonPropertyName("startTime")] + public float StartTime { get; set; } + + /// + /// + /// Time immediately before the browser starts the domain name lookup for the resource. + /// The value is given in milliseconds relative to startTime, -1 if not available. + /// + /// + [JsonPropertyName("domainLookupStart")] + public float DomainLookupStart { get; set; } + + /// + /// + /// Time immediately after the browser starts the domain name lookup for the resource. + /// The value is given in milliseconds relative to startTime, -1 if not available. + /// + /// + [JsonPropertyName("domainLookupEnd")] + public float DomainLookupEnd { get; set; } + + /// + /// + /// Time immediately before the user agent starts establishing the connection to the + /// server to retrieve the resource. The value is given in milliseconds relative to + /// startTime, -1 if not available. + /// + /// + [JsonPropertyName("connectStart")] + public float ConnectStart { get; set; } + + /// + /// + /// Time immediately before the browser starts the handshake process to secure the current + /// connection. The value is given in milliseconds relative to startTime, -1 + /// if not available. + /// + /// + [JsonPropertyName("secureConnectionStart")] + public float SecureConnectionStart { get; set; } + + /// + /// + /// Time immediately before the user agent starts establishing the connection to the + /// server to retrieve the resource. The value is given in milliseconds relative to + /// startTime, -1 if not available. + /// + /// + [JsonPropertyName("connectEnd")] + public float ConnectEnd { get; set; } + + /// + /// + /// Time immediately before the browser starts requesting the resource from the server, + /// cache, or local resource. The value is given in milliseconds relative to startTime, + /// -1 if not available. + /// + /// + [JsonPropertyName("requestStart")] + public float RequestStart { get; set; } + + /// + /// + /// Time immediately after the browser starts requesting the resource from the server, + /// cache, or local resource. The value is given in milliseconds relative to startTime, + /// -1 if not available. + /// + /// + [JsonPropertyName("responseStart")] + public float ResponseStart { get; set; } + + /// + /// + /// Time immediately after the browser receives the last byte of the resource or immediately + /// before the transport connection is closed, whichever comes first. The value is given + /// in milliseconds relative to startTime, -1 if not available. + /// + /// + [JsonPropertyName("responseEnd")] + public float ResponseEnd { get; set; } + } +} diff --git a/src/PlaywrightSharp/Frame.cs b/src/PlaywrightSharp/Frame.cs index b656e5198b..05100bf571 100644 --- a/src/PlaywrightSharp/Frame.cs +++ b/src/PlaywrightSharp/Frame.cs @@ -24,14 +24,12 @@ * SOFTWARE. */ using System; -using System.Collections; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; using System.Text.Json; using System.Text.RegularExpressions; -using System.Threading; using System.Threading.Tasks; using PlaywrightSharp.Helpers; using PlaywrightSharp.Input; diff --git a/src/PlaywrightSharp/Helpers/JsonExtensions.cs b/src/PlaywrightSharp/Helpers/JsonExtensions.cs index 69265b9f50..7bfaa05b5b 100644 --- a/src/PlaywrightSharp/Helpers/JsonExtensions.cs +++ b/src/PlaywrightSharp/Helpers/JsonExtensions.cs @@ -71,7 +71,6 @@ internal static JsonSerializerOptions GetNewDefaultSerializerOptions(bool ignore IgnoreNullValues = ignoreNullValues, Converters = { - new FlexibleStringEnumConverter(ResourceType.Unknown), new MixedStateConverter(), new JsonStringEnumMemberConverter(JsonNamingPolicy.CamelCase), }, diff --git a/src/PlaywrightSharp/IRequest.cs b/src/PlaywrightSharp/IRequest.cs deleted file mode 100644 index 0703e6824f..0000000000 --- a/src/PlaywrightSharp/IRequest.cs +++ /dev/null @@ -1,93 +0,0 @@ -using System.Collections.Generic; -using System.Net.Http; -using System.Text.Json; -using System.Threading.Tasks; - -namespace PlaywrightSharp -{ - /// - /// Whenever the page sends a request, the following events are emitted by an . - /// emitted when the request is issued by the page. - /// - public interface IRequest - { - /// - /// URL of the request. - /// - string Url { get; } - - /// - /// Gets or sets the HTTP method. - /// - HttpMethod Method { get; } - - /// - /// Gets or sets the HTTP headers. - /// - Dictionary Headers { get; } - - /// - /// Post data as string. - /// - string PostData { get; } - - /// - /// Post data as a byte[]. - /// - byte[] PostDataBuffer { get; } - - /// - /// An that initiated this request, or null if navigating to error pages. - /// - IFrame Frame { get; } - - /// - /// Gets whether this request is driving frame's navigation. - /// - bool IsNavigationRequest { get; } - - /// - /// Gets or sets the type of the resource. - /// - ResourceType ResourceType { get; } - - /// - /// When the server responds with a redirect, Playwright creates a new object. - /// The two requests are connected by and methods. - /// When multiple server redirects has happened, it is possible to construct the whole redirect chain by repeatedly calling . - /// - IRequest RedirectedFrom { get; } - - /// - /// When the server responds with a redirect, Playwright creates a new object. - /// The two requests are connected by and methods. - /// When multiple server redirects has happened, it is possible to construct the whole redirect chain by repeatedly calling .. - /// - IRequest RedirectedTo { get; } - - /// - /// Gets or sets the failure. - /// - string Failure { get; } - - /// - /// Returns resource timing information for given request. - /// Most of the timing values become available upon the response, responseEnd becomes available when request finishes. - /// Find more information at Resource Timing API. - /// - public ResourceTiming Timing { get; } - - /// - /// Responsed attached to the request. - /// - /// A that completes when the response is resolved. - Task GetResponseAsync(); - - /// - /// Returns the parsed request's body for form-urlencoded and JSON as a fallback if any. - /// - /// Parser options. - /// A representing the request body. - JsonDocument GetPostDataJson(JsonDocumentOptions options = default); - } -} diff --git a/src/PlaywrightSharp/IResponse.cs b/src/PlaywrightSharp/IResponse.cs deleted file mode 100644 index 2c1f4c87bf..0000000000 --- a/src/PlaywrightSharp/IResponse.cs +++ /dev/null @@ -1,81 +0,0 @@ -using System.Collections.Generic; -using System.Net; -using System.Text.Json; -using System.Threading.Tasks; - -namespace PlaywrightSharp -{ - /// - /// Represents responses which are received by page. - /// - public interface IResponse - { - /// - /// Status code of the response. - /// - HttpStatusCode Status { get; } - - /// - /// Contains the status text of the response (e.g. usually an "OK" for a success). - /// - string StatusText { get; } - - /// - /// An that initiated this response, or null if navigating to error pages. - /// - IFrame Frame { get; } - - /// - /// The URL of the response. - /// - string Url { get; } - - /// - /// An object with HTTP headers associated with the response. All header names are lower-case. - /// - IDictionary Headers { get; } - - /// - /// Whether the response was successful (status in the range 200-299) or not. - /// - bool Ok { get; } - - /// - /// A matching object. - /// - IRequest Request { get; } - - /// - /// A text representation of response body. - /// - /// A that completes when the text was processed, yielding to a text representation of response body. - Task GetTextAsync(); - - /// - /// Returns a which resolves to a representation of response body. - /// - /// Parser options. - /// A that completes when the json body is parsed, yielding a representation of response body. - Task GetJsonAsync(JsonDocumentOptions options = default); - - /// - /// Returns a which resolves to a representation of response body. - /// - /// Return type. - /// Parser options. - /// A that completes when the json body is parsed, yielding a representation of response body. - Task GetJsonAsync(JsonSerializerOptions options = null); - - /// - /// Returns a which resolves to a buffer with response body. - /// - /// A that completes when the response is returned by the server, yielding a array. - Task GetBodyAsync(); - - /// - /// Waits for this response to finish, returns failure error if request failed. - /// - /// A that completes when the response finished. - Task FinishedAsync(); - } -} diff --git a/src/PlaywrightSharp/Request.cs b/src/PlaywrightSharp/Request.cs index 6877e348c3..fb3463f5dd 100644 --- a/src/PlaywrightSharp/Request.cs +++ b/src/PlaywrightSharp/Request.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; -using System.Collections.Specialized; -using System.Net.Http; +using System.Linq; using System.Text; using System.Text.Json; using System.Threading.Tasks; @@ -20,11 +19,12 @@ public class Request : ChannelOwnerBase, IChannelOwner, IRequest internal Request(IChannelOwner parent, string guid, RequestInitializer initializer) : base(parent, guid) { + // TODO: Consider using a mapper between RequestInitiliazer and this object _channel = new RequestChannel(guid, parent.Connection, this); _initializer = initializer; RedirectedFrom = _initializer.RedirectedFrom?.Object; PostDataBuffer = _initializer.PostData != null ? Convert.FromBase64String(_initializer.PostData) : null; - Timing = new ResourceTiming(); + Timing = new RequestTimingResult(); if (RedirectedFrom != null) { @@ -33,10 +33,11 @@ internal Request(IChannelOwner parent, string guid, RequestInitializer initializ if (initializer.Headers != null) { - foreach (var kv in initializer.Headers) - { - Headers[kv.Name] = kv.Value; - } + Headers = initializer.Headers.Select(x => new KeyValuePair(x.Name, x.Value)).ToArray(); + } + else + { + Headers = Array.Empty>(); } } @@ -46,68 +47,58 @@ internal Request(IChannelOwner parent, string guid, RequestInitializer initializ /// IChannel IChannelOwner.Channel => _channel; - /// - public ResourceTiming Timing { get; internal set; } + /// + public string Failure { get; internal set; } + + /// + public IFrame Frame => _initializer.Frame; - /// - public string Url => _initializer.Url; + /// + public IEnumerable> Headers { get; } - /// - public HttpMethod Method => _initializer.Method; + /// + public bool IsNavigationRequest => _initializer.IsNavigationRequest; - /// - public Dictionary Headers { get; } = new Dictionary(StringComparer.OrdinalIgnoreCase); + /// + public string Method => _initializer.Method.Method; - /// + /// public string PostData => PostDataBuffer == null ? null : Encoding.UTF8.GetString(PostDataBuffer); - /// + /// public byte[] PostDataBuffer { get; } - /// - public IFrame Frame => _initializer.Frame; - - /// - public bool IsNavigationRequest => _initializer.IsNavigationRequest; - - /// - public ResourceType ResourceType => _initializer.ResourceType; - - /// - public string Failure { get; internal set; } - - /// + /// public IRequest RedirectedFrom { get; } - /// + /// public IRequest RedirectedTo { get; internal set; } - internal Request FinalRequest => RedirectedTo != null ? ((Request)RedirectedTo).FinalRequest : this; + /// + public string ResourceType => _initializer.ResourceType; - /// - public async Task GetResponseAsync() => (await _channel.GetResponseAsync().ConfigureAwait(false))?.Object; + /// + public RequestTimingResult Timing { get; internal set; } - /// - public JsonDocument GetPostDataJson(JsonDocumentOptions options = default) - { - string content = GetRequestForJson(); + /// + public string Url => _initializer.Url; - if (content == null) - { - return null; - } + internal Request FinalRequest => RedirectedTo != null ? ((Request)RedirectedTo).FinalRequest : this; - return JsonDocument.Parse(content, options); - } + /// + public async Task GetResponseAsync() => (await _channel.GetResponseAsync().ConfigureAwait(false))?.Object; - private string GetRequestForJson() + /// + public JsonDocument GetPayloadAsJson(JsonDocumentOptions documentOptions = default) { if (PostData == null) { return null; } - if (Headers.TryGetValue("content-type", out string contentType) && contentType == "application/x-www-form-urlencoded") + string content = PostData; + + if ("application/x-www-form-urlencoded".Equals(this.GetHeaderValue("content-type"), StringComparison.OrdinalIgnoreCase)) { var parsed = HttpUtility.ParseQueryString(PostData); var dictionary = new Dictionary(); @@ -117,10 +108,15 @@ private string GetRequestForJson() dictionary[key] = parsed[key]; } - return JsonSerializer.Serialize(dictionary); + content = JsonSerializer.Serialize(dictionary); + } + + if (content == null) + { + return null; } - return PostData; + return JsonDocument.Parse(content, documentOptions); } } } diff --git a/src/PlaywrightSharp/ResourceTiming.cs b/src/PlaywrightSharp/ResourceTiming.cs deleted file mode 100644 index e3e2ab2368..0000000000 --- a/src/PlaywrightSharp/ResourceTiming.cs +++ /dev/null @@ -1,61 +0,0 @@ -namespace PlaywrightSharp -{ - /// - /// See . - /// - public class ResourceTiming - { - /// - /// Request start time in milliseconds elapsed since January 1, 1970 00:00:00 UTC. - /// - public decimal StartTime { get; set; } - - /// - /// Time immediately before the browser starts the domain name lookup for the resource. - /// The value is given in milliseconds relative to startTime, -1 if not available. - /// - public decimal DomainLookupStart { get; set; } = -1; - - /// - /// Time immediately after the browser starts the domain name lookup for the resource. - /// The value is given in milliseconds relative to startTime, -1 if not available. - /// - public decimal DomainLookupEnd { get; set; } = -1; - - /// - /// Time immediately before the user agent starts establishing the connection to the server to retrieve the resource. - /// The value is given in milliseconds relative to startTime, -1 if not available. - /// - public decimal ConnectStart { get; set; } = -1; - - /// - /// Time immediately before the browser starts the handshake process to secure the current connection. - /// The value is given in milliseconds relative to startTime, -1 if not available. - /// - public decimal SecureConnectionStart { get; set; } = -1; - - /// - /// Time immediately before the user agent starts establishing the connection to the server to retrieve the resource. - /// The value is given in milliseconds relative to startTime, -1 if not available. - /// - public decimal ConnectEnd { get; set; } = -1; - - /// - /// Time immediately before the browser starts requesting the resource from the server, cache, or local resource. - /// The value is given in milliseconds relative to startTime, -1 if not available. - /// - public decimal RequestStart { get; set; } = -1; - - /// - /// Time immediately after the browser starts requesting the resource from the server, cache, or local resource. - /// The value is given in milliseconds relative to startTime, -1 if not available. - /// - public decimal ResponseStart { get; set; } = -1; - - /// - /// Time immediately after the browser receives the last byte of the resource or immediately before the transport connection is closed, whichever comes first. - /// The value is given in milliseconds relative to startTime, -1 if not available. - /// - public decimal ResponseEnd { get; set; } = -1; - } -} diff --git a/src/PlaywrightSharp/ResourceType.cs b/src/PlaywrightSharp/ResourceType.cs deleted file mode 100644 index 6034c387a8..0000000000 --- a/src/PlaywrightSharp/ResourceType.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System.Runtime.Serialization; -using System.Text.Json.Serialization; -using PlaywrightSharp.Helpers; - -namespace PlaywrightSharp -{ - /// - /// Resource type. - /// - /// - public enum ResourceType - { - /// - /// Unknown. - /// - Unknown = -1, - - /// - /// Document. - /// - Document, - - /// - /// Stylesheet. - /// - [EnumMember(Value = "stylesheet")] - StyleSheet, - - /// - /// Image. - /// - Image, - - /// - /// Media. - /// - Media, - - /// - /// Font. - /// - Font, - - /// - /// Script. - /// - Script, - - /// - /// Texttrack. - /// - [EnumMember(Value = "texttrack")] - TextTrack, - - /// - /// XHR. - /// - Xhr, - - /// - /// Fetch. - /// - Fetch, - - /// - /// Event source. - /// - [EnumMember(Value = "eventsource")] - EventSource, - - /// - /// Web Socket. - /// - [EnumMember(Value = "websocket")] - WebSocket, - - /// - /// Manifest. - /// - Manifest, - - /// - /// Ping. - /// - Ping, - - /// - /// Other. - /// - Other, - - /// - /// SignedExchange. - /// - SignedExchange, - - /// - /// CSPViolationReport. - /// - CSPViolationReport, - - /// - /// Images. - /// - Images, - - /// - /// Beacon. - /// - Beacon, - } -} diff --git a/src/PlaywrightSharp/Response.cs b/src/PlaywrightSharp/Response.cs index 262932e984..0158bf9204 100644 --- a/src/PlaywrightSharp/Response.cs +++ b/src/PlaywrightSharp/Response.cs @@ -32,41 +32,50 @@ internal Response(IChannelOwner parent, string guid, ResponseInitializer initial } } - /// - ChannelBase IChannelOwner.Channel => _channel; + /// + public IFrame Frame => _initializer.Request.Object.Frame; - /// - IChannel IChannelOwner.Channel => _channel; + /// + public IEnumerable> Headers => _headers; /// - public HttpStatusCode Status => _initializer.Status; + public bool Ok => Status is 0 or >= 200 and <= 299; /// - public string StatusText => _initializer.StatusText; + public IRequest Request => _initializer.Request.Object; /// - public IFrame Frame => _initializer.Request.Object.Frame; + public int Status => _initializer.Status; /// - public string Url => _initializer.Url; + public string StatusText => _initializer.StatusText; /// - public IDictionary Headers => _headers; + public string Url => _initializer.Url; + + /// + public HttpStatusCode StatusCode => (HttpStatusCode)this.Status; + + /// + ChannelBase IChannelOwner.Channel => _channel; + + /// + IChannel IChannelOwner.Channel => _channel; /// - public bool Ok => Status == 0 || ((int)Status >= 200 && (int)Status <= 299); + public async Task GetBodyAsync() => Convert.FromBase64String(await _channel.GetBodyAsync().ConfigureAwait(false)); /// - public IRequest Request => _initializer.Request.Object; + public Task GetFinishedAsync() => _channel.FinishedAsync(); /// - public async Task GetTextAsync() + public async Task GetJsonAsync() { - byte[] content = await GetBodyAsync().ConfigureAwait(false); - return Encoding.UTF8.GetString(content); + string content = await GetTextAsync().ConfigureAwait(false); + return JsonSerializer.Deserialize(content, _channel.Connection.GetDefaultJsonSerializerOptions()); } - /// + /// public async Task GetJsonAsync(JsonDocumentOptions options = default) { string content = await GetTextAsync().ConfigureAwait(false); @@ -74,16 +83,10 @@ public async Task GetJsonAsync(JsonDocumentOptions options = defau } /// - public async Task GetJsonAsync(JsonSerializerOptions options = null) + public async Task GetTextAsync() { - string content = await GetTextAsync().ConfigureAwait(false); - return JsonSerializer.Deserialize(content, options ?? _channel.Connection.GetDefaultJsonSerializerOptions()); + byte[] content = await GetBodyAsync().ConfigureAwait(false); + return Encoding.UTF8.GetString(content); } - - /// - public async Task GetBodyAsync() => Convert.FromBase64String(await _channel.GetBodyAsync().ConfigureAwait(false)); - - /// - public Task FinishedAsync() => _channel.FinishedAsync(); } } diff --git a/src/PlaywrightSharp/Transport/Channels/PageChannelRequestEventArgs.cs b/src/PlaywrightSharp/Transport/Channels/PageChannelRequestEventArgs.cs index 9c37b65798..b47eec7eb9 100644 --- a/src/PlaywrightSharp/Transport/Channels/PageChannelRequestEventArgs.cs +++ b/src/PlaywrightSharp/Transport/Channels/PageChannelRequestEventArgs.cs @@ -8,6 +8,6 @@ internal class PageChannelRequestEventArgs : EventArgs public string FailureText { get; set; } - public decimal ResponseEndTiming { get; set; } + public float ResponseEndTiming { get; set; } } } diff --git a/src/PlaywrightSharp/Transport/Channels/ResponseChannel.cs b/src/PlaywrightSharp/Transport/Channels/ResponseChannel.cs index 3e09c1555e..e7712f47f8 100644 --- a/src/PlaywrightSharp/Transport/Channels/ResponseChannel.cs +++ b/src/PlaywrightSharp/Transport/Channels/ResponseChannel.cs @@ -1,4 +1,5 @@ using System; +using System.Text.Json; using System.Threading.Tasks; namespace PlaywrightSharp.Transport.Channels @@ -12,6 +13,18 @@ public ResponseChannel(string guid, Connection connection, Response owner) : bas internal async Task GetBodyAsync() => (await Connection.SendMessageToServerAsync(Guid, "body", null).ConfigureAwait(false))?.GetProperty("binary").ToString(); - internal Task FinishedAsync() => Connection.SendMessageToServerAsync(Guid, "finished", null); + internal async Task FinishedAsync() + { + var element = await Connection.SendMessageToServerAsync(Guid, "finished", null).ConfigureAwait(false); + if (element != null) + { + if (element.Value.TryGetProperty("error", out var errorValue)) + { + return errorValue.GetString(); + } + } + + return null; + } } } diff --git a/src/PlaywrightSharp/Transport/Protocol/RequestInitializer.cs b/src/PlaywrightSharp/Transport/Protocol/RequestInitializer.cs index b8380a2f29..f2f786245d 100644 --- a/src/PlaywrightSharp/Transport/Protocol/RequestInitializer.cs +++ b/src/PlaywrightSharp/Transport/Protocol/RequestInitializer.cs @@ -20,6 +20,6 @@ internal class RequestInitializer public RequestChannel RedirectedFrom { get; set; } - public ResourceType ResourceType { get; set; } + public string ResourceType { get; set; } } } diff --git a/src/PlaywrightSharp/Transport/Protocol/ResponseInitializer.cs b/src/PlaywrightSharp/Transport/Protocol/ResponseInitializer.cs index 7fbaee863e..c3f7213b70 100644 --- a/src/PlaywrightSharp/Transport/Protocol/ResponseInitializer.cs +++ b/src/PlaywrightSharp/Transport/Protocol/ResponseInitializer.cs @@ -1,12 +1,11 @@ using System.Collections.Generic; -using System.Net; using PlaywrightSharp.Transport.Channels; namespace PlaywrightSharp.Transport.Protocol { internal class ResponseInitializer { - public HttpStatusCode Status { get; set; } + public int Status { get; set; } public string Url { get; set; } @@ -16,6 +15,6 @@ internal class ResponseInitializer public RequestChannel Request { get; set; } - public ResourceTiming Timing { get; set; } + public RequestTimingResult Timing { get; set; } } }