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
6 changes: 5 additions & 1 deletion dotnet/src/webdriver/BiDi/BiDi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,11 @@ public static async Task<IBiDi> ConnectAsync(Uri url, Action<BiDiOptionsBuilder>
BiDiOptionsBuilder builder = new();
configure?.Invoke(builder);

var transport = await builder.TransportFactory(url, cancellationToken).ConfigureAwait(false);
var transportFactoryTask = builder.TransportFactory(url, cancellationToken)
?? throw new InvalidOperationException("The transport factory must return a non-null Task<ITransport> instance.");

var transport = await transportFactoryTask.ConfigureAwait(false)
Comment thread
qodo-code-review[bot] marked this conversation as resolved.
Comment thread
qodo-code-review[bot] marked this conversation as resolved.
?? throw new InvalidOperationException("The transport factory must return a non-null ITransport instance.");

BiDi bidi = new();

Expand Down
36 changes: 15 additions & 21 deletions dotnet/src/webdriver/BiDi/BiDiOptionsBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,11 @@ namespace OpenQA.Selenium.BiDi;
/// </summary>
public sealed class BiDiOptionsBuilder
{
private static readonly Func<Uri, CancellationToken, Task<ITransport>> DefaultTransportFactory =
(uri, ct) => WebSocketTransport.ConnectAsync(uri, null, ct);

internal Func<Uri, CancellationToken, Task<ITransport>> TransportFactory { get; private set; }
= (uri, ct) => WebSocketTransport.ConnectAsync(uri, null, ct);
= DefaultTransportFactory;

/// <summary>
/// Configures the BiDi connection to use a WebSocket transport.
Expand All @@ -42,36 +45,27 @@ public sealed class BiDiOptionsBuilder
/// <returns>The current <see cref="BiDiOptionsBuilder"/> instance for chaining.</returns>
public BiDiOptionsBuilder UseWebSocket(Action<ClientWebSocketOptions>? configure = null)
{
return UseTransport((uri, ct) => WebSocketTransport.ConnectAsync(uri, configure, ct));
TransportFactory = (uri, ct) => WebSocketTransport.ConnectAsync(uri, configure, ct);
return this;
}

/// <summary>
/// Configures the BiDi connection to use a transport created by the specified factory.
/// Composes a transport factory into the current transport pipeline.
/// </summary>
/// <remarks>
/// BiDi takes ownership of the transport instance returned by the factory and will dispose it.
/// The <paramref name="next"/> callback receives the current transport factory and returns
/// the next factory in the chain. BiDi takes ownership of the transport instance returned by
/// the final factory and will dispose it.
/// </remarks>
/// <param name="factory">A factory function that creates the <see cref="ITransport"/> instance.</param>
/// <param name="next">A callback that composes a new transport factory from the current one.</param>
/// <returns>The current <see cref="BiDiOptionsBuilder"/> instance for chaining.</returns>
public BiDiOptionsBuilder UseTransport(Func<ITransport> factory)
public BiDiOptionsBuilder UseTransport(Func<Func<Uri, CancellationToken, Task<ITransport>>, Func<Uri, CancellationToken, Task<ITransport>>> next)
Comment thread
qodo-code-review[bot] marked this conversation as resolved.
{
ArgumentNullException.ThrowIfNull(factory);

return UseTransport((_, ct) =>
{
if (ct.IsCancellationRequested)
{
return Task.FromCanceled<ITransport>(ct);
}
ArgumentNullException.ThrowIfNull(next);

var transport = factory() ?? throw new InvalidOperationException("The transport factory must return a non-null ITransport instance.");
var factory = next(TransportFactory)
?? throw new InvalidOperationException("The transport factory decorator must return a non-null factory.");

return Task.FromResult(transport);
});
}

private BiDiOptionsBuilder UseTransport(Func<Uri, CancellationToken, Task<ITransport>> factory)
{
TransportFactory = factory;
return this;
Comment thread
nvborisenko marked this conversation as resolved.
}
Expand Down
3 changes: 2 additions & 1 deletion dotnet/test/webdriver/BiDi/SessionUnitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ class SessionUnitTests
public async Task SetUp()
{
_transport = new FakeTransport();
_bidi = await Selenium.BiDi.BiDi.ConnectAsync(new Uri("ws://fake"), opts => opts.UseTransport(() => _transport));
_bidi = await Selenium.BiDi.BiDi.ConnectAsync(new Uri("ws://fake"), opts =>
opts.UseTransport(_ => (_, _) => Task.FromResult<ITransport>(_transport)));
}

[TearDown]
Expand Down