From b595dfc343af8b3df900d084db390ac82b9500f7 Mon Sep 17 00:00:00 2001 From: Michael Render Date: Sat, 11 Oct 2025 17:04:00 -0400 Subject: [PATCH 01/25] [dotnet] Enable external BiDi modules --- dotnet/src/webdriver/BiDi/BiDi.cs | 47 ++++++++++--------- .../webdriver/BiDi/Browser/BrowserModule.cs | 2 +- .../BrowsingContext/BrowsingContextModule.cs | 2 +- .../BiDi/Emulation/EmulationModule.cs | 2 +- .../src/webdriver/BiDi/Input/InputModule.cs | 2 +- dotnet/src/webdriver/BiDi/Log/LogModule.cs | 2 +- dotnet/src/webdriver/BiDi/Module.cs | 13 +++-- .../webdriver/BiDi/Network/NetworkModule.cs | 2 +- .../src/webdriver/BiDi/Script/ScriptModule.cs | 2 +- .../webdriver/BiDi/Session/SessionModule.cs | 2 +- .../webdriver/BiDi/Storage/StorageModule.cs | 2 +- .../BiDi/WebExtension/WebExtensionModule.cs | 2 +- 12 files changed, 42 insertions(+), 38 deletions(-) diff --git a/dotnet/src/webdriver/BiDi/BiDi.cs b/dotnet/src/webdriver/BiDi/BiDi.cs index 448e0ea85bf48..d88105b7ca9a2 100644 --- a/dotnet/src/webdriver/BiDi/BiDi.cs +++ b/dotnet/src/webdriver/BiDi/BiDi.cs @@ -30,15 +30,13 @@ namespace OpenQA.Selenium.BiDi; public sealed class BiDi : IAsyncDisposable { - private readonly Broker _broker; - private readonly JsonSerializerOptions _jsonOptions; + internal Broker Broker { get; } + internal JsonSerializerOptions JsonOptions { get; } private readonly BiDiJsonSerializerContext _jsonContext; - private BiDi(string url) + public JsonSerializerOptions DefaultBiDiOptions() { - var uri = new Uri(url); - - _jsonOptions = new JsonSerializerOptions + return new JsonSerializerOptions { PropertyNameCaseInsensitive = true, PropertyNamingPolicy = JsonNamingPolicy.CamelCase, @@ -61,20 +59,27 @@ private BiDi(string url) new WebExtensionConverter(this), } }; + } + + private BiDi(string url) + { + var uri = new Uri(url); - _jsonContext = new BiDiJsonSerializerContext(_jsonOptions); - - _broker = new Broker(this, uri, _jsonOptions); - SessionModule = Module.Create(this, _broker, _jsonOptions, _jsonContext); - BrowsingContext = Module.Create(this, _broker, _jsonOptions, _jsonContext); - Browser = Module.Create(this, _broker, _jsonOptions, _jsonContext); - Network = Module.Create(this, _broker, _jsonOptions, _jsonContext); - InputModule = Module.Create(this, _broker, _jsonOptions, _jsonContext); - Script = Module.Create(this, _broker, _jsonOptions, _jsonContext); - Log = Module.Create(this, _broker, _jsonOptions, _jsonContext); - Storage = Module.Create(this, _broker, _jsonOptions, _jsonContext); - WebExtension = Module.Create(this, _broker, _jsonOptions, _jsonContext); - Emulation = Module.Create(this, _broker, _jsonOptions, _jsonContext); + JsonOptions = DefaultBiDiOptions(); + + _jsonContext = new BiDiJsonSerializerContext(JsonOptions); + + Broker = new Broker(this, uri, JsonOptions); + SessionModule = Module.Create(this, JsonOptions, _jsonContext); + BrowsingContext = Module.Create(this, JsonOptions, _jsonContext); + Browser = Module.Create(this, JsonOptions, _jsonContext); + Network = Module.Create(this, JsonOptions, _jsonContext); + InputModule = Module.Create(this, JsonOptions, _jsonContext); + Script = Module.Create(this, JsonOptions, _jsonContext); + Log = Module.Create(this, JsonOptions, _jsonContext); + Storage = Module.Create(this, JsonOptions, _jsonContext); + WebExtension = Module.Create(this, JsonOptions, _jsonContext); + Emulation = Module.Create(this, JsonOptions, _jsonContext); } internal Session.SessionModule SessionModule { get; } @@ -106,7 +111,7 @@ public static async Task ConnectAsync(string url, BiDiOptions? options = n { var bidi = new BiDi(url); - await bidi._broker.ConnectAsync(CancellationToken.None).ConfigureAwait(false); + await bidi.Broker.ConnectAsync(CancellationToken.None).ConfigureAwait(false); return bidi; } @@ -118,7 +123,7 @@ public Task EndAsync(Session.EndOptions? options = null) public async ValueTask DisposeAsync() { - await _broker.DisposeAsync().ConfigureAwait(false); + await Broker.DisposeAsync().ConfigureAwait(false); GC.SuppressFinalize(this); } } diff --git a/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs b/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs index 61c5ce4008f05..5fe96636381a1 100644 --- a/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs +++ b/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs @@ -22,7 +22,7 @@ namespace OpenQA.Selenium.BiDi.Browser; -public sealed class BrowserModule : Module +public sealed class BrowserModule : InternalModule { public async Task CloseAsync(CloseOptions? options = null) { diff --git a/dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs b/dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs index f50d23085da40..ab9a888d288d1 100644 --- a/dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs +++ b/dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs @@ -23,7 +23,7 @@ namespace OpenQA.Selenium.BiDi.BrowsingContext; -public sealed class BrowsingContextModule : Module +public sealed class BrowsingContextModule : InternalModule { public async Task CreateAsync(ContextType type, CreateOptions? options = null) { diff --git a/dotnet/src/webdriver/BiDi/Emulation/EmulationModule.cs b/dotnet/src/webdriver/BiDi/Emulation/EmulationModule.cs index 6be60f7769c60..fba3edb71ed16 100644 --- a/dotnet/src/webdriver/BiDi/Emulation/EmulationModule.cs +++ b/dotnet/src/webdriver/BiDi/Emulation/EmulationModule.cs @@ -22,7 +22,7 @@ namespace OpenQA.Selenium.BiDi.Emulation; -public sealed class EmulationModule : Module +public sealed class EmulationModule : InternalModule { public async Task SetTimezoneOverrideAsync(string? timezone, SetTimezoneOverrideOptions? options = null) { diff --git a/dotnet/src/webdriver/BiDi/Input/InputModule.cs b/dotnet/src/webdriver/BiDi/Input/InputModule.cs index 8d2662caa035a..9a1d79c266fa9 100644 --- a/dotnet/src/webdriver/BiDi/Input/InputModule.cs +++ b/dotnet/src/webdriver/BiDi/Input/InputModule.cs @@ -23,7 +23,7 @@ namespace OpenQA.Selenium.BiDi.Input; -public sealed class InputModule : Module +public sealed class InputModule : InternalModule { public async Task PerformActionsAsync(BrowsingContext.BrowsingContext context, IEnumerable actions, PerformActionsOptions? options = null) { diff --git a/dotnet/src/webdriver/BiDi/Log/LogModule.cs b/dotnet/src/webdriver/BiDi/Log/LogModule.cs index a3887d7f052cf..b5e175827ce5e 100644 --- a/dotnet/src/webdriver/BiDi/Log/LogModule.cs +++ b/dotnet/src/webdriver/BiDi/Log/LogModule.cs @@ -23,7 +23,7 @@ namespace OpenQA.Selenium.BiDi.Log; -public sealed class LogModule : Module +public sealed class LogModule : InternalModule { public async Task OnEntryAddedAsync(Func handler, SubscriptionOptions? options = null) { diff --git a/dotnet/src/webdriver/BiDi/Module.cs b/dotnet/src/webdriver/BiDi/Module.cs index 202bc30bbcd75..70a2b829d5019 100644 --- a/dotnet/src/webdriver/BiDi/Module.cs +++ b/dotnet/src/webdriver/BiDi/Module.cs @@ -18,8 +18,8 @@ // using OpenQA.Selenium.BiDi.Communication; -using OpenQA.Selenium.BiDi.Communication.Json; using System.Text.Json; +using System.Text.Json.Serialization; namespace OpenQA.Selenium.BiDi; @@ -27,20 +27,19 @@ public abstract class Module { protected Broker Broker { get; private set; } - internal BiDiJsonSerializerContext JsonContext { get; private set; } + internal JsonSerializerContext JsonContext { get; private set; } - protected virtual void Initialize(JsonSerializerOptions options) { } + protected abstract JsonSerializerContext Initialize(JsonSerializerOptions options); - internal static TModule Create(BiDi bidi, Broker broker, JsonSerializerOptions jsonOptions, BiDiJsonSerializerContext context) + public static TModule Create(BiDi bidi, JsonSerializerOptions jsonOptions, JsonSerializerContext? cachedContext = null) where TModule : Module, new() { TModule module = new() { - Broker = broker, - JsonContext = context + Broker = bidi.Broker, }; - module.Initialize(jsonOptions); + module.JsonContext = cachedContext ?? module.Initialize(jsonOptions); return module; } diff --git a/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs b/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs index 4242f8515bab9..6bf18aba01ec2 100644 --- a/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs +++ b/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs @@ -24,7 +24,7 @@ namespace OpenQA.Selenium.BiDi.Network; -public sealed partial class NetworkModule : Module +public sealed partial class NetworkModule : InternalModule { public async Task AddDataCollectorAsync(IEnumerable DataTypes, int MaxEncodedDataSize, AddDataCollectorOptions? options = null) { diff --git a/dotnet/src/webdriver/BiDi/Script/ScriptModule.cs b/dotnet/src/webdriver/BiDi/Script/ScriptModule.cs index 6867941312362..0c4f0e42ea217 100644 --- a/dotnet/src/webdriver/BiDi/Script/ScriptModule.cs +++ b/dotnet/src/webdriver/BiDi/Script/ScriptModule.cs @@ -24,7 +24,7 @@ namespace OpenQA.Selenium.BiDi.Script; -public sealed class ScriptModule : Module +public sealed class ScriptModule : InternalModule { public async Task EvaluateAsync(string expression, bool awaitPromise, Target target, EvaluateOptions? options = null) { diff --git a/dotnet/src/webdriver/BiDi/Session/SessionModule.cs b/dotnet/src/webdriver/BiDi/Session/SessionModule.cs index b545d51f6d441..40b404fbabafc 100644 --- a/dotnet/src/webdriver/BiDi/Session/SessionModule.cs +++ b/dotnet/src/webdriver/BiDi/Session/SessionModule.cs @@ -23,7 +23,7 @@ namespace OpenQA.Selenium.BiDi.Session; -internal sealed class SessionModule : Module +internal sealed class SessionModule : InternalModule { public async Task StatusAsync(StatusOptions? options = null) { diff --git a/dotnet/src/webdriver/BiDi/Storage/StorageModule.cs b/dotnet/src/webdriver/BiDi/Storage/StorageModule.cs index 3e71db576c760..b5bbfe1b7d640 100644 --- a/dotnet/src/webdriver/BiDi/Storage/StorageModule.cs +++ b/dotnet/src/webdriver/BiDi/Storage/StorageModule.cs @@ -22,7 +22,7 @@ namespace OpenQA.Selenium.BiDi.Storage; -public sealed class StorageModule : Module +public sealed class StorageModule : InternalModule { public async Task GetCookiesAsync(GetCookiesOptions? options = null) { diff --git a/dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs b/dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs index 8432ccc36bd01..948c6f0eb4510 100644 --- a/dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs +++ b/dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs @@ -22,7 +22,7 @@ namespace OpenQA.Selenium.BiDi.WebExtension; -public sealed class WebExtensionModule : Module +public sealed class WebExtensionModule : InternalModule { public async Task InstallAsync(ExtensionData extensionData, InstallOptions? options = null) { From eaa3d5c353fbb68d50de78b1037e3fe36b2a9ba3 Mon Sep 17 00:00:00 2001 From: Michael Render Date: Sat, 11 Oct 2025 17:04:17 -0400 Subject: [PATCH 02/25] Add InternalModule --- dotnet/src/webdriver/BiDi/InternalModule.cs | 34 +++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 dotnet/src/webdriver/BiDi/InternalModule.cs diff --git a/dotnet/src/webdriver/BiDi/InternalModule.cs b/dotnet/src/webdriver/BiDi/InternalModule.cs new file mode 100644 index 0000000000000..dbc2f3a079bf2 --- /dev/null +++ b/dotnet/src/webdriver/BiDi/InternalModule.cs @@ -0,0 +1,34 @@ +// +// 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 OpenQA.Selenium.BiDi.Communication.Json; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace OpenQA.Selenium.BiDi; + +public abstract class InternalModule : Module +{ + internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; + + protected override JsonSerializerContext Initialize(JsonSerializerOptions options) + { + return new BiDiJsonSerializerContext(options); + } +} From 71a748936f530e7cdea41eb279a2931ad208ff45 Mon Sep 17 00:00:00 2001 From: Michael Render Date: Sat, 11 Oct 2025 17:22:52 -0400 Subject: [PATCH 03/25] Rename InternalModule to CoreModule --- dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs | 2 +- .../webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs | 2 +- .../src/webdriver/BiDi/{InternalModule.cs => CoreModule.cs} | 4 ++-- dotnet/src/webdriver/BiDi/Emulation/EmulationModule.cs | 2 +- dotnet/src/webdriver/BiDi/Input/InputModule.cs | 2 +- dotnet/src/webdriver/BiDi/Log/LogModule.cs | 2 +- dotnet/src/webdriver/BiDi/Network/NetworkModule.cs | 2 +- dotnet/src/webdriver/BiDi/Script/ScriptModule.cs | 2 +- dotnet/src/webdriver/BiDi/Session/SessionModule.cs | 2 +- dotnet/src/webdriver/BiDi/Storage/StorageModule.cs | 2 +- dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-) rename dotnet/src/webdriver/BiDi/{InternalModule.cs => CoreModule.cs} (91%) diff --git a/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs b/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs index 5fe96636381a1..e418122dc443b 100644 --- a/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs +++ b/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs @@ -22,7 +22,7 @@ namespace OpenQA.Selenium.BiDi.Browser; -public sealed class BrowserModule : InternalModule +public sealed class BrowserModule : CoreModule { public async Task CloseAsync(CloseOptions? options = null) { diff --git a/dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs b/dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs index ab9a888d288d1..60f24a0ecfc95 100644 --- a/dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs +++ b/dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs @@ -23,7 +23,7 @@ namespace OpenQA.Selenium.BiDi.BrowsingContext; -public sealed class BrowsingContextModule : InternalModule +public sealed class BrowsingContextModule : CoreModule { public async Task CreateAsync(ContextType type, CreateOptions? options = null) { diff --git a/dotnet/src/webdriver/BiDi/InternalModule.cs b/dotnet/src/webdriver/BiDi/CoreModule.cs similarity index 91% rename from dotnet/src/webdriver/BiDi/InternalModule.cs rename to dotnet/src/webdriver/BiDi/CoreModule.cs index dbc2f3a079bf2..32d2d23bc702c 100644 --- a/dotnet/src/webdriver/BiDi/InternalModule.cs +++ b/dotnet/src/webdriver/BiDi/CoreModule.cs @@ -1,4 +1,4 @@ -// +// // 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 @@ -23,7 +23,7 @@ namespace OpenQA.Selenium.BiDi; -public abstract class InternalModule : Module +public abstract class CoreModule : Module { internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; diff --git a/dotnet/src/webdriver/BiDi/Emulation/EmulationModule.cs b/dotnet/src/webdriver/BiDi/Emulation/EmulationModule.cs index fba3edb71ed16..29c87fdb47586 100644 --- a/dotnet/src/webdriver/BiDi/Emulation/EmulationModule.cs +++ b/dotnet/src/webdriver/BiDi/Emulation/EmulationModule.cs @@ -22,7 +22,7 @@ namespace OpenQA.Selenium.BiDi.Emulation; -public sealed class EmulationModule : InternalModule +public sealed class EmulationModule : CoreModule { public async Task SetTimezoneOverrideAsync(string? timezone, SetTimezoneOverrideOptions? options = null) { diff --git a/dotnet/src/webdriver/BiDi/Input/InputModule.cs b/dotnet/src/webdriver/BiDi/Input/InputModule.cs index 9a1d79c266fa9..ec31bbf1fd35d 100644 --- a/dotnet/src/webdriver/BiDi/Input/InputModule.cs +++ b/dotnet/src/webdriver/BiDi/Input/InputModule.cs @@ -23,7 +23,7 @@ namespace OpenQA.Selenium.BiDi.Input; -public sealed class InputModule : InternalModule +public sealed class InputModule : CoreModule { public async Task PerformActionsAsync(BrowsingContext.BrowsingContext context, IEnumerable actions, PerformActionsOptions? options = null) { diff --git a/dotnet/src/webdriver/BiDi/Log/LogModule.cs b/dotnet/src/webdriver/BiDi/Log/LogModule.cs index b5e175827ce5e..3d5a37d430bee 100644 --- a/dotnet/src/webdriver/BiDi/Log/LogModule.cs +++ b/dotnet/src/webdriver/BiDi/Log/LogModule.cs @@ -23,7 +23,7 @@ namespace OpenQA.Selenium.BiDi.Log; -public sealed class LogModule : InternalModule +public sealed class LogModule : CoreModule { public async Task OnEntryAddedAsync(Func handler, SubscriptionOptions? options = null) { diff --git a/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs b/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs index 6bf18aba01ec2..0c3d2641e7f1e 100644 --- a/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs +++ b/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs @@ -24,7 +24,7 @@ namespace OpenQA.Selenium.BiDi.Network; -public sealed partial class NetworkModule : InternalModule +public sealed partial class NetworkModule : CoreModule { public async Task AddDataCollectorAsync(IEnumerable DataTypes, int MaxEncodedDataSize, AddDataCollectorOptions? options = null) { diff --git a/dotnet/src/webdriver/BiDi/Script/ScriptModule.cs b/dotnet/src/webdriver/BiDi/Script/ScriptModule.cs index 0c4f0e42ea217..d8494f5b08a09 100644 --- a/dotnet/src/webdriver/BiDi/Script/ScriptModule.cs +++ b/dotnet/src/webdriver/BiDi/Script/ScriptModule.cs @@ -24,7 +24,7 @@ namespace OpenQA.Selenium.BiDi.Script; -public sealed class ScriptModule : InternalModule +public sealed class ScriptModule : CoreModule { public async Task EvaluateAsync(string expression, bool awaitPromise, Target target, EvaluateOptions? options = null) { diff --git a/dotnet/src/webdriver/BiDi/Session/SessionModule.cs b/dotnet/src/webdriver/BiDi/Session/SessionModule.cs index 40b404fbabafc..44f37a5399c30 100644 --- a/dotnet/src/webdriver/BiDi/Session/SessionModule.cs +++ b/dotnet/src/webdriver/BiDi/Session/SessionModule.cs @@ -23,7 +23,7 @@ namespace OpenQA.Selenium.BiDi.Session; -internal sealed class SessionModule : InternalModule +internal sealed class SessionModule : CoreModule { public async Task StatusAsync(StatusOptions? options = null) { diff --git a/dotnet/src/webdriver/BiDi/Storage/StorageModule.cs b/dotnet/src/webdriver/BiDi/Storage/StorageModule.cs index b5bbfe1b7d640..32fc59f5f1352 100644 --- a/dotnet/src/webdriver/BiDi/Storage/StorageModule.cs +++ b/dotnet/src/webdriver/BiDi/Storage/StorageModule.cs @@ -22,7 +22,7 @@ namespace OpenQA.Selenium.BiDi.Storage; -public sealed class StorageModule : InternalModule +public sealed class StorageModule : CoreModule { public async Task GetCookiesAsync(GetCookiesOptions? options = null) { diff --git a/dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs b/dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs index 948c6f0eb4510..b5a5526430a44 100644 --- a/dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs +++ b/dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs @@ -22,7 +22,7 @@ namespace OpenQA.Selenium.BiDi.WebExtension; -public sealed class WebExtensionModule : InternalModule +public sealed class WebExtensionModule : CoreModule { public async Task InstallAsync(ExtensionData extensionData, InstallOptions? options = null) { From 1fbf4c6ac4f6d10336be94ad9ccbd12b5a0487e8 Mon Sep 17 00:00:00 2001 From: Michael Render Date: Sat, 11 Oct 2025 18:45:39 -0400 Subject: [PATCH 04/25] [dotnet] Implement Permissions module --- .../Permissions/PermissionDescriptor.cs | 22 ++++++++++ .../Extensions/Permissions/PermissionState.cs | 31 ++++++++++++++ .../Permissions/PermissionsModule.cs | 29 +++++++++++++ .../Permissions/SetPermissionCommand.cs | 17 ++++++++ .../webdriver/BiDi/WebDriver.Extensions.cs | 6 +++ .../Permissions/PermissionsTests.cs | 42 +++++++++++++++++++ 6 files changed, 147 insertions(+) create mode 100644 dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionDescriptor.cs create mode 100644 dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionState.cs create mode 100644 dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionsModule.cs create mode 100644 dotnet/src/webdriver/BiDi/Extensions/Permissions/SetPermissionCommand.cs create mode 100644 dotnet/test/common/BiDi/Extensions/Permissions/PermissionsTests.cs diff --git a/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionDescriptor.cs b/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionDescriptor.cs new file mode 100644 index 0000000000000..8523515a8a748 --- /dev/null +++ b/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionDescriptor.cs @@ -0,0 +1,22 @@ +// +// 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.Extensions.Permissions; + +internal record PermissionDescriptor(string Name); diff --git a/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionState.cs b/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionState.cs new file mode 100644 index 0000000000000..3707011bdec22 --- /dev/null +++ b/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionState.cs @@ -0,0 +1,31 @@ +// +// 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 OpenQA.Selenium.BiDi.Communication.Json.Converters; +using System.Text.Json.Serialization; + +namespace OpenQA.Selenium.BiDi.Extensions.Permissions; + +[JsonConverter(typeof(CamelCaseEnumConverter))] +public enum PermissionState +{ + Granted, + Denied, + Prompt +} diff --git a/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionsModule.cs b/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionsModule.cs new file mode 100644 index 0000000000000..2bcea8262d379 --- /dev/null +++ b/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionsModule.cs @@ -0,0 +1,29 @@ +using OpenQA.Selenium.BiDi.Browser; +using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json.Converters; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace OpenQA.Selenium.BiDi.Extensions.Permissions; + +public class PermissionsModule : Module +{ + private PermissionsJsonSerializerContext JsonContext => (PermissionsJsonSerializerContext)base.JsonContext; + + public async Task SetPermissionAsync(string permissionName, PermissionState state, string origin, UserContext? userContext, SetPermissionOptions? options = null) + { + var @params = new SetPermissionCommandParameters(new PermissionDescriptor(permissionName), state, origin, userContext); + + await Broker.ExecuteCommandAsync(new SetPermissionCommand(@params), options, JsonContext.Permissions_SetPermissionCommand, JsonContext.Permissions_SetPermissionResult).ConfigureAwait(false); + } + + protected override JsonSerializerContext Initialize(JsonSerializerOptions options) + { + return new PermissionsJsonSerializerContext(options); + } +} + +[JsonSerializable(typeof(SetPermissionCommand), TypeInfoPropertyName = "Permissions_SetPermissionCommand")] +[JsonSerializable(typeof(SetPermissionResult), TypeInfoPropertyName = "Permissions_SetPermissionResult")] +internal partial class PermissionsJsonSerializerContext : JsonSerializerContext; diff --git a/dotnet/src/webdriver/BiDi/Extensions/Permissions/SetPermissionCommand.cs b/dotnet/src/webdriver/BiDi/Extensions/Permissions/SetPermissionCommand.cs new file mode 100644 index 0000000000000..dac45688cc8c5 --- /dev/null +++ b/dotnet/src/webdriver/BiDi/Extensions/Permissions/SetPermissionCommand.cs @@ -0,0 +1,17 @@ +using OpenQA.Selenium.BiDi.Browser; +using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json.Converters; +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.Json.Serialization; + +namespace OpenQA.Selenium.BiDi.Extensions.Permissions; + +internal class SetPermissionCommand(SetPermissionCommandParameters @params) + : Command(@params, "permissions.setPermission"); + +public class SetPermissionOptions : CommandOptions; +public sealed record SetPermissionResult : EmptyResult; + +internal record SetPermissionCommandParameters(PermissionDescriptor Descriptor, PermissionState State, string Origin, UserContext? UserContext) : Parameters; diff --git a/dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs b/dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs index 2aedc80a2c092..84c3b7eec9bbb 100644 --- a/dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs +++ b/dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs @@ -17,6 +17,7 @@ // under the License. // +using OpenQA.Selenium.BiDi.Extensions.Permissions; using System; using System.Threading.Tasks; @@ -41,4 +42,9 @@ public static async Task AsBiDiAsync(this IWebDriver webDriver, BiDiOption return bidi; } + + public static PermissionsModule AsPermissionsAsync(this BiDi bidi) + { + return Module.Create(bidi, bidi.DefaultBiDiOptions()); + } } diff --git a/dotnet/test/common/BiDi/Extensions/Permissions/PermissionsTests.cs b/dotnet/test/common/BiDi/Extensions/Permissions/PermissionsTests.cs new file mode 100644 index 0000000000000..1f9e43ae4ad34 --- /dev/null +++ b/dotnet/test/common/BiDi/Extensions/Permissions/PermissionsTests.cs @@ -0,0 +1,42 @@ +using NUnit.Framework; +using OpenQA.Selenium.BiDi.BrowsingContext; +using OpenQA.Selenium.BiDi.Script; +using OpenQA.Selenium.Environment; +using System.Threading.Tasks; + +namespace OpenQA.Selenium.BiDi.Extensions.Permissions; + +internal class PermissionsTests : BiDiTestFixture +{ + [Test] + public async Task SettingPermissionsTest() + { + var userContext = await bidi.Browser.CreateUserContextAsync(); + var window = (await bidi.BrowsingContext.CreateAsync(ContextType.Window, new() + { + ReferenceContext = context, + UserContext = userContext.UserContext, + Background = true + })).Context; + + var newPage = EnvironmentManager.Instance.UrlBuilder.CreateInlinePage(new InlinePage() + .WithBody("
new page
")); + + await window.NavigateAsync(newPage); + + var before = await window.Script.CallFunctionAsync(""" + async () => (await navigator.permissions.query({ name: "geolocation" })).state + """, awaitPromise: true, new() { UserActivation = true, }); + + Assert.That(before.AsSuccessResult(), Is.EqualTo(new StringRemoteValue("prompt"))); + + var permissions = bidi.AsPermissionsAsync(); + await permissions.SetPermissionAsync("geolocation", PermissionState.Denied, newPage, userContext.UserContext); + + var after = await window.Script.CallFunctionAsync(""" + async () => (await navigator.permissions.query({ name: "geolocation" })).state + """, awaitPromise: true, new() { UserActivation = true }); + + Assert.That(after.AsSuccessResult(), Is.EqualTo(new StringRemoteValue("denied"))); + } +} From 9a26d1e129a745cdba16793fd820a122ef65de90 Mon Sep 17 00:00:00 2001 From: Michael Render Date: Sat, 11 Oct 2025 18:46:35 -0400 Subject: [PATCH 05/25] Rename type --- dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs | 2 +- .../test/common/BiDi/Extensions/Permissions/PermissionsTests.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs b/dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs index 84c3b7eec9bbb..fc270b7b58839 100644 --- a/dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs +++ b/dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs @@ -43,7 +43,7 @@ public static async Task AsBiDiAsync(this IWebDriver webDriver, BiDiOption return bidi; } - public static PermissionsModule AsPermissionsAsync(this BiDi bidi) + public static PermissionsModule AsPermissions(this BiDi bidi) { return Module.Create(bidi, bidi.DefaultBiDiOptions()); } diff --git a/dotnet/test/common/BiDi/Extensions/Permissions/PermissionsTests.cs b/dotnet/test/common/BiDi/Extensions/Permissions/PermissionsTests.cs index 1f9e43ae4ad34..26cf1648680bc 100644 --- a/dotnet/test/common/BiDi/Extensions/Permissions/PermissionsTests.cs +++ b/dotnet/test/common/BiDi/Extensions/Permissions/PermissionsTests.cs @@ -30,7 +30,7 @@ public async Task SettingPermissionsTest() Assert.That(before.AsSuccessResult(), Is.EqualTo(new StringRemoteValue("prompt"))); - var permissions = bidi.AsPermissionsAsync(); + var permissions = bidi.AsPermissions(); await permissions.SetPermissionAsync("geolocation", PermissionState.Denied, newPage, userContext.UserContext); var after = await window.Script.CallFunctionAsync(""" From dbe8e0b05a1172e9ce729541c10dd13d55c4fd71 Mon Sep 17 00:00:00 2001 From: Michael Render Date: Sat, 11 Oct 2025 19:09:10 -0400 Subject: [PATCH 06/25] Remove CoreModule --- .../webdriver/BiDi/Browser/BrowserModule.cs | 11 +++++- .../BrowsingContext/BrowsingContextModule.cs | 13 +++++-- dotnet/src/webdriver/BiDi/CoreModule.cs | 34 ------------------- .../BiDi/Emulation/EmulationModule.cs | 13 +++++-- .../src/webdriver/BiDi/Input/InputModule.cs | 11 +++++- dotnet/src/webdriver/BiDi/Log/LogModule.cs | 15 ++++++-- .../webdriver/BiDi/Network/NetworkModule.cs | 13 +++++-- .../src/webdriver/BiDi/Script/ScriptModule.cs | 11 +++++- .../webdriver/BiDi/Session/SessionModule.cs | 11 +++++- .../webdriver/BiDi/Storage/StorageModule.cs | 11 +++++- .../BiDi/WebExtension/WebExtensionModule.cs | 11 +++++- 11 files changed, 105 insertions(+), 49 deletions(-) delete mode 100644 dotnet/src/webdriver/BiDi/CoreModule.cs diff --git a/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs b/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs index e418122dc443b..c41ab1426dd7e 100644 --- a/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs +++ b/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs @@ -18,12 +18,17 @@ //
using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json; +using System.Text.Json; +using System.Text.Json.Serialization; using System.Threading.Tasks; namespace OpenQA.Selenium.BiDi.Browser; -public sealed class BrowserModule : CoreModule +public sealed class BrowserModule : Module { + internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; + public async Task CloseAsync(CloseOptions? options = null) { return await Broker.ExecuteCommandAsync(new CloseCommand(), options, JsonContext.Browser_CloseCommand, JsonContext.Browser_CloseResult).ConfigureAwait(false); @@ -74,4 +79,8 @@ public async Task SetDownloadBehaviorDeniedAsync(SetD return await Broker.ExecuteCommandAsync(new SetDownloadBehaviorCommand(@params), options, JsonContext.SetDownloadBehaviorCommand, JsonContext.SetDownloadBehaviorResult).ConfigureAwait(false); } + protected override JsonSerializerContext Initialize(JsonSerializerOptions options) + { + return new BiDiJsonSerializerContext(options); + } } diff --git a/dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs b/dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs index 60f24a0ecfc95..c2c609738061e 100644 --- a/dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs +++ b/dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs @@ -17,14 +17,19 @@ // under the License. // +using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json; using System; +using System.Text.Json; +using System.Text.Json.Serialization; using System.Threading.Tasks; -using OpenQA.Selenium.BiDi.Communication; namespace OpenQA.Selenium.BiDi.BrowsingContext; -public sealed class BrowsingContextModule : CoreModule +public sealed class BrowsingContextModule : Module { + internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; + public async Task CreateAsync(ContextType type, CreateOptions? options = null) { var @params = new CreateParameters(type, options?.ReferenceContext, options?.Background, options?.UserContext); @@ -248,4 +253,8 @@ public async Task OnUserPromptClosedAsync(Action -// 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 OpenQA.Selenium.BiDi.Communication.Json; -using System.Text.Json; -using System.Text.Json.Serialization; - -namespace OpenQA.Selenium.BiDi; - -public abstract class CoreModule : Module -{ - internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; - - protected override JsonSerializerContext Initialize(JsonSerializerOptions options) - { - return new BiDiJsonSerializerContext(options); - } -} diff --git a/dotnet/src/webdriver/BiDi/Emulation/EmulationModule.cs b/dotnet/src/webdriver/BiDi/Emulation/EmulationModule.cs index 29c87fdb47586..19076e139b8f0 100644 --- a/dotnet/src/webdriver/BiDi/Emulation/EmulationModule.cs +++ b/dotnet/src/webdriver/BiDi/Emulation/EmulationModule.cs @@ -17,13 +17,18 @@ // under the License. // -using System.Threading.Tasks; using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Threading.Tasks; namespace OpenQA.Selenium.BiDi.Emulation; -public sealed class EmulationModule : CoreModule +public sealed class EmulationModule : Module { + internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; + public async Task SetTimezoneOverrideAsync(string? timezone, SetTimezoneOverrideOptions? options = null) { var @params = new SetTimezoneOverrideParameters(timezone, options?.Contexts, options?.UserContexts); @@ -88,4 +93,8 @@ public async Task SetGeolocationPositionErrorOverr return await Broker.ExecuteCommandAsync(new SetGeolocationOverrideCommand(@params), options, JsonContext.SetGeolocationOverrideCommand, JsonContext.SetGeolocationOverrideResult).ConfigureAwait(false); } + protected override JsonSerializerContext Initialize(JsonSerializerOptions options) + { + return new BiDiJsonSerializerContext(options); + } } diff --git a/dotnet/src/webdriver/BiDi/Input/InputModule.cs b/dotnet/src/webdriver/BiDi/Input/InputModule.cs index ec31bbf1fd35d..73fe2e124bc97 100644 --- a/dotnet/src/webdriver/BiDi/Input/InputModule.cs +++ b/dotnet/src/webdriver/BiDi/Input/InputModule.cs @@ -18,13 +18,18 @@ // using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json; using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; using System.Threading.Tasks; namespace OpenQA.Selenium.BiDi.Input; -public sealed class InputModule : CoreModule +public sealed class InputModule : Module { + internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; + public async Task PerformActionsAsync(BrowsingContext.BrowsingContext context, IEnumerable actions, PerformActionsOptions? options = null) { var @params = new PerformActionsParameters(context, actions); @@ -45,4 +50,8 @@ public async Task SetFilesAsync(BrowsingContext.BrowsingContext return await Broker.ExecuteCommandAsync(new SetFilesCommand(@params), options, JsonContext.SetFilesCommand, JsonContext.SetFilesResult).ConfigureAwait(false); } + protected override JsonSerializerContext Initialize(JsonSerializerOptions options) + { + return new BiDiJsonSerializerContext(options); + } } diff --git a/dotnet/src/webdriver/BiDi/Log/LogModule.cs b/dotnet/src/webdriver/BiDi/Log/LogModule.cs index 3d5a37d430bee..90c6868b60a82 100644 --- a/dotnet/src/webdriver/BiDi/Log/LogModule.cs +++ b/dotnet/src/webdriver/BiDi/Log/LogModule.cs @@ -17,14 +17,19 @@ // under the License. // -using System.Threading.Tasks; -using System; using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json; +using System; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Threading.Tasks; namespace OpenQA.Selenium.BiDi.Log; -public sealed class LogModule : CoreModule +public sealed class LogModule : Module { + internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; + public async Task OnEntryAddedAsync(Func handler, SubscriptionOptions? options = null) { return await Broker.SubscribeAsync("log.entryAdded", handler, options, JsonContext.LogEntry).ConfigureAwait(false); @@ -34,4 +39,8 @@ public async Task OnEntryAddedAsync(Action handler, Subs { return await Broker.SubscribeAsync("log.entryAdded", handler, options, JsonContext.LogEntry).ConfigureAwait(false); } + protected override JsonSerializerContext Initialize(JsonSerializerOptions options) + { + return new BiDiJsonSerializerContext(options); + } } diff --git a/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs b/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs index 0c3d2641e7f1e..599c4e6b8e2d4 100644 --- a/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs +++ b/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs @@ -17,15 +17,20 @@ // under the License. // +using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json; using System; using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; using System.Threading.Tasks; -using OpenQA.Selenium.BiDi.Communication; namespace OpenQA.Selenium.BiDi.Network; -public sealed partial class NetworkModule : CoreModule +public sealed partial class NetworkModule : Module { + internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; + public async Task AddDataCollectorAsync(IEnumerable DataTypes, int MaxEncodedDataSize, AddDataCollectorOptions? options = null) { var @params = new AddDataCollectorParameters(DataTypes, MaxEncodedDataSize, options?.CollectorType, options?.Contexts, options?.UserContexts); @@ -173,4 +178,8 @@ public async Task OnAuthRequiredAsync(Action using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json; using System; using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; using System.Threading.Tasks; namespace OpenQA.Selenium.BiDi.Script; -public sealed class ScriptModule : CoreModule +public sealed class ScriptModule : Module { + internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; + public async Task EvaluateAsync(string expression, bool awaitPromise, Target target, EvaluateOptions? options = null) { var @params = new EvaluateParameters(expression, target, awaitPromise, options?.ResultOwnership, options?.SerializationOptions, options?.UserActivation); @@ -111,4 +116,8 @@ public async Task OnRealmDestroyedAsync(Action using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json; using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; using System.Threading.Tasks; namespace OpenQA.Selenium.BiDi.Session; -internal sealed class SessionModule : CoreModule +internal sealed class SessionModule : Module { + internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; + public async Task StatusAsync(StatusOptions? options = null) { return await Broker.ExecuteCommandAsync(new StatusCommand(), options, JsonContext.StatusCommand, JsonContext.StatusResult).ConfigureAwait(false); @@ -55,4 +60,8 @@ public async Task EndAsync(EndOptions? options = null) { return await Broker.ExecuteCommandAsync(new EndCommand(), options, JsonContext.EndCommand, JsonContext.EndResult).ConfigureAwait(false); } + protected override JsonSerializerContext Initialize(JsonSerializerOptions options) + { + return new BiDiJsonSerializerContext(options); + } } diff --git a/dotnet/src/webdriver/BiDi/Storage/StorageModule.cs b/dotnet/src/webdriver/BiDi/Storage/StorageModule.cs index 32fc59f5f1352..29410895ce187 100644 --- a/dotnet/src/webdriver/BiDi/Storage/StorageModule.cs +++ b/dotnet/src/webdriver/BiDi/Storage/StorageModule.cs @@ -18,12 +18,17 @@ // using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json; +using System.Text.Json; +using System.Text.Json.Serialization; using System.Threading.Tasks; namespace OpenQA.Selenium.BiDi.Storage; -public sealed class StorageModule : CoreModule +public sealed class StorageModule : Module { + internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; + public async Task GetCookiesAsync(GetCookiesOptions? options = null) { var @params = new GetCookiesParameters(options?.Filter, options?.Partition); @@ -44,4 +49,8 @@ public async Task SetCookieAsync(PartialCookie cookie, SetCooki return await Broker.ExecuteCommandAsync(new SetCookieCommand(@params), options, JsonContext.SetCookieCommand, JsonContext.SetCookieResult).ConfigureAwait(false); } + protected override JsonSerializerContext Initialize(JsonSerializerOptions options) + { + return new BiDiJsonSerializerContext(options); + } } diff --git a/dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs b/dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs index b5a5526430a44..2a3d13e9e9064 100644 --- a/dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs +++ b/dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs @@ -18,12 +18,17 @@ // using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json; +using System.Text.Json; +using System.Text.Json.Serialization; using System.Threading.Tasks; namespace OpenQA.Selenium.BiDi.WebExtension; -public sealed class WebExtensionModule : CoreModule +public sealed class WebExtensionModule : Module { + internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; + public async Task InstallAsync(ExtensionData extensionData, InstallOptions? options = null) { var @params = new InstallParameters(extensionData); @@ -37,4 +42,8 @@ public async Task UninstallAsync(Extension extension, Uninstall return await Broker.ExecuteCommandAsync(new UninstallCommand(@params), options, JsonContext.UninstallCommand, JsonContext.UninstallResult).ConfigureAwait(false); } + protected override JsonSerializerContext Initialize(JsonSerializerOptions options) + { + return new BiDiJsonSerializerContext(options); + } } From 6449944523ac91fadc4a93f855528b3bf54e68ff Mon Sep 17 00:00:00 2001 From: Michael Render Date: Mon, 20 Oct 2025 17:16:03 -0400 Subject: [PATCH 07/25] Move Permissions module out of a separate Extensions folder --- .../BiDi/{Extensions => }/Permissions/PermissionDescriptor.cs | 2 +- .../BiDi/{Extensions => }/Permissions/PermissionState.cs | 2 +- .../BiDi/{Extensions => }/Permissions/PermissionsModule.cs | 1 + .../BiDi/{Extensions => }/Permissions/SetPermissionCommand.cs | 2 +- .../BiDi/{Extensions => }/Permissions/PermissionsTests.cs | 2 +- 5 files changed, 5 insertions(+), 4 deletions(-) rename dotnet/src/webdriver/BiDi/{Extensions => }/Permissions/PermissionDescriptor.cs (94%) rename dotnet/src/webdriver/BiDi/{Extensions => }/Permissions/PermissionState.cs (95%) rename dotnet/src/webdriver/BiDi/{Extensions => }/Permissions/PermissionsModule.cs (97%) rename dotnet/src/webdriver/BiDi/{Extensions => }/Permissions/SetPermissionCommand.cs (92%) rename dotnet/test/common/BiDi/{Extensions => }/Permissions/PermissionsTests.cs (96%) diff --git a/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionDescriptor.cs b/dotnet/src/webdriver/BiDi/Permissions/PermissionDescriptor.cs similarity index 94% rename from dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionDescriptor.cs rename to dotnet/src/webdriver/BiDi/Permissions/PermissionDescriptor.cs index 8523515a8a748..a418c4387b485 100644 --- a/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionDescriptor.cs +++ b/dotnet/src/webdriver/BiDi/Permissions/PermissionDescriptor.cs @@ -17,6 +17,6 @@ // under the License. // -namespace OpenQA.Selenium.BiDi.Extensions.Permissions; +namespace OpenQA.Selenium.BiDi.Permissions; internal record PermissionDescriptor(string Name); diff --git a/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionState.cs b/dotnet/src/webdriver/BiDi/Permissions/PermissionState.cs similarity index 95% rename from dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionState.cs rename to dotnet/src/webdriver/BiDi/Permissions/PermissionState.cs index 3707011bdec22..1b3c9d3486655 100644 --- a/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionState.cs +++ b/dotnet/src/webdriver/BiDi/Permissions/PermissionState.cs @@ -20,7 +20,7 @@ using OpenQA.Selenium.BiDi.Communication.Json.Converters; using System.Text.Json.Serialization; -namespace OpenQA.Selenium.BiDi.Extensions.Permissions; +namespace OpenQA.Selenium.BiDi.Permissions; [JsonConverter(typeof(CamelCaseEnumConverter))] public enum PermissionState diff --git a/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionsModule.cs b/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs similarity index 97% rename from dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionsModule.cs rename to dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs index 2bcea8262d379..7c75b6252a7ca 100644 --- a/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionsModule.cs +++ b/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs @@ -1,6 +1,7 @@ using OpenQA.Selenium.BiDi.Browser; using OpenQA.Selenium.BiDi.Communication; using OpenQA.Selenium.BiDi.Communication.Json.Converters; +using OpenQA.Selenium.BiDi.Permissions; using System.Text.Json; using System.Text.Json.Serialization; using System.Threading.Tasks; diff --git a/dotnet/src/webdriver/BiDi/Extensions/Permissions/SetPermissionCommand.cs b/dotnet/src/webdriver/BiDi/Permissions/SetPermissionCommand.cs similarity index 92% rename from dotnet/src/webdriver/BiDi/Extensions/Permissions/SetPermissionCommand.cs rename to dotnet/src/webdriver/BiDi/Permissions/SetPermissionCommand.cs index dac45688cc8c5..6fe2d93712d15 100644 --- a/dotnet/src/webdriver/BiDi/Extensions/Permissions/SetPermissionCommand.cs +++ b/dotnet/src/webdriver/BiDi/Permissions/SetPermissionCommand.cs @@ -6,7 +6,7 @@ using System.Text; using System.Text.Json.Serialization; -namespace OpenQA.Selenium.BiDi.Extensions.Permissions; +namespace OpenQA.Selenium.BiDi.Permissions; internal class SetPermissionCommand(SetPermissionCommandParameters @params) : Command(@params, "permissions.setPermission"); diff --git a/dotnet/test/common/BiDi/Extensions/Permissions/PermissionsTests.cs b/dotnet/test/common/BiDi/Permissions/PermissionsTests.cs similarity index 96% rename from dotnet/test/common/BiDi/Extensions/Permissions/PermissionsTests.cs rename to dotnet/test/common/BiDi/Permissions/PermissionsTests.cs index 26cf1648680bc..bb832b74828b6 100644 --- a/dotnet/test/common/BiDi/Extensions/Permissions/PermissionsTests.cs +++ b/dotnet/test/common/BiDi/Permissions/PermissionsTests.cs @@ -4,7 +4,7 @@ using OpenQA.Selenium.Environment; using System.Threading.Tasks; -namespace OpenQA.Selenium.BiDi.Extensions.Permissions; +namespace OpenQA.Selenium.BiDi.Permissions; internal class PermissionsTests : BiDiTestFixture { From 43dd406df206c55544affdab910aad82eada780a Mon Sep 17 00:00:00 2001 From: Michael Render Date: Mon, 20 Oct 2025 17:17:13 -0400 Subject: [PATCH 08/25] Remove unused usings --- dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs | 1 - .../src/webdriver/BiDi/Permissions/SetPermissionCommand.cs | 5 ----- 2 files changed, 6 deletions(-) diff --git a/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs b/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs index 7c75b6252a7ca..78143a7db2a8d 100644 --- a/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs +++ b/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs @@ -1,6 +1,5 @@ using OpenQA.Selenium.BiDi.Browser; using OpenQA.Selenium.BiDi.Communication; -using OpenQA.Selenium.BiDi.Communication.Json.Converters; using OpenQA.Selenium.BiDi.Permissions; using System.Text.Json; using System.Text.Json.Serialization; diff --git a/dotnet/src/webdriver/BiDi/Permissions/SetPermissionCommand.cs b/dotnet/src/webdriver/BiDi/Permissions/SetPermissionCommand.cs index 6fe2d93712d15..9e49f436e59c0 100644 --- a/dotnet/src/webdriver/BiDi/Permissions/SetPermissionCommand.cs +++ b/dotnet/src/webdriver/BiDi/Permissions/SetPermissionCommand.cs @@ -1,10 +1,5 @@ using OpenQA.Selenium.BiDi.Browser; using OpenQA.Selenium.BiDi.Communication; -using OpenQA.Selenium.BiDi.Communication.Json.Converters; -using System; -using System.Collections.Generic; -using System.Text; -using System.Text.Json.Serialization; namespace OpenQA.Selenium.BiDi.Permissions; From 341338f948f590ebfb72c4c2843b6fed9534e8e8 Mon Sep 17 00:00:00 2001 From: Michael Render Date: Mon, 20 Oct 2025 17:20:14 -0400 Subject: [PATCH 09/25] Rename Initialize to CreateJsonContext --- dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs | 2 +- .../webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs | 2 +- dotnet/src/webdriver/BiDi/Emulation/EmulationModule.cs | 2 +- dotnet/src/webdriver/BiDi/Input/InputModule.cs | 2 +- dotnet/src/webdriver/BiDi/Log/LogModule.cs | 2 +- dotnet/src/webdriver/BiDi/Module.cs | 4 ++-- dotnet/src/webdriver/BiDi/Network/NetworkModule.cs | 2 +- dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs | 2 +- dotnet/src/webdriver/BiDi/Script/ScriptModule.cs | 2 +- dotnet/src/webdriver/BiDi/Session/SessionModule.cs | 2 +- dotnet/src/webdriver/BiDi/Storage/StorageModule.cs | 2 +- dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs | 2 +- 12 files changed, 13 insertions(+), 13 deletions(-) diff --git a/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs b/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs index c41ab1426dd7e..6ec20caa7e90e 100644 --- a/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs +++ b/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs @@ -79,7 +79,7 @@ public async Task SetDownloadBehaviorDeniedAsync(SetD return await Broker.ExecuteCommandAsync(new SetDownloadBehaviorCommand(@params), options, JsonContext.SetDownloadBehaviorCommand, JsonContext.SetDownloadBehaviorResult).ConfigureAwait(false); } - protected override JsonSerializerContext Initialize(JsonSerializerOptions options) + protected override JsonSerializerContext CreateJsonContext(JsonSerializerOptions options) { return new BiDiJsonSerializerContext(options); } diff --git a/dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs b/dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs index c2c609738061e..b2c4d3b2e8d50 100644 --- a/dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs +++ b/dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs @@ -253,7 +253,7 @@ public async Task OnUserPromptClosedAsync(Action SetGeolocationPositionErrorOverr return await Broker.ExecuteCommandAsync(new SetGeolocationOverrideCommand(@params), options, JsonContext.SetGeolocationOverrideCommand, JsonContext.SetGeolocationOverrideResult).ConfigureAwait(false); } - protected override JsonSerializerContext Initialize(JsonSerializerOptions options) + protected override JsonSerializerContext CreateJsonContext(JsonSerializerOptions options) { return new BiDiJsonSerializerContext(options); } diff --git a/dotnet/src/webdriver/BiDi/Input/InputModule.cs b/dotnet/src/webdriver/BiDi/Input/InputModule.cs index 73fe2e124bc97..5a7765119629a 100644 --- a/dotnet/src/webdriver/BiDi/Input/InputModule.cs +++ b/dotnet/src/webdriver/BiDi/Input/InputModule.cs @@ -50,7 +50,7 @@ public async Task SetFilesAsync(BrowsingContext.BrowsingContext return await Broker.ExecuteCommandAsync(new SetFilesCommand(@params), options, JsonContext.SetFilesCommand, JsonContext.SetFilesResult).ConfigureAwait(false); } - protected override JsonSerializerContext Initialize(JsonSerializerOptions options) + protected override JsonSerializerContext CreateJsonContext(JsonSerializerOptions options) { return new BiDiJsonSerializerContext(options); } diff --git a/dotnet/src/webdriver/BiDi/Log/LogModule.cs b/dotnet/src/webdriver/BiDi/Log/LogModule.cs index 90c6868b60a82..55b68c46e3a98 100644 --- a/dotnet/src/webdriver/BiDi/Log/LogModule.cs +++ b/dotnet/src/webdriver/BiDi/Log/LogModule.cs @@ -39,7 +39,7 @@ public async Task OnEntryAddedAsync(Action handler, Subs { return await Broker.SubscribeAsync("log.entryAdded", handler, options, JsonContext.LogEntry).ConfigureAwait(false); } - protected override JsonSerializerContext Initialize(JsonSerializerOptions options) + protected override JsonSerializerContext CreateJsonContext(JsonSerializerOptions options) { return new BiDiJsonSerializerContext(options); } diff --git a/dotnet/src/webdriver/BiDi/Module.cs b/dotnet/src/webdriver/BiDi/Module.cs index 70a2b829d5019..fda2c5199dbe9 100644 --- a/dotnet/src/webdriver/BiDi/Module.cs +++ b/dotnet/src/webdriver/BiDi/Module.cs @@ -29,7 +29,7 @@ public abstract class Module internal JsonSerializerContext JsonContext { get; private set; } - protected abstract JsonSerializerContext Initialize(JsonSerializerOptions options); + protected abstract JsonSerializerContext CreateJsonContext(JsonSerializerOptions options); public static TModule Create(BiDi bidi, JsonSerializerOptions jsonOptions, JsonSerializerContext? cachedContext = null) where TModule : Module, new() @@ -39,7 +39,7 @@ public static TModule Create(BiDi bidi, JsonSerializerOptions jsonOptio Broker = bidi.Broker, }; - module.JsonContext = cachedContext ?? module.Initialize(jsonOptions); + module.JsonContext = cachedContext ?? module.CreateJsonContext(jsonOptions); return module; } diff --git a/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs b/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs index 599c4e6b8e2d4..198d4698391e2 100644 --- a/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs +++ b/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs @@ -178,7 +178,7 @@ public async Task OnAuthRequiredAsync(Action OnRealmDestroyedAsync(Action EndAsync(EndOptions? options = null) { return await Broker.ExecuteCommandAsync(new EndCommand(), options, JsonContext.EndCommand, JsonContext.EndResult).ConfigureAwait(false); } - protected override JsonSerializerContext Initialize(JsonSerializerOptions options) + protected override JsonSerializerContext CreateJsonContext(JsonSerializerOptions options) { return new BiDiJsonSerializerContext(options); } diff --git a/dotnet/src/webdriver/BiDi/Storage/StorageModule.cs b/dotnet/src/webdriver/BiDi/Storage/StorageModule.cs index 29410895ce187..4890804a71328 100644 --- a/dotnet/src/webdriver/BiDi/Storage/StorageModule.cs +++ b/dotnet/src/webdriver/BiDi/Storage/StorageModule.cs @@ -49,7 +49,7 @@ public async Task SetCookieAsync(PartialCookie cookie, SetCooki return await Broker.ExecuteCommandAsync(new SetCookieCommand(@params), options, JsonContext.SetCookieCommand, JsonContext.SetCookieResult).ConfigureAwait(false); } - protected override JsonSerializerContext Initialize(JsonSerializerOptions options) + protected override JsonSerializerContext CreateJsonContext(JsonSerializerOptions options) { return new BiDiJsonSerializerContext(options); } diff --git a/dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs b/dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs index 2a3d13e9e9064..85db9f69da2f0 100644 --- a/dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs +++ b/dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs @@ -42,7 +42,7 @@ public async Task UninstallAsync(Extension extension, Uninstall return await Broker.ExecuteCommandAsync(new UninstallCommand(@params), options, JsonContext.UninstallCommand, JsonContext.UninstallResult).ConfigureAwait(false); } - protected override JsonSerializerContext Initialize(JsonSerializerOptions options) + protected override JsonSerializerContext CreateJsonContext(JsonSerializerOptions options) { return new BiDiJsonSerializerContext(options); } From 6bec7723bfcd9d1acfe4e2d086afbe5730e1b3c1 Mon Sep 17 00:00:00 2001 From: Michael Render Date: Mon, 20 Oct 2025 18:55:29 -0400 Subject: [PATCH 10/25] Fix format --- .../BiDi/Permissions/PermissionsModule.cs | 19 +++++++++++++++++++ .../BiDi/Permissions/SetPermissionCommand.cs | 19 +++++++++++++++++++ .../BiDi/Permissions/PermissionsTests.cs | 19 +++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs b/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs index 0d03bd0d382f8..52b3ac53c267e 100644 --- a/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs +++ b/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs @@ -1,3 +1,22 @@ +// +// 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 OpenQA.Selenium.BiDi.Browser; using OpenQA.Selenium.BiDi.Communication; using OpenQA.Selenium.BiDi.Permissions; diff --git a/dotnet/src/webdriver/BiDi/Permissions/SetPermissionCommand.cs b/dotnet/src/webdriver/BiDi/Permissions/SetPermissionCommand.cs index 9e49f436e59c0..f41b0e5f16a20 100644 --- a/dotnet/src/webdriver/BiDi/Permissions/SetPermissionCommand.cs +++ b/dotnet/src/webdriver/BiDi/Permissions/SetPermissionCommand.cs @@ -1,3 +1,22 @@ +// +// 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 OpenQA.Selenium.BiDi.Browser; using OpenQA.Selenium.BiDi.Communication; diff --git a/dotnet/test/common/BiDi/Permissions/PermissionsTests.cs b/dotnet/test/common/BiDi/Permissions/PermissionsTests.cs index bb832b74828b6..c567326ac0a6d 100644 --- a/dotnet/test/common/BiDi/Permissions/PermissionsTests.cs +++ b/dotnet/test/common/BiDi/Permissions/PermissionsTests.cs @@ -1,3 +1,22 @@ +// +// 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 NUnit.Framework; using OpenQA.Selenium.BiDi.BrowsingContext; using OpenQA.Selenium.BiDi.Script; From 875f5e48e019a574ca676093d1195f4f9d44fb41 Mon Sep 17 00:00:00 2001 From: Michael Render Date: Wed, 22 Oct 2025 12:03:11 -0400 Subject: [PATCH 11/25] Rename extensions files, move Permissions into a separate file from general BiDi extensinos --- ...Driver.Extensions.cs => BiDiExtensions.cs} | 10 ++---- .../BiDi/Permissions/PermissionsExtensions.cs | 36 +++++++++++++++++++ 2 files changed, 38 insertions(+), 8 deletions(-) rename dotnet/src/webdriver/BiDi/{WebDriver.Extensions.cs => BiDiExtensions.cs} (82%) create mode 100644 dotnet/src/webdriver/BiDi/Permissions/PermissionsExtensions.cs diff --git a/dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs b/dotnet/src/webdriver/BiDi/BiDiExtensions.cs similarity index 82% rename from dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs rename to dotnet/src/webdriver/BiDi/BiDiExtensions.cs index fc270b7b58839..13d58b7ff0b0c 100644 --- a/dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs +++ b/dotnet/src/webdriver/BiDi/BiDiExtensions.cs @@ -1,4 +1,4 @@ -// +// // 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 @@ -17,13 +17,12 @@ // under the License. // -using OpenQA.Selenium.BiDi.Extensions.Permissions; using System; using System.Threading.Tasks; namespace OpenQA.Selenium.BiDi; -public static class WebDriverExtensions +public static class BiDiExtensions { public static async Task AsBiDiAsync(this IWebDriver webDriver, BiDiOptions? options = null) { @@ -42,9 +41,4 @@ public static async Task AsBiDiAsync(this IWebDriver webDriver, BiDiOption return bidi; } - - public static PermissionsModule AsPermissions(this BiDi bidi) - { - return Module.Create(bidi, bidi.DefaultBiDiOptions()); - } } diff --git a/dotnet/src/webdriver/BiDi/Permissions/PermissionsExtensions.cs b/dotnet/src/webdriver/BiDi/Permissions/PermissionsExtensions.cs new file mode 100644 index 0000000000000..d24c3f0238c11 --- /dev/null +++ b/dotnet/src/webdriver/BiDi/Permissions/PermissionsExtensions.cs @@ -0,0 +1,36 @@ +// +// 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 OpenQA.Selenium.BiDi.Extensions.Permissions; +using System; + +namespace OpenQA.Selenium.BiDi.Permissions; + +public static class PermissionsExtensions +{ + public static PermissionsModule AsPermissions(this BiDi bidi) + { + if (bidi is null) + { + throw new ArgumentNullException(nameof(bidi)); + } + + return Module.Create(bidi, bidi.DefaultBiDiOptions()); + } +} From 3c6d2f7dfebe548f92a9890df35a5dfba2d2345f Mon Sep 17 00:00:00 2001 From: Michael Render Date: Fri, 24 Oct 2025 16:29:24 -0400 Subject: [PATCH 12/25] Rename PermissionsExtensions to PermissionsBiDiExtensions --- ...{PermissionsExtensions.cs => PermissionsBiDiExtensions.cs} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename dotnet/src/webdriver/BiDi/Permissions/{PermissionsExtensions.cs => PermissionsBiDiExtensions.cs} (90%) diff --git a/dotnet/src/webdriver/BiDi/Permissions/PermissionsExtensions.cs b/dotnet/src/webdriver/BiDi/Permissions/PermissionsBiDiExtensions.cs similarity index 90% rename from dotnet/src/webdriver/BiDi/Permissions/PermissionsExtensions.cs rename to dotnet/src/webdriver/BiDi/Permissions/PermissionsBiDiExtensions.cs index d24c3f0238c11..ff8dff47db1e6 100644 --- a/dotnet/src/webdriver/BiDi/Permissions/PermissionsExtensions.cs +++ b/dotnet/src/webdriver/BiDi/Permissions/PermissionsBiDiExtensions.cs @@ -1,4 +1,4 @@ -// +// // 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 @@ -22,7 +22,7 @@ namespace OpenQA.Selenium.BiDi.Permissions; -public static class PermissionsExtensions +public static class PermissionsBiDiExtensions { public static PermissionsModule AsPermissions(this BiDi bidi) { From 22e3caa98b1c8cd457224e9ddcf526172362fa04 Mon Sep 17 00:00:00 2001 From: Michael Render Date: Fri, 28 Nov 2025 19:14:41 -0500 Subject: [PATCH 13/25] Fix imports after Communications refactor --- dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs | 3 +-- .../webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs | 3 +-- dotnet/src/webdriver/BiDi/Emulation/EmulationModule.cs | 3 +-- dotnet/src/webdriver/BiDi/Input/InputModule.cs | 3 +-- dotnet/src/webdriver/BiDi/Log/LogModule.cs | 3 +-- dotnet/src/webdriver/BiDi/Module.cs | 1 - dotnet/src/webdriver/BiDi/Network/NetworkModule.cs | 3 +-- dotnet/src/webdriver/BiDi/Permissions/PermissionState.cs | 2 +- dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs | 1 - dotnet/src/webdriver/BiDi/Permissions/SetPermissionCommand.cs | 1 - dotnet/src/webdriver/BiDi/Script/ScriptModule.cs | 3 +-- dotnet/src/webdriver/BiDi/Session/SessionModule.cs | 3 +-- dotnet/src/webdriver/BiDi/Storage/StorageModule.cs | 3 +-- dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs | 3 +-- 14 files changed, 11 insertions(+), 24 deletions(-) diff --git a/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs b/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs index 6ec20caa7e90e..2b242b5715704 100644 --- a/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs +++ b/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs @@ -17,8 +17,7 @@ // under the License. // -using OpenQA.Selenium.BiDi.Communication; -using OpenQA.Selenium.BiDi.Communication.Json; +using OpenQA.Selenium.BiDi.Json; using System.Text.Json; using System.Text.Json.Serialization; using System.Threading.Tasks; diff --git a/dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs b/dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs index caf07787c84f4..aa33194a89680 100644 --- a/dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs +++ b/dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs @@ -17,8 +17,7 @@ // under the License. // -using OpenQA.Selenium.BiDi.Communication; -using OpenQA.Selenium.BiDi.Communication.Json; +using OpenQA.Selenium.BiDi.Json; using System; using System.Text.Json; using System.Text.Json.Serialization; diff --git a/dotnet/src/webdriver/BiDi/Emulation/EmulationModule.cs b/dotnet/src/webdriver/BiDi/Emulation/EmulationModule.cs index 5e1af9225613a..17b07bf18220b 100644 --- a/dotnet/src/webdriver/BiDi/Emulation/EmulationModule.cs +++ b/dotnet/src/webdriver/BiDi/Emulation/EmulationModule.cs @@ -17,8 +17,7 @@ // under the License. // -using OpenQA.Selenium.BiDi.Communication; -using OpenQA.Selenium.BiDi.Communication.Json; +using OpenQA.Selenium.BiDi.Json; using System.Text.Json; using System.Text.Json.Serialization; using System.Threading.Tasks; diff --git a/dotnet/src/webdriver/BiDi/Input/InputModule.cs b/dotnet/src/webdriver/BiDi/Input/InputModule.cs index 5a7765119629a..0e8597d0f822d 100644 --- a/dotnet/src/webdriver/BiDi/Input/InputModule.cs +++ b/dotnet/src/webdriver/BiDi/Input/InputModule.cs @@ -17,8 +17,7 @@ // under the License. // -using OpenQA.Selenium.BiDi.Communication; -using OpenQA.Selenium.BiDi.Communication.Json; +using OpenQA.Selenium.BiDi.Json; using System.Collections.Generic; using System.Text.Json; using System.Text.Json.Serialization; diff --git a/dotnet/src/webdriver/BiDi/Log/LogModule.cs b/dotnet/src/webdriver/BiDi/Log/LogModule.cs index 55b68c46e3a98..343fa5d8a0eb8 100644 --- a/dotnet/src/webdriver/BiDi/Log/LogModule.cs +++ b/dotnet/src/webdriver/BiDi/Log/LogModule.cs @@ -17,8 +17,7 @@ // under the License. // -using OpenQA.Selenium.BiDi.Communication; -using OpenQA.Selenium.BiDi.Communication.Json; +using OpenQA.Selenium.BiDi.Json; using System; using System.Text.Json; using System.Text.Json.Serialization; diff --git a/dotnet/src/webdriver/BiDi/Module.cs b/dotnet/src/webdriver/BiDi/Module.cs index fda2c5199dbe9..78a2753c68c9a 100644 --- a/dotnet/src/webdriver/BiDi/Module.cs +++ b/dotnet/src/webdriver/BiDi/Module.cs @@ -17,7 +17,6 @@ // under the License. // -using OpenQA.Selenium.BiDi.Communication; using System.Text.Json; using System.Text.Json.Serialization; diff --git a/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs b/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs index 198d4698391e2..ec57917925ba3 100644 --- a/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs +++ b/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs @@ -17,8 +17,7 @@ // under the License. // -using OpenQA.Selenium.BiDi.Communication; -using OpenQA.Selenium.BiDi.Communication.Json; +using OpenQA.Selenium.BiDi.Json; using System; using System.Collections.Generic; using System.Text.Json; diff --git a/dotnet/src/webdriver/BiDi/Permissions/PermissionState.cs b/dotnet/src/webdriver/BiDi/Permissions/PermissionState.cs index 1b3c9d3486655..0bc4c0c220349 100644 --- a/dotnet/src/webdriver/BiDi/Permissions/PermissionState.cs +++ b/dotnet/src/webdriver/BiDi/Permissions/PermissionState.cs @@ -17,7 +17,7 @@ // under the License. // -using OpenQA.Selenium.BiDi.Communication.Json.Converters; +using OpenQA.Selenium.BiDi.Json.Converters; using System.Text.Json.Serialization; namespace OpenQA.Selenium.BiDi.Permissions; diff --git a/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs b/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs index 52b3ac53c267e..e5a5be06aa076 100644 --- a/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs +++ b/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs @@ -18,7 +18,6 @@ // using OpenQA.Selenium.BiDi.Browser; -using OpenQA.Selenium.BiDi.Communication; using OpenQA.Selenium.BiDi.Permissions; using System.Text.Json; using System.Text.Json.Serialization; diff --git a/dotnet/src/webdriver/BiDi/Permissions/SetPermissionCommand.cs b/dotnet/src/webdriver/BiDi/Permissions/SetPermissionCommand.cs index f41b0e5f16a20..75b0835673df9 100644 --- a/dotnet/src/webdriver/BiDi/Permissions/SetPermissionCommand.cs +++ b/dotnet/src/webdriver/BiDi/Permissions/SetPermissionCommand.cs @@ -18,7 +18,6 @@ // using OpenQA.Selenium.BiDi.Browser; -using OpenQA.Selenium.BiDi.Communication; namespace OpenQA.Selenium.BiDi.Permissions; diff --git a/dotnet/src/webdriver/BiDi/Script/ScriptModule.cs b/dotnet/src/webdriver/BiDi/Script/ScriptModule.cs index efebfe3a1a833..99e0dd0c47700 100644 --- a/dotnet/src/webdriver/BiDi/Script/ScriptModule.cs +++ b/dotnet/src/webdriver/BiDi/Script/ScriptModule.cs @@ -17,8 +17,7 @@ // under the License. // -using OpenQA.Selenium.BiDi.Communication; -using OpenQA.Selenium.BiDi.Communication.Json; +using OpenQA.Selenium.BiDi.Json; using System; using System.Collections.Generic; using System.Text.Json; diff --git a/dotnet/src/webdriver/BiDi/Session/SessionModule.cs b/dotnet/src/webdriver/BiDi/Session/SessionModule.cs index 927d58c9443cf..b391c4eaf4ff3 100644 --- a/dotnet/src/webdriver/BiDi/Session/SessionModule.cs +++ b/dotnet/src/webdriver/BiDi/Session/SessionModule.cs @@ -17,8 +17,7 @@ // under the License. // -using OpenQA.Selenium.BiDi.Communication; -using OpenQA.Selenium.BiDi.Communication.Json; +using OpenQA.Selenium.BiDi.Json; using System.Collections.Generic; using System.Text.Json; using System.Text.Json.Serialization; diff --git a/dotnet/src/webdriver/BiDi/Storage/StorageModule.cs b/dotnet/src/webdriver/BiDi/Storage/StorageModule.cs index 4890804a71328..8f4a72514f646 100644 --- a/dotnet/src/webdriver/BiDi/Storage/StorageModule.cs +++ b/dotnet/src/webdriver/BiDi/Storage/StorageModule.cs @@ -17,8 +17,7 @@ // under the License. // -using OpenQA.Selenium.BiDi.Communication; -using OpenQA.Selenium.BiDi.Communication.Json; +using OpenQA.Selenium.BiDi.Json; using System.Text.Json; using System.Text.Json.Serialization; using System.Threading.Tasks; diff --git a/dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs b/dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs index 85db9f69da2f0..8e1b71d07fed7 100644 --- a/dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs +++ b/dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs @@ -17,8 +17,7 @@ // under the License. // -using OpenQA.Selenium.BiDi.Communication; -using OpenQA.Selenium.BiDi.Communication.Json; +using OpenQA.Selenium.BiDi.Json; using System.Text.Json; using System.Text.Json.Serialization; using System.Threading.Tasks; From cb6e3f2651b0bf8de2ca50c1fe514a84a27170fc Mon Sep 17 00:00:00 2001 From: Michael Render Date: Fri, 28 Nov 2025 19:25:32 -0500 Subject: [PATCH 14/25] [dotnet] Add missing embeddedOrigin parameter, PR feedback --- dotnet/src/webdriver/BiDi/Browser/UserContext.cs | 14 +++++++++----- .../BiDi/Permissions/PermissionsModule.cs | 10 +++++----- .../BiDi/Permissions/SetPermissionCommand.cs | 2 +- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/dotnet/src/webdriver/BiDi/Browser/UserContext.cs b/dotnet/src/webdriver/BiDi/Browser/UserContext.cs index 6f7bc3f8dab5d..83402190561ec 100644 --- a/dotnet/src/webdriver/BiDi/Browser/UserContext.cs +++ b/dotnet/src/webdriver/BiDi/Browser/UserContext.cs @@ -22,7 +22,7 @@ namespace OpenQA.Selenium.BiDi.Browser; -public sealed class UserContext : IAsyncDisposable +public sealed class UserContext :IEquatable, IAsyncDisposable { private readonly BiDi _bidi; @@ -44,15 +44,19 @@ public async ValueTask DisposeAsync() await RemoveAsync().ConfigureAwait(false); } - public override bool Equals(object? obj) + public bool Equals(UserContext? other) { - if (obj is UserContext userContextObj) return userContextObj.Id == Id; + return other is not null && string.Equals(Id, other.Id, StringComparison.Ordinal); + } + - return false; + public override bool Equals(object? obj) + { + return Equals(obj as UserContext); } public override int GetHashCode() { - return Id.GetHashCode(); + return StringComparer.Ordinal.GetHashCode(Id); } } diff --git a/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs b/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs index e5a5be06aa076..7c67054df5224 100644 --- a/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs +++ b/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs @@ -29,11 +29,11 @@ public class PermissionsModule : Module { private PermissionsJsonSerializerContext JsonContext => (PermissionsJsonSerializerContext)base.JsonContext; - public async Task SetPermissionAsync(string permissionName, PermissionState state, string origin, UserContext? userContext, SetPermissionOptions? options = null) + public async Task SetPermissionAsync(string permissionName, PermissionState state, string origin, string? embeddedOrigin, UserContext? userContext, SetPermissionOptions? options = null) { - var @params = new SetPermissionCommandParameters(new PermissionDescriptor(permissionName), state, origin, userContext); + var @params = new SetPermissionCommandParameters(new PermissionDescriptor(permissionName), state, origin, embeddedOrigin, userContext); - await Broker.ExecuteCommandAsync(new SetPermissionCommand(@params), options, JsonContext.Permissions_SetPermissionCommand, JsonContext.Permissions_SetPermissionResult).ConfigureAwait(false); + await Broker.ExecuteCommandAsync(new SetPermissionCommand(@params), options, JsonContext.SetPermissionCommand, JsonContext.SetPermissionResult).ConfigureAwait(false); } protected override JsonSerializerContext CreateJsonContext(JsonSerializerOptions options) @@ -42,6 +42,6 @@ protected override JsonSerializerContext CreateJsonContext(JsonSerializerOptions } } -[JsonSerializable(typeof(SetPermissionCommand), TypeInfoPropertyName = "Permissions_SetPermissionCommand")] -[JsonSerializable(typeof(SetPermissionResult), TypeInfoPropertyName = "Permissions_SetPermissionResult")] +[JsonSerializable(typeof(SetPermissionCommand))] +[JsonSerializable(typeof(SetPermissionResult))] internal partial class PermissionsJsonSerializerContext : JsonSerializerContext; diff --git a/dotnet/src/webdriver/BiDi/Permissions/SetPermissionCommand.cs b/dotnet/src/webdriver/BiDi/Permissions/SetPermissionCommand.cs index 75b0835673df9..96f1fd033dabd 100644 --- a/dotnet/src/webdriver/BiDi/Permissions/SetPermissionCommand.cs +++ b/dotnet/src/webdriver/BiDi/Permissions/SetPermissionCommand.cs @@ -27,4 +27,4 @@ internal class SetPermissionCommand(SetPermissionCommandParameters @params) public class SetPermissionOptions : CommandOptions; public sealed record SetPermissionResult : EmptyResult; -internal record SetPermissionCommandParameters(PermissionDescriptor Descriptor, PermissionState State, string Origin, UserContext? UserContext) : Parameters; +internal record SetPermissionCommandParameters(PermissionDescriptor Descriptor, PermissionState State, string Origin, string? EmbeddedOrigin, UserContext? UserContext) : Parameters; From 194e2c8cbcfc3b65381fed965c5c4a596b2d2f7d Mon Sep 17 00:00:00 2001 From: Michael Render Date: Fri, 28 Nov 2025 19:27:16 -0500 Subject: [PATCH 15/25] [dotnet] Expose PermissionDescriptor directly --- dotnet/src/webdriver/BiDi/Permissions/PermissionDescriptor.cs | 2 +- dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs | 4 ++-- dotnet/test/common/BiDi/Permissions/PermissionsTests.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dotnet/src/webdriver/BiDi/Permissions/PermissionDescriptor.cs b/dotnet/src/webdriver/BiDi/Permissions/PermissionDescriptor.cs index a418c4387b485..e49a4197ecf84 100644 --- a/dotnet/src/webdriver/BiDi/Permissions/PermissionDescriptor.cs +++ b/dotnet/src/webdriver/BiDi/Permissions/PermissionDescriptor.cs @@ -19,4 +19,4 @@ namespace OpenQA.Selenium.BiDi.Permissions; -internal record PermissionDescriptor(string Name); +public record PermissionDescriptor(string Name); diff --git a/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs b/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs index 7c67054df5224..62029b8b35893 100644 --- a/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs +++ b/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs @@ -29,9 +29,9 @@ public class PermissionsModule : Module { private PermissionsJsonSerializerContext JsonContext => (PermissionsJsonSerializerContext)base.JsonContext; - public async Task SetPermissionAsync(string permissionName, PermissionState state, string origin, string? embeddedOrigin, UserContext? userContext, SetPermissionOptions? options = null) + public async Task SetPermissionAsync(PermissionDescriptor permissionName, PermissionState state, string origin, string? embeddedOrigin, UserContext? userContext, SetPermissionOptions? options = null) { - var @params = new SetPermissionCommandParameters(new PermissionDescriptor(permissionName), state, origin, embeddedOrigin, userContext); + var @params = new SetPermissionCommandParameters(permissionName, state, origin, embeddedOrigin, userContext); await Broker.ExecuteCommandAsync(new SetPermissionCommand(@params), options, JsonContext.SetPermissionCommand, JsonContext.SetPermissionResult).ConfigureAwait(false); } diff --git a/dotnet/test/common/BiDi/Permissions/PermissionsTests.cs b/dotnet/test/common/BiDi/Permissions/PermissionsTests.cs index c567326ac0a6d..a8b14618f39c1 100644 --- a/dotnet/test/common/BiDi/Permissions/PermissionsTests.cs +++ b/dotnet/test/common/BiDi/Permissions/PermissionsTests.cs @@ -50,7 +50,7 @@ public async Task SettingPermissionsTest() Assert.That(before.AsSuccessResult(), Is.EqualTo(new StringRemoteValue("prompt"))); var permissions = bidi.AsPermissions(); - await permissions.SetPermissionAsync("geolocation", PermissionState.Denied, newPage, userContext.UserContext); + await permissions.SetPermissionAsync(new PermissionDescriptor("geolocation"), PermissionState.Denied, newPage, embeddedOrigin: null, userContext.UserContext); var after = await window.Script.CallFunctionAsync(""" async () => (await navigator.permissions.query({ name: "geolocation" })).state From 6a010eb1bf35b17ef9bfae348452cc5d6800d4bf Mon Sep 17 00:00:00 2001 From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com> Date: Sat, 29 Nov 2025 15:58:06 +0300 Subject: [PATCH 16/25] Fix merge --- dotnet/src/webdriver/BiDi/Network/NetworkModule.cs | 3 +-- dotnet/src/webdriver/BiDi/Permissions/PermissionState.cs | 2 +- dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs | 1 - dotnet/src/webdriver/BiDi/Permissions/SetPermissionCommand.cs | 1 - 4 files changed, 2 insertions(+), 5 deletions(-) diff --git a/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs b/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs index 198d4698391e2..ec57917925ba3 100644 --- a/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs +++ b/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs @@ -17,8 +17,7 @@ // under the License. // -using OpenQA.Selenium.BiDi.Communication; -using OpenQA.Selenium.BiDi.Communication.Json; +using OpenQA.Selenium.BiDi.Json; using System; using System.Collections.Generic; using System.Text.Json; diff --git a/dotnet/src/webdriver/BiDi/Permissions/PermissionState.cs b/dotnet/src/webdriver/BiDi/Permissions/PermissionState.cs index 1b3c9d3486655..0bc4c0c220349 100644 --- a/dotnet/src/webdriver/BiDi/Permissions/PermissionState.cs +++ b/dotnet/src/webdriver/BiDi/Permissions/PermissionState.cs @@ -17,7 +17,7 @@ // under the License. // -using OpenQA.Selenium.BiDi.Communication.Json.Converters; +using OpenQA.Selenium.BiDi.Json.Converters; using System.Text.Json.Serialization; namespace OpenQA.Selenium.BiDi.Permissions; diff --git a/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs b/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs index 52b3ac53c267e..e5a5be06aa076 100644 --- a/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs +++ b/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs @@ -18,7 +18,6 @@ // using OpenQA.Selenium.BiDi.Browser; -using OpenQA.Selenium.BiDi.Communication; using OpenQA.Selenium.BiDi.Permissions; using System.Text.Json; using System.Text.Json.Serialization; diff --git a/dotnet/src/webdriver/BiDi/Permissions/SetPermissionCommand.cs b/dotnet/src/webdriver/BiDi/Permissions/SetPermissionCommand.cs index f41b0e5f16a20..75b0835673df9 100644 --- a/dotnet/src/webdriver/BiDi/Permissions/SetPermissionCommand.cs +++ b/dotnet/src/webdriver/BiDi/Permissions/SetPermissionCommand.cs @@ -18,7 +18,6 @@ // using OpenQA.Selenium.BiDi.Browser; -using OpenQA.Selenium.BiDi.Communication; namespace OpenQA.Selenium.BiDi.Permissions; From e10ef6c14f3c5636746069e092adf4572c87a4b1 Mon Sep 17 00:00:00 2001 From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com> Date: Sat, 29 Nov 2025 15:59:31 +0300 Subject: [PATCH 17/25] Format --- dotnet/src/webdriver/BiDi/Browser/UserContext.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/src/webdriver/BiDi/Browser/UserContext.cs b/dotnet/src/webdriver/BiDi/Browser/UserContext.cs index 83402190561ec..46066271be9e1 100644 --- a/dotnet/src/webdriver/BiDi/Browser/UserContext.cs +++ b/dotnet/src/webdriver/BiDi/Browser/UserContext.cs @@ -22,7 +22,7 @@ namespace OpenQA.Selenium.BiDi.Browser; -public sealed class UserContext :IEquatable, IAsyncDisposable +public sealed class UserContext : IEquatable, IAsyncDisposable { private readonly BiDi _bidi; From dd903dc1a43bb8732f69205363c5126faf76212e Mon Sep 17 00:00:00 2001 From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com> Date: Sat, 29 Nov 2025 16:01:27 +0300 Subject: [PATCH 18/25] Format globally --- dotnet/src/webdriver/Chromium/ChromiumDriverLogLevel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/src/webdriver/Chromium/ChromiumDriverLogLevel.cs b/dotnet/src/webdriver/Chromium/ChromiumDriverLogLevel.cs index 4e87858b065f3..96f771cea8d58 100644 --- a/dotnet/src/webdriver/Chromium/ChromiumDriverLogLevel.cs +++ b/dotnet/src/webdriver/Chromium/ChromiumDriverLogLevel.cs @@ -42,7 +42,7 @@ public enum ChromiumDriverLogLevel /// /// Represents the Warning value /// - Warning , + Warning, /// /// Represents the Severe value From bf05704e68223ee12ad23e37e8eccdbbc8dcae91 Mon Sep 17 00:00:00 2001 From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com> Date: Sat, 29 Nov 2025 16:05:24 +0300 Subject: [PATCH 19/25] Unify command signatures --- .../webdriver/BiDi/Permissions/PermissionsModule.cs | 7 +++---- .../BiDi/Permissions/SetPermissionCommand.cs | 12 +++++++++--- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs b/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs index 62029b8b35893..cc7d086c6a41b 100644 --- a/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs +++ b/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs @@ -17,7 +17,6 @@ // under the License. // -using OpenQA.Selenium.BiDi.Browser; using OpenQA.Selenium.BiDi.Permissions; using System.Text.Json; using System.Text.Json.Serialization; @@ -29,11 +28,11 @@ public class PermissionsModule : Module { private PermissionsJsonSerializerContext JsonContext => (PermissionsJsonSerializerContext)base.JsonContext; - public async Task SetPermissionAsync(PermissionDescriptor permissionName, PermissionState state, string origin, string? embeddedOrigin, UserContext? userContext, SetPermissionOptions? options = null) + public async Task SetPermissionAsync(PermissionDescriptor permissionName, PermissionState state, string origin, SetPermissionOptions? options = null) { - var @params = new SetPermissionCommandParameters(permissionName, state, origin, embeddedOrigin, userContext); + var @params = new SetPermissionCommandParameters(permissionName, state, origin, options?.EmbeddedOrigin, options?.UserContext); - await Broker.ExecuteCommandAsync(new SetPermissionCommand(@params), options, JsonContext.SetPermissionCommand, JsonContext.SetPermissionResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new SetPermissionCommand(@params), options, JsonContext.SetPermissionCommand, JsonContext.SetPermissionResult).ConfigureAwait(false); } protected override JsonSerializerContext CreateJsonContext(JsonSerializerOptions options) diff --git a/dotnet/src/webdriver/BiDi/Permissions/SetPermissionCommand.cs b/dotnet/src/webdriver/BiDi/Permissions/SetPermissionCommand.cs index 96f1fd033dabd..12d7ae0cc3b0f 100644 --- a/dotnet/src/webdriver/BiDi/Permissions/SetPermissionCommand.cs +++ b/dotnet/src/webdriver/BiDi/Permissions/SetPermissionCommand.cs @@ -24,7 +24,13 @@ namespace OpenQA.Selenium.BiDi.Permissions; internal class SetPermissionCommand(SetPermissionCommandParameters @params) : Command(@params, "permissions.setPermission"); -public class SetPermissionOptions : CommandOptions; -public sealed record SetPermissionResult : EmptyResult; - internal record SetPermissionCommandParameters(PermissionDescriptor Descriptor, PermissionState State, string Origin, string? EmbeddedOrigin, UserContext? UserContext) : Parameters; + +public class SetPermissionOptions : CommandOptions +{ + public string? EmbeddedOrigin { get; set; } + + public UserContext? UserContext { get; set; } +} + +public sealed record SetPermissionResult : EmptyResult; From b3fd21fde9c4f03efd2b9502caeffff5ae87c1fc Mon Sep 17 00:00:00 2001 From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com> Date: Sat, 29 Nov 2025 16:09:28 +0300 Subject: [PATCH 20/25] Fix test --- .../BiDi/{BiDiExtensions.cs => WebDriver.Extensions.cs} | 4 ++-- dotnet/test/common/BiDi/Permissions/PermissionsTests.cs | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) rename dotnet/src/webdriver/BiDi/{BiDiExtensions.cs => WebDriver.Extensions.cs} (93%) diff --git a/dotnet/src/webdriver/BiDi/BiDiExtensions.cs b/dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs similarity index 93% rename from dotnet/src/webdriver/BiDi/BiDiExtensions.cs rename to dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs index 13d58b7ff0b0c..2aedc80a2c092 100644 --- a/dotnet/src/webdriver/BiDi/BiDiExtensions.cs +++ b/dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs @@ -1,4 +1,4 @@ -// +// // 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 @@ -22,7 +22,7 @@ namespace OpenQA.Selenium.BiDi; -public static class BiDiExtensions +public static class WebDriverExtensions { public static async Task AsBiDiAsync(this IWebDriver webDriver, BiDiOptions? options = null) { diff --git a/dotnet/test/common/BiDi/Permissions/PermissionsTests.cs b/dotnet/test/common/BiDi/Permissions/PermissionsTests.cs index a8b14618f39c1..a9d0cabef4f6e 100644 --- a/dotnet/test/common/BiDi/Permissions/PermissionsTests.cs +++ b/dotnet/test/common/BiDi/Permissions/PermissionsTests.cs @@ -50,7 +50,8 @@ public async Task SettingPermissionsTest() Assert.That(before.AsSuccessResult(), Is.EqualTo(new StringRemoteValue("prompt"))); var permissions = bidi.AsPermissions(); - await permissions.SetPermissionAsync(new PermissionDescriptor("geolocation"), PermissionState.Denied, newPage, embeddedOrigin: null, userContext.UserContext); + + await permissions.SetPermissionAsync(new PermissionDescriptor("geolocation"), PermissionState.Denied, newPage, new() { UserContext = userContext.UserContext }); var after = await window.Script.CallFunctionAsync(""" async () => (await navigator.permissions.query({ name: "geolocation" })).state From 15e0d1a49a2ae54f8d6f11d3da6b254d6ff03197 Mon Sep 17 00:00:00 2001 From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com> Date: Sat, 29 Nov 2025 16:10:10 +0300 Subject: [PATCH 21/25] Rename descriptor --- dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs b/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs index cc7d086c6a41b..2a977abb301d8 100644 --- a/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs +++ b/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs @@ -28,9 +28,9 @@ public class PermissionsModule : Module { private PermissionsJsonSerializerContext JsonContext => (PermissionsJsonSerializerContext)base.JsonContext; - public async Task SetPermissionAsync(PermissionDescriptor permissionName, PermissionState state, string origin, SetPermissionOptions? options = null) + public async Task SetPermissionAsync(PermissionDescriptor desriptor, PermissionState state, string origin, SetPermissionOptions? options = null) { - var @params = new SetPermissionCommandParameters(permissionName, state, origin, options?.EmbeddedOrigin, options?.UserContext); + var @params = new SetPermissionCommandParameters(desriptor, state, origin, options?.EmbeddedOrigin, options?.UserContext); return await Broker.ExecuteCommandAsync(new SetPermissionCommand(@params), options, JsonContext.SetPermissionCommand, JsonContext.SetPermissionResult).ConfigureAwait(false); } From 080749cc296e756753e1eed927436880970e5a86 Mon Sep 17 00:00:00 2001 From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com> Date: Sat, 29 Nov 2025 16:37:49 +0300 Subject: [PATCH 22/25] JsonContext per module --- .../webdriver/BiDi/Browser/BrowserModule.cs | 24 ++--- .../BrowsingContext/BrowsingContextModule.cs | 88 +++++++++---------- .../BiDi/Emulation/EmulationModule.cs | 26 +++--- .../src/webdriver/BiDi/Input/InputModule.cs | 14 +-- dotnet/src/webdriver/BiDi/Log/LogModule.cs | 12 +-- dotnet/src/webdriver/BiDi/Module.cs | 6 +- .../webdriver/BiDi/Network/NetworkModule.cs | 56 ++++++------ .../BiDi/Permissions/PermissionsModule.cs | 8 +- .../src/webdriver/BiDi/Script/ScriptModule.cs | 32 +++---- .../webdriver/BiDi/Session/SessionModule.cs | 18 ++-- .../webdriver/BiDi/Storage/StorageModule.cs | 14 +-- .../BiDi/WebExtension/WebExtensionModule.cs | 12 +-- 12 files changed, 153 insertions(+), 157 deletions(-) diff --git a/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs b/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs index 2b242b5715704..6cf8c78c25e3b 100644 --- a/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs +++ b/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs @@ -19,42 +19,41 @@ using OpenQA.Selenium.BiDi.Json; using System.Text.Json; -using System.Text.Json.Serialization; using System.Threading.Tasks; namespace OpenQA.Selenium.BiDi.Browser; public sealed class BrowserModule : Module { - internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; + private BiDiJsonSerializerContext _jsonContext = null!; public async Task CloseAsync(CloseOptions? options = null) { - return await Broker.ExecuteCommandAsync(new CloseCommand(), options, JsonContext.Browser_CloseCommand, JsonContext.Browser_CloseResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new CloseCommand(), options, _jsonContext.Browser_CloseCommand, _jsonContext.Browser_CloseResult).ConfigureAwait(false); } public async Task CreateUserContextAsync(CreateUserContextOptions? options = null) { var @params = new CreateUserContextParameters(options?.AcceptInsecureCerts, options?.Proxy, options?.UnhandledPromptBehavior); - return await Broker.ExecuteCommandAsync(new CreateUserContextCommand(@params), options, JsonContext.CreateUserContextCommand, JsonContext.CreateUserContextResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new CreateUserContextCommand(@params), options, _jsonContext.CreateUserContextCommand, _jsonContext.CreateUserContextResult).ConfigureAwait(false); } public async Task GetUserContextsAsync(GetUserContextsOptions? options = null) { - return await Broker.ExecuteCommandAsync(new GetUserContextsCommand(), options, JsonContext.GetUserContextsCommand, JsonContext.GetUserContextsResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new GetUserContextsCommand(), options, _jsonContext.GetUserContextsCommand, _jsonContext.GetUserContextsResult).ConfigureAwait(false); } public async Task RemoveUserContextAsync(UserContext userContext, RemoveUserContextOptions? options = null) { var @params = new RemoveUserContextParameters(userContext); - return await Broker.ExecuteCommandAsync(new RemoveUserContextCommand(@params), options, JsonContext.RemoveUserContextCommand, JsonContext.RemoveUserContextResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new RemoveUserContextCommand(@params), options, _jsonContext.RemoveUserContextCommand, _jsonContext.RemoveUserContextResult).ConfigureAwait(false); } public async Task GetClientWindowsAsync(GetClientWindowsOptions? options = null) { - return await Broker.ExecuteCommandAsync(new(), options, JsonContext.GetClientWindowsCommand, JsonContext.GetClientWindowsResult + return await Broker.ExecuteCommandAsync(new(), options, _jsonContext.GetClientWindowsCommand, _jsonContext.GetClientWindowsResult ).ConfigureAwait(false); } @@ -62,24 +61,25 @@ public async Task SetDownloadBehaviorAllowedAsync(str { var @params = new SetDownloadBehaviorParameters(new DownloadBehaviorAllowed(destinationFolder), options?.UserContexts); - return await Broker.ExecuteCommandAsync(new SetDownloadBehaviorCommand(@params), options, JsonContext.SetDownloadBehaviorCommand, JsonContext.SetDownloadBehaviorResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new SetDownloadBehaviorCommand(@params), options, _jsonContext.SetDownloadBehaviorCommand, _jsonContext.SetDownloadBehaviorResult).ConfigureAwait(false); } public async Task SetDownloadBehaviorAllowedAsync(SetDownloadBehaviorOptions? options = null) { var @params = new SetDownloadBehaviorParameters(null, options?.UserContexts); - return await Broker.ExecuteCommandAsync(new SetDownloadBehaviorCommand(@params), options, JsonContext.SetDownloadBehaviorCommand, JsonContext.SetDownloadBehaviorResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new SetDownloadBehaviorCommand(@params), options, _jsonContext.SetDownloadBehaviorCommand, _jsonContext.SetDownloadBehaviorResult).ConfigureAwait(false); } public async Task SetDownloadBehaviorDeniedAsync(SetDownloadBehaviorOptions? options = null) { var @params = new SetDownloadBehaviorParameters(new DownloadBehaviorDenied(), options?.UserContexts); - return await Broker.ExecuteCommandAsync(new SetDownloadBehaviorCommand(@params), options, JsonContext.SetDownloadBehaviorCommand, JsonContext.SetDownloadBehaviorResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new SetDownloadBehaviorCommand(@params), options, _jsonContext.SetDownloadBehaviorCommand, _jsonContext.SetDownloadBehaviorResult).ConfigureAwait(false); } - protected override JsonSerializerContext CreateJsonContext(JsonSerializerOptions options) + + protected override void Initialize(JsonSerializerOptions options) { - return new BiDiJsonSerializerContext(options); + _jsonContext = new BiDiJsonSerializerContext(options); } } diff --git a/dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs b/dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs index aa33194a89680..d865759e51c5e 100644 --- a/dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs +++ b/dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs @@ -20,240 +20,240 @@ using OpenQA.Selenium.BiDi.Json; using System; using System.Text.Json; -using System.Text.Json.Serialization; using System.Threading.Tasks; namespace OpenQA.Selenium.BiDi.BrowsingContext; public sealed class BrowsingContextModule : Module { - internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; + private BiDiJsonSerializerContext _jsonContext = null!; public async Task CreateAsync(ContextType type, CreateOptions? options = null) { var @params = new CreateParameters(type, options?.ReferenceContext, options?.Background, options?.UserContext); - return await Broker.ExecuteCommandAsync(new CreateCommand(@params), options, JsonContext.CreateCommand, JsonContext.CreateResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new CreateCommand(@params), options, _jsonContext.CreateCommand, _jsonContext.CreateResult).ConfigureAwait(false); } public async Task NavigateAsync(BrowsingContext context, string url, NavigateOptions? options = null) { var @params = new NavigateParameters(context, url, options?.Wait); - return await Broker.ExecuteCommandAsync(new NavigateCommand(@params), options, JsonContext.NavigateCommand, JsonContext.NavigateResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new NavigateCommand(@params), options, _jsonContext.NavigateCommand, _jsonContext.NavigateResult).ConfigureAwait(false); } public async Task ActivateAsync(BrowsingContext context, ActivateOptions? options = null) { var @params = new ActivateParameters(context); - return await Broker.ExecuteCommandAsync(new ActivateCommand(@params), options, JsonContext.ActivateCommand, JsonContext.ActivateResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new ActivateCommand(@params), options, _jsonContext.ActivateCommand, _jsonContext.ActivateResult).ConfigureAwait(false); } public async Task LocateNodesAsync(BrowsingContext context, Locator locator, LocateNodesOptions? options = null) { var @params = new LocateNodesParameters(context, locator, options?.MaxNodeCount, options?.SerializationOptions, options?.StartNodes); - return await Broker.ExecuteCommandAsync(new LocateNodesCommand(@params), options, JsonContext.LocateNodesCommand, JsonContext.LocateNodesResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new LocateNodesCommand(@params), options, _jsonContext.LocateNodesCommand, _jsonContext.LocateNodesResult).ConfigureAwait(false); } public async Task CaptureScreenshotAsync(BrowsingContext context, CaptureScreenshotOptions? options = null) { var @params = new CaptureScreenshotParameters(context, options?.Origin, options?.Format, options?.Clip); - return await Broker.ExecuteCommandAsync(new CaptureScreenshotCommand(@params), options, JsonContext.CaptureScreenshotCommand, JsonContext.CaptureScreenshotResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new CaptureScreenshotCommand(@params), options, _jsonContext.CaptureScreenshotCommand, _jsonContext.CaptureScreenshotResult).ConfigureAwait(false); } public async Task CloseAsync(BrowsingContext context, CloseOptions? options = null) { var @params = new CloseParameters(context, options?.PromptUnload); - return await Broker.ExecuteCommandAsync(new CloseCommand(@params), options, JsonContext.BrowsingContext_CloseCommand, JsonContext.BrowsingContext_CloseResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new CloseCommand(@params), options, _jsonContext.BrowsingContext_CloseCommand, _jsonContext.BrowsingContext_CloseResult).ConfigureAwait(false); } public async Task TraverseHistoryAsync(BrowsingContext context, int delta, TraverseHistoryOptions? options = null) { var @params = new TraverseHistoryParameters(context, delta); - return await Broker.ExecuteCommandAsync(new TraverseHistoryCommand(@params), options, JsonContext.TraverseHistoryCommand, JsonContext.TraverseHistoryResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new TraverseHistoryCommand(@params), options, _jsonContext.TraverseHistoryCommand, _jsonContext.TraverseHistoryResult).ConfigureAwait(false); } public async Task ReloadAsync(BrowsingContext context, ReloadOptions? options = null) { var @params = new ReloadParameters(context, options?.IgnoreCache, options?.Wait); - return await Broker.ExecuteCommandAsync(new ReloadCommand(@params), options, JsonContext.ReloadCommand, JsonContext.ReloadResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new ReloadCommand(@params), options, _jsonContext.ReloadCommand, _jsonContext.ReloadResult).ConfigureAwait(false); } public async Task SetViewportAsync(BrowsingContext context, SetViewportOptions? options = null) { var @params = new SetViewportParameters(context, options?.Viewport, options?.DevicePixelRatio); - return await Broker.ExecuteCommandAsync(new SetViewportCommand(@params), options, JsonContext.SetViewportCommand, JsonContext.SetViewportResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new SetViewportCommand(@params), options, _jsonContext.SetViewportCommand, _jsonContext.SetViewportResult).ConfigureAwait(false); } public async Task GetTreeAsync(GetTreeOptions? options = null) { var @params = new GetTreeParameters(options?.MaxDepth, options?.Root); - return await Broker.ExecuteCommandAsync(new GetTreeCommand(@params), options, JsonContext.GetTreeCommand, JsonContext.GetTreeResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new GetTreeCommand(@params), options, _jsonContext.GetTreeCommand, _jsonContext.GetTreeResult).ConfigureAwait(false); } public async Task PrintAsync(BrowsingContext context, PrintOptions? options = null) { var @params = new PrintParameters(context, options?.Background, options?.Margin, options?.Orientation, options?.Page, options?.PageRanges, options?.Scale, options?.ShrinkToFit); - return await Broker.ExecuteCommandAsync(new PrintCommand(@params), options, JsonContext.PrintCommand, JsonContext.PrintResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new PrintCommand(@params), options, _jsonContext.PrintCommand, _jsonContext.PrintResult).ConfigureAwait(false); } public async Task HandleUserPromptAsync(BrowsingContext context, HandleUserPromptOptions? options = null) { var @params = new HandleUserPromptParameters(context, options?.Accept, options?.UserText); - return await Broker.ExecuteCommandAsync(new HandleUserPromptCommand(@params), options, JsonContext.HandleUserPromptCommand, JsonContext.HandleUserPromptResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new HandleUserPromptCommand(@params), options, _jsonContext.HandleUserPromptCommand, _jsonContext.HandleUserPromptResult).ConfigureAwait(false); } public async Task OnNavigationStartedAsync(Func handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("browsingContext.navigationStarted", handler, options, JsonContext.NavigationInfo).ConfigureAwait(false); + return await Broker.SubscribeAsync("browsingContext.navigationStarted", handler, options, _jsonContext.NavigationInfo).ConfigureAwait(false); } public async Task OnNavigationStartedAsync(Action handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("browsingContext.navigationStarted", handler, options, JsonContext.NavigationInfo).ConfigureAwait(false); + return await Broker.SubscribeAsync("browsingContext.navigationStarted", handler, options, _jsonContext.NavigationInfo).ConfigureAwait(false); } public async Task OnFragmentNavigatedAsync(Func handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("browsingContext.fragmentNavigated", handler, options, JsonContext.NavigationInfo).ConfigureAwait(false); + return await Broker.SubscribeAsync("browsingContext.fragmentNavigated", handler, options, _jsonContext.NavigationInfo).ConfigureAwait(false); } public async Task OnFragmentNavigatedAsync(Action handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("browsingContext.fragmentNavigated", handler, options, JsonContext.NavigationInfo).ConfigureAwait(false); + return await Broker.SubscribeAsync("browsingContext.fragmentNavigated", handler, options, _jsonContext.NavigationInfo).ConfigureAwait(false); } public async Task OnHistoryUpdatedAsync(Func handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("browsingContext.historyUpdated", handler, options, JsonContext.HistoryUpdatedEventArgs).ConfigureAwait(false); + return await Broker.SubscribeAsync("browsingContext.historyUpdated", handler, options, _jsonContext.HistoryUpdatedEventArgs).ConfigureAwait(false); } public async Task OnHistoryUpdatedAsync(Action handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("browsingContext.historyUpdated", handler, options, JsonContext.HistoryUpdatedEventArgs).ConfigureAwait(false); + return await Broker.SubscribeAsync("browsingContext.historyUpdated", handler, options, _jsonContext.HistoryUpdatedEventArgs).ConfigureAwait(false); } public async Task OnDomContentLoadedAsync(Func handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("browsingContext.domContentLoaded", handler, options, JsonContext.NavigationInfo).ConfigureAwait(false); + return await Broker.SubscribeAsync("browsingContext.domContentLoaded", handler, options, _jsonContext.NavigationInfo).ConfigureAwait(false); } public async Task OnDomContentLoadedAsync(Action handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("browsingContext.domContentLoaded", handler, options, JsonContext.NavigationInfo).ConfigureAwait(false); + return await Broker.SubscribeAsync("browsingContext.domContentLoaded", handler, options, _jsonContext.NavigationInfo).ConfigureAwait(false); } public async Task OnLoadAsync(Func handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("browsingContext.load", handler, options, JsonContext.NavigationInfo).ConfigureAwait(false); + return await Broker.SubscribeAsync("browsingContext.load", handler, options, _jsonContext.NavigationInfo).ConfigureAwait(false); } public async Task OnLoadAsync(Action handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("browsingContext.load", handler, options, JsonContext.NavigationInfo).ConfigureAwait(false); + return await Broker.SubscribeAsync("browsingContext.load", handler, options, _jsonContext.NavigationInfo).ConfigureAwait(false); } public async Task OnDownloadWillBeginAsync(Func handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("browsingContext.downloadWillBegin", handler, options, JsonContext.DownloadWillBeginEventArgs).ConfigureAwait(false); + return await Broker.SubscribeAsync("browsingContext.downloadWillBegin", handler, options, _jsonContext.DownloadWillBeginEventArgs).ConfigureAwait(false); } public async Task OnDownloadWillBeginAsync(Action handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("browsingContext.downloadWillBegin", handler, options, JsonContext.DownloadWillBeginEventArgs).ConfigureAwait(false); + return await Broker.SubscribeAsync("browsingContext.downloadWillBegin", handler, options, _jsonContext.DownloadWillBeginEventArgs).ConfigureAwait(false); } public async Task OnDownloadEndAsync(Func handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("browsingContext.downloadEnd", handler, options, JsonContext.DownloadEndEventArgs).ConfigureAwait(false); + return await Broker.SubscribeAsync("browsingContext.downloadEnd", handler, options, _jsonContext.DownloadEndEventArgs).ConfigureAwait(false); } public async Task OnDownloadEndAsync(Action handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("browsingContext.downloadEnd", handler, options, JsonContext.DownloadEndEventArgs).ConfigureAwait(false); + return await Broker.SubscribeAsync("browsingContext.downloadEnd", handler, options, _jsonContext.DownloadEndEventArgs).ConfigureAwait(false); } public async Task OnNavigationAbortedAsync(Func handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("browsingContext.navigationAborted", handler, options, JsonContext.NavigationInfo).ConfigureAwait(false); + return await Broker.SubscribeAsync("browsingContext.navigationAborted", handler, options, _jsonContext.NavigationInfo).ConfigureAwait(false); } public async Task OnNavigationAbortedAsync(Action handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("browsingContext.navigationAborted", handler, options, JsonContext.NavigationInfo).ConfigureAwait(false); + return await Broker.SubscribeAsync("browsingContext.navigationAborted", handler, options, _jsonContext.NavigationInfo).ConfigureAwait(false); } public async Task OnNavigationFailedAsync(Func handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("browsingContext.navigationFailed", handler, options, JsonContext.NavigationInfo).ConfigureAwait(false); + return await Broker.SubscribeAsync("browsingContext.navigationFailed", handler, options, _jsonContext.NavigationInfo).ConfigureAwait(false); } public async Task OnNavigationFailedAsync(Action handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("browsingContext.navigationFailed", handler, options, JsonContext.NavigationInfo).ConfigureAwait(false); + return await Broker.SubscribeAsync("browsingContext.navigationFailed", handler, options, _jsonContext.NavigationInfo).ConfigureAwait(false); } public async Task OnNavigationCommittedAsync(Func handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("browsingContext.navigationCommitted", handler, options, JsonContext.NavigationInfo).ConfigureAwait(false); + return await Broker.SubscribeAsync("browsingContext.navigationCommitted", handler, options, _jsonContext.NavigationInfo).ConfigureAwait(false); } public async Task OnNavigationCommittedAsync(Action handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("browsingContext.navigationCommitted", handler, options, JsonContext.NavigationInfo).ConfigureAwait(false); + return await Broker.SubscribeAsync("browsingContext.navigationCommitted", handler, options, _jsonContext.NavigationInfo).ConfigureAwait(false); } public async Task OnContextCreatedAsync(Func handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("browsingContext.contextCreated", handler, options, JsonContext.BrowsingContextInfo).ConfigureAwait(false); + return await Broker.SubscribeAsync("browsingContext.contextCreated", handler, options, _jsonContext.BrowsingContextInfo).ConfigureAwait(false); } public async Task OnContextCreatedAsync(Action handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("browsingContext.contextCreated", handler, options, JsonContext.BrowsingContextInfo).ConfigureAwait(false); + return await Broker.SubscribeAsync("browsingContext.contextCreated", handler, options, _jsonContext.BrowsingContextInfo).ConfigureAwait(false); } public async Task OnContextDestroyedAsync(Func handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("browsingContext.contextDestroyed", handler, options, JsonContext.BrowsingContextInfo).ConfigureAwait(false); + return await Broker.SubscribeAsync("browsingContext.contextDestroyed", handler, options, _jsonContext.BrowsingContextInfo).ConfigureAwait(false); } public async Task OnContextDestroyedAsync(Action handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("browsingContext.contextDestroyed", handler, options, JsonContext.BrowsingContextInfo).ConfigureAwait(false); + return await Broker.SubscribeAsync("browsingContext.contextDestroyed", handler, options, _jsonContext.BrowsingContextInfo).ConfigureAwait(false); } public async Task OnUserPromptOpenedAsync(Func handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("browsingContext.userPromptOpened", handler, options, JsonContext.UserPromptOpenedEventArgs).ConfigureAwait(false); + return await Broker.SubscribeAsync("browsingContext.userPromptOpened", handler, options, _jsonContext.UserPromptOpenedEventArgs).ConfigureAwait(false); } public async Task OnUserPromptOpenedAsync(Action handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("browsingContext.userPromptOpened", handler, options, JsonContext.UserPromptOpenedEventArgs).ConfigureAwait(false); + return await Broker.SubscribeAsync("browsingContext.userPromptOpened", handler, options, _jsonContext.UserPromptOpenedEventArgs).ConfigureAwait(false); } public async Task OnUserPromptClosedAsync(Func handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("browsingContext.userPromptClosed", handler, options, JsonContext.UserPromptClosedEventArgs).ConfigureAwait(false); + return await Broker.SubscribeAsync("browsingContext.userPromptClosed", handler, options, _jsonContext.UserPromptClosedEventArgs).ConfigureAwait(false); } public async Task OnUserPromptClosedAsync(Action handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("browsingContext.userPromptClosed", handler, options, JsonContext.UserPromptClosedEventArgs).ConfigureAwait(false); + return await Broker.SubscribeAsync("browsingContext.userPromptClosed", handler, options, _jsonContext.UserPromptClosedEventArgs).ConfigureAwait(false); } - protected override JsonSerializerContext CreateJsonContext(JsonSerializerOptions options) + + protected override void Initialize(JsonSerializerOptions options) { - return new BiDiJsonSerializerContext(options); + _jsonContext = new BiDiJsonSerializerContext(options); } } diff --git a/dotnet/src/webdriver/BiDi/Emulation/EmulationModule.cs b/dotnet/src/webdriver/BiDi/Emulation/EmulationModule.cs index 17b07bf18220b..09b110c480e55 100644 --- a/dotnet/src/webdriver/BiDi/Emulation/EmulationModule.cs +++ b/dotnet/src/webdriver/BiDi/Emulation/EmulationModule.cs @@ -19,55 +19,54 @@ using OpenQA.Selenium.BiDi.Json; using System.Text.Json; -using System.Text.Json.Serialization; using System.Threading.Tasks; namespace OpenQA.Selenium.BiDi.Emulation; public sealed class EmulationModule : Module { - internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; + private BiDiJsonSerializerContext _jsonContext = null!; public async Task SetTimezoneOverrideAsync(string? timezone, SetTimezoneOverrideOptions? options = null) { var @params = new SetTimezoneOverrideParameters(timezone, options?.Contexts, options?.UserContexts); - return await Broker.ExecuteCommandAsync(new SetTimezoneOverrideCommand(@params), options, JsonContext.SetTimezoneOverrideCommand, JsonContext.SetTimezoneOverrideResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new SetTimezoneOverrideCommand(@params), options, _jsonContext.SetTimezoneOverrideCommand, _jsonContext.SetTimezoneOverrideResult).ConfigureAwait(false); } public async Task SetUserAgentOverrideAsync(string? userAgent, SetUserAgentOverrideOptions? options = null) { var @params = new SetUserAgentOverrideParameters(userAgent, options?.Contexts, options?.UserContexts); - return await Broker.ExecuteCommandAsync(new SetUserAgentOverrideCommand(@params), options, JsonContext.SetUserAgentOverrideCommand, JsonContext.SetUserAgentOverrideResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new SetUserAgentOverrideCommand(@params), options, _jsonContext.SetUserAgentOverrideCommand, _jsonContext.SetUserAgentOverrideResult).ConfigureAwait(false); } public async Task SetLocaleOverrideAsync(string? locale, SetLocaleOverrideOptions? options = null) { var @params = new SetLocaleOverrideParameters(locale, options?.Contexts, options?.UserContexts); - return await Broker.ExecuteCommandAsync(new SetLocaleOverrideCommand(@params), options, JsonContext.SetLocaleOverrideCommand, JsonContext.SetLocaleOverrideResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new SetLocaleOverrideCommand(@params), options, _jsonContext.SetLocaleOverrideCommand, _jsonContext.SetLocaleOverrideResult).ConfigureAwait(false); } public async Task SetForcedColorsModeThemeOverrideAsync(ForcedColorsModeTheme? theme, SetForcedColorsModeThemeOverrideOptions? options = null) { var @params = new SetForcedColorsModeThemeOverrideParameters(theme, options?.Contexts, options?.UserContexts); - return await Broker.ExecuteCommandAsync(new SetForcedColorsModeThemeOverrideCommand(@params), options, JsonContext.SetForcedColorsModeThemeOverrideCommand, JsonContext.SetForcedColorsModeThemeOverrideResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new SetForcedColorsModeThemeOverrideCommand(@params), options, _jsonContext.SetForcedColorsModeThemeOverrideCommand, _jsonContext.SetForcedColorsModeThemeOverrideResult).ConfigureAwait(false); } public async Task SetScriptingEnabledAsync(bool? enabled, SetScriptingEnabledOptions? options = null) { var @params = new SetScriptingEnabledParameters(enabled, options?.Contexts, options?.UserContexts); - return await Broker.ExecuteCommandAsync(new SetScriptingEnabledCommand(@params), options, JsonContext.SetScriptingEnabledCommand, JsonContext.SetScriptingEnabledResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new SetScriptingEnabledCommand(@params), options, _jsonContext.SetScriptingEnabledCommand, _jsonContext.SetScriptingEnabledResult).ConfigureAwait(false); } public async Task SetScreenOrientationOverrideAsync(ScreenOrientation? screenOrientation, SetScreenOrientationOverrideOptions? options = null) { var @params = new SetScreenOrientationOverrideParameters(screenOrientation, options?.Contexts, options?.UserContexts); - return await Broker.ExecuteCommandAsync(new SetScreenOrientationOverrideCommand(@params), options, JsonContext.SetScreenOrientationOverrideCommand, JsonContext.SetScreenOrientationOverrideResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new SetScreenOrientationOverrideCommand(@params), options, _jsonContext.SetScreenOrientationOverrideCommand, _jsonContext.SetScreenOrientationOverrideResult).ConfigureAwait(false); } public async Task SetGeolocationCoordinatesOverrideAsync(double latitude, double longitude, SetGeolocationCoordinatesOverrideOptions? options = null) @@ -76,24 +75,25 @@ public async Task SetGeolocationCoordinatesOverrid var @params = new SetGeolocationOverrideCoordinatesParameters(coordinates, options?.Contexts, options?.UserContexts); - return await Broker.ExecuteCommandAsync(new SetGeolocationOverrideCommand(@params), options, JsonContext.SetGeolocationOverrideCommand, JsonContext.SetGeolocationOverrideResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new SetGeolocationOverrideCommand(@params), options, _jsonContext.SetGeolocationOverrideCommand, _jsonContext.SetGeolocationOverrideResult).ConfigureAwait(false); } public async Task SetGeolocationCoordinatesOverrideAsync(SetGeolocationOverrideOptions? options = null) { var @params = new SetGeolocationOverrideCoordinatesParameters(null, options?.Contexts, options?.UserContexts); - return await Broker.ExecuteCommandAsync(new SetGeolocationOverrideCommand(@params), options, JsonContext.SetGeolocationOverrideCommand, JsonContext.SetGeolocationOverrideResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new SetGeolocationOverrideCommand(@params), options, _jsonContext.SetGeolocationOverrideCommand, _jsonContext.SetGeolocationOverrideResult).ConfigureAwait(false); } public async Task SetGeolocationPositionErrorOverrideAsync(SetGeolocationPositionErrorOverrideOptions? options = null) { var @params = new SetGeolocationOverridePositionErrorParameters(new GeolocationPositionError(), options?.Contexts, options?.UserContexts); - return await Broker.ExecuteCommandAsync(new SetGeolocationOverrideCommand(@params), options, JsonContext.SetGeolocationOverrideCommand, JsonContext.SetGeolocationOverrideResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new SetGeolocationOverrideCommand(@params), options, _jsonContext.SetGeolocationOverrideCommand, _jsonContext.SetGeolocationOverrideResult).ConfigureAwait(false); } - protected override JsonSerializerContext CreateJsonContext(JsonSerializerOptions options) + + protected override void Initialize(JsonSerializerOptions options) { - return new BiDiJsonSerializerContext(options); + _jsonContext = new BiDiJsonSerializerContext(options); } } diff --git a/dotnet/src/webdriver/BiDi/Input/InputModule.cs b/dotnet/src/webdriver/BiDi/Input/InputModule.cs index 0e8597d0f822d..341c0999b88d2 100644 --- a/dotnet/src/webdriver/BiDi/Input/InputModule.cs +++ b/dotnet/src/webdriver/BiDi/Input/InputModule.cs @@ -20,37 +20,37 @@ using OpenQA.Selenium.BiDi.Json; using System.Collections.Generic; using System.Text.Json; -using System.Text.Json.Serialization; using System.Threading.Tasks; namespace OpenQA.Selenium.BiDi.Input; public sealed class InputModule : Module { - internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; + private BiDiJsonSerializerContext _jsonContext = null!; public async Task PerformActionsAsync(BrowsingContext.BrowsingContext context, IEnumerable actions, PerformActionsOptions? options = null) { var @params = new PerformActionsParameters(context, actions); - return await Broker.ExecuteCommandAsync(new PerformActionsCommand(@params), options, JsonContext.PerformActionsCommand, JsonContext.PerformActionsResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new PerformActionsCommand(@params), options, _jsonContext.PerformActionsCommand, _jsonContext.PerformActionsResult).ConfigureAwait(false); } public async Task ReleaseActionsAsync(BrowsingContext.BrowsingContext context, ReleaseActionsOptions? options = null) { var @params = new ReleaseActionsParameters(context); - return await Broker.ExecuteCommandAsync(new ReleaseActionsCommand(@params), options, JsonContext.ReleaseActionsCommand, JsonContext.ReleaseActionsResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new ReleaseActionsCommand(@params), options, _jsonContext.ReleaseActionsCommand, _jsonContext.ReleaseActionsResult).ConfigureAwait(false); } public async Task SetFilesAsync(BrowsingContext.BrowsingContext context, Script.ISharedReference element, IEnumerable files, SetFilesOptions? options = null) { var @params = new SetFilesParameters(context, element, files); - return await Broker.ExecuteCommandAsync(new SetFilesCommand(@params), options, JsonContext.SetFilesCommand, JsonContext.SetFilesResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new SetFilesCommand(@params), options, _jsonContext.SetFilesCommand, _jsonContext.SetFilesResult).ConfigureAwait(false); } - protected override JsonSerializerContext CreateJsonContext(JsonSerializerOptions options) + + protected override void Initialize(JsonSerializerOptions options) { - return new BiDiJsonSerializerContext(options); + _jsonContext = new BiDiJsonSerializerContext(options); } } diff --git a/dotnet/src/webdriver/BiDi/Log/LogModule.cs b/dotnet/src/webdriver/BiDi/Log/LogModule.cs index 343fa5d8a0eb8..a51ad3f9a4802 100644 --- a/dotnet/src/webdriver/BiDi/Log/LogModule.cs +++ b/dotnet/src/webdriver/BiDi/Log/LogModule.cs @@ -20,26 +20,26 @@ using OpenQA.Selenium.BiDi.Json; using System; using System.Text.Json; -using System.Text.Json.Serialization; using System.Threading.Tasks; namespace OpenQA.Selenium.BiDi.Log; public sealed class LogModule : Module { - internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; + private BiDiJsonSerializerContext _jsonContext = null!; public async Task OnEntryAddedAsync(Func handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("log.entryAdded", handler, options, JsonContext.LogEntry).ConfigureAwait(false); + return await Broker.SubscribeAsync("log.entryAdded", handler, options, _jsonContext.LogEntry).ConfigureAwait(false); } public async Task OnEntryAddedAsync(Action handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("log.entryAdded", handler, options, JsonContext.LogEntry).ConfigureAwait(false); + return await Broker.SubscribeAsync("log.entryAdded", handler, options, _jsonContext.LogEntry).ConfigureAwait(false); } - protected override JsonSerializerContext CreateJsonContext(JsonSerializerOptions options) + + protected override void Initialize(JsonSerializerOptions options) { - return new BiDiJsonSerializerContext(options); + _jsonContext = new BiDiJsonSerializerContext(options); } } diff --git a/dotnet/src/webdriver/BiDi/Module.cs b/dotnet/src/webdriver/BiDi/Module.cs index 78a2753c68c9a..876511089e095 100644 --- a/dotnet/src/webdriver/BiDi/Module.cs +++ b/dotnet/src/webdriver/BiDi/Module.cs @@ -26,9 +26,7 @@ public abstract class Module { protected Broker Broker { get; private set; } - internal JsonSerializerContext JsonContext { get; private set; } - - protected abstract JsonSerializerContext CreateJsonContext(JsonSerializerOptions options); + protected abstract void Initialize(JsonSerializerOptions options); public static TModule Create(BiDi bidi, JsonSerializerOptions jsonOptions, JsonSerializerContext? cachedContext = null) where TModule : Module, new() @@ -38,8 +36,6 @@ public static TModule Create(BiDi bidi, JsonSerializerOptions jsonOptio Broker = bidi.Broker, }; - module.JsonContext = cachedContext ?? module.CreateJsonContext(jsonOptions); - return module; } } diff --git a/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs b/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs index ec57917925ba3..eb2ba0068665d 100644 --- a/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs +++ b/dotnet/src/webdriver/BiDi/Network/NetworkModule.cs @@ -21,20 +21,19 @@ using System; using System.Collections.Generic; using System.Text.Json; -using System.Text.Json.Serialization; using System.Threading.Tasks; namespace OpenQA.Selenium.BiDi.Network; public sealed partial class NetworkModule : Module { - internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; + private BiDiJsonSerializerContext _jsonContext = null!; public async Task AddDataCollectorAsync(IEnumerable DataTypes, int MaxEncodedDataSize, AddDataCollectorOptions? options = null) { var @params = new AddDataCollectorParameters(DataTypes, MaxEncodedDataSize, options?.CollectorType, options?.Contexts, options?.UserContexts); - var result = await Broker.ExecuteCommandAsync(new AddDataCollectorCommand(@params), options, JsonContext.AddDataCollectorCommand, JsonContext.AddDataCollectorResult).ConfigureAwait(false); + var result = await Broker.ExecuteCommandAsync(new AddDataCollectorCommand(@params), options, _jsonContext.AddDataCollectorCommand, _jsonContext.AddDataCollectorResult).ConfigureAwait(false); return result.Collector; } @@ -43,7 +42,7 @@ public async Task AddInterceptAsync(IEnumerable phase { var @params = new AddInterceptParameters(phases, options?.Contexts, options?.UrlPatterns); - var result = await Broker.ExecuteCommandAsync(new AddInterceptCommand(@params), options, JsonContext.AddInterceptCommand, JsonContext.AddInterceptResult).ConfigureAwait(false); + var result = await Broker.ExecuteCommandAsync(new AddInterceptCommand(@params), options, _jsonContext.AddInterceptCommand, _jsonContext.AddInterceptResult).ConfigureAwait(false); return result.Intercept; } @@ -52,56 +51,56 @@ public async Task RemoveDataCollectorAsync(Collector { var @params = new RemoveDataCollectorParameters(collector); - return await Broker.ExecuteCommandAsync(new RemoveDataCollectorCommand(@params), options, JsonContext.RemoveDataCollectorCommand, JsonContext.RemoveDataCollectorResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new RemoveDataCollectorCommand(@params), options, _jsonContext.RemoveDataCollectorCommand, _jsonContext.RemoveDataCollectorResult).ConfigureAwait(false); } public async Task RemoveInterceptAsync(Intercept intercept, RemoveInterceptOptions? options = null) { var @params = new RemoveInterceptParameters(intercept); - return await Broker.ExecuteCommandAsync(new RemoveInterceptCommand(@params), options, JsonContext.RemoveInterceptCommand, JsonContext.RemoveInterceptResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new RemoveInterceptCommand(@params), options, _jsonContext.RemoveInterceptCommand, _jsonContext.RemoveInterceptResult).ConfigureAwait(false); } public async Task SetCacheBehaviorAsync(CacheBehavior behavior, SetCacheBehaviorOptions? options = null) { var @params = new SetCacheBehaviorParameters(behavior, options?.Contexts); - return await Broker.ExecuteCommandAsync(new SetCacheBehaviorCommand(@params), options, JsonContext.SetCacheBehaviorCommand, JsonContext.SetCacheBehaviorResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new SetCacheBehaviorCommand(@params), options, _jsonContext.SetCacheBehaviorCommand, _jsonContext.SetCacheBehaviorResult).ConfigureAwait(false); } public async Task SetExtraHeadersAsync(IEnumerable
headers, SetExtraHeadersOptions? options = null) { var @params = new SetExtraHeadersParameters(headers, options?.Contexts, options?.UserContexts); - return await Broker.ExecuteCommandAsync(new SetExtraHeadersCommand(@params), options, JsonContext.SetExtraHeadersCommand, JsonContext.SetExtraHeadersResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new SetExtraHeadersCommand(@params), options, _jsonContext.SetExtraHeadersCommand, _jsonContext.SetExtraHeadersResult).ConfigureAwait(false); } public async Task ContinueRequestAsync(Request request, ContinueRequestOptions? options = null) { var @params = new ContinueRequestParameters(request, options?.Body, options?.Cookies, options?.Headers, options?.Method, options?.Url); - return await Broker.ExecuteCommandAsync(new ContinueRequestCommand(@params), options, JsonContext.ContinueRequestCommand, JsonContext.ContinueRequestResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new ContinueRequestCommand(@params), options, _jsonContext.ContinueRequestCommand, _jsonContext.ContinueRequestResult).ConfigureAwait(false); } public async Task ContinueResponseAsync(Request request, ContinueResponseOptions? options = null) { var @params = new ContinueResponseParameters(request, options?.Cookies, options?.Credentials, options?.Headers, options?.ReasonPhrase, options?.StatusCode); - return await Broker.ExecuteCommandAsync(new ContinueResponseCommand(@params), options, JsonContext.ContinueResponseCommand, JsonContext.ContinueResponseResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new ContinueResponseCommand(@params), options, _jsonContext.ContinueResponseCommand, _jsonContext.ContinueResponseResult).ConfigureAwait(false); } public async Task FailRequestAsync(Request request, FailRequestOptions? options = null) { var @params = new FailRequestParameters(request); - return await Broker.ExecuteCommandAsync(new FailRequestCommand(@params), options, JsonContext.FailRequestCommand, JsonContext.FailRequestResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new FailRequestCommand(@params), options, _jsonContext.FailRequestCommand, _jsonContext.FailRequestResult).ConfigureAwait(false); } public async Task GetDataAsync(DataType dataType, Request request, GetDataOptions? options = null) { var @params = new GetDataParameters(dataType, request, options?.Collector, options?.Disown); - var result = await Broker.ExecuteCommandAsync(new GetDataCommand(@params), options, JsonContext.GetDataCommand, JsonContext.GetDataResult).ConfigureAwait(false); + var result = await Broker.ExecuteCommandAsync(new GetDataCommand(@params), options, _jsonContext.GetDataCommand, _jsonContext.GetDataResult).ConfigureAwait(false); return result.Bytes; } @@ -110,75 +109,76 @@ public async Task ProvideResponseAsync(Request request, P { var @params = new ProvideResponseParameters(request, options?.Body, options?.Cookies, options?.Headers, options?.ReasonPhrase, options?.StatusCode); - return await Broker.ExecuteCommandAsync(new ProvideResponseCommand(@params), options, JsonContext.ProvideResponseCommand, JsonContext.ProvideResponseResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new ProvideResponseCommand(@params), options, _jsonContext.ProvideResponseCommand, _jsonContext.ProvideResponseResult).ConfigureAwait(false); } public async Task ContinueWithAuthAsync(Request request, AuthCredentials credentials, ContinueWithAuthCredentialsOptions? options = null) { - return await Broker.ExecuteCommandAsync(new ContinueWithAuthCommand(new ContinueWithAuthCredentials(request, credentials)), options, JsonContext.ContinueWithAuthCommand, JsonContext.ContinueWithAuthResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new ContinueWithAuthCommand(new ContinueWithAuthCredentials(request, credentials)), options, _jsonContext.ContinueWithAuthCommand, _jsonContext.ContinueWithAuthResult).ConfigureAwait(false); } public async Task ContinueWithAuthAsync(Request request, ContinueWithAuthDefaultCredentialsOptions? options = null) { - return await Broker.ExecuteCommandAsync(new ContinueWithAuthCommand(new ContinueWithAuthDefaultCredentials(request)), options, JsonContext.ContinueWithAuthCommand, JsonContext.ContinueWithAuthResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new ContinueWithAuthCommand(new ContinueWithAuthDefaultCredentials(request)), options, _jsonContext.ContinueWithAuthCommand, _jsonContext.ContinueWithAuthResult).ConfigureAwait(false); } public async Task ContinueWithAuthAsync(Request request, ContinueWithAuthCancelCredentialsOptions? options = null) { - return await Broker.ExecuteCommandAsync(new ContinueWithAuthCommand(new ContinueWithAuthCancelCredentials(request)), options, JsonContext.ContinueWithAuthCommand, JsonContext.ContinueWithAuthResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new ContinueWithAuthCommand(new ContinueWithAuthCancelCredentials(request)), options, _jsonContext.ContinueWithAuthCommand, _jsonContext.ContinueWithAuthResult).ConfigureAwait(false); } public async Task OnBeforeRequestSentAsync(Func handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("network.beforeRequestSent", handler, options, JsonContext.BeforeRequestSentEventArgs).ConfigureAwait(false); + return await Broker.SubscribeAsync("network.beforeRequestSent", handler, options, _jsonContext.BeforeRequestSentEventArgs).ConfigureAwait(false); } public async Task OnBeforeRequestSentAsync(Action handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("network.beforeRequestSent", handler, options, JsonContext.BeforeRequestSentEventArgs).ConfigureAwait(false); + return await Broker.SubscribeAsync("network.beforeRequestSent", handler, options, _jsonContext.BeforeRequestSentEventArgs).ConfigureAwait(false); } public async Task OnResponseStartedAsync(Func handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("network.responseStarted", handler, options, JsonContext.ResponseStartedEventArgs).ConfigureAwait(false); + return await Broker.SubscribeAsync("network.responseStarted", handler, options, _jsonContext.ResponseStartedEventArgs).ConfigureAwait(false); } public async Task OnResponseStartedAsync(Action handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("network.responseStarted", handler, options, JsonContext.ResponseStartedEventArgs).ConfigureAwait(false); + return await Broker.SubscribeAsync("network.responseStarted", handler, options, _jsonContext.ResponseStartedEventArgs).ConfigureAwait(false); } public async Task OnResponseCompletedAsync(Func handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("network.responseCompleted", handler, options, JsonContext.ResponseCompletedEventArgs).ConfigureAwait(false); + return await Broker.SubscribeAsync("network.responseCompleted", handler, options, _jsonContext.ResponseCompletedEventArgs).ConfigureAwait(false); } public async Task OnResponseCompletedAsync(Action handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("network.responseCompleted", handler, options, JsonContext.ResponseCompletedEventArgs).ConfigureAwait(false); + return await Broker.SubscribeAsync("network.responseCompleted", handler, options, _jsonContext.ResponseCompletedEventArgs).ConfigureAwait(false); } public async Task OnFetchErrorAsync(Func handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("network.fetchError", handler, options, JsonContext.FetchErrorEventArgs).ConfigureAwait(false); + return await Broker.SubscribeAsync("network.fetchError", handler, options, _jsonContext.FetchErrorEventArgs).ConfigureAwait(false); } public async Task OnFetchErrorAsync(Action handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("network.fetchError", handler, options, JsonContext.FetchErrorEventArgs).ConfigureAwait(false); + return await Broker.SubscribeAsync("network.fetchError", handler, options, _jsonContext.FetchErrorEventArgs).ConfigureAwait(false); } public async Task OnAuthRequiredAsync(Func handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("network.authRequired", handler, options, JsonContext.AuthRequiredEventArgs).ConfigureAwait(false); + return await Broker.SubscribeAsync("network.authRequired", handler, options, _jsonContext.AuthRequiredEventArgs).ConfigureAwait(false); } public async Task OnAuthRequiredAsync(Action handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("network.authRequired", handler, options, JsonContext.AuthRequiredEventArgs).ConfigureAwait(false); + return await Broker.SubscribeAsync("network.authRequired", handler, options, _jsonContext.AuthRequiredEventArgs).ConfigureAwait(false); } - protected override JsonSerializerContext CreateJsonContext(JsonSerializerOptions options) + + protected override void Initialize(JsonSerializerOptions options) { - return new BiDiJsonSerializerContext(options); + _jsonContext = new BiDiJsonSerializerContext(options); } } diff --git a/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs b/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs index 2a977abb301d8..476166c516370 100644 --- a/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs +++ b/dotnet/src/webdriver/BiDi/Permissions/PermissionsModule.cs @@ -26,18 +26,18 @@ namespace OpenQA.Selenium.BiDi.Extensions.Permissions; public class PermissionsModule : Module { - private PermissionsJsonSerializerContext JsonContext => (PermissionsJsonSerializerContext)base.JsonContext; + private PermissionsJsonSerializerContext _jsonContext = null!; public async Task SetPermissionAsync(PermissionDescriptor desriptor, PermissionState state, string origin, SetPermissionOptions? options = null) { var @params = new SetPermissionCommandParameters(desriptor, state, origin, options?.EmbeddedOrigin, options?.UserContext); - return await Broker.ExecuteCommandAsync(new SetPermissionCommand(@params), options, JsonContext.SetPermissionCommand, JsonContext.SetPermissionResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new SetPermissionCommand(@params), options, _jsonContext.SetPermissionCommand, _jsonContext.SetPermissionResult).ConfigureAwait(false); } - protected override JsonSerializerContext CreateJsonContext(JsonSerializerOptions options) + protected override void Initialize(JsonSerializerOptions options) { - return new PermissionsJsonSerializerContext(options); + _jsonContext = new PermissionsJsonSerializerContext(options); } } diff --git a/dotnet/src/webdriver/BiDi/Script/ScriptModule.cs b/dotnet/src/webdriver/BiDi/Script/ScriptModule.cs index 99e0dd0c47700..3f6c60a79b957 100644 --- a/dotnet/src/webdriver/BiDi/Script/ScriptModule.cs +++ b/dotnet/src/webdriver/BiDi/Script/ScriptModule.cs @@ -21,20 +21,19 @@ using System; using System.Collections.Generic; using System.Text.Json; -using System.Text.Json.Serialization; using System.Threading.Tasks; namespace OpenQA.Selenium.BiDi.Script; public sealed class ScriptModule : Module { - internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; + private BiDiJsonSerializerContext _jsonContext = null!; public async Task EvaluateAsync(string expression, bool awaitPromise, Target target, EvaluateOptions? options = null) { var @params = new EvaluateParameters(expression, target, awaitPromise, options?.ResultOwnership, options?.SerializationOptions, options?.UserActivation); - return await Broker.ExecuteCommandAsync(new EvaluateCommand(@params), options, JsonContext.EvaluateCommand, JsonContext.EvaluateResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new EvaluateCommand(@params), options, _jsonContext.EvaluateCommand, _jsonContext.EvaluateResult).ConfigureAwait(false); } public async Task EvaluateAsync(string expression, bool awaitPromise, Target target, EvaluateOptions? options = null) @@ -48,7 +47,7 @@ public async Task CallFunctionAsync(string functionDeclaration, { var @params = new CallFunctionParameters(functionDeclaration, awaitPromise, target, options?.Arguments, options?.ResultOwnership, options?.SerializationOptions, options?.This, options?.UserActivation); - return await Broker.ExecuteCommandAsync(new CallFunctionCommand(@params), options, JsonContext.CallFunctionCommand, JsonContext.EvaluateResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new CallFunctionCommand(@params), options, _jsonContext.CallFunctionCommand, _jsonContext.EvaluateResult).ConfigureAwait(false); } public async Task CallFunctionAsync(string functionDeclaration, bool awaitPromise, Target target, CallFunctionOptions? options = null) @@ -62,61 +61,62 @@ public async Task DisownAsync(IEnumerable handles, Target { var @params = new DisownParameters(handles, target); - return await Broker.ExecuteCommandAsync(new DisownCommand(@params), options, JsonContext.DisownCommand, JsonContext.DisownResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new DisownCommand(@params), options, _jsonContext.DisownCommand, _jsonContext.DisownResult).ConfigureAwait(false); } public async Task GetRealmsAsync(GetRealmsOptions? options = null) { var @params = new GetRealmsParameters(options?.Context, options?.Type); - return await Broker.ExecuteCommandAsync(new GetRealmsCommand(@params), options, JsonContext.GetRealmsCommand, JsonContext.GetRealmsResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new GetRealmsCommand(@params), options, _jsonContext.GetRealmsCommand, _jsonContext.GetRealmsResult).ConfigureAwait(false); } public async Task AddPreloadScriptAsync(string functionDeclaration, AddPreloadScriptOptions? options = null) { var @params = new AddPreloadScriptParameters(functionDeclaration, options?.Arguments, options?.Contexts, options?.Sandbox); - return await Broker.ExecuteCommandAsync(new AddPreloadScriptCommand(@params), options, JsonContext.AddPreloadScriptCommand, JsonContext.AddPreloadScriptResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new AddPreloadScriptCommand(@params), options, _jsonContext.AddPreloadScriptCommand, _jsonContext.AddPreloadScriptResult).ConfigureAwait(false); } public async Task RemovePreloadScriptAsync(PreloadScript script, RemovePreloadScriptOptions? options = null) { var @params = new RemovePreloadScriptParameters(script); - return await Broker.ExecuteCommandAsync(new RemovePreloadScriptCommand(@params), options, JsonContext.RemovePreloadScriptCommand, JsonContext.RemovePreloadScriptResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new RemovePreloadScriptCommand(@params), options, _jsonContext.RemovePreloadScriptCommand, _jsonContext.RemovePreloadScriptResult).ConfigureAwait(false); } public async Task OnMessageAsync(Func handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("script.message", handler, options, JsonContext.MessageEventArgs).ConfigureAwait(false); + return await Broker.SubscribeAsync("script.message", handler, options, _jsonContext.MessageEventArgs).ConfigureAwait(false); } public async Task OnMessageAsync(Action handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("script.message", handler, options, JsonContext.MessageEventArgs).ConfigureAwait(false); + return await Broker.SubscribeAsync("script.message", handler, options, _jsonContext.MessageEventArgs).ConfigureAwait(false); } public async Task OnRealmCreatedAsync(Func handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("script.realmCreated", handler, options, JsonContext.RealmInfo).ConfigureAwait(false); + return await Broker.SubscribeAsync("script.realmCreated", handler, options, _jsonContext.RealmInfo).ConfigureAwait(false); } public async Task OnRealmCreatedAsync(Action handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("script.realmCreated", handler, options, JsonContext.RealmInfo).ConfigureAwait(false); + return await Broker.SubscribeAsync("script.realmCreated", handler, options, _jsonContext.RealmInfo).ConfigureAwait(false); } public async Task OnRealmDestroyedAsync(Func handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("script.realmDestroyed", handler, options, JsonContext.RealmDestroyedEventArgs).ConfigureAwait(false); + return await Broker.SubscribeAsync("script.realmDestroyed", handler, options, _jsonContext.RealmDestroyedEventArgs).ConfigureAwait(false); } public async Task OnRealmDestroyedAsync(Action handler, SubscriptionOptions? options = null) { - return await Broker.SubscribeAsync("script.realmDestroyed", handler, options, JsonContext.RealmDestroyedEventArgs).ConfigureAwait(false); + return await Broker.SubscribeAsync("script.realmDestroyed", handler, options, _jsonContext.RealmDestroyedEventArgs).ConfigureAwait(false); } - protected override JsonSerializerContext CreateJsonContext(JsonSerializerOptions options) + + protected override void Initialize(JsonSerializerOptions options) { - return new BiDiJsonSerializerContext(options); + _jsonContext = new BiDiJsonSerializerContext(options); } } diff --git a/dotnet/src/webdriver/BiDi/Session/SessionModule.cs b/dotnet/src/webdriver/BiDi/Session/SessionModule.cs index b391c4eaf4ff3..e9076badbcb0b 100644 --- a/dotnet/src/webdriver/BiDi/Session/SessionModule.cs +++ b/dotnet/src/webdriver/BiDi/Session/SessionModule.cs @@ -20,47 +20,47 @@ using OpenQA.Selenium.BiDi.Json; using System.Collections.Generic; using System.Text.Json; -using System.Text.Json.Serialization; using System.Threading.Tasks; namespace OpenQA.Selenium.BiDi.Session; internal sealed class SessionModule : Module { - internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; + private BiDiJsonSerializerContext _jsonContext = null!; public async Task StatusAsync(StatusOptions? options = null) { - return await Broker.ExecuteCommandAsync(new StatusCommand(), options, JsonContext.StatusCommand, JsonContext.StatusResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new StatusCommand(), options, _jsonContext.StatusCommand, _jsonContext.StatusResult).ConfigureAwait(false); } public async Task SubscribeAsync(IEnumerable events, SubscribeOptions? options = null) { var @params = new SubscribeParameters(events, options?.Contexts); - return await Broker.ExecuteCommandAsync(new(@params), options, JsonContext.SubscribeCommand, JsonContext.SubscribeResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new(@params), options, _jsonContext.SubscribeCommand, _jsonContext.SubscribeResult).ConfigureAwait(false); } public async Task UnsubscribeAsync(IEnumerable subscriptions, UnsubscribeByIdOptions? options = null) { var @params = new UnsubscribeByIdParameters(subscriptions); - return await Broker.ExecuteCommandAsync(new UnsubscribeByIdCommand(@params), options, JsonContext.UnsubscribeByIdCommand, JsonContext.UnsubscribeResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new UnsubscribeByIdCommand(@params), options, _jsonContext.UnsubscribeByIdCommand, _jsonContext.UnsubscribeResult).ConfigureAwait(false); } public async Task NewAsync(CapabilitiesRequest capabilitiesRequest, NewOptions? options = null) { var @params = new NewParameters(capabilitiesRequest); - return await Broker.ExecuteCommandAsync(new NewCommand(@params), options, JsonContext.NewCommand, JsonContext.NewResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new NewCommand(@params), options, _jsonContext.NewCommand, _jsonContext.NewResult).ConfigureAwait(false); } public async Task EndAsync(EndOptions? options = null) { - return await Broker.ExecuteCommandAsync(new EndCommand(), options, JsonContext.EndCommand, JsonContext.EndResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new EndCommand(), options, _jsonContext.EndCommand, _jsonContext.EndResult).ConfigureAwait(false); } - protected override JsonSerializerContext CreateJsonContext(JsonSerializerOptions options) + + protected override void Initialize(JsonSerializerOptions options) { - return new BiDiJsonSerializerContext(options); + _jsonContext = new BiDiJsonSerializerContext(options); } } diff --git a/dotnet/src/webdriver/BiDi/Storage/StorageModule.cs b/dotnet/src/webdriver/BiDi/Storage/StorageModule.cs index 8f4a72514f646..48a0d6c11031c 100644 --- a/dotnet/src/webdriver/BiDi/Storage/StorageModule.cs +++ b/dotnet/src/webdriver/BiDi/Storage/StorageModule.cs @@ -19,37 +19,37 @@ using OpenQA.Selenium.BiDi.Json; using System.Text.Json; -using System.Text.Json.Serialization; using System.Threading.Tasks; namespace OpenQA.Selenium.BiDi.Storage; public sealed class StorageModule : Module { - internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; + private BiDiJsonSerializerContext _jsonContext = null!; public async Task GetCookiesAsync(GetCookiesOptions? options = null) { var @params = new GetCookiesParameters(options?.Filter, options?.Partition); - return await Broker.ExecuteCommandAsync(new GetCookiesCommand(@params), options, JsonContext.GetCookiesCommand, JsonContext.GetCookiesResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new GetCookiesCommand(@params), options, _jsonContext.GetCookiesCommand, _jsonContext.GetCookiesResult).ConfigureAwait(false); } public async Task DeleteCookiesAsync(DeleteCookiesOptions? options = null) { var @params = new DeleteCookiesParameters(options?.Filter, options?.Partition); - return await Broker.ExecuteCommandAsync(new DeleteCookiesCommand(@params), options, JsonContext.DeleteCookiesCommand, JsonContext.DeleteCookiesResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new DeleteCookiesCommand(@params), options, _jsonContext.DeleteCookiesCommand, _jsonContext.DeleteCookiesResult).ConfigureAwait(false); } public async Task SetCookieAsync(PartialCookie cookie, SetCookieOptions? options = null) { var @params = new SetCookieParameters(cookie, options?.Partition); - return await Broker.ExecuteCommandAsync(new SetCookieCommand(@params), options, JsonContext.SetCookieCommand, JsonContext.SetCookieResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new SetCookieCommand(@params), options, _jsonContext.SetCookieCommand, _jsonContext.SetCookieResult).ConfigureAwait(false); } - protected override JsonSerializerContext CreateJsonContext(JsonSerializerOptions options) + + protected override void Initialize(JsonSerializerOptions options) { - return new BiDiJsonSerializerContext(options); + _jsonContext = new BiDiJsonSerializerContext(options); } } diff --git a/dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs b/dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs index 8e1b71d07fed7..a44ee2c75d21d 100644 --- a/dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs +++ b/dotnet/src/webdriver/BiDi/WebExtension/WebExtensionModule.cs @@ -19,30 +19,30 @@ using OpenQA.Selenium.BiDi.Json; using System.Text.Json; -using System.Text.Json.Serialization; using System.Threading.Tasks; namespace OpenQA.Selenium.BiDi.WebExtension; public sealed class WebExtensionModule : Module { - internal new BiDiJsonSerializerContext JsonContext => (BiDiJsonSerializerContext)base.JsonContext; + private BiDiJsonSerializerContext _jsonContext = null!; public async Task InstallAsync(ExtensionData extensionData, InstallOptions? options = null) { var @params = new InstallParameters(extensionData); - return await Broker.ExecuteCommandAsync(new InstallCommand(@params), options, JsonContext.InstallCommand, JsonContext.InstallResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new InstallCommand(@params), options, _jsonContext.InstallCommand, _jsonContext.InstallResult).ConfigureAwait(false); } public async Task UninstallAsync(Extension extension, UninstallOptions? options = null) { var @params = new UninstallParameters(extension); - return await Broker.ExecuteCommandAsync(new UninstallCommand(@params), options, JsonContext.UninstallCommand, JsonContext.UninstallResult).ConfigureAwait(false); + return await Broker.ExecuteCommandAsync(new UninstallCommand(@params), options, _jsonContext.UninstallCommand, _jsonContext.UninstallResult).ConfigureAwait(false); } - protected override JsonSerializerContext CreateJsonContext(JsonSerializerOptions options) + + protected override void Initialize(JsonSerializerOptions options) { - return new BiDiJsonSerializerContext(options); + _jsonContext = new BiDiJsonSerializerContext(options); } } From 217d859708e1b96fd2c254a9b785ef34773dfe61 Mon Sep 17 00:00:00 2001 From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com> Date: Sat, 29 Nov 2025 16:55:41 +0300 Subject: [PATCH 23/25] Hide GetJsonOptions internally --- dotnet/src/webdriver/BiDi/BiDi.cs | 88 +++++++++---------- dotnet/src/webdriver/BiDi/Broker.cs | 2 +- .../webdriver/BiDi/Browser/BrowserModule.cs | 5 -- dotnet/src/webdriver/BiDi/Module.cs | 5 +- .../Permissions/PermissionsBiDiExtensions.cs | 2 +- 5 files changed, 46 insertions(+), 56 deletions(-) diff --git a/dotnet/src/webdriver/BiDi/BiDi.cs b/dotnet/src/webdriver/BiDi/BiDi.cs index 61c6e9557884d..7f782ec5f2c13 100644 --- a/dotnet/src/webdriver/BiDi/BiDi.cs +++ b/dotnet/src/webdriver/BiDi/BiDi.cs @@ -17,7 +17,6 @@ // under the License. // -using OpenQA.Selenium.BiDi.Json; using OpenQA.Selenium.BiDi.Json.Converters; using System; using System.Text.Json; @@ -29,56 +28,22 @@ namespace OpenQA.Selenium.BiDi; public sealed class BiDi : IAsyncDisposable { - internal Broker Broker { get; } - internal JsonSerializerOptions JsonOptions { get; } - private readonly BiDiJsonSerializerContext _jsonContext; - - public JsonSerializerOptions DefaultBiDiOptions() - { - return new JsonSerializerOptions - { - PropertyNameCaseInsensitive = true, - PropertyNamingPolicy = JsonNamingPolicy.CamelCase, - DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, - - // BiDi returns special numbers such as "NaN" as strings - // Additionally, -0 is returned as a string "-0" - NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals | JsonNumberHandling.AllowReadingFromString, - Converters = - { - new BrowsingContextConverter(this), - new BrowserUserContextConverter(this), - new CollectorConverter(this), - new InterceptConverter(this), - new HandleConverter(this), - new InternalIdConverter(this), - new PreloadScriptConverter(this), - new RealmConverter(this), - new DateTimeOffsetConverter(), - new WebExtensionConverter(this), - } - }; - } - private BiDi(string url) { var uri = new Uri(url); - JsonOptions = DefaultBiDiOptions(); - - _jsonContext = new BiDiJsonSerializerContext(JsonOptions); - - Broker = new Broker(this, uri, JsonOptions); - SessionModule = Module.Create(this, JsonOptions, _jsonContext); - BrowsingContext = Module.Create(this, JsonOptions, _jsonContext); - Browser = Module.Create(this, JsonOptions, _jsonContext); - Network = Module.Create(this, JsonOptions, _jsonContext); - InputModule = Module.Create(this, JsonOptions, _jsonContext); - Script = Module.Create(this, JsonOptions, _jsonContext); - Log = Module.Create(this, JsonOptions, _jsonContext); - Storage = Module.Create(this, JsonOptions, _jsonContext); - WebExtension = Module.Create(this, JsonOptions, _jsonContext); - Emulation = Module.Create(this, JsonOptions, _jsonContext); + Broker = new Broker(this, uri); + + SessionModule = Module.Create(this); + BrowsingContext = Module.Create(this); + Browser = Module.Create(this); + Network = Module.Create(this); + InputModule = Module.Create(this); + Script = Module.Create(this); + Log = Module.Create(this); + Storage = Module.Create(this); + WebExtension = Module.Create(this); + Emulation = Module.Create(this); } internal Session.SessionModule SessionModule { get; } @@ -125,4 +90,33 @@ public async ValueTask DisposeAsync() await Broker.DisposeAsync().ConfigureAwait(false); GC.SuppressFinalize(this); } + + internal Broker Broker { get; } + + internal JsonSerializerOptions GetJsonOptions() + { + return new JsonSerializerOptions + { + PropertyNameCaseInsensitive = true, + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, + + // BiDi returns special numbers such as "NaN" as strings + // Additionally, -0 is returned as a string "-0" + NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals | JsonNumberHandling.AllowReadingFromString, + Converters = + { + new BrowsingContextConverter(this), + new BrowserUserContextConverter(this), + new CollectorConverter(this), + new InterceptConverter(this), + new HandleConverter(this), + new InternalIdConverter(this), + new PreloadScriptConverter(this), + new RealmConverter(this), + new DateTimeOffsetConverter(), + new WebExtensionConverter(this), + } + }; + } } diff --git a/dotnet/src/webdriver/BiDi/Broker.cs b/dotnet/src/webdriver/BiDi/Broker.cs index a4d7a09e99ac1..1eaf30797b8ba 100644 --- a/dotnet/src/webdriver/BiDi/Broker.cs +++ b/dotnet/src/webdriver/BiDi/Broker.cs @@ -50,7 +50,7 @@ public sealed class Broker : IAsyncDisposable private Task? _eventEmitterTask; private CancellationTokenSource? _receiveMessagesCancellationTokenSource; - internal Broker(BiDi bidi, Uri url, JsonSerializerOptions jsonOptions) + internal Broker(BiDi bidi, Uri url) { _bidi = bidi; _transport = new WebSocketTransport(url); diff --git a/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs b/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs index 9ab014c97f6be..6cf8c78c25e3b 100644 --- a/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs +++ b/dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs @@ -82,9 +82,4 @@ protected override void Initialize(JsonSerializerOptions options) { _jsonContext = new BiDiJsonSerializerContext(options); } - - protected override void Initialize(JsonSerializerOptions options) - { - _jsonContext = new BiDiJsonSerializerContext(options); - } } diff --git a/dotnet/src/webdriver/BiDi/Module.cs b/dotnet/src/webdriver/BiDi/Module.cs index 876511089e095..94abd3384f66f 100644 --- a/dotnet/src/webdriver/BiDi/Module.cs +++ b/dotnet/src/webdriver/BiDi/Module.cs @@ -18,7 +18,6 @@ // using System.Text.Json; -using System.Text.Json.Serialization; namespace OpenQA.Selenium.BiDi; @@ -28,7 +27,7 @@ public abstract class Module protected abstract void Initialize(JsonSerializerOptions options); - public static TModule Create(BiDi bidi, JsonSerializerOptions jsonOptions, JsonSerializerContext? cachedContext = null) + public static TModule Create(BiDi bidi) where TModule : Module, new() { TModule module = new() @@ -36,6 +35,8 @@ public static TModule Create(BiDi bidi, JsonSerializerOptions jsonOptio Broker = bidi.Broker, }; + module.Initialize(bidi.GetJsonOptions()); + return module; } } diff --git a/dotnet/src/webdriver/BiDi/Permissions/PermissionsBiDiExtensions.cs b/dotnet/src/webdriver/BiDi/Permissions/PermissionsBiDiExtensions.cs index ff8dff47db1e6..190c9f0f79497 100644 --- a/dotnet/src/webdriver/BiDi/Permissions/PermissionsBiDiExtensions.cs +++ b/dotnet/src/webdriver/BiDi/Permissions/PermissionsBiDiExtensions.cs @@ -31,6 +31,6 @@ public static PermissionsModule AsPermissions(this BiDi bidi) throw new ArgumentNullException(nameof(bidi)); } - return Module.Create(bidi, bidi.DefaultBiDiOptions()); + return Module.Create(bidi); } } From 8e140a9b41044e8acd510380c1d0c717912543a8 Mon Sep 17 00:00:00 2001 From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com> Date: Sat, 29 Nov 2025 17:30:36 +0300 Subject: [PATCH 24/25] Cache modules --- dotnet/src/webdriver/BiDi/BiDi.cs | 32 ++++++++++++------- dotnet/src/webdriver/BiDi/Module.cs | 6 ++-- .../Permissions/PermissionsBiDiExtensions.cs | 2 +- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/dotnet/src/webdriver/BiDi/BiDi.cs b/dotnet/src/webdriver/BiDi/BiDi.cs index 7f782ec5f2c13..b235a3b58e695 100644 --- a/dotnet/src/webdriver/BiDi/BiDi.cs +++ b/dotnet/src/webdriver/BiDi/BiDi.cs @@ -19,6 +19,7 @@ using OpenQA.Selenium.BiDi.Json.Converters; using System; +using System.Collections.Concurrent; using System.Text.Json; using System.Text.Json.Serialization; using System.Threading; @@ -28,22 +29,24 @@ namespace OpenQA.Selenium.BiDi; public sealed class BiDi : IAsyncDisposable { + private readonly ConcurrentDictionary _modules = new(); + private BiDi(string url) { var uri = new Uri(url); Broker = new Broker(this, uri); - SessionModule = Module.Create(this); - BrowsingContext = Module.Create(this); - Browser = Module.Create(this); - Network = Module.Create(this); - InputModule = Module.Create(this); - Script = Module.Create(this); - Log = Module.Create(this); - Storage = Module.Create(this); - WebExtension = Module.Create(this); - Emulation = Module.Create(this); + SessionModule = AsModule(); + BrowsingContext = AsModule(); + Browser = AsModule(); + Network = AsModule(); + InputModule = AsModule(); + Script = AsModule(); + Log = AsModule(); + Storage = AsModule(); + WebExtension = AsModule(); + Emulation = AsModule(); } internal Session.SessionModule SessionModule { get; } @@ -91,9 +94,14 @@ public async ValueTask DisposeAsync() GC.SuppressFinalize(this); } - internal Broker Broker { get; } + public T AsModule() where T : Module, new() + { + return (T)_modules.GetOrAdd(typeof(T), Module.Create(this, Broker, GetJsonOptions())); + } + + private Broker Broker { get; } - internal JsonSerializerOptions GetJsonOptions() + private JsonSerializerOptions GetJsonOptions() { return new JsonSerializerOptions { diff --git a/dotnet/src/webdriver/BiDi/Module.cs b/dotnet/src/webdriver/BiDi/Module.cs index 94abd3384f66f..1746a783e3dcc 100644 --- a/dotnet/src/webdriver/BiDi/Module.cs +++ b/dotnet/src/webdriver/BiDi/Module.cs @@ -27,15 +27,15 @@ public abstract class Module protected abstract void Initialize(JsonSerializerOptions options); - public static TModule Create(BiDi bidi) + public static TModule Create(BiDi bidi, Broker broker, JsonSerializerOptions jsonSerializerOptions) where TModule : Module, new() { TModule module = new() { - Broker = bidi.Broker, + Broker = broker }; - module.Initialize(bidi.GetJsonOptions()); + module.Initialize(jsonSerializerOptions); return module; } diff --git a/dotnet/src/webdriver/BiDi/Permissions/PermissionsBiDiExtensions.cs b/dotnet/src/webdriver/BiDi/Permissions/PermissionsBiDiExtensions.cs index 190c9f0f79497..792d10162936c 100644 --- a/dotnet/src/webdriver/BiDi/Permissions/PermissionsBiDiExtensions.cs +++ b/dotnet/src/webdriver/BiDi/Permissions/PermissionsBiDiExtensions.cs @@ -31,6 +31,6 @@ public static PermissionsModule AsPermissions(this BiDi bidi) throw new ArgumentNullException(nameof(bidi)); } - return Module.Create(bidi); + return bidi.AsModule(); } } From d4b5310151e7abcfc5ca86804e9a7ee5a16b647c Mon Sep 17 00:00:00 2001 From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com> Date: Sat, 29 Nov 2025 17:42:19 +0300 Subject: [PATCH 25/25] Module may have access to BiDi --- dotnet/src/webdriver/BiDi/Module.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dotnet/src/webdriver/BiDi/Module.cs b/dotnet/src/webdriver/BiDi/Module.cs index 1746a783e3dcc..df3101a195b39 100644 --- a/dotnet/src/webdriver/BiDi/Module.cs +++ b/dotnet/src/webdriver/BiDi/Module.cs @@ -23,15 +23,18 @@ namespace OpenQA.Selenium.BiDi; public abstract class Module { + protected BiDi BiDi { get; private set; } + protected Broker Broker { get; private set; } protected abstract void Initialize(JsonSerializerOptions options); - public static TModule Create(BiDi bidi, Broker broker, JsonSerializerOptions jsonSerializerOptions) + internal static TModule Create(BiDi bidi, Broker broker, JsonSerializerOptions jsonSerializerOptions) where TModule : Module, new() { TModule module = new() { + BiDi = bidi, Broker = broker };