Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -98,21 +98,6 @@
"FAIL"
]
},
{
"comment": "This is part of organizing the webdriver bidi implementation, We will remove it one by one",
"testIdPattern": "[navigation.spec] *should navigate to about:blank*",
"platforms": [
"darwin",
"linux",
"win32"
],
"parameters": [
"webDriverBiDi"
],
"expectations": [
"FAIL"
]
},
{
"comment": "This is part of organizing the webdriver bidi implementation, We will remove it one by one",
"testIdPattern": "[navigation.spec] navigation Page.waitForNavigation*",
Expand Down
106 changes: 77 additions & 29 deletions lib/PuppeteerSharp/Bidi/BidiFrame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using PuppeteerSharp.Bidi.Core;
using PuppeteerSharp.Helpers;

namespace PuppeteerSharp.Bidi;

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

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

// TODO: Async void is not safe. Refactor code.
BrowsingContext.Navigation += (sender, args) =>
async Task<Navigation> WaitForEventNavigationAsync()
{
args.Navigation.RequestCreated += async (o, eventArgs) =>
// TODO: This logic is missing tons of things.
var navigationTcs = new TaskCompletionSource<Navigation>(TaskCreationOptions.RunContinuationsAsynchronously);

// TODO: Async void is not safe. Refactor code.
BrowsingContext.Navigation += (sender, args) => navigationTcs.TrySetResult(args.Navigation);

await navigationTcs.Task.ConfigureAwait(false);

var waitForLoadTask = WaitForLoadAsync(options);

// TODO: Add frame detached event.
// TODO: Add fragment, failed and aborted events.
await Task.WhenAny(waitForLoadTask).WithTimeout(timeout).ConfigureAwait(false);

return navigationTcs.Task.Result;
}

var waitForEventNavigationTask = WaitForEventNavigationAsync();
var waitForNetworkIdleTask = WaitForNetworkIdleAsync(options);

var waitForResponse = new Func<Task<IResponse>>(async () =>
{
await Task.WhenAll(waitForEventNavigationTask, waitForNetworkIdleTask).ConfigureAwait(false);
var navigation = waitForEventNavigationTask.Result;
var request = navigation.Request;

if (navigation.Request == null)
{
try
{
var httpRequest = await BidiHttpRequest.Requests.GetItemAsync(args.Navigation.Request)
.ConfigureAwait(false);

if (httpRequest.Response != null)
{
navigationTcs.TrySetResult(httpRequest.Response);
return;
}

args.Navigation.Request.Success += (o, eventArgs) =>
{
navigationTcs.TrySetResult(httpRequest.Response);
};
}
catch (Exception ex)
{
navigationTcs.TrySetException(ex);
}
};
};
return null;
}

var lastRequest = request.LastRedirect ?? request;
BidiHttpRequest.Requests.TryGetValue(lastRequest, out var httpRequest);

return navigationTcs.Task;
return httpRequest.Response;
});

var waitForResponseTask = waitForResponse();

// TODO: Listen to frame detached event.
await Task.WhenAny(waitForResponseTask).WithTimeout(timeout).ConfigureAwait(false);

return waitForResponseTask.Result;
}

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

private Task WaitForLoadAsync(NavigationOptions options)
{
var waitUntil = options?.WaitUntil ?? new[] { WaitUntilNavigation.Load };
var timeout = options?.Timeout ?? TimeoutSettings.NavigationTimeout;

List<Task> tasks = new();

if (waitUntil.Contains(WaitUntilNavigation.Load))
{
var loadTcs = new TaskCompletionSource<bool>();
BrowsingContext.Load += (sender, args) => loadTcs.TrySetResult(true);
tasks.Add(loadTcs.Task);
}

if (waitUntil.Contains(WaitUntilNavigation.DOMContentLoaded))
{
var domContentLoadedTcs = new TaskCompletionSource<bool>();
BrowsingContext.DomContentLoaded += (sender, args) => domContentLoadedTcs.TrySetResult(true);
tasks.Add(domContentLoadedTcs.Task);
}

// TODO: Check frame detached event.
return Task.WhenAll(tasks).WithTimeout(timeout);
}

private Task WaitForNetworkIdleAsync(NavigationOptions options)
{
// TODO: Complete this method.
return Task.CompletedTask;
}

private async Task NavigateAsync(string url)
{
// Some implementations currently only report errors when the
Expand Down
2 changes: 2 additions & 0 deletions lib/PuppeteerSharp/Bidi/Core/Request.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ private Request(BrowsingContext browsingContext, BeforeRequestSentEventArgs args

public FetchTimingInfo Timings { get; private set; }

public Request LastRedirect { get; set; }

public static Request From(BrowsingContext browsingContext, BeforeRequestSentEventArgs args)
{
var request = new Request(browsingContext, args);
Expand Down
Loading