Skip to content

Commit 53abf4d

Browse files
authored
Fix should navigate to about:blank in webdriver (#2816)
* Fix should navigate to about:blank in webdriver * Fix some TCS
1 parent aacc4e8 commit 53abf4d

File tree

3 files changed

+79
-44
lines changed

3 files changed

+79
-44
lines changed

lib/PuppeteerSharp.Nunit/TestExpectations/TestExpectations.local.json

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -98,21 +98,6 @@
9898
"FAIL"
9999
]
100100
},
101-
{
102-
"comment": "This is part of organizing the webdriver bidi implementation, We will remove it one by one",
103-
"testIdPattern": "[navigation.spec] *should navigate to about:blank*",
104-
"platforms": [
105-
"darwin",
106-
"linux",
107-
"win32"
108-
],
109-
"parameters": [
110-
"webDriverBiDi"
111-
],
112-
"expectations": [
113-
"FAIL"
114-
]
115-
},
116101
{
117102
"comment": "This is part of organizing the webdriver bidi implementation, We will remove it one by one",
118103
"testIdPattern": "[navigation.spec] navigation Page.waitForNavigation*",

lib/PuppeteerSharp/Bidi/BidiFrame.cs

Lines changed: 77 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@
2323
using System;
2424
using System.Collections.Concurrent;
2525
using System.Collections.Generic;
26+
using System.Linq;
2627
using System.Threading.Tasks;
2728
using PuppeteerSharp.Bidi.Core;
29+
using PuppeteerSharp.Helpers;
2830

2931
namespace PuppeteerSharp.Bidi;
3032

@@ -102,40 +104,55 @@ public override async Task<IResponse> GoToAsync(string url, NavigationOptions op
102104
}
103105

104106
/// <inheritdoc />
105-
public override Task<IResponse> WaitForNavigationAsync(NavigationOptions options = null)
107+
public override async Task<IResponse> WaitForNavigationAsync(NavigationOptions options = null)
106108
{
107-
// TODO: This logic is missing tons of things.
108-
var navigationTcs = new TaskCompletionSource<IResponse>(TaskCreationOptions.RunContinuationsAsynchronously);
109+
var timeout = options?.Timeout ?? TimeoutSettings.NavigationTimeout;
109110

110-
// TODO: Async void is not safe. Refactor code.
111-
BrowsingContext.Navigation += (sender, args) =>
111+
async Task<Navigation> WaitForEventNavigationAsync()
112112
{
113-
args.Navigation.RequestCreated += async (o, eventArgs) =>
113+
// TODO: This logic is missing tons of things.
114+
var navigationTcs = new TaskCompletionSource<Navigation>(TaskCreationOptions.RunContinuationsAsynchronously);
115+
116+
// TODO: Async void is not safe. Refactor code.
117+
BrowsingContext.Navigation += (sender, args) => navigationTcs.TrySetResult(args.Navigation);
118+
119+
await navigationTcs.Task.ConfigureAwait(false);
120+
121+
var waitForLoadTask = WaitForLoadAsync(options);
122+
123+
// TODO: Add frame detached event.
124+
// TODO: Add fragment, failed and aborted events.
125+
await Task.WhenAny(waitForLoadTask).WithTimeout(timeout).ConfigureAwait(false);
126+
127+
return navigationTcs.Task.Result;
128+
}
129+
130+
var waitForEventNavigationTask = WaitForEventNavigationAsync();
131+
var waitForNetworkIdleTask = WaitForNetworkIdleAsync(options);
132+
133+
var waitForResponse = new Func<Task<IResponse>>(async () =>
134+
{
135+
await Task.WhenAll(waitForEventNavigationTask, waitForNetworkIdleTask).ConfigureAwait(false);
136+
var navigation = waitForEventNavigationTask.Result;
137+
var request = navigation.Request;
138+
139+
if (navigation.Request == null)
114140
{
115-
try
116-
{
117-
var httpRequest = await BidiHttpRequest.Requests.GetItemAsync(args.Navigation.Request)
118-
.ConfigureAwait(false);
119-
120-
if (httpRequest.Response != null)
121-
{
122-
navigationTcs.TrySetResult(httpRequest.Response);
123-
return;
124-
}
125-
126-
args.Navigation.Request.Success += (o, eventArgs) =>
127-
{
128-
navigationTcs.TrySetResult(httpRequest.Response);
129-
};
130-
}
131-
catch (Exception ex)
132-
{
133-
navigationTcs.TrySetException(ex);
134-
}
135-
};
136-
};
141+
return null;
142+
}
143+
144+
var lastRequest = request.LastRedirect ?? request;
145+
BidiHttpRequest.Requests.TryGetValue(lastRequest, out var httpRequest);
137146

138-
return navigationTcs.Task;
147+
return httpRequest.Response;
148+
});
149+
150+
var waitForResponseTask = waitForResponse();
151+
152+
// TODO: Listen to frame detached event.
153+
await Task.WhenAny(waitForResponseTask).WithTimeout(timeout).ConfigureAwait(false);
154+
155+
return waitForResponseTask.Result;
139156
}
140157

141158
internal static BidiFrame From(BidiPage parentPage, BidiFrame parentFrame, BrowsingContext browsingContext)
@@ -155,6 +172,37 @@ private PuppeteerException RewriteNavigationError(Exception ex, string url, int
155172
: new PuppeteerException("Navigation failed: " + ex.Message, ex);
156173
}
157174

175+
private Task WaitForLoadAsync(NavigationOptions options)
176+
{
177+
var waitUntil = options?.WaitUntil ?? new[] { WaitUntilNavigation.Load };
178+
var timeout = options?.Timeout ?? TimeoutSettings.NavigationTimeout;
179+
180+
List<Task> tasks = new();
181+
182+
if (waitUntil.Contains(WaitUntilNavigation.Load))
183+
{
184+
var loadTcs = new TaskCompletionSource<bool>();
185+
BrowsingContext.Load += (sender, args) => loadTcs.TrySetResult(true);
186+
tasks.Add(loadTcs.Task);
187+
}
188+
189+
if (waitUntil.Contains(WaitUntilNavigation.DOMContentLoaded))
190+
{
191+
var domContentLoadedTcs = new TaskCompletionSource<bool>();
192+
BrowsingContext.DomContentLoaded += (sender, args) => domContentLoadedTcs.TrySetResult(true);
193+
tasks.Add(domContentLoadedTcs.Task);
194+
}
195+
196+
// TODO: Check frame detached event.
197+
return Task.WhenAll(tasks).WithTimeout(timeout);
198+
}
199+
200+
private Task WaitForNetworkIdleAsync(NavigationOptions options)
201+
{
202+
// TODO: Complete this method.
203+
return Task.CompletedTask;
204+
}
205+
158206
private async Task NavigateAsync(string url)
159207
{
160208
// Some implementations currently only report errors when the

lib/PuppeteerSharp/Bidi/Core/Request.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ private Request(BrowsingContext browsingContext, BeforeRequestSentEventArgs args
5858

5959
public FetchTimingInfo Timings { get; private set; }
6060

61+
public Request LastRedirect { get; set; }
62+
6163
public static Request From(BrowsingContext browsingContext, BeforeRequestSentEventArgs args)
6264
{
6365
var request = new Request(browsingContext, args);

0 commit comments

Comments
 (0)