diff --git a/dotnet/src/webdriver/BiDi/BiDi.cs b/dotnet/src/webdriver/BiDi/BiDi.cs index b65b15078cbd1..e6933b933e660 100644 --- a/dotnet/src/webdriver/BiDi/BiDi.cs +++ b/dotnet/src/webdriver/BiDi/BiDi.cs @@ -52,9 +52,12 @@ private BiDi() { } public Emulation.IEmulationModule Emulation => AsModule(); - public static async Task ConnectAsync(string url, BiDiOptions? options = null, CancellationToken cancellationToken = default) + public static async Task ConnectAsync(string url, Action? configure = null, CancellationToken cancellationToken = default) { - var transport = await WebSocketTransport.ConnectAsync(new Uri(url), cancellationToken).ConfigureAwait(false); + BiDiOptionsBuilder builder = new(); + configure?.Invoke(builder); + + var transport = await builder.TransportFactory(new Uri(url), cancellationToken).ConfigureAwait(false); BiDi bidi = new(); diff --git a/dotnet/src/webdriver/BiDi/BiDiOptions.cs b/dotnet/src/webdriver/BiDi/BiDiOptions.cs deleted file mode 100644 index 7bcac32ca6c0d..0000000000000 --- a/dotnet/src/webdriver/BiDi/BiDiOptions.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Licensed to the Software Freedom Conservancy (SFC) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The SFC licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -// - -namespace OpenQA.Selenium.BiDi; - -public sealed class BiDiOptions -{ -} diff --git a/dotnet/src/webdriver/BiDi/BiDiOptionsBuilder.cs b/dotnet/src/webdriver/BiDi/BiDiOptionsBuilder.cs new file mode 100644 index 0000000000000..96b17b516bb56 --- /dev/null +++ b/dotnet/src/webdriver/BiDi/BiDiOptionsBuilder.cs @@ -0,0 +1,48 @@ +// +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +using System.Net.WebSockets; + +namespace OpenQA.Selenium.BiDi; + +/// +/// Provides a fluent API for configuring BiDi connection options, +/// such as the underlying transport mechanism. +/// +public sealed class BiDiOptionsBuilder +{ + internal Func> TransportFactory { get; private set; } + = (uri, ct) => WebSocketTransport.ConnectAsync(uri, null, ct); + + /// + /// Configures the BiDi connection to use a WebSocket transport. + /// + /// + /// WebSocket is the default transport; calling this method is only necessary + /// when you need to customize the underlying + /// (e.g., to set headers, proxy, or certificates). + /// + /// An optional action to configure the before connecting. + /// The current instance for chaining. + public BiDiOptionsBuilder UseWebSocket(Action? configure = null) + { + TransportFactory = (uri, ct) => WebSocketTransport.ConnectAsync(uri, configure, ct); + return this; + } +} diff --git a/dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs b/dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs index 124d6bebd18b6..f3eed2d70a17d 100644 --- a/dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs +++ b/dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs @@ -21,7 +21,7 @@ namespace OpenQA.Selenium.BiDi; public static class WebDriverExtensions { - public static async Task AsBiDiAsync(this IWebDriver webDriver, BiDiOptions? options = null, CancellationToken cancellationToken = default) + public static async Task AsBiDiAsync(this IWebDriver webDriver, Action? configure = null, CancellationToken cancellationToken = default) { if (webDriver is null) throw new ArgumentNullException(nameof(webDriver)); @@ -34,7 +34,7 @@ public static async Task AsBiDiAsync(this IWebDriver webDriver, BiDiOptio if (webSocketUrl is null) throw new BiDiException("The driver is not compatible with bidirectional protocol or \"webSocketUrl\" not enabled in driver options."); - var bidi = await BiDi.ConnectAsync(webSocketUrl, options, cancellationToken).ConfigureAwait(false); + var bidi = await BiDi.ConnectAsync(webSocketUrl, configure, cancellationToken).ConfigureAwait(false); return bidi; } diff --git a/dotnet/src/webdriver/BiDi/WebSocketTransport.cs b/dotnet/src/webdriver/BiDi/WebSocketTransport.cs index fcab07b9a7770..6b0920500b6d3 100644 --- a/dotnet/src/webdriver/BiDi/WebSocketTransport.cs +++ b/dotnet/src/webdriver/BiDi/WebSocketTransport.cs @@ -32,12 +32,14 @@ sealed class WebSocketTransport(ClientWebSocket webSocket) : ITransport private readonly SemaphoreSlim _socketSendSemaphoreSlim = new(1, 1); private readonly MemoryStream _sharedMemoryStream = new(); - public static async Task ConnectAsync(Uri uri, CancellationToken cancellationToken) + public static async Task ConnectAsync(Uri uri, Action? configure, CancellationToken cancellationToken) { ClientWebSocket webSocket = new(); try { + configure?.Invoke(webSocket.Options); + await webSocket.ConnectAsync(uri, cancellationToken).ConfigureAwait(false); } catch (Exception)