Skip to content
20 changes: 10 additions & 10 deletions dotnet/src/webdriver/BiDi/BiDi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ internal Session.SessionModule SessionModule
if (_sessionModule is not null) return _sessionModule;
lock (_moduleLock)
{
_sessionModule ??= new Session.SessionModule(_broker);
_sessionModule ??= Module.Create<Session.SessionModule>(_broker);
}
return _sessionModule;
}
Expand All @@ -68,7 +68,7 @@ public BrowsingContext.BrowsingContextModule BrowsingContext
if (_browsingContextModule is not null) return _browsingContextModule;
lock (_moduleLock)
{
_browsingContextModule ??= new BrowsingContext.BrowsingContextModule(_broker);
_browsingContextModule ??= Module.Create<BrowsingContext.BrowsingContextModule>(_broker);
}
return _browsingContextModule;
}
Expand All @@ -81,7 +81,7 @@ public Browser.BrowserModule Browser
if (_browserModule is not null) return _browserModule;
lock (_moduleLock)
{
_browserModule ??= new Browser.BrowserModule(_broker);
_browserModule ??= Module.Create<Browser.BrowserModule>(_broker);
}
return _browserModule;
}
Expand All @@ -94,7 +94,7 @@ public Network.NetworkModule Network
if (_networkModule is not null) return _networkModule;
lock (_moduleLock)
{
_networkModule ??= new Network.NetworkModule(_broker);
_networkModule ??= Module.Create<Network.NetworkModule>(_broker);
}
return _networkModule;
}
Expand All @@ -107,7 +107,7 @@ internal Input.InputModule InputModule
if (_inputModule is not null) return _inputModule;
lock (_moduleLock)
{
_inputModule ??= new Input.InputModule(_broker);
_inputModule ??= Module.Create<Input.InputModule>(_broker);
}
return _inputModule;
}
Expand All @@ -120,7 +120,7 @@ public Script.ScriptModule Script
if (_scriptModule is not null) return _scriptModule;
lock (_moduleLock)
{
_scriptModule ??= new Script.ScriptModule(_broker);
_scriptModule ??= Module.Create<Script.ScriptModule>(_broker);
}
return _scriptModule;
}
Expand All @@ -133,7 +133,7 @@ public Log.LogModule Log
if (_logModule is not null) return _logModule;
lock (_moduleLock)
{
_logModule ??= new Log.LogModule(_broker);
_logModule ??= Module.Create<Log.LogModule>(_broker);
}
return _logModule;
}
Expand All @@ -146,7 +146,7 @@ public Storage.StorageModule Storage
if (_storageModule is not null) return _storageModule;
lock (_moduleLock)
{
_storageModule ??= new Storage.StorageModule(_broker);
_storageModule ??= Module.Create<Storage.StorageModule>(_broker);
}
return _storageModule;
}
Expand All @@ -159,7 +159,7 @@ public WebExtension.WebExtensionModule WebExtension
if (_webExtensionModule is not null) return _webExtensionModule;
lock (_moduleLock)
{
_webExtensionModule ??= new WebExtension.WebExtensionModule(_broker);
_webExtensionModule ??= Module.Create<WebExtension.WebExtensionModule>(_broker);
}
return _webExtensionModule;
}
Expand All @@ -172,7 +172,7 @@ public Emulation.EmulationModule Emulation
if (_emulationModule is not null) return _emulationModule;
lock (_moduleLock)
{
_emulationModule ??= new Emulation.EmulationModule(_broker);
_emulationModule ??= Module.Create<Emulation.EmulationModule>(_broker);
}
return _emulationModule;
}
Expand Down
24 changes: 22 additions & 2 deletions dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@
// under the License.
// </copyright>

using System.Threading.Tasks;
using OpenQA.Selenium.BiDi.Communication;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using System.Threading.Tasks;

namespace OpenQA.Selenium.BiDi.Browser;

public sealed class BrowserModule(Broker broker) : Module(broker)
public sealed class BrowserModule : Module
{
public async Task<EmptyResult> CloseAsync(CloseOptions? options = null)
{
Expand Down Expand Up @@ -73,4 +75,22 @@ public async Task<EmptyResult> SetDownloadBehaviorDeniedAsync(SetDownloadBehavio

return await Broker.ExecuteCommandAsync<SetDownloadBehaviorCommand, EmptyResult>(new SetDownloadBehaviorCommand(@params), options).ConfigureAwait(false);
}

protected internal override void Initialize(Broker broker)
{
broker.ConfigureJsonContext(opts => opts.TypeInfoResolverChain.Add(BrowserModuleJsonSerializerContext.Default));
}
}

[JsonSerializable(typeof(CloseCommand))]
[JsonSerializable(typeof(CreateUserContextCommand))]
[JsonSerializable(typeof(GetUserContextsCommand))]
[JsonSerializable(typeof(GetUserContextsResult))]
[JsonSerializable(typeof(RemoveUserContextCommand))]
[JsonSerializable(typeof(GetClientWindowsCommand))]
[JsonSerializable(typeof(GetClientWindowsResult))]
[JsonSerializable(typeof(SetDownloadBehaviorCommand))]
[JsonSerializable(typeof(UserContextInfo))]
[JsonSerializable(typeof(IReadOnlyList<UserContextInfo>))]
[JsonSerializable(typeof(IReadOnlyList<ClientWindowInfo>))]
internal partial class BrowserModuleJsonSerializerContext : JsonSerializerContext;
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

namespace OpenQA.Selenium.BiDi.BrowsingContext;

public sealed class BrowsingContextModule(Broker broker) : Module(broker)
public sealed class BrowsingContextModule : Module
{
public async Task<BrowsingContext> CreateAsync(ContextType type, CreateOptions? options = null)
{
Expand Down Expand Up @@ -250,4 +250,9 @@ public async Task<Subscription> OnUserPromptClosedAsync(Action<UserPromptClosedE
{
return await Broker.SubscribeAsync("browsingContext.userPromptClosed", handler, options).ConfigureAwait(false);
}

protected internal override void Initialize(Broker broker)
{

}
}
30 changes: 15 additions & 15 deletions dotnet/src/webdriver/BiDi/Communication/Broker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,14 @@ public sealed class Broker : IAsyncDisposable
private Task? _eventEmitterTask;
private CancellationTokenSource? _receiveMessagesCancellationTokenSource;

private readonly BiDiJsonSerializerContext _jsonSerializerContext;
private readonly JsonSerializerOptions _jsonSerializerOptions;

internal Broker(BiDi bidi, Uri url)
{
_bidi = bidi;
_transport = new WebSocketTransport(url);

var jsonSerializerOptions = new JsonSerializerOptions
_jsonSerializerOptions = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
Expand Down Expand Up @@ -108,7 +108,14 @@ internal Broker(BiDi bidi, Uri url)
}
};

_jsonSerializerContext = new BiDiJsonSerializerContext(jsonSerializerOptions);
// Add base BiDi generated context resolver; keep options mutable for module contexts
_jsonSerializerOptions.TypeInfoResolverChain.Add(BiDiJsonSerializerContext.Default);
}

public void ConfigureJsonContext(Action<JsonSerializerOptions> action)
{
// Keep options mutable; do not create a context bound to them (avoids InvalidOperationException)
action(_jsonSerializerOptions);
}

public async Task ConnectAsync(CancellationToken cancellationToken)
Expand Down Expand Up @@ -205,21 +212,14 @@ private async Task<EmptyResult> ExecuteCommandCoreAsync<TCommand>(TCommand comma
where TCommand : Command
{
command.Id = Interlocked.Increment(ref _currentCommandId);

var tcs = new TaskCompletionSource<EmptyResult>(TaskCreationOptions.RunContinuationsAsynchronously);

var timeout = options?.Timeout ?? TimeSpan.FromSeconds(30);

using var cts = new CancellationTokenSource(timeout);

cts.Token.Register(() => tcs.TrySetCanceled(cts.Token));

_pendingCommands[command.Id] = new(command.Id, command.ResultType, tcs);

var data = JsonSerializer.SerializeToUtf8Bytes(command, typeof(TCommand), _jsonSerializerContext);

var data = JsonSerializer.SerializeToUtf8Bytes(command, typeof(TCommand), _jsonSerializerOptions);
await _transport.SendAsync(data, cts.Token).ConfigureAwait(false);

return await tcs.Task.ConfigureAwait(false);
}

Expand Down Expand Up @@ -341,11 +341,11 @@ private void ProcessReceivedMessage(byte[]? data)
break;

case "result":
resultReader = reader; // cloning reader with current position
resultReader = reader; // snapshot
break;

case "params":
paramsReader = reader; // cloning reader with current position
paramsReader = reader; // snapshot
break;

case "error":
Expand All @@ -368,7 +368,7 @@ private void ProcessReceivedMessage(byte[]? data)

if (_pendingCommands.TryGetValue(id.Value, out var successCommand))
{
var messageSuccess = JsonSerializer.Deserialize(ref resultReader, successCommand.ResultType, _jsonSerializerContext)!;
var messageSuccess = JsonSerializer.Deserialize(ref resultReader, successCommand.ResultType, _jsonSerializerOptions)!;
successCommand.TaskCompletionSource.SetResult((EmptyResult)messageSuccess);
_pendingCommands.TryRemove(id.Value, out _);
}
Expand All @@ -384,7 +384,7 @@ private void ProcessReceivedMessage(byte[]? data)

if (_eventTypesMap.TryGetValue(method, out var eventType))
{
var eventArgs = (EventArgs)JsonSerializer.Deserialize(ref paramsReader, eventType, _jsonSerializerContext)!;
var eventArgs = (EventArgs)JsonSerializer.Deserialize(ref paramsReader, eventType, _jsonSerializerOptions)!;

var messageEvent = new MessageEvent(method, eventArgs);
_pendingEvents.Add(messageEvent);
Expand Down
7 changes: 6 additions & 1 deletion dotnet/src/webdriver/BiDi/Emulation/EmulationModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

namespace OpenQA.Selenium.BiDi.Emulation;

public sealed class EmulationModule(Broker broker) : Module(broker)
public sealed class EmulationModule : Module
{
public async Task<EmptyResult> SetTimezoneOverrideAsync(string? timezone, SetTimezoneOverrideOptions? options = null)
{
Expand Down Expand Up @@ -89,4 +89,9 @@ public async Task<EmptyResult> SetGeolocationPositionErrorOverrideAsync(SetGeolo

return await Broker.ExecuteCommandAsync<SetGeolocationOverrideCommand, EmptyResult>(new SetGeolocationOverrideCommand(@params), options).ConfigureAwait(false);
}

protected internal override void Initialize(Broker broker)
{
throw new NotImplementedException();
}
}
7 changes: 6 additions & 1 deletion dotnet/src/webdriver/BiDi/Input/InputModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

namespace OpenQA.Selenium.BiDi.Input;

public sealed class InputModule(Broker broker) : Module(broker)
public sealed class InputModule : Module
{
public async Task<EmptyResult> PerformActionsAsync(BrowsingContext.BrowsingContext context, IEnumerable<SourceActions> actions, PerformActionsOptions? options = null)
{
Expand All @@ -45,4 +45,9 @@ public async Task<EmptyResult> SetFilesAsync(BrowsingContext.BrowsingContext con

return await Broker.ExecuteCommandAsync<SetFilesCommand, EmptyResult>(new SetFilesCommand(@params), options).ConfigureAwait(false);
}

protected internal override void Initialize(Broker broker)
{
throw new System.NotImplementedException();
}
}
7 changes: 6 additions & 1 deletion dotnet/src/webdriver/BiDi/Log/LogModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

namespace OpenQA.Selenium.BiDi.Log;

public sealed class LogModule(Broker broker) : Module(broker)
public sealed class LogModule : Module
{
public async Task<Subscription> OnEntryAddedAsync(Func<LogEntry, Task> handler, SubscriptionOptions? options = null)
{
Expand All @@ -34,4 +34,9 @@ public async Task<Subscription> OnEntryAddedAsync(Action<LogEntry> handler, Subs
{
return await Broker.SubscribeAsync("log.entryAdded", handler, options).ConfigureAwait(false);
}

protected internal override void Initialize(Broker broker)
{
throw new NotImplementedException();
}
}
14 changes: 12 additions & 2 deletions dotnet/src/webdriver/BiDi/Module.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,17 @@

namespace OpenQA.Selenium.BiDi;

public abstract class Module(Broker broker)
public abstract class Module
{
protected Broker Broker { get; } = broker;
protected Broker Broker { get; private set; }

protected internal abstract void Initialize(Broker broker);

public static TModule Create<TModule>(Broker broker) where TModule : Module, new()
{
TModule module = new();
module.Broker = broker;
module.Initialize(broker);
return module;
}
}
7 changes: 6 additions & 1 deletion dotnet/src/webdriver/BiDi/Network/NetworkModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

namespace OpenQA.Selenium.BiDi.Network;

public sealed partial class NetworkModule(Broker broker) : Module(broker)
public sealed partial class NetworkModule : Module
{
public async Task<Collector> AddDataCollectorAsync(IEnumerable<DataType> DataTypes, int MaxEncodedDataSize, AddDataCollectorOptions? options = null)
{
Expand Down Expand Up @@ -173,4 +173,9 @@ public async Task<Subscription> OnAuthRequiredAsync(Action<AuthRequiredEventArgs
{
return await Broker.SubscribeAsync("network.authRequired", handler, options).ConfigureAwait(false);
}

protected internal override void Initialize(Broker broker)
{
throw new System.NotImplementedException();
}
}
7 changes: 6 additions & 1 deletion dotnet/src/webdriver/BiDi/Script/ScriptModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

namespace OpenQA.Selenium.BiDi.Script;

public sealed class ScriptModule(Broker broker) : Module(broker)
public sealed class ScriptModule : Module
{
public async Task<EvaluateResult> EvaluateAsync(string expression, bool awaitPromise, Target target, EvaluateOptions? options = null)
{
Expand Down Expand Up @@ -105,4 +105,9 @@ public async Task<Subscription> OnRealmDestroyedAsync(Action<RealmDestroyedEvent
{
return await Broker.SubscribeAsync("script.realmDestroyed", handler, options).ConfigureAwait(false);
}

protected internal override void Initialize(Broker broker)
{
throw new NotImplementedException();
}
}
7 changes: 6 additions & 1 deletion dotnet/src/webdriver/BiDi/Session/SessionModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

namespace OpenQA.Selenium.BiDi.Session;

internal sealed class SessionModule(Broker broker) : Module(broker)
internal sealed class SessionModule : Module
{
public async Task<StatusResult> StatusAsync(StatusOptions? options = null)
{
Expand Down Expand Up @@ -55,4 +55,9 @@ public async Task<EmptyResult> EndAsync(EndOptions? options = null)
{
return await Broker.ExecuteCommandAsync<EndCommand, EmptyResult>(new EndCommand(), options).ConfigureAwait(false);
}

protected internal override void Initialize(Broker broker)
{
throw new System.NotImplementedException();
}
}
7 changes: 6 additions & 1 deletion dotnet/src/webdriver/BiDi/Storage/StorageModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

namespace OpenQA.Selenium.BiDi.Storage;

public sealed class StorageModule(Broker broker) : Module(broker)
public sealed class StorageModule : Module
{
public async Task<GetCookiesResult> GetCookiesAsync(GetCookiesOptions? options = null)
{
Expand All @@ -44,4 +44,9 @@ public async Task<SetCookieResult> SetCookieAsync(PartialCookie cookie, SetCooki

return await Broker.ExecuteCommandAsync<SetCookieCommand, SetCookieResult>(new SetCookieCommand(@params), options).ConfigureAwait(false);
}

protected internal override void Initialize(Broker broker)
{
throw new System.NotImplementedException();
}
}
Loading
Loading