From fd619197e0f2975839555181a75d8844e0e38ef5 Mon Sep 17 00:00:00 2001 From: Michael Render Date: Sat, 15 Mar 2025 01:15:23 -0400 Subject: [PATCH 01/13] [dotnet] [bidi] Maintain JSON converters with their respective types --- .../webdriver/BiDi/Communication/Broker.cs | 20 ++----------------- ...rter.cs => BiDiDateTimeOffsetConverter.cs} | 4 ++-- .../GetClientWindowsResultConverter.cs | 2 +- .../Enumerable/GetCookiesResultConverter.cs | 2 +- .../Enumerable/GetRealmsResultConverter.cs | 2 +- .../GetUserContextsResultConverter.cs | 2 +- .../Enumerable/InputSourceActionsConverter.cs | 2 +- .../Enumerable/LocateNodesResultConverter.cs | 2 +- .../Json/Converters/InputOriginConverter.cs | 2 +- .../Converters/PrintPageRangeConverter.cs | 2 +- .../BiDi/Modules/Browser/ClientWindow.cs | 4 ++++ .../Browser/GetClientWindowsCommand.cs | 3 +++ .../Modules/Browser/GetUserContextsCommand.cs | 3 +++ .../BrowsingContext/LocateNodesCommand.cs | 3 +++ .../Modules/BrowsingContext/Navigation.cs | 4 ++++ .../Modules/BrowsingContext/PrintCommand.cs | 3 +++ .../webdriver/BiDi/Modules/Input/Origin.cs | 2 ++ .../BiDi/Modules/Input/SourceActions.cs | 2 ++ .../webdriver/BiDi/Modules/Script/Channel.cs | 4 ++++ .../BiDi/Modules/Script/GetRealmsCommand.cs | 3 +++ .../BiDi/Modules/Script/RealmType.cs | 4 ++++ .../BiDi/Modules/Session/Subscription.cs | 4 ++++ .../BiDi/Modules/Storage/GetCookiesCommand.cs | 2 ++ 23 files changed, 53 insertions(+), 28 deletions(-) rename dotnet/src/webdriver/BiDi/Communication/Json/Converters/{DateTimeOffsetConverter.cs => BiDiDateTimeOffsetConverter.cs} (91%) diff --git a/dotnet/src/webdriver/BiDi/Communication/Broker.cs b/dotnet/src/webdriver/BiDi/Communication/Broker.cs index bd999ed947e13..9194228f22103 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Broker.cs +++ b/dotnet/src/webdriver/BiDi/Communication/Broker.cs @@ -67,21 +67,14 @@ internal Broker(BiDi bidi, Uri url) Converters = { new BrowsingContextConverter(_bidi), - new BrowserUserContextConverter(bidi), - new BrowserClientWindowConverter(), - new NavigationConverter(), + new BrowserUserContextConverter(_bidi), new InterceptConverter(_bidi), new RequestConverter(_bidi), - new ChannelConverter(), new HandleConverter(_bidi), new InternalIdConverter(_bidi), new PreloadScriptConverter(_bidi), new RealmConverter(_bidi), - new RealmTypeConverter(), - new DateTimeOffsetConverter(), - new PrintPageRangeConverter(), - new InputOriginConverter(), - new SubscriptionConverter(), + new BiDiDateTimeOffsetConverter(), new JsonStringEnumConverter(JsonNamingPolicy.CamelCase), // https://github.com/dotnet/runtime/issues/72604 @@ -90,15 +83,6 @@ internal Broker(BiDi bidi, Uri url) new Json.Converters.Polymorphic.RemoteValueConverter(), new Json.Converters.Polymorphic.RealmInfoConverter(), new Json.Converters.Polymorphic.LogEntryConverter(), - // - - // Enumerable - new Json.Converters.Enumerable.GetCookiesResultConverter(), - new Json.Converters.Enumerable.LocateNodesResultConverter(), - new Json.Converters.Enumerable.InputSourceActionsConverter(), - new Json.Converters.Enumerable.GetUserContextsResultConverter(), - new Json.Converters.Enumerable.GetClientWindowsResultConverter(), - new Json.Converters.Enumerable.GetRealmsResultConverter(), } }; diff --git a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/DateTimeOffsetConverter.cs b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/BiDiDateTimeOffsetConverter.cs similarity index 91% rename from dotnet/src/webdriver/BiDi/Communication/Json/Converters/DateTimeOffsetConverter.cs rename to dotnet/src/webdriver/BiDi/Communication/Json/Converters/BiDiDateTimeOffsetConverter.cs index 4ffa57f627bba..dc380c4eb6bed 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/DateTimeOffsetConverter.cs +++ b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/BiDiDateTimeOffsetConverter.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.Communication.Json.Converters; -internal class DateTimeOffsetConverter : JsonConverter +internal class BiDiDateTimeOffsetConverter : JsonConverter { public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { diff --git a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetClientWindowsResultConverter.cs b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetClientWindowsResultConverter.cs index e3bee0238a8e1..b14ca62969452 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetClientWindowsResultConverter.cs +++ b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetClientWindowsResultConverter.cs @@ -37,6 +37,6 @@ public override GetClientWindowsResult Read(ref Utf8JsonReader reader, Type type public override void Write(Utf8JsonWriter writer, GetClientWindowsResult value, JsonSerializerOptions options) { - throw new NotImplementedException(); + throw new NotSupportedException(); } } diff --git a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetCookiesResultConverter.cs b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetCookiesResultConverter.cs index 48c4fcd83f75d..a76b4c258f82d 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetCookiesResultConverter.cs +++ b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetCookiesResultConverter.cs @@ -38,6 +38,6 @@ public override GetCookiesResult Read(ref Utf8JsonReader reader, Type typeToConv public override void Write(Utf8JsonWriter writer, GetCookiesResult value, JsonSerializerOptions options) { - throw new NotImplementedException(); + throw new NotSupportedException(); } } diff --git a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetRealmsResultConverter.cs b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetRealmsResultConverter.cs index 069628d4f0776..0a1b5aad77975 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetRealmsResultConverter.cs +++ b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetRealmsResultConverter.cs @@ -37,6 +37,6 @@ public override GetRealmsResult Read(ref Utf8JsonReader reader, Type typeToConve public override void Write(Utf8JsonWriter writer, GetRealmsResult value, JsonSerializerOptions options) { - throw new NotImplementedException(); + throw new NotSupportedException(); } } diff --git a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetUserContextsResultConverter.cs b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetUserContextsResultConverter.cs index 02b22c2e82a02..1b75323e00f17 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetUserContextsResultConverter.cs +++ b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetUserContextsResultConverter.cs @@ -37,6 +37,6 @@ public override GetUserContextsResult Read(ref Utf8JsonReader reader, Type typeT public override void Write(Utf8JsonWriter writer, GetUserContextsResult value, JsonSerializerOptions options) { - throw new NotImplementedException(); + throw new NotSupportedException(); } } diff --git a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/InputSourceActionsConverter.cs b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/InputSourceActionsConverter.cs index f66ff5e9c6ed9..dc500320a53b8 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/InputSourceActionsConverter.cs +++ b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/InputSourceActionsConverter.cs @@ -29,7 +29,7 @@ internal class InputSourceActionsConverter : JsonConverter { public override SourceActions Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - throw new NotImplementedException(); + throw new NotSupportedException(); } public override void Write(Utf8JsonWriter writer, SourceActions value, JsonSerializerOptions options) diff --git a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/LocateNodesResultConverter.cs b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/LocateNodesResultConverter.cs index 027575d31acf1..05bfecdda50c2 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/LocateNodesResultConverter.cs +++ b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/LocateNodesResultConverter.cs @@ -38,6 +38,6 @@ public override LocateNodesResult Read(ref Utf8JsonReader reader, Type typeToCon public override void Write(Utf8JsonWriter writer, LocateNodesResult value, JsonSerializerOptions options) { - throw new NotImplementedException(); + throw new NotSupportedException(); } } diff --git a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/InputOriginConverter.cs b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/InputOriginConverter.cs index 997fc7b5a6d43..7bff799069e56 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/InputOriginConverter.cs +++ b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/InputOriginConverter.cs @@ -28,7 +28,7 @@ internal class InputOriginConverter : JsonConverter { public override Origin Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - throw new NotImplementedException(); + throw new NotSupportedException(); } public override void Write(Utf8JsonWriter writer, Origin value, JsonSerializerOptions options) diff --git a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/PrintPageRangeConverter.cs b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/PrintPageRangeConverter.cs index 009984cd90919..a3f2aafc09184 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/PrintPageRangeConverter.cs +++ b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/PrintPageRangeConverter.cs @@ -28,7 +28,7 @@ internal class PrintPageRangeConverter : JsonConverter { public override PrintPageRange Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - throw new NotImplementedException(); + throw new NotSupportedException(); } public override void Write(Utf8JsonWriter writer, PrintPageRange value, JsonSerializerOptions options) diff --git a/dotnet/src/webdriver/BiDi/Modules/Browser/ClientWindow.cs b/dotnet/src/webdriver/BiDi/Modules/Browser/ClientWindow.cs index fe80e23374bd3..91969caf6329c 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Browser/ClientWindow.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Browser/ClientWindow.cs @@ -17,8 +17,12 @@ // under the License. // +using OpenQA.Selenium.BiDi.Communication.Json.Converters; +using System.Text.Json.Serialization; + namespace OpenQA.Selenium.BiDi.Modules.Browser; +[JsonConverter(typeof(BrowserClientWindowConverter))] public record ClientWindow { internal ClientWindow(string id) diff --git a/dotnet/src/webdriver/BiDi/Modules/Browser/GetClientWindowsCommand.cs b/dotnet/src/webdriver/BiDi/Modules/Browser/GetClientWindowsCommand.cs index 432457c85bb61..d8367135bdd6a 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Browser/GetClientWindowsCommand.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Browser/GetClientWindowsCommand.cs @@ -18,8 +18,10 @@ // using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json.Converters.Enumerable; using System.Collections; using System.Collections.Generic; +using System.Text.Json.Serialization; namespace OpenQA.Selenium.BiDi.Modules.Browser; @@ -28,6 +30,7 @@ internal class GetClientWindowsCommand() public record GetClientWindowsOptions : CommandOptions; +[JsonConverter(typeof(GetClientWindowsResultConverter))] public record GetClientWindowsResult : IReadOnlyList { private readonly IReadOnlyList _clientWindows; diff --git a/dotnet/src/webdriver/BiDi/Modules/Browser/GetUserContextsCommand.cs b/dotnet/src/webdriver/BiDi/Modules/Browser/GetUserContextsCommand.cs index e9185b2308634..e79f13cc8d973 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Browser/GetUserContextsCommand.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Browser/GetUserContextsCommand.cs @@ -18,8 +18,10 @@ // using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json.Converters.Enumerable; using System.Collections; using System.Collections.Generic; +using System.Text.Json.Serialization; namespace OpenQA.Selenium.BiDi.Modules.Browser; @@ -28,6 +30,7 @@ internal class GetUserContextsCommand() public record GetUserContextsOptions : CommandOptions; +[JsonConverter(typeof(GetUserContextsResultConverter))] public record GetUserContextsResult : IReadOnlyList { private readonly IReadOnlyList _userContexts; diff --git a/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/LocateNodesCommand.cs b/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/LocateNodesCommand.cs index fdc7e29b7b04c..07129a0b98aaf 100644 --- a/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/LocateNodesCommand.cs +++ b/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/LocateNodesCommand.cs @@ -18,8 +18,10 @@ // using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json.Converters.Enumerable; using System.Collections; using System.Collections.Generic; +using System.Text.Json.Serialization; namespace OpenQA.Selenium.BiDi.Modules.BrowsingContext; @@ -37,6 +39,7 @@ public record LocateNodesOptions : CommandOptions public IEnumerable? StartNodes { get; set; } } +[JsonConverter(typeof(LocateNodesResultConverter))] public record LocateNodesResult : IReadOnlyList { private readonly IReadOnlyList _nodes; diff --git a/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/Navigation.cs b/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/Navigation.cs index 04784f995ea36..722dfd9cfb0f8 100644 --- a/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/Navigation.cs +++ b/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/Navigation.cs @@ -17,6 +17,10 @@ // under the License. // +using OpenQA.Selenium.BiDi.Communication.Json.Converters; +using System.Text.Json.Serialization; + namespace OpenQA.Selenium.BiDi.Modules.BrowsingContext; +[JsonConverter(typeof(NavigationConverter))] public record Navigation(string Id); diff --git a/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/PrintCommand.cs b/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/PrintCommand.cs index b3362f59fa139..fbf50cdf6f4bc 100644 --- a/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/PrintCommand.cs +++ b/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/PrintCommand.cs @@ -18,8 +18,10 @@ // using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json.Converters; using System; using System.Collections.Generic; +using System.Text.Json.Serialization; namespace OpenQA.Selenium.BiDi.Modules.BrowsingContext; @@ -69,6 +71,7 @@ public struct PrintPage public double? Width { get; set; } } +[JsonConverter(typeof(PrintPageRangeConverter))] public readonly record struct PrintPageRange(int? Start, int? End) { public static implicit operator PrintPageRange(int index) { return new PrintPageRange(index, index); } diff --git a/dotnet/src/webdriver/BiDi/Modules/Input/Origin.cs b/dotnet/src/webdriver/BiDi/Modules/Input/Origin.cs index 616570662fc65..e4e773dd9def8 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Input/Origin.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Input/Origin.cs @@ -17,10 +17,12 @@ // under the License. // +using OpenQA.Selenium.BiDi.Communication.Json.Converters; using System.Text.Json.Serialization; namespace OpenQA.Selenium.BiDi.Modules.Input; +[JsonConverter(typeof(InputOriginConverter))] public abstract record Origin { public record Viewport() : Origin; diff --git a/dotnet/src/webdriver/BiDi/Modules/Input/SourceActions.cs b/dotnet/src/webdriver/BiDi/Modules/Input/SourceActions.cs index a078c80fbf3fd..dcd55c1c115c3 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Input/SourceActions.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Input/SourceActions.cs @@ -17,6 +17,7 @@ // under the License. // +using OpenQA.Selenium.BiDi.Communication.Json.Converters.Enumerable; using System; using System.Collections; using System.Collections.Generic; @@ -24,6 +25,7 @@ namespace OpenQA.Selenium.BiDi.Modules.Input; +[JsonConverter(typeof(InputSourceActionsConverter))] public abstract record SourceActions { public string Id { get; } = Guid.NewGuid().ToString(); diff --git a/dotnet/src/webdriver/BiDi/Modules/Script/Channel.cs b/dotnet/src/webdriver/BiDi/Modules/Script/Channel.cs index 53856b51ad373..0bb2f2e23f3c6 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Script/Channel.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Script/Channel.cs @@ -17,6 +17,10 @@ // under the License. // +using OpenQA.Selenium.BiDi.Communication.Json.Converters; +using System.Text.Json.Serialization; + namespace OpenQA.Selenium.BiDi.Modules.Script; +[JsonConverter(typeof(ChannelConverter))] public record Channel(string Id); diff --git a/dotnet/src/webdriver/BiDi/Modules/Script/GetRealmsCommand.cs b/dotnet/src/webdriver/BiDi/Modules/Script/GetRealmsCommand.cs index 9d7348e32f9dd..6fdb9fead5bd0 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Script/GetRealmsCommand.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Script/GetRealmsCommand.cs @@ -18,8 +18,10 @@ // using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json.Converters.Enumerable; using System.Collections; using System.Collections.Generic; +using System.Text.Json.Serialization; namespace OpenQA.Selenium.BiDi.Modules.Script; @@ -35,6 +37,7 @@ public record GetRealmsOptions : CommandOptions public RealmType? Type { get; set; } } +[JsonConverter(typeof(GetRealmsResultConverter))] public record GetRealmsResult : IReadOnlyList { private readonly IReadOnlyList _realms; diff --git a/dotnet/src/webdriver/BiDi/Modules/Script/RealmType.cs b/dotnet/src/webdriver/BiDi/Modules/Script/RealmType.cs index 0958b42929edf..3f543dd473946 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Script/RealmType.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Script/RealmType.cs @@ -17,8 +17,12 @@ // under the License. // +using OpenQA.Selenium.BiDi.Communication.Json.Converters; +using System.Text.Json.Serialization; + namespace OpenQA.Selenium.BiDi.Modules.Script; +[JsonConverter(typeof(RealmTypeConverter))] public enum RealmType { Window, diff --git a/dotnet/src/webdriver/BiDi/Modules/Session/Subscription.cs b/dotnet/src/webdriver/BiDi/Modules/Session/Subscription.cs index 60aaf2ddbf90b..92c9afa1f3658 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Session/Subscription.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Session/Subscription.cs @@ -17,8 +17,12 @@ // under the License. // +using OpenQA.Selenium.BiDi.Communication.Json.Converters; +using System.Text.Json.Serialization; + namespace OpenQA.Selenium.BiDi.Modules.Session; +[JsonConverter(typeof(SubscriptionConverter))] public sealed class Subscription { internal Subscription(string id) diff --git a/dotnet/src/webdriver/BiDi/Modules/Storage/GetCookiesCommand.cs b/dotnet/src/webdriver/BiDi/Modules/Storage/GetCookiesCommand.cs index 1cf13bd5489ed..02b5281d9488b 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Storage/GetCookiesCommand.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Storage/GetCookiesCommand.cs @@ -18,6 +18,7 @@ // using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json.Converters.Enumerable; using System; using System.Collections; using System.Collections.Generic; @@ -37,6 +38,7 @@ public record GetCookiesOptions : CommandOptions public PartitionDescriptor? Partition { get; set; } } +[JsonConverter(typeof(GetCookiesResultConverter))] public record GetCookiesResult : IReadOnlyList { private readonly IReadOnlyList _cookies; From ea862d665057eb41671ac2b916943c1bf85ae4e4 Mon Sep 17 00:00:00 2001 From: Michael Render Date: Sat, 15 Mar 2025 01:23:17 -0400 Subject: [PATCH 02/13] Move the rest of `NotImplementedException` to `NotSupportedException` --- .../Json/Converters/Polymorphic/EvaluateResultConverter.cs | 2 +- .../Json/Converters/Polymorphic/LogEntryConverter.cs | 2 +- .../Json/Converters/Polymorphic/MessageConverter.cs | 2 +- .../Json/Converters/Polymorphic/RealmInfoConverter.cs | 2 +- .../Json/Converters/Polymorphic/RemoteValueConverter.cs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/EvaluateResultConverter.cs b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/EvaluateResultConverter.cs index 0aa560798cf87..21734afa32ebf 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/EvaluateResultConverter.cs +++ b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/EvaluateResultConverter.cs @@ -41,6 +41,6 @@ internal class EvaluateResultConverter : JsonConverter public override void Write(Utf8JsonWriter writer, EvaluateResult value, JsonSerializerOptions options) { - throw new NotImplementedException(); + throw new NotSupportedException(); } } diff --git a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/LogEntryConverter.cs b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/LogEntryConverter.cs index e573ea57df0fe..eebf7627859eb 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/LogEntryConverter.cs +++ b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/LogEntryConverter.cs @@ -41,6 +41,6 @@ internal class LogEntryConverter : JsonConverter public override void Write(Utf8JsonWriter writer, Modules.Log.Entry value, JsonSerializerOptions options) { - throw new NotImplementedException(); + throw new NotSupportedException(); } } diff --git a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/MessageConverter.cs b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/MessageConverter.cs index 8e10f9b0565d9..88352993b94e5 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/MessageConverter.cs +++ b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/MessageConverter.cs @@ -41,6 +41,6 @@ internal class MessageConverter : JsonConverter public override void Write(Utf8JsonWriter writer, Message value, JsonSerializerOptions options) { - throw new NotImplementedException(); + throw new NotSupportedException(); } } diff --git a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/RealmInfoConverter.cs b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/RealmInfoConverter.cs index a916fd3734d5a..d9bfadd20c52b 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/RealmInfoConverter.cs +++ b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/RealmInfoConverter.cs @@ -47,6 +47,6 @@ internal class RealmInfoConverter : JsonConverter public override void Write(Utf8JsonWriter writer, RealmInfo value, JsonSerializerOptions options) { - throw new NotImplementedException(); + throw new NotSupportedException(); } } diff --git a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/RemoteValueConverter.cs b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/RemoteValueConverter.cs index 88539ce7b55fd..b8d9835a3aaf5 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/RemoteValueConverter.cs +++ b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/RemoteValueConverter.cs @@ -69,6 +69,6 @@ internal class RemoteValueConverter : JsonConverter public override void Write(Utf8JsonWriter writer, RemoteValue value, JsonSerializerOptions options) { - throw new NotImplementedException(); + throw new NotSupportedException(); } } From 5b50e5f6583db4f939a32b8e4158bbcd4fadee35 Mon Sep 17 00:00:00 2001 From: Michael Render Date: Sat, 15 Mar 2025 01:30:29 -0400 Subject: [PATCH 03/13] Move polymorphic workaround converters to direct type attributes --- dotnet/src/webdriver/BiDi/Communication/Broker.cs | 8 +------- dotnet/src/webdriver/BiDi/Communication/Message.cs | 4 ++++ dotnet/src/webdriver/BiDi/Modules/Log/Entry.cs | 4 ++++ .../src/webdriver/BiDi/Modules/Script/EvaluateCommand.cs | 4 ++++ dotnet/src/webdriver/BiDi/Modules/Script/RealmInfo.cs | 4 ++++ dotnet/src/webdriver/BiDi/Modules/Script/RemoteValue.cs | 3 +++ 6 files changed, 20 insertions(+), 7 deletions(-) diff --git a/dotnet/src/webdriver/BiDi/Communication/Broker.cs b/dotnet/src/webdriver/BiDi/Communication/Broker.cs index 9194228f22103..3b9e5b094eab6 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Broker.cs +++ b/dotnet/src/webdriver/BiDi/Communication/Broker.cs @@ -74,15 +74,9 @@ internal Broker(BiDi bidi, Uri url) new InternalIdConverter(_bidi), new PreloadScriptConverter(_bidi), new RealmConverter(_bidi), + new BiDiDateTimeOffsetConverter(), new JsonStringEnumConverter(JsonNamingPolicy.CamelCase), - - // https://github.com/dotnet/runtime/issues/72604 - new Json.Converters.Polymorphic.MessageConverter(), - new Json.Converters.Polymorphic.EvaluateResultConverter(), - new Json.Converters.Polymorphic.RemoteValueConverter(), - new Json.Converters.Polymorphic.RealmInfoConverter(), - new Json.Converters.Polymorphic.LogEntryConverter(), } }; diff --git a/dotnet/src/webdriver/BiDi/Communication/Message.cs b/dotnet/src/webdriver/BiDi/Communication/Message.cs index fc8c2020ffe8a..7420e11068ac5 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Message.cs +++ b/dotnet/src/webdriver/BiDi/Communication/Message.cs @@ -17,11 +17,15 @@ // under the License. // +using OpenQA.Selenium.BiDi.Communication.Json.Converters.Polymorphic; using System.Text.Json; +using System.Text.Json.Serialization; namespace OpenQA.Selenium.BiDi.Communication; // https://github.com/dotnet/runtime/issues/72604 +[JsonConverter(typeof(MessageConverter))] + //[JsonPolymorphic(TypeDiscriminatorPropertyName = "type")] //[JsonDerivedType(typeof(MessageSuccess), "success")] //[JsonDerivedType(typeof(MessageError), "error")] diff --git a/dotnet/src/webdriver/BiDi/Modules/Log/Entry.cs b/dotnet/src/webdriver/BiDi/Modules/Log/Entry.cs index 52b57a4db11fd..2a15852a54e09 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Log/Entry.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Log/Entry.cs @@ -17,12 +17,16 @@ // under the License. // +using OpenQA.Selenium.BiDi.Communication.Json.Converters.Polymorphic; using System; using System.Collections.Generic; +using System.Text.Json.Serialization; namespace OpenQA.Selenium.BiDi.Modules.Log; // https://github.com/dotnet/runtime/issues/72604 +[JsonConverter(typeof(LogEntryConverter))] + //[JsonPolymorphic(TypeDiscriminatorPropertyName = "type")] //[JsonDerivedType(typeof(Console), "console")] //[JsonDerivedType(typeof(Javascript), "javascript")] diff --git a/dotnet/src/webdriver/BiDi/Modules/Script/EvaluateCommand.cs b/dotnet/src/webdriver/BiDi/Modules/Script/EvaluateCommand.cs index 94b5d93ab3348..7ff8d99ea8aeb 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Script/EvaluateCommand.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Script/EvaluateCommand.cs @@ -18,6 +18,8 @@ // using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json.Converters.Polymorphic; +using System.Text.Json.Serialization; namespace OpenQA.Selenium.BiDi.Modules.Script; @@ -36,6 +38,8 @@ public record EvaluateOptions : CommandOptions } // https://github.com/dotnet/runtime/issues/72604 +[JsonConverter(typeof(EvaluateResultConverter))] + //[JsonPolymorphic(TypeDiscriminatorPropertyName = "type")] //[JsonDerivedType(typeof(Success), "success")] //[JsonDerivedType(typeof(Exception), "exception")] diff --git a/dotnet/src/webdriver/BiDi/Modules/Script/RealmInfo.cs b/dotnet/src/webdriver/BiDi/Modules/Script/RealmInfo.cs index 81a3024e8473c..414fa670fc3f2 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Script/RealmInfo.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Script/RealmInfo.cs @@ -17,11 +17,15 @@ // under the License. // +using OpenQA.Selenium.BiDi.Communication.Json.Converters.Polymorphic; using System.Collections.Generic; +using System.Text.Json.Serialization; namespace OpenQA.Selenium.BiDi.Modules.Script; // https://github.com/dotnet/runtime/issues/72604 +[JsonConverter(typeof(RealmInfoConverter))] + //[JsonPolymorphic(TypeDiscriminatorPropertyName = "type")] //[JsonDerivedType(typeof(Window), "window")] //[JsonDerivedType(typeof(DedicatedWorker), "dedicated-worker")] diff --git a/dotnet/src/webdriver/BiDi/Modules/Script/RemoteValue.cs b/dotnet/src/webdriver/BiDi/Modules/Script/RemoteValue.cs index 8ff737adf44cf..f15ba8f3ad78d 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Script/RemoteValue.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Script/RemoteValue.cs @@ -17,6 +17,7 @@ // under the License. // +using OpenQA.Selenium.BiDi.Communication.Json.Converters.Polymorphic; using System; using System.Collections.Generic; using System.Text.Json; @@ -25,6 +26,8 @@ namespace OpenQA.Selenium.BiDi.Modules.Script; // https://github.com/dotnet/runtime/issues/72604 +[JsonConverter(typeof(RemoteValueConverter))] + //[JsonPolymorphic(TypeDiscriminatorPropertyName = "type")] //[JsonDerivedType(typeof(Number), "number")] //[JsonDerivedType(typeof(Boolean), "boolean")] From 18a8e84d9d0cbb221043c2e4c61e93315de7503d Mon Sep 17 00:00:00 2001 From: Michael Render Date: Sat, 15 Mar 2025 11:20:48 -0400 Subject: [PATCH 04/13] Revert migration of `NotSupportedException` to `NotImplementedException` --- .../Converters/Enumerable/GetClientWindowsResultConverter.cs | 2 +- .../Json/Converters/Enumerable/GetCookiesResultConverter.cs | 2 +- .../Json/Converters/Enumerable/GetRealmsResultConverter.cs | 2 +- .../Converters/Enumerable/GetUserContextsResultConverter.cs | 2 +- .../Json/Converters/Enumerable/InputSourceActionsConverter.cs | 2 +- .../Json/Converters/Enumerable/LocateNodesResultConverter.cs | 2 +- .../BiDi/Communication/Json/Converters/InputOriginConverter.cs | 2 +- .../Json/Converters/Polymorphic/EvaluateResultConverter.cs | 2 +- .../Json/Converters/Polymorphic/LogEntryConverter.cs | 2 +- .../Json/Converters/Polymorphic/MessageConverter.cs | 2 +- .../Json/Converters/Polymorphic/RealmInfoConverter.cs | 2 +- .../Json/Converters/Polymorphic/RemoteValueConverter.cs | 2 +- .../Communication/Json/Converters/PrintPageRangeConverter.cs | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetClientWindowsResultConverter.cs b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetClientWindowsResultConverter.cs index b14ca62969452..e3bee0238a8e1 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetClientWindowsResultConverter.cs +++ b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetClientWindowsResultConverter.cs @@ -37,6 +37,6 @@ public override GetClientWindowsResult Read(ref Utf8JsonReader reader, Type type public override void Write(Utf8JsonWriter writer, GetClientWindowsResult value, JsonSerializerOptions options) { - throw new NotSupportedException(); + throw new NotImplementedException(); } } diff --git a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetCookiesResultConverter.cs b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetCookiesResultConverter.cs index a76b4c258f82d..48c4fcd83f75d 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetCookiesResultConverter.cs +++ b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetCookiesResultConverter.cs @@ -38,6 +38,6 @@ public override GetCookiesResult Read(ref Utf8JsonReader reader, Type typeToConv public override void Write(Utf8JsonWriter writer, GetCookiesResult value, JsonSerializerOptions options) { - throw new NotSupportedException(); + throw new NotImplementedException(); } } diff --git a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetRealmsResultConverter.cs b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetRealmsResultConverter.cs index 0a1b5aad77975..069628d4f0776 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetRealmsResultConverter.cs +++ b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetRealmsResultConverter.cs @@ -37,6 +37,6 @@ public override GetRealmsResult Read(ref Utf8JsonReader reader, Type typeToConve public override void Write(Utf8JsonWriter writer, GetRealmsResult value, JsonSerializerOptions options) { - throw new NotSupportedException(); + throw new NotImplementedException(); } } diff --git a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetUserContextsResultConverter.cs b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetUserContextsResultConverter.cs index 1b75323e00f17..02b22c2e82a02 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetUserContextsResultConverter.cs +++ b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/GetUserContextsResultConverter.cs @@ -37,6 +37,6 @@ public override GetUserContextsResult Read(ref Utf8JsonReader reader, Type typeT public override void Write(Utf8JsonWriter writer, GetUserContextsResult value, JsonSerializerOptions options) { - throw new NotSupportedException(); + throw new NotImplementedException(); } } diff --git a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/InputSourceActionsConverter.cs b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/InputSourceActionsConverter.cs index dc500320a53b8..f66ff5e9c6ed9 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/InputSourceActionsConverter.cs +++ b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/InputSourceActionsConverter.cs @@ -29,7 +29,7 @@ internal class InputSourceActionsConverter : JsonConverter { public override SourceActions Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - throw new NotSupportedException(); + throw new NotImplementedException(); } public override void Write(Utf8JsonWriter writer, SourceActions value, JsonSerializerOptions options) diff --git a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/LocateNodesResultConverter.cs b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/LocateNodesResultConverter.cs index 05bfecdda50c2..027575d31acf1 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/LocateNodesResultConverter.cs +++ b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Enumerable/LocateNodesResultConverter.cs @@ -38,6 +38,6 @@ public override LocateNodesResult Read(ref Utf8JsonReader reader, Type typeToCon public override void Write(Utf8JsonWriter writer, LocateNodesResult value, JsonSerializerOptions options) { - throw new NotSupportedException(); + throw new NotImplementedException(); } } diff --git a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/InputOriginConverter.cs b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/InputOriginConverter.cs index 7bff799069e56..997fc7b5a6d43 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/InputOriginConverter.cs +++ b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/InputOriginConverter.cs @@ -28,7 +28,7 @@ internal class InputOriginConverter : JsonConverter { public override Origin Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - throw new NotSupportedException(); + throw new NotImplementedException(); } public override void Write(Utf8JsonWriter writer, Origin value, JsonSerializerOptions options) diff --git a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/EvaluateResultConverter.cs b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/EvaluateResultConverter.cs index 21734afa32ebf..0aa560798cf87 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/EvaluateResultConverter.cs +++ b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/EvaluateResultConverter.cs @@ -41,6 +41,6 @@ internal class EvaluateResultConverter : JsonConverter public override void Write(Utf8JsonWriter writer, EvaluateResult value, JsonSerializerOptions options) { - throw new NotSupportedException(); + throw new NotImplementedException(); } } diff --git a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/LogEntryConverter.cs b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/LogEntryConverter.cs index eebf7627859eb..e573ea57df0fe 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/LogEntryConverter.cs +++ b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/LogEntryConverter.cs @@ -41,6 +41,6 @@ internal class LogEntryConverter : JsonConverter public override void Write(Utf8JsonWriter writer, Modules.Log.Entry value, JsonSerializerOptions options) { - throw new NotSupportedException(); + throw new NotImplementedException(); } } diff --git a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/MessageConverter.cs b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/MessageConverter.cs index 88352993b94e5..8e10f9b0565d9 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/MessageConverter.cs +++ b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/MessageConverter.cs @@ -41,6 +41,6 @@ internal class MessageConverter : JsonConverter public override void Write(Utf8JsonWriter writer, Message value, JsonSerializerOptions options) { - throw new NotSupportedException(); + throw new NotImplementedException(); } } diff --git a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/RealmInfoConverter.cs b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/RealmInfoConverter.cs index d9bfadd20c52b..a916fd3734d5a 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/RealmInfoConverter.cs +++ b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/RealmInfoConverter.cs @@ -47,6 +47,6 @@ internal class RealmInfoConverter : JsonConverter public override void Write(Utf8JsonWriter writer, RealmInfo value, JsonSerializerOptions options) { - throw new NotSupportedException(); + throw new NotImplementedException(); } } diff --git a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/RemoteValueConverter.cs b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/RemoteValueConverter.cs index b8d9835a3aaf5..88539ce7b55fd 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/RemoteValueConverter.cs +++ b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/RemoteValueConverter.cs @@ -69,6 +69,6 @@ internal class RemoteValueConverter : JsonConverter public override void Write(Utf8JsonWriter writer, RemoteValue value, JsonSerializerOptions options) { - throw new NotSupportedException(); + throw new NotImplementedException(); } } diff --git a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/PrintPageRangeConverter.cs b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/PrintPageRangeConverter.cs index a3f2aafc09184..009984cd90919 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Json/Converters/PrintPageRangeConverter.cs +++ b/dotnet/src/webdriver/BiDi/Communication/Json/Converters/PrintPageRangeConverter.cs @@ -28,7 +28,7 @@ internal class PrintPageRangeConverter : JsonConverter { public override PrintPageRange Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - throw new NotSupportedException(); + throw new NotImplementedException(); } public override void Write(Utf8JsonWriter writer, PrintPageRange value, JsonSerializerOptions options) From 718ca7652a0c2848ed334827b62b21c62b70743b Mon Sep 17 00:00:00 2001 From: Michael Render Date: Thu, 20 Mar 2025 17:18:39 -0400 Subject: [PATCH 05/13] revert change --- py/docs/source/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py/docs/source/index.rst b/py/docs/source/index.rst index 4d81155e043e8..1beb6b7b24b41 100755 --- a/py/docs/source/index.rst +++ b/py/docs/source/index.rst @@ -157,4 +157,4 @@ Contributing - If tox exits `0`, commit and push. Otherwise fix the newly introduced style violations. - `flake8` requires manual fixes - `black` will rewrite the violations automatically, however the files are unstaged and should staged again. - - `isort` will rewrite the violations automatically, however the files are unstaged and should staged again. + - `isort` will rewrite the violations automatically, however the files are unstaged and should staged again. \ No newline at end of file From 7e0efd4db1f0990c6b67a646c81992c573be2716 Mon Sep 17 00:00:00 2001 From: Michael Render Date: Thu, 20 Mar 2025 17:20:50 -0400 Subject: [PATCH 06/13] revert change again --- py/docs/source/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py/docs/source/index.rst b/py/docs/source/index.rst index 1beb6b7b24b41..4d81155e043e8 100755 --- a/py/docs/source/index.rst +++ b/py/docs/source/index.rst @@ -157,4 +157,4 @@ Contributing - If tox exits `0`, commit and push. Otherwise fix the newly introduced style violations. - `flake8` requires manual fixes - `black` will rewrite the violations automatically, however the files are unstaged and should staged again. - - `isort` will rewrite the violations automatically, however the files are unstaged and should staged again. \ No newline at end of file + - `isort` will rewrite the violations automatically, however the files are unstaged and should staged again. From 7217bf611b2ff43270cfb928ab7f2603b2d1ab9f Mon Sep 17 00:00:00 2001 From: Michael Render Date: Sat, 22 Mar 2025 01:25:18 -0400 Subject: [PATCH 07/13] Implement BiDi extensions, add Permissions extension --- dotnet/src/webdriver/BiDi/BiDi.cs | 76 +++++++++---- .../{Broker.cs => BiDiConnection.cs} | 103 ++++++++++-------- .../BiDiConnectionJsonSerializerContext.cs | 72 ++++++++++++ .../Json/BiDiJsonSerializerContext.cs | 17 --- dotnet/src/webdriver/BiDi/EventArgs.cs | 7 +- .../PermissionsJsonSerializerContext .cs | 26 +++++ .../Permissions/PermissionsModule.cs | 42 +++++++ .../Permissions/SetPermissionCommand.cs | 39 +++++++ .../BiDi/Modules/Browser/BrowserModule.cs | 2 +- .../BrowsingContext/BrowsingContextInfo.cs | 3 +- .../BrowsingContext/BrowsingContextModule.cs | 2 +- .../Modules/BrowsingContext/NavigationInfo.cs | 4 +- .../UserPromptClosedEventArgs.cs | 3 +- .../UserPromptOpenedEventArgs.cs | 3 +- .../BiDi/Modules/Input/InputModule.cs | 2 +- .../webdriver/BiDi/Modules/Log/LogEntry.cs | 7 +- .../webdriver/BiDi/Modules/Log/LogModule.cs | 2 +- dotnet/src/webdriver/BiDi/Modules/Module.cs | 5 +- .../Modules/Network/AuthRequiredEventArgs.cs | 4 +- .../Network/BaseParametersEventArgs.cs | 3 +- .../Network/BeforeRequestSentEventArgs.cs | 4 +- .../Modules/Network/FetchErrorEventArgs.cs | 4 +- .../BiDi/Modules/Network/NetworkModule.cs | 2 +- .../Network/ResponseCompletedEventArgs.cs | 4 +- .../Network/ResponseStartedEventArgs.cs | 4 +- .../BiDi/Modules/Script/MessageEventArgs.cs | 5 +- .../Modules/Script/RealmDestroyedEventArgs.cs | 5 +- .../BiDi/Modules/Script/RealmInfo.cs | 19 ++-- .../BiDi/Modules/Script/ScriptModule.cs | 2 +- .../BiDi/Modules/Session/SessionModule.cs | 2 +- .../BiDi/Modules/Storage/StorageModule.cs | 2 +- dotnet/src/webdriver/BiDi/Subscription.cs | 4 +- .../webdriver/BiDi/WebDriver.Extensions.cs | 28 ++++- dotnet/test/common/BiDi/BiDiFixture.cs | 7 +- .../BiDi/Permissions/PermissionsTests.cs | 64 +++++++++++ 35 files changed, 451 insertions(+), 127 deletions(-) rename dotnet/src/webdriver/BiDi/Communication/{Broker.cs => BiDiConnection.cs} (72%) create mode 100644 dotnet/src/webdriver/BiDi/Communication/Json/BiDiConnectionJsonSerializerContext.cs create mode 100644 dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionsJsonSerializerContext .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/Permissions/PermissionsTests.cs diff --git a/dotnet/src/webdriver/BiDi/BiDi.cs b/dotnet/src/webdriver/BiDi/BiDi.cs index 478f467012bff..c5636aaa7a6ef 100644 --- a/dotnet/src/webdriver/BiDi/BiDi.cs +++ b/dotnet/src/webdriver/BiDi/BiDi.cs @@ -17,17 +17,19 @@ // under the License. // +using OpenQA.Selenium.BiDi.Communication; +using OpenQA.Selenium.BiDi.Communication.Json; +using OpenQA.Selenium.BiDi.Communication.Json.Converters; using System; using System.Threading.Tasks; -using OpenQA.Selenium.BiDi.Communication; namespace OpenQA.Selenium.BiDi; public class BiDi : IAsyncDisposable { - private readonly Broker _broker; + private readonly bool _ownsConnection; + protected BiDiConnection BiDiConnection { get; } - private readonly Lazy _sessionModule; private readonly Lazy _browsingContextModule; private readonly Lazy _browserModule; private readonly Lazy _networkModule; @@ -36,23 +38,49 @@ public class BiDi : IAsyncDisposable private readonly Lazy _logModule; private readonly Lazy _storageModule; - internal BiDi(string url) + private BiDi(BiDiConnection connection) : this() + { + _ownsConnection = false; + BiDiConnection = connection; + AddBiDiModuleJsonInfo(connection); + } + + private BiDi(string url) : this() + { + _ownsConnection = true; + BiDiConnection = new BiDiConnection(new Uri(url)); + AddBiDiModuleJsonInfo(BiDiConnection); + } + + private BiDi() { - var uri = new Uri(url); - - _broker = new Broker(this, uri); - - _sessionModule = new Lazy(() => new Modules.Session.SessionModule(_broker)); - _browsingContextModule = new Lazy(() => new Modules.BrowsingContext.BrowsingContextModule(_broker)); - _browserModule = new Lazy(() => new Modules.Browser.BrowserModule(_broker)); - _networkModule = new Lazy(() => new Modules.Network.NetworkModule(_broker)); - _inputModule = new Lazy(() => new Modules.Input.InputModule(_broker)); - _scriptModule = new Lazy(() => new Modules.Script.ScriptModule(_broker)); - _logModule = new Lazy(() => new Modules.Log.LogModule(_broker)); - _storageModule = new Lazy(() => new Modules.Storage.StorageModule(_broker)); + _browsingContextModule = new Lazy(() => new Modules.BrowsingContext.BrowsingContextModule(BiDiConnection)); + _browserModule = new Lazy(() => new Modules.Browser.BrowserModule(BiDiConnection)); + _networkModule = new Lazy(() => new Modules.Network.NetworkModule(BiDiConnection)); + _inputModule = new Lazy(() => new Modules.Input.InputModule(BiDiConnection)); + _scriptModule = new Lazy(() => new Modules.Script.ScriptModule(BiDiConnection)); + _logModule = new Lazy(() => new Modules.Log.LogModule(BiDiConnection)); + _storageModule = new Lazy(() => new Modules.Storage.StorageModule(BiDiConnection)); } - internal Modules.Session.SessionModule SessionModule => _sessionModule.Value; + private BiDiConnection AddBiDiModuleJsonInfo(BiDiConnection connection) + { + connection.AddSerializerContextAndConverters(BiDiJsonSerializerContext.Default, + [ + new BrowsingContextConverter(this), + new BrowserUserContextConverter(this), + new InterceptConverter(this), + new RequestConverter(this), + new HandleConverter(this), + new InternalIdConverter(this), + new PreloadScriptConverter(this), + new RealmConverter(this), + ]); + + return connection; + } + + internal Modules.Session.SessionModule SessionModule => BiDiConnection.SessionModule; public Modules.BrowsingContext.BrowsingContextModule BrowsingContext => _browsingContextModule.Value; public Modules.Browser.BrowserModule Browser => _browserModule.Value; public Modules.Network.NetworkModule Network => _networkModule.Value; @@ -70,11 +98,18 @@ public static async Task ConnectAsync(string url) { var bidi = new BiDi(url); - await bidi._broker.ConnectAsync(default).ConfigureAwait(false); + await bidi.BiDiConnection.ConnectAsync(default).ConfigureAwait(false); return bidi; } + public static ValueTask AttachAsync(BiDiConnection connection) + { + var bidi = new BiDi(connection); + + return new ValueTask(bidi); + } + public Task EndAsync(Modules.Session.EndOptions? options = null) { return SessionModule.EndAsync(options); @@ -88,6 +123,9 @@ public async ValueTask DisposeAsync() protected virtual async ValueTask DisposeAsyncCore() { - await _broker.DisposeAsync().ConfigureAwait(false); + if (_ownsConnection) + { + await BiDiConnection.DisposeAsync().ConfigureAwait(false); + } } } diff --git a/dotnet/src/webdriver/BiDi/Communication/Broker.cs b/dotnet/src/webdriver/BiDi/Communication/BiDiConnection.cs similarity index 72% rename from dotnet/src/webdriver/BiDi/Communication/Broker.cs rename to dotnet/src/webdriver/BiDi/Communication/BiDiConnection.cs index 2924b20fee2ed..4d9ebfd4ea2c6 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Broker.cs +++ b/dotnet/src/webdriver/BiDi/Communication/BiDiConnection.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 @@ -18,25 +18,24 @@ // using OpenQA.Selenium.BiDi.Communication.Json; -using OpenQA.Selenium.BiDi.Communication.Json.Converters; using OpenQA.Selenium.BiDi.Communication.Transport; using OpenQA.Selenium.Internal.Logging; using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text.Json; using System.Text.Json.Serialization; +using System.Text.Json.Serialization.Metadata; using System.Threading; using System.Threading.Tasks; namespace OpenQA.Selenium.BiDi.Communication; -public class Broker : IAsyncDisposable +public class BiDiConnection : IAsyncDisposable { - private readonly ILogger _logger = Log.GetLogger(); - - private readonly BiDi _bidi; + private readonly ILogger _logger = Log.GetLogger(); private readonly ITransport _transport; private readonly ConcurrentDictionary> _pendingCommands = new(); @@ -52,39 +51,42 @@ public class Broker : IAsyncDisposable private Task? _eventEmitterTask; private CancellationTokenSource? _receiveMessagesCancellationTokenSource; - private readonly BiDiJsonSerializerContext _jsonSerializerContext; + private readonly JsonSerializerOptions _jsonSerializerContext; + private readonly Lazy _sessionModule; + + internal Modules.Session.SessionModule SessionModule => _sessionModule.Value; - internal Broker(BiDi bidi, Uri url) + public BiDiConnection(Uri url) { - _bidi = bidi; _transport = new WebSocketTransport(url); + _jsonSerializerContext = BiDiConnectionJsonSerializerContext.CreateOptions(); + _sessionModule = new Lazy(() => new Modules.Session.SessionModule(this)); + } - var jsonSerializerOptions = new JsonSerializerOptions + [RequiresUnreferencedCode("Enables reflection-based JSON serialization. Use a source-generated JsonSerializerContext for AOT safety.")] + [RequiresDynamicCode("Enables reflection-based JSON serialization. Use a source-generated JsonSerializerContext for AOT safety.")] + public void EnableReflectionBasedJson() + { + if (_jsonSerializerContext.IsReadOnly) { - 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(_bidi), - new BrowserUserContextConverter(_bidi), - new InterceptConverter(_bidi), - new RequestConverter(_bidi), - new HandleConverter(_bidi), - new InternalIdConverter(_bidi), - new PreloadScriptConverter(_bidi), - new RealmConverter(_bidi), - - new BiDiDateTimeOffsetConverter(), - new JsonStringEnumConverter(JsonNamingPolicy.CamelCase), - } - }; + throw new InvalidOperationException("Cannot add JSON serializer context after ConnectAsync has been called"); + } + + _jsonSerializerContext.TypeInfoResolverChain.Add(new DefaultJsonTypeInfoResolver()); + } + + public void AddSerializerContextAndConverters(JsonSerializerContext context, IList? converters = null) + { + if (_jsonSerializerContext.IsReadOnly) + { + throw new InvalidOperationException("Cannot add JSON serializer context after ConnectAsync has been called"); + } - _jsonSerializerContext = new BiDiJsonSerializerContext(jsonSerializerOptions); + _jsonSerializerContext.TypeInfoResolverChain.Add(context); + foreach (JsonConverter converter in converters ?? []) + { + _jsonSerializerContext.Converters.Add(converter); + } } public async Task ConnectAsync(CancellationToken cancellationToken) @@ -102,7 +104,8 @@ private async Task ReceiveMessagesAsync(CancellationToken cancellationToken) { var data = await _transport.ReceiveAsync(cancellationToken).ConfigureAwait(false); - var message = JsonSerializer.Deserialize(new ReadOnlySpan(data), _jsonSerializerContext.Message); + var messageTypeInfo = (JsonTypeInfo)_jsonSerializerContext.GetTypeInfo(typeof(Message)); + var message = JsonSerializer.Deserialize(new ReadOnlySpan(data), messageTypeInfo); switch (message) { @@ -110,12 +113,22 @@ private async Task ReceiveMessagesAsync(CancellationToken cancellationToken) _pendingCommands[messageSuccess.Id].SetResult(messageSuccess.Result); _pendingCommands.TryRemove(messageSuccess.Id, out _); break; + case MessageEvent messageEvent: _pendingEvents.Add(messageEvent); break; - case MessageError mesageError: - _pendingCommands[mesageError.Id].SetException(new BiDiException($"{mesageError.Error}: {mesageError.Message}")); - _pendingCommands.TryRemove(mesageError.Id, out _); + + case MessageError messageError: + _pendingCommands[messageError.Id].SetException(new BiDiException($"{messageError.Error}: {messageError.Message}")); + _pendingCommands.TryRemove(messageError.Id, out _); + break; + + default: + if (_logger.IsEnabled(LogEventLevel.Warn)) + { + _logger.Warn($"Received invalid message type: {message}"); + } + break; } } @@ -135,7 +148,7 @@ private async Task ProcessEventsAwaiterAsync() { var args = (EventArgs)result.Params.Deserialize(handler.EventArgsType, _jsonSerializerContext)!; - args.BiDi = _bidi; + args.BiDi = this; // handle browsing context subscriber if (handler.Contexts is not null && args is BrowsingContextEventArgs browsingContextEventArgs && handler.Contexts.Contains(browsingContextEventArgs.Context)) @@ -204,7 +217,7 @@ public async Task SubscribeAsync(string eventName, Act if (options is BrowsingContextsSubscriptionOptions browsingContextsOptions) { - var subscribeResult = await _bidi.SessionModule.SubscribeAsync([eventName], new() { Contexts = browsingContextsOptions.Contexts }).ConfigureAwait(false); + var subscribeResult = await SessionModule.SubscribeAsync([eventName], new() { Contexts = browsingContextsOptions.Contexts }).ConfigureAwait(false); var eventHandler = new SyncEventHandler(eventName, action, browsingContextsOptions?.Contexts); @@ -214,7 +227,7 @@ public async Task SubscribeAsync(string eventName, Act } else { - var subscribeResult = await _bidi.SessionModule.SubscribeAsync([eventName]).ConfigureAwait(false); + var subscribeResult = await SessionModule.SubscribeAsync([eventName]).ConfigureAwait(false); var eventHandler = new SyncEventHandler(eventName, action); @@ -231,7 +244,7 @@ public async Task SubscribeAsync(string eventName, Fun if (options is BrowsingContextsSubscriptionOptions browsingContextsOptions) { - var subscribeResult = await _bidi.SessionModule.SubscribeAsync([eventName], new() { Contexts = browsingContextsOptions.Contexts }).ConfigureAwait(false); + var subscribeResult = await SessionModule.SubscribeAsync([eventName], new() { Contexts = browsingContextsOptions.Contexts }).ConfigureAwait(false); var eventHandler = new AsyncEventHandler(eventName, func, browsingContextsOptions.Contexts); @@ -241,7 +254,7 @@ public async Task SubscribeAsync(string eventName, Fun } else { - var subscribeResult = await _bidi.SessionModule.SubscribeAsync([eventName]).ConfigureAwait(false); + var subscribeResult = await SessionModule.SubscribeAsync([eventName]).ConfigureAwait(false); var eventHandler = new AsyncEventHandler(eventName, func); @@ -259,7 +272,7 @@ public async Task UnsubscribeAsync(Modules.Session.Subscription subscription, Ev if (subscription is not null) { - await _bidi.SessionModule.UnsubscribeAsync([subscription]).ConfigureAwait(false); + await SessionModule.UnsubscribeAsync([subscription]).ConfigureAwait(false); } else { @@ -267,14 +280,14 @@ public async Task UnsubscribeAsync(Modules.Session.Subscription subscription, Ev { if (!eventHandlers.Any(h => eventHandler.Contexts.Equals(h.Contexts)) && !eventHandlers.Any(h => h.Contexts is null)) { - await _bidi.SessionModule.UnsubscribeAsync([eventHandler.EventName], new() { Contexts = eventHandler.Contexts }).ConfigureAwait(false); + await SessionModule.UnsubscribeAsync([eventHandler.EventName], new() { Contexts = eventHandler.Contexts }).ConfigureAwait(false); } } else { if (!eventHandlers.Any(h => h.Contexts is not null) && !eventHandlers.Any(h => h.Contexts is null)) { - await _bidi.SessionModule.UnsubscribeAsync([eventHandler.EventName]).ConfigureAwait(false); + await SessionModule.UnsubscribeAsync([eventHandler.EventName]).ConfigureAwait(false); } } } diff --git a/dotnet/src/webdriver/BiDi/Communication/Json/BiDiConnectionJsonSerializerContext.cs b/dotnet/src/webdriver/BiDi/Communication/Json/BiDiConnectionJsonSerializerContext.cs new file mode 100644 index 0000000000000..b4b5e8275d2f3 --- /dev/null +++ b/dotnet/src/webdriver/BiDi/Communication/Json/BiDiConnectionJsonSerializerContext.cs @@ -0,0 +1,72 @@ +// +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +using System.Text.Json; +using System.Text.Json.Serialization; + +using OpenQA.Selenium.BiDi.Communication.Json.Converters; + +namespace OpenQA.Selenium.BiDi.Communication.Json; + +#region https://github.com/dotnet/runtime/issues/72604 +[JsonSerializable(typeof(MessageSuccess))] +[JsonSerializable(typeof(MessageError))] +[JsonSerializable(typeof(MessageEvent))] +#endregion + +[JsonSerializable(typeof(Message))] +[JsonSerializable(typeof(Command))] + +[JsonSerializable(typeof(EventArgs))] +[JsonSerializable(typeof(BrowsingContextEventArgs))] +[JsonSerializable(typeof(Modules.Session.StatusCommand))] +[JsonSerializable(typeof(Modules.Session.StatusResult))] +[JsonSerializable(typeof(Modules.Session.NewCommand))] +[JsonSerializable(typeof(Modules.Session.NewResult))] +[JsonSerializable(typeof(Modules.Session.EndCommand))] +[JsonSerializable(typeof(Modules.Session.SubscribeCommand))] +[JsonSerializable(typeof(Modules.Session.SubscribeResult))] +[JsonSerializable(typeof(Modules.Session.UnsubscribeByIdCommand))] +[JsonSerializable(typeof(Modules.Session.UnsubscribeByAttributesCommand))] + +internal partial class BiDiConnectionJsonSerializerContext : JsonSerializerContext +{ + public static JsonSerializerOptions CreateOptions() + { + 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 BiDiDateTimeOffsetConverter(), + new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) + }, + TypeInfoResolverChain = + { + Default + } + }; + } +} diff --git a/dotnet/src/webdriver/BiDi/Communication/Json/BiDiJsonSerializerContext.cs b/dotnet/src/webdriver/BiDi/Communication/Json/BiDiJsonSerializerContext.cs index 2749caf266f0a..6cce0e518834d 100644 --- a/dotnet/src/webdriver/BiDi/Communication/Json/BiDiJsonSerializerContext.cs +++ b/dotnet/src/webdriver/BiDi/Communication/Json/BiDiJsonSerializerContext.cs @@ -23,10 +23,6 @@ namespace OpenQA.Selenium.BiDi.Communication.Json; #region https://github.com/dotnet/runtime/issues/72604 -[JsonSerializable(typeof(MessageSuccess))] -[JsonSerializable(typeof(MessageError))] -[JsonSerializable(typeof(MessageEvent))] - [JsonSerializable(typeof(Modules.Script.EvaluateResult.Success))] [JsonSerializable(typeof(Modules.Script.EvaluateResult.Exception))] @@ -70,19 +66,6 @@ namespace OpenQA.Selenium.BiDi.Communication.Json; [JsonSerializable(typeof(Modules.Log.JavascriptLogEntry))] #endregion -[JsonSerializable(typeof(Command))] -[JsonSerializable(typeof(Message))] - -[JsonSerializable(typeof(Modules.Session.StatusCommand))] -[JsonSerializable(typeof(Modules.Session.StatusResult))] -[JsonSerializable(typeof(Modules.Session.NewCommand))] -[JsonSerializable(typeof(Modules.Session.NewResult))] -[JsonSerializable(typeof(Modules.Session.EndCommand))] -[JsonSerializable(typeof(Modules.Session.SubscribeCommand))] -[JsonSerializable(typeof(Modules.Session.SubscribeResult))] -[JsonSerializable(typeof(Modules.Session.UnsubscribeByIdCommand))] -[JsonSerializable(typeof(Modules.Session.UnsubscribeByAttributesCommand))] - [JsonSerializable(typeof(Modules.Browser.CloseCommand), TypeInfoPropertyName = "Browser_CloseCommand")] [JsonSerializable(typeof(Modules.Browser.CreateUserContextCommand))] [JsonSerializable(typeof(Modules.Browser.GetUserContextsCommand))] diff --git a/dotnet/src/webdriver/BiDi/EventArgs.cs b/dotnet/src/webdriver/BiDi/EventArgs.cs index 5bd9fc9a3ba98..793f348ce4c82 100644 --- a/dotnet/src/webdriver/BiDi/EventArgs.cs +++ b/dotnet/src/webdriver/BiDi/EventArgs.cs @@ -17,16 +17,17 @@ // under the License. // +using OpenQA.Selenium.BiDi.Communication; using OpenQA.Selenium.BiDi.Modules.BrowsingContext; using System.Text.Json.Serialization; namespace OpenQA.Selenium.BiDi; -public abstract record EventArgs(BiDi BiDi) +public abstract record EventArgs(BiDiConnection BiDi) { [JsonIgnore] - public BiDi BiDi { get; internal set; } = BiDi; + public BiDiConnection BiDi { get; internal set; } = BiDi; } -public abstract record BrowsingContextEventArgs(BiDi BiDi, BrowsingContext Context) +public abstract record BrowsingContextEventArgs([property: JsonIgnore] BiDiConnection BiDi, BrowsingContext Context) : EventArgs(BiDi); diff --git a/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionsJsonSerializerContext .cs b/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionsJsonSerializerContext .cs new file mode 100644 index 0000000000000..47dd75d4d592f --- /dev/null +++ b/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionsJsonSerializerContext .cs @@ -0,0 +1,26 @@ +// +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +using System.Text.Json.Serialization; + +namespace OpenQA.Selenium.BiDi.Extensions.Permissions; + + +[JsonSerializable(typeof(SetPermissionCommand), TypeInfoPropertyName = "Permissions_SetPermissionCommand")] +internal partial class PermissionsJsonSerializerContext : JsonSerializerContext; 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..55e963e27ac03 --- /dev/null +++ b/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionsModule.cs @@ -0,0 +1,42 @@ +// +// 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; +using OpenQA.Selenium.BiDi.Modules; +using OpenQA.Selenium.BiDi.Modules.Browser; +using System.Threading.Tasks; + +namespace OpenQA.Selenium.BiDi.Extensions.Permissions; + +public class PermissionsModule(BiDiConnection broker) : Module(broker) +{ + internal static ValueTask AttachAsync(BiDiConnection connection) + { + connection.AddSerializerContextAndConverters(PermissionsJsonSerializerContext.Default); + + return new ValueTask(new PermissionsModule(connection)); + } + + 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).ConfigureAwait(false); + } +} 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..2bff4df15220b --- /dev/null +++ b/dotnet/src/webdriver/BiDi/Extensions/Permissions/SetPermissionCommand.cs @@ -0,0 +1,39 @@ +// +// 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; +using OpenQA.Selenium.BiDi.Modules.Browser; + +namespace OpenQA.Selenium.BiDi.Extensions.Permissions; + +internal class SetPermissionCommand(SetPermissionCommandParameters @params) + : Command(@params, "permissions.setPermission"); + +public record SetPermissionOptions : CommandOptions; + +internal record SetPermissionCommandParameters(PermissionDescriptor Descriptor, PermissionState State, string Origin, UserContext? UserContext) : CommandParameters; + +internal record PermissionDescriptor(string Name); + +public enum PermissionState +{ + Granted, + Denied, + Prompt +} diff --git a/dotnet/src/webdriver/BiDi/Modules/Browser/BrowserModule.cs b/dotnet/src/webdriver/BiDi/Modules/Browser/BrowserModule.cs index 822fbe26ae33d..53c905b760fc2 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Browser/BrowserModule.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Browser/BrowserModule.cs @@ -23,7 +23,7 @@ namespace OpenQA.Selenium.BiDi.Modules.Browser; -public sealed class BrowserModule(Broker broker) : Module(broker) +public sealed class BrowserModule(BiDiConnection broker) : Module(broker) { public async Task CloseAsync(CloseOptions? options = null) { diff --git a/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/BrowsingContextInfo.cs b/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/BrowsingContextInfo.cs index 7b42bc9f677a0..98b3723cb7637 100644 --- a/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/BrowsingContextInfo.cs +++ b/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/BrowsingContextInfo.cs @@ -17,13 +17,14 @@ // under the License. // +using OpenQA.Selenium.BiDi.Communication; using System.Collections.Generic; using System.Text.Json.Serialization; namespace OpenQA.Selenium.BiDi.Modules.BrowsingContext; // TODO: Split it to separate class with just info and event args -public record BrowsingContextInfo(BiDi BiDi, IReadOnlyList Children, Browser.ClientWindow ClientWindow, BrowsingContext Context, BrowsingContext OriginalOpener, string Url, Browser.UserContext UserContext) +public record BrowsingContextInfo([property: JsonIgnore] BiDiConnection BiDi, IReadOnlyList Children, Browser.ClientWindow ClientWindow, BrowsingContext Context, BrowsingContext OriginalOpener, string Url, Browser.UserContext UserContext) : BrowsingContextEventArgs(BiDi, Context) { [JsonInclude] diff --git a/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/BrowsingContextModule.cs b/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/BrowsingContextModule.cs index 369325323bd11..ba003e2d35148 100644 --- a/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/BrowsingContextModule.cs +++ b/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/BrowsingContextModule.cs @@ -24,7 +24,7 @@ namespace OpenQA.Selenium.BiDi.Modules.BrowsingContext; -public class BrowsingContextModule(Broker broker) : Module(broker) +public class BrowsingContextModule(BiDiConnection broker) : Module(broker) { public async Task CreateAsync(ContextType type, CreateOptions? options = null) { diff --git a/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/NavigationInfo.cs b/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/NavigationInfo.cs index 544618e1f4abe..7fb662595e1b9 100644 --- a/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/NavigationInfo.cs +++ b/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/NavigationInfo.cs @@ -17,9 +17,11 @@ // under the License. // +using OpenQA.Selenium.BiDi.Communication; using System; +using System.Text.Json.Serialization; namespace OpenQA.Selenium.BiDi.Modules.BrowsingContext; -public record NavigationInfo(BiDi BiDi, BrowsingContext Context, Navigation Navigation, DateTimeOffset Timestamp, string Url) +public record NavigationInfo([property: JsonIgnore] BiDiConnection BiDi, BrowsingContext Context, Navigation Navigation, DateTimeOffset Timestamp, string Url) : BrowsingContextEventArgs(BiDi, Context); diff --git a/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/UserPromptClosedEventArgs.cs b/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/UserPromptClosedEventArgs.cs index cff09c3113b04..614b660c975fc 100644 --- a/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/UserPromptClosedEventArgs.cs +++ b/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/UserPromptClosedEventArgs.cs @@ -17,11 +17,12 @@ // under the License. // +using OpenQA.Selenium.BiDi.Communication; using System.Text.Json.Serialization; namespace OpenQA.Selenium.BiDi.Modules.BrowsingContext; -public record UserPromptClosedEventArgs(BiDi BiDi, BrowsingContext Context, bool Accepted) +public record UserPromptClosedEventArgs([property: JsonIgnore] BiDiConnection BiDi, BrowsingContext Context, bool Accepted) : BrowsingContextEventArgs(BiDi, Context) { [JsonInclude] diff --git a/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/UserPromptOpenedEventArgs.cs b/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/UserPromptOpenedEventArgs.cs index 2a748c34a3c9c..d078ce35a93e9 100644 --- a/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/UserPromptOpenedEventArgs.cs +++ b/dotnet/src/webdriver/BiDi/Modules/BrowsingContext/UserPromptOpenedEventArgs.cs @@ -17,11 +17,12 @@ // under the License. // +using OpenQA.Selenium.BiDi.Communication; using System.Text.Json.Serialization; namespace OpenQA.Selenium.BiDi.Modules.BrowsingContext; -public record UserPromptOpenedEventArgs(BiDi BiDi, BrowsingContext Context, Session.UserPromptHandlerType Handler, UserPromptType Type, string Message) +public record UserPromptOpenedEventArgs([property: JsonIgnore] BiDiConnection BiDi, BrowsingContext Context, Session.UserPromptHandlerType Handler, UserPromptType Type, string Message) : BrowsingContextEventArgs(BiDi, Context) { [JsonInclude] diff --git a/dotnet/src/webdriver/BiDi/Modules/Input/InputModule.cs b/dotnet/src/webdriver/BiDi/Modules/Input/InputModule.cs index d8ad18043ffc0..efd0344c8568e 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Input/InputModule.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Input/InputModule.cs @@ -23,7 +23,7 @@ namespace OpenQA.Selenium.BiDi.Modules.Input; -public sealed class InputModule(Broker broker) : Module(broker) +public sealed class InputModule(BiDiConnection broker) : Module(broker) { public async Task PerformActionsAsync(BrowsingContext.BrowsingContext context, IEnumerable actions, PerformActionsOptions? options = null) { diff --git a/dotnet/src/webdriver/BiDi/Modules/Log/LogEntry.cs b/dotnet/src/webdriver/BiDi/Modules/Log/LogEntry.cs index def8a2bf7723e..706f849119a6c 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Log/LogEntry.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Log/LogEntry.cs @@ -17,6 +17,7 @@ // under the License. // +using OpenQA.Selenium.BiDi.Communication; using OpenQA.Selenium.BiDi.Communication.Json.Converters.Polymorphic; using System; using System.Collections.Generic; @@ -30,16 +31,16 @@ namespace OpenQA.Selenium.BiDi.Modules.Log; //[JsonPolymorphic(TypeDiscriminatorPropertyName = "type")] //[JsonDerivedType(typeof(ConsoleLogEntry), "console")] //[JsonDerivedType(typeof(JavascriptLogEntry), "javascript")] -public abstract record LogEntry(BiDi BiDi, Level Level, Script.Source Source, string Text, DateTimeOffset Timestamp) +public abstract record LogEntry(BiDiConnection BiDi, Level Level, Script.Source Source, string Text, DateTimeOffset Timestamp) : EventArgs(BiDi) { public Script.StackTrace? StackTrace { get; set; } } -public record ConsoleLogEntry(BiDi BiDi, Level Level, Script.Source Source, string Text, DateTimeOffset Timestamp, string Method, IReadOnlyList Args) +public record ConsoleLogEntry(BiDiConnection BiDi, Level Level, Script.Source Source, string Text, DateTimeOffset Timestamp, string Method, IReadOnlyList Args) : LogEntry(BiDi, Level, Source, Text, Timestamp); -public record JavascriptLogEntry(BiDi BiDi, Level Level, Script.Source Source, string Text, DateTimeOffset Timestamp) +public record JavascriptLogEntry(BiDiConnection BiDi, Level Level, Script.Source Source, string Text, DateTimeOffset Timestamp) : LogEntry(BiDi, Level, Source, Text, Timestamp); public enum Level diff --git a/dotnet/src/webdriver/BiDi/Modules/Log/LogModule.cs b/dotnet/src/webdriver/BiDi/Modules/Log/LogModule.cs index f1442ee1ee358..47587663669af 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Log/LogModule.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Log/LogModule.cs @@ -23,7 +23,7 @@ namespace OpenQA.Selenium.BiDi.Modules.Log; -public sealed class LogModule(Broker broker) : Module(broker) +public sealed class LogModule(BiDiConnection broker) : Module(broker) { public async Task OnEntryAddedAsync(Func handler, SubscriptionOptions? options = null) { diff --git a/dotnet/src/webdriver/BiDi/Modules/Module.cs b/dotnet/src/webdriver/BiDi/Modules/Module.cs index a24fea89f2f25..63dc3fef602b6 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Module.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Module.cs @@ -18,10 +18,11 @@ // using OpenQA.Selenium.BiDi.Communication; +using System; namespace OpenQA.Selenium.BiDi.Modules; -public abstract class Module(Broker broker) +public abstract class Module(BiDiConnection broker) { - protected Broker Broker { get; } = broker; + protected BiDiConnection Broker { get; } = broker ?? throw new ArgumentNullException(nameof(broker)); } diff --git a/dotnet/src/webdriver/BiDi/Modules/Network/AuthRequiredEventArgs.cs b/dotnet/src/webdriver/BiDi/Modules/Network/AuthRequiredEventArgs.cs index ed2f461a17723..4bdad0ba2e66e 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Network/AuthRequiredEventArgs.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Network/AuthRequiredEventArgs.cs @@ -17,9 +17,11 @@ // under the License. // +using OpenQA.Selenium.BiDi.Communication; using System; +using System.Text.Json.Serialization; namespace OpenQA.Selenium.BiDi.Modules.Network; -public record AuthRequiredEventArgs(BiDi BiDi, BrowsingContext.BrowsingContext Context, bool IsBlocked, BrowsingContext.Navigation Navigation, long RedirectCount, RequestData Request, DateTimeOffset Timestamp, ResponseData Response) : +public record AuthRequiredEventArgs([property: JsonIgnore] BiDiConnection BiDi, BrowsingContext.BrowsingContext Context, bool IsBlocked, BrowsingContext.Navigation Navigation, long RedirectCount, RequestData Request, DateTimeOffset Timestamp, ResponseData Response) : BaseParametersEventArgs(BiDi, Context, IsBlocked, Navigation, RedirectCount, Request, Timestamp); diff --git a/dotnet/src/webdriver/BiDi/Modules/Network/BaseParametersEventArgs.cs b/dotnet/src/webdriver/BiDi/Modules/Network/BaseParametersEventArgs.cs index 58cf915a20e82..d2ec8846284d4 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Network/BaseParametersEventArgs.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Network/BaseParametersEventArgs.cs @@ -20,10 +20,11 @@ using System.Collections.Generic; using System.Text.Json.Serialization; using System; +using OpenQA.Selenium.BiDi.Communication; namespace OpenQA.Selenium.BiDi.Modules.Network; -public abstract record BaseParametersEventArgs(BiDi BiDi, BrowsingContext.BrowsingContext Context, bool IsBlocked, BrowsingContext.Navigation Navigation, long RedirectCount, RequestData Request, DateTimeOffset Timestamp) +public abstract record BaseParametersEventArgs([property: JsonIgnore] BiDiConnection BiDi, BrowsingContext.BrowsingContext Context, bool IsBlocked, BrowsingContext.Navigation Navigation, long RedirectCount, RequestData Request, DateTimeOffset Timestamp) : BrowsingContextEventArgs(BiDi, Context) { [JsonInclude] diff --git a/dotnet/src/webdriver/BiDi/Modules/Network/BeforeRequestSentEventArgs.cs b/dotnet/src/webdriver/BiDi/Modules/Network/BeforeRequestSentEventArgs.cs index 5315777c798e9..8f1f2284ce46d 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Network/BeforeRequestSentEventArgs.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Network/BeforeRequestSentEventArgs.cs @@ -17,10 +17,12 @@ // under the License. // +using OpenQA.Selenium.BiDi.Communication; using OpenQA.Selenium.BiDi.Modules.BrowsingContext; using System; +using System.Text.Json.Serialization; namespace OpenQA.Selenium.BiDi.Modules.Network; -public record BeforeRequestSentEventArgs(BiDi BiDi, BrowsingContext.BrowsingContext Context, bool IsBlocked, Navigation Navigation, long RedirectCount, RequestData Request, DateTimeOffset Timestamp, Initiator Initiator) +public record BeforeRequestSentEventArgs([property: JsonIgnore] BiDiConnection BiDi, BrowsingContext.BrowsingContext Context, bool IsBlocked, Navigation Navigation, long RedirectCount, RequestData Request, DateTimeOffset Timestamp, Initiator Initiator) : BaseParametersEventArgs(BiDi, Context, IsBlocked, Navigation, RedirectCount, Request, Timestamp); diff --git a/dotnet/src/webdriver/BiDi/Modules/Network/FetchErrorEventArgs.cs b/dotnet/src/webdriver/BiDi/Modules/Network/FetchErrorEventArgs.cs index 4a4b5b320ba4b..9fcccc42a8b94 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Network/FetchErrorEventArgs.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Network/FetchErrorEventArgs.cs @@ -17,10 +17,12 @@ // under the License. // +using OpenQA.Selenium.BiDi.Communication; using OpenQA.Selenium.BiDi.Modules.BrowsingContext; using System; +using System.Text.Json.Serialization; namespace OpenQA.Selenium.BiDi.Modules.Network; -public record FetchErrorEventArgs(BiDi BiDi, BrowsingContext.BrowsingContext Context, bool IsBlocked, Navigation Navigation, long RedirectCount, RequestData Request, DateTimeOffset Timestamp, string ErrorText) +public record FetchErrorEventArgs([property: JsonIgnore] BiDiConnection BiDi, BrowsingContext.BrowsingContext Context, bool IsBlocked, Navigation Navigation, long RedirectCount, RequestData Request, DateTimeOffset Timestamp, string ErrorText) : BaseParametersEventArgs(BiDi, Context, IsBlocked, Navigation, RedirectCount, Request, Timestamp); diff --git a/dotnet/src/webdriver/BiDi/Modules/Network/NetworkModule.cs b/dotnet/src/webdriver/BiDi/Modules/Network/NetworkModule.cs index fb279ef947b9e..fd5124401f600 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Network/NetworkModule.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Network/NetworkModule.cs @@ -24,7 +24,7 @@ namespace OpenQA.Selenium.BiDi.Modules.Network; -public sealed class NetworkModule(Broker broker) : Module(broker) +public sealed class NetworkModule(BiDiConnection broker) : Module(broker) { internal async Task AddInterceptAsync(IEnumerable phases, AddInterceptOptions? options = null) { diff --git a/dotnet/src/webdriver/BiDi/Modules/Network/ResponseCompletedEventArgs.cs b/dotnet/src/webdriver/BiDi/Modules/Network/ResponseCompletedEventArgs.cs index ff03768ee183d..e49e55d454e78 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Network/ResponseCompletedEventArgs.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Network/ResponseCompletedEventArgs.cs @@ -17,10 +17,12 @@ // under the License. // +using OpenQA.Selenium.BiDi.Communication; using OpenQA.Selenium.BiDi.Modules.BrowsingContext; using System; +using System.Text.Json.Serialization; namespace OpenQA.Selenium.BiDi.Modules.Network; -public record ResponseCompletedEventArgs(BiDi BiDi, BrowsingContext.BrowsingContext Context, bool IsBlocked, Navigation Navigation, long RedirectCount, RequestData Request, DateTimeOffset Timestamp, ResponseData Response) +public record ResponseCompletedEventArgs([property: JsonIgnore] BiDiConnection BiDi, BrowsingContext.BrowsingContext Context, bool IsBlocked, Navigation Navigation, long RedirectCount, RequestData Request, DateTimeOffset Timestamp, ResponseData Response) : BaseParametersEventArgs(BiDi, Context, IsBlocked, Navigation, RedirectCount, Request, Timestamp); diff --git a/dotnet/src/webdriver/BiDi/Modules/Network/ResponseStartedEventArgs.cs b/dotnet/src/webdriver/BiDi/Modules/Network/ResponseStartedEventArgs.cs index 39d74946e56c2..84b3e5d4fdb6e 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Network/ResponseStartedEventArgs.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Network/ResponseStartedEventArgs.cs @@ -17,10 +17,12 @@ // under the License. // +using OpenQA.Selenium.BiDi.Communication; using OpenQA.Selenium.BiDi.Modules.BrowsingContext; using System; +using System.Text.Json.Serialization; namespace OpenQA.Selenium.BiDi.Modules.Network; -public record ResponseStartedEventArgs(BiDi BiDi, BrowsingContext.BrowsingContext Context, bool IsBlocked, Navigation Navigation, long RedirectCount, RequestData Request, DateTimeOffset Timestamp, ResponseData Response) +public record ResponseStartedEventArgs([property: JsonIgnore] BiDiConnection BiDi, BrowsingContext.BrowsingContext Context, bool IsBlocked, Navigation Navigation, long RedirectCount, RequestData Request, DateTimeOffset Timestamp, ResponseData Response) : BaseParametersEventArgs(BiDi, Context, IsBlocked, Navigation, RedirectCount, Request, Timestamp); diff --git a/dotnet/src/webdriver/BiDi/Modules/Script/MessageEventArgs.cs b/dotnet/src/webdriver/BiDi/Modules/Script/MessageEventArgs.cs index 11743c2ddd316..a08ccaeae0edd 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Script/MessageEventArgs.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Script/MessageEventArgs.cs @@ -17,6 +17,9 @@ // under the License. // +using System.Text.Json.Serialization; +using OpenQA.Selenium.BiDi.Communication; + namespace OpenQA.Selenium.BiDi.Modules.Script; -public record MessageEventArgs(BiDi BiDi, Channel Channel, RemoteValue Data, Source Source) : EventArgs(BiDi); +public record MessageEventArgs([property: JsonIgnore] BiDiConnection BiDi, Channel Channel, RemoteValue Data, Source Source) : EventArgs(BiDi); diff --git a/dotnet/src/webdriver/BiDi/Modules/Script/RealmDestroyedEventArgs.cs b/dotnet/src/webdriver/BiDi/Modules/Script/RealmDestroyedEventArgs.cs index 5c5c9434b0e76..2c61a742a00bc 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Script/RealmDestroyedEventArgs.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Script/RealmDestroyedEventArgs.cs @@ -17,6 +17,9 @@ // under the License. // +using OpenQA.Selenium.BiDi.Communication; +using System.Text.Json.Serialization; + namespace OpenQA.Selenium.BiDi.Modules.Script; -public record RealmDestroyedEventArgs(BiDi BiDi, Realm Realm) : EventArgs(BiDi); +public record RealmDestroyedEventArgs([property: JsonIgnore] BiDiConnection BiDi, Realm Realm) : EventArgs(BiDi); diff --git a/dotnet/src/webdriver/BiDi/Modules/Script/RealmInfo.cs b/dotnet/src/webdriver/BiDi/Modules/Script/RealmInfo.cs index fe12ef4617cd0..201272443a888 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Script/RealmInfo.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Script/RealmInfo.cs @@ -17,6 +17,7 @@ // under the License. // +using OpenQA.Selenium.BiDi.Communication; using OpenQA.Selenium.BiDi.Communication.Json.Converters.Polymorphic; using System.Collections.Generic; using System.Text.Json.Serialization; @@ -35,23 +36,23 @@ namespace OpenQA.Selenium.BiDi.Modules.Script; //[JsonDerivedType(typeof(PaintWorkletRealmInfo), "paint-worklet")] //[JsonDerivedType(typeof(AudioWorkletRealmInfo), "audio-worklet")] //[JsonDerivedType(typeof(WorkletRealmInfo), "worklet")] -public abstract record RealmInfo(BiDi BiDi, Realm Realm, string Origin) : EventArgs(BiDi); +public abstract record RealmInfo(BiDiConnection BiDi, Realm Realm, string Origin) : EventArgs(BiDi); -public record WindowRealmInfo(BiDi BiDi, Realm Realm, string Origin, BrowsingContext.BrowsingContext Context) : RealmInfo(BiDi, Realm, Origin) +public record WindowRealmInfo(BiDiConnection BiDi, Realm Realm, string Origin, BrowsingContext.BrowsingContext Context) : RealmInfo(BiDi, Realm, Origin) { public string? Sandbox { get; set; } } -public record DedicatedWorkerRealmInfo(BiDi BiDi, Realm Realm, string Origin, IReadOnlyList Owners) : RealmInfo(BiDi, Realm, Origin); +public record DedicatedWorkerRealmInfo(BiDiConnection BiDi, Realm Realm, string Origin, IReadOnlyList Owners) : RealmInfo(BiDi, Realm, Origin); -public record SharedWorkerRealmInfo(BiDi BiDi, Realm Realm, string Origin) : RealmInfo(BiDi, Realm, Origin); +public record SharedWorkerRealmInfo(BiDiConnection BiDi, Realm Realm, string Origin) : RealmInfo(BiDi, Realm, Origin); -public record ServiceWorkerRealmInfo(BiDi BiDi, Realm Realm, string Origin) : RealmInfo(BiDi, Realm, Origin); +public record ServiceWorkerRealmInfo(BiDiConnection BiDi, Realm Realm, string Origin) : RealmInfo(BiDi, Realm, Origin); -public record WorkerRealmInfo(BiDi BiDi, Realm Realm, string Origin) : RealmInfo(BiDi, Realm, Origin); +public record WorkerRealmInfo(BiDiConnection BiDi, Realm Realm, string Origin) : RealmInfo(BiDi, Realm, Origin); -public record PaintWorkletRealmInfo(BiDi BiDi, Realm Realm, string Origin) : RealmInfo(BiDi, Realm, Origin); +public record PaintWorkletRealmInfo(BiDiConnection BiDi, Realm Realm, string Origin) : RealmInfo(BiDi, Realm, Origin); -public record AudioWorkletRealmInfo(BiDi BiDi, Realm Realm, string Origin) : RealmInfo(BiDi, Realm, Origin); +public record AudioWorkletRealmInfo(BiDiConnection BiDi, Realm Realm, string Origin) : RealmInfo(BiDi, Realm, Origin); -public record WorkletRealmInfo(BiDi BiDi, Realm Realm, string Origin) : RealmInfo(BiDi, Realm, Origin); +public record WorkletRealmInfo(BiDiConnection BiDi, Realm Realm, string Origin) : RealmInfo(BiDi, Realm, Origin); diff --git a/dotnet/src/webdriver/BiDi/Modules/Script/ScriptModule.cs b/dotnet/src/webdriver/BiDi/Modules/Script/ScriptModule.cs index bb6a9f1a18021..e04c42a6ba4d5 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Script/ScriptModule.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Script/ScriptModule.cs @@ -23,7 +23,7 @@ namespace OpenQA.Selenium.BiDi.Modules.Script; -public sealed class ScriptModule(Broker broker) : Module(broker) +public sealed class ScriptModule(BiDiConnection broker) : Module(broker) { public async Task EvaluateAsync(string expression, bool awaitPromise, Target target, EvaluateOptions? options = null) { diff --git a/dotnet/src/webdriver/BiDi/Modules/Session/SessionModule.cs b/dotnet/src/webdriver/BiDi/Modules/Session/SessionModule.cs index e3572966b6833..c709b4ec98c3e 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Session/SessionModule.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Session/SessionModule.cs @@ -23,7 +23,7 @@ namespace OpenQA.Selenium.BiDi.Modules.Session; -internal sealed class SessionModule(Broker broker) : Module(broker) +internal sealed class SessionModule(BiDiConnection broker) : Module(broker) { public async Task StatusAsync(StatusOptions? options = null) { diff --git a/dotnet/src/webdriver/BiDi/Modules/Storage/StorageModule.cs b/dotnet/src/webdriver/BiDi/Modules/Storage/StorageModule.cs index 6acf132dcf018..495c59eebeab1 100644 --- a/dotnet/src/webdriver/BiDi/Modules/Storage/StorageModule.cs +++ b/dotnet/src/webdriver/BiDi/Modules/Storage/StorageModule.cs @@ -22,7 +22,7 @@ namespace OpenQA.Selenium.BiDi.Modules.Storage; -public class StorageModule(Broker broker) : Module(broker) +public class StorageModule(BiDiConnection broker) : Module(broker) { public async Task GetCookiesAsync(GetCookiesOptions? options = null) { diff --git a/dotnet/src/webdriver/BiDi/Subscription.cs b/dotnet/src/webdriver/BiDi/Subscription.cs index 59ecb9b74ae60..abd5364ad4a58 100644 --- a/dotnet/src/webdriver/BiDi/Subscription.cs +++ b/dotnet/src/webdriver/BiDi/Subscription.cs @@ -27,10 +27,10 @@ namespace OpenQA.Selenium.BiDi; public class Subscription : IAsyncDisposable { private readonly Modules.Session.Subscription _subscription; - private readonly Broker _broker; + private readonly BiDiConnection _broker; private readonly Communication.EventHandler _eventHandler; - internal Subscription(Modules.Session.Subscription subscription, Broker broker, Communication.EventHandler eventHandler) + internal Subscription(Modules.Session.Subscription subscription, BiDiConnection broker, Communication.EventHandler eventHandler) { _subscription = subscription; _broker = broker; diff --git a/dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs b/dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs index ee494f877957c..602d30e7bfb28 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.Communication; using System; using System.Threading.Tasks; @@ -26,7 +27,26 @@ public static class WebDriverExtensions { public static async Task AsBiDiAsync(this IWebDriver webDriver) { - if (webDriver is null) throw new ArgumentNullException(nameof(webDriver)); + string webSocketUrl = GetWebSocketUrl(webDriver); + var bidi = await BiDi.ConnectAsync(webSocketUrl).ConfigureAwait(false); + + return bidi; + } + + public static Task AsBiDiConnectionAsync(this IWebDriver webDriver) + { + string webSocketUrl = GetWebSocketUrl(webDriver); + var connection = new BiDiConnection(new Uri(webSocketUrl)); + + return Task.FromResult(connection); + } + + private static string GetWebSocketUrl(IWebDriver webDriver) + { + if (webDriver is null) + { + throw new ArgumentNullException(nameof(webDriver)); + } string? webSocketUrl = null; @@ -35,10 +55,6 @@ public static async Task AsBiDiAsync(this IWebDriver webDriver) webSocketUrl = hasCapabilities.Capabilities.GetCapability("webSocketUrl")?.ToString(); } - if (webSocketUrl is null) throw new BiDiException("The driver is not compatible with bidirectional protocol or \"webSocketUrl\" not enabled in driver options."); - - var bidi = await BiDi.ConnectAsync(webSocketUrl).ConfigureAwait(false); - - return bidi; + return webSocketUrl ?? throw new BiDiException("The driver is not compatible with bidirectional protocol or \"webSocketUrl\" not enabled in driver options."); ; } } diff --git a/dotnet/test/common/BiDi/BiDiFixture.cs b/dotnet/test/common/BiDi/BiDiFixture.cs index d81501a3df668..68de58ebfb657 100644 --- a/dotnet/test/common/BiDi/BiDiFixture.cs +++ b/dotnet/test/common/BiDi/BiDiFixture.cs @@ -44,11 +44,16 @@ public async Task BiDiSetUp() driver = EnvironmentManager.Instance.CreateDriverInstance(options); - bidi = await driver.AsBiDiAsync(); + bidi = await CreateBiDi(driver); context = (await bidi.BrowsingContext.GetTreeAsync())[0].Context; } + protected virtual async Task CreateBiDi(IWebDriver driver) + { + return await driver.AsBiDiAsync(); + } + [TearDown] public async Task BiDiTearDown() { diff --git a/dotnet/test/common/BiDi/Permissions/PermissionsTests.cs b/dotnet/test/common/BiDi/Permissions/PermissionsTests.cs new file mode 100644 index 0000000000000..696f18f55c696 --- /dev/null +++ b/dotnet/test/common/BiDi/Permissions/PermissionsTests.cs @@ -0,0 +1,64 @@ +using NUnit.Framework; +using OpenQA.Selenium.BiDi.Extensions.Permissions; +using OpenQA.Selenium.BiDi.Modules.BrowsingContext; +using OpenQA.Selenium.BiDi.Modules.Script; +using OpenQA.Selenium.Environment; +using System.Threading.Tasks; + +namespace OpenQA.Selenium.BiDi.Permissions +{ + internal class PermissionsTests : BiDiTestFixture + { + private PermissionsModule _permissions; + private Communication.BiDiConnection _connection; + + protected override async Task CreateBiDi(IWebDriver driver) + { + _connection = await driver.AsBiDiConnectionAsync(); + _permissions = await PermissionsModule.AttachAsync(_connection); + var bidi = await BiDi.AttachAsync(_connection); + await _connection.ConnectAsync(default); + return bidi; + } + + [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 + }); + + 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.Result, Is.EqualTo(new StringRemoteValue("prompt"))); + + 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.Result, Is.EqualTo(new StringRemoteValue("denied"))); + } + + [TearDown] + public async Task TearDown() + { + if (_connection is not null) + { + await _connection.DisposeAsync(); + } + } + } +} From 1f8c435021c4a1cf9988a330ef8045706db0f35a Mon Sep 17 00:00:00 2001 From: Michael Render Date: Sat, 22 Mar 2025 01:26:38 -0400 Subject: [PATCH 08/13] Remove local typo fix --- dotnet/src/webdriver/BiDi/Communication/BiDiConnection.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dotnet/src/webdriver/BiDi/Communication/BiDiConnection.cs b/dotnet/src/webdriver/BiDi/Communication/BiDiConnection.cs index 4d9ebfd4ea2c6..f6cd32a4d4bca 100644 --- a/dotnet/src/webdriver/BiDi/Communication/BiDiConnection.cs +++ b/dotnet/src/webdriver/BiDi/Communication/BiDiConnection.cs @@ -118,9 +118,9 @@ private async Task ReceiveMessagesAsync(CancellationToken cancellationToken) _pendingEvents.Add(messageEvent); break; - case MessageError messageError: - _pendingCommands[messageError.Id].SetException(new BiDiException($"{messageError.Error}: {messageError.Message}")); - _pendingCommands.TryRemove(messageError.Id, out _); + case MessageError mesageError: + _pendingCommands[mesageError.Id].SetException(new BiDiException($"{mesageError.Error}: {mesageError.Message}")); + _pendingCommands.TryRemove(mesageError.Id, out _); break; default: From c604f3ce27f799ac70e225083c45932aa5ab0bb3 Mon Sep 17 00:00:00 2001 From: Michael Render Date: Sat, 22 Mar 2025 01:28:55 -0400 Subject: [PATCH 09/13] reorder methods --- .../BiDi/Permissions/PermissionsTests.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/dotnet/test/common/BiDi/Permissions/PermissionsTests.cs b/dotnet/test/common/BiDi/Permissions/PermissionsTests.cs index 696f18f55c696..fece6bf8a66f7 100644 --- a/dotnet/test/common/BiDi/Permissions/PermissionsTests.cs +++ b/dotnet/test/common/BiDi/Permissions/PermissionsTests.cs @@ -21,6 +21,15 @@ protected override async Task CreateBiDi(IWebDriver driver) return bidi; } + [TearDown] + public async Task TearDown() + { + if (_connection is not null) + { + await _connection.DisposeAsync(); + } + } + [Test] public async Task SettingPermissionsTest() { @@ -51,14 +60,5 @@ public async Task SettingPermissionsTest() Assert.That(after.Result, Is.EqualTo(new StringRemoteValue("denied"))); } - - [TearDown] - public async Task TearDown() - { - if (_connection is not null) - { - await _connection.DisposeAsync(); - } - } } } From 12c655356f6141d1aa566be23fecd6e6edcf9534 Mon Sep 17 00:00:00 2001 From: Michael Render Date: Sat, 22 Mar 2025 01:41:12 -0400 Subject: [PATCH 10/13] Remove space from file name --- ...erializerContext .cs => PermissionsJsonSerializerContext.cs} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename dotnet/src/webdriver/BiDi/Extensions/Permissions/{PermissionsJsonSerializerContext .cs => PermissionsJsonSerializerContext.cs} (92%) diff --git a/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionsJsonSerializerContext .cs b/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionsJsonSerializerContext.cs similarity index 92% rename from dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionsJsonSerializerContext .cs rename to dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionsJsonSerializerContext.cs index 47dd75d4d592f..9b8bb9ddef94d 100644 --- a/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionsJsonSerializerContext .cs +++ b/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionsJsonSerializerContext.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 From 809411eb5ab0d6ddf4a7085edea507322ce5a409 Mon Sep 17 00:00:00 2001 From: Michael Render Date: Sat, 22 Mar 2025 02:12:12 -0400 Subject: [PATCH 11/13] Fix formatting --- .../BiDi/Permissions/PermissionsTests.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/dotnet/test/common/BiDi/Permissions/PermissionsTests.cs b/dotnet/test/common/BiDi/Permissions/PermissionsTests.cs index fece6bf8a66f7..e4a3e7fa993b8 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.Extensions.Permissions; using OpenQA.Selenium.BiDi.Modules.BrowsingContext; From 4a8d5bdeb46b8fcfe26f12f9dbdf839c9f96cf58 Mon Sep 17 00:00:00 2001 From: Michael Render Date: Sat, 22 Mar 2025 14:43:51 -0400 Subject: [PATCH 12/13] Add disposeConnection --- dotnet/src/webdriver/BiDi/BiDi.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dotnet/src/webdriver/BiDi/BiDi.cs b/dotnet/src/webdriver/BiDi/BiDi.cs index c5636aaa7a6ef..918604252833e 100644 --- a/dotnet/src/webdriver/BiDi/BiDi.cs +++ b/dotnet/src/webdriver/BiDi/BiDi.cs @@ -38,9 +38,9 @@ public class BiDi : IAsyncDisposable private readonly Lazy _logModule; private readonly Lazy _storageModule; - private BiDi(BiDiConnection connection) : this() + private BiDi(BiDiConnection connection, bool disposeConnection) : this() { - _ownsConnection = false; + _ownsConnection = disposeConnection; BiDiConnection = connection; AddBiDiModuleJsonInfo(connection); } @@ -103,9 +103,9 @@ public static async Task ConnectAsync(string url) return bidi; } - public static ValueTask AttachAsync(BiDiConnection connection) + public static ValueTask AttachAsync(BiDiConnection connection, bool disposeConnection = false) { - var bidi = new BiDi(connection); + var bidi = new BiDi(connection, disposeConnection); return new ValueTask(bidi); } From 71f2ec9184c0a6e07f8428693b16288adb44c2ae Mon Sep 17 00:00:00 2001 From: Michael Render Date: Sun, 23 Mar 2025 13:12:01 -0400 Subject: [PATCH 13/13] Add `BiDiBuilder` and necessary BiDi APIs --- dotnet/src/webdriver/BiDi/BiDi.cs | 18 ++---- .../BiDi/Communication/BiDiBuilder.cs | 58 +++++++++++++++++++ .../Permissions/PermissionsModule.cs | 4 +- .../webdriver/BiDi/WebDriver.Extensions.cs | 6 ++ .../BiDi/Permissions/PermissionsTests.cs | 19 ++---- 5 files changed, 75 insertions(+), 30 deletions(-) create mode 100644 dotnet/src/webdriver/BiDi/Communication/BiDiBuilder.cs diff --git a/dotnet/src/webdriver/BiDi/BiDi.cs b/dotnet/src/webdriver/BiDi/BiDi.cs index 918604252833e..0df53af3dce40 100644 --- a/dotnet/src/webdriver/BiDi/BiDi.cs +++ b/dotnet/src/webdriver/BiDi/BiDi.cs @@ -38,20 +38,13 @@ public class BiDi : IAsyncDisposable private readonly Lazy _logModule; private readonly Lazy _storageModule; - private BiDi(BiDiConnection connection, bool disposeConnection) : this() + protected BiDi(BiDiConnection connection, bool disposeConnection) : this() { _ownsConnection = disposeConnection; BiDiConnection = connection; AddBiDiModuleJsonInfo(connection); } - private BiDi(string url) : this() - { - _ownsConnection = true; - BiDiConnection = new BiDiConnection(new Uri(url)); - AddBiDiModuleJsonInfo(BiDiConnection); - } - private BiDi() { _browsingContextModule = new Lazy(() => new Modules.BrowsingContext.BrowsingContextModule(BiDiConnection)); @@ -96,18 +89,17 @@ private BiDiConnection AddBiDiModuleJsonInfo(BiDiConnection connection) public static async Task ConnectAsync(string url) { - var bidi = new BiDi(url); + var connection = new BiDiConnection(new Uri(url)); + var bidi = new BiDi(connection, disposeConnection: true); await bidi.BiDiConnection.ConnectAsync(default).ConfigureAwait(false); return bidi; } - public static ValueTask AttachAsync(BiDiConnection connection, bool disposeConnection = false) + public static BiDi Attach(BiDiConnection connection, bool disposeConnection = false) { - var bidi = new BiDi(connection, disposeConnection); - - return new ValueTask(bidi); + return new BiDi(connection, disposeConnection); } public Task EndAsync(Modules.Session.EndOptions? options = null) diff --git a/dotnet/src/webdriver/BiDi/Communication/BiDiBuilder.cs b/dotnet/src/webdriver/BiDi/Communication/BiDiBuilder.cs new file mode 100644 index 0000000000000..9e07f5533274a --- /dev/null +++ b/dotnet/src/webdriver/BiDi/Communication/BiDiBuilder.cs @@ -0,0 +1,58 @@ +// +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace OpenQA.Selenium.BiDi.Communication; + +public class BiDiBuilder +{ + private readonly BiDiConnection _connection; + private readonly BiDi _coreBidi; + public List Extensions { get; } = []; + + public BiDiBuilder(string url) : this(new Uri(url)) + { + } + + public BiDiBuilder(Uri url) + { + _connection = new BiDiConnection(url); + _coreBidi = BiDi.Attach(_connection, disposeConnection: true); + } + + public BiDiBuilder AddExtension(Func addModuleFactory, out TModule module) + where TModule : Modules.Module + { + var newModule = addModuleFactory(_connection); + Extensions.Add(newModule); + module = newModule; + + return this; + } + + public async Task BuildAsync() + { + await _connection.ConnectAsync(default); + + return _coreBidi; + } +} diff --git a/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionsModule.cs b/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionsModule.cs index 55e963e27ac03..272e70d82961c 100644 --- a/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionsModule.cs +++ b/dotnet/src/webdriver/BiDi/Extensions/Permissions/PermissionsModule.cs @@ -26,11 +26,11 @@ namespace OpenQA.Selenium.BiDi.Extensions.Permissions; public class PermissionsModule(BiDiConnection broker) : Module(broker) { - internal static ValueTask AttachAsync(BiDiConnection connection) + public static PermissionsModule Attach(BiDiConnection connection) { connection.AddSerializerContextAndConverters(PermissionsJsonSerializerContext.Default); - return new ValueTask(new PermissionsModule(connection)); + return new PermissionsModule(connection); } public async Task SetPermissionAsync(string permissionName, PermissionState state, string origin, UserContext? userContext, SetPermissionOptions? options = null) diff --git a/dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs b/dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs index 602d30e7bfb28..daa86cdffb28c 100644 --- a/dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs +++ b/dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs @@ -41,6 +41,12 @@ public static Task AsBiDiConnectionAsync(this IWebDriver webDriv return Task.FromResult(connection); } + public static BiDiBuilder AsBiDiBuilder(this IWebDriver webDriver) + { + string webSocketUrl = GetWebSocketUrl(webDriver); + return new BiDiBuilder(webSocketUrl); + } + private static string GetWebSocketUrl(IWebDriver webDriver) { if (webDriver is null) diff --git a/dotnet/test/common/BiDi/Permissions/PermissionsTests.cs b/dotnet/test/common/BiDi/Permissions/PermissionsTests.cs index e4a3e7fa993b8..38c1529cc4015 100644 --- a/dotnet/test/common/BiDi/Permissions/PermissionsTests.cs +++ b/dotnet/test/common/BiDi/Permissions/PermissionsTests.cs @@ -29,24 +29,13 @@ namespace OpenQA.Selenium.BiDi.Permissions internal class PermissionsTests : BiDiTestFixture { private PermissionsModule _permissions; - private Communication.BiDiConnection _connection; protected override async Task CreateBiDi(IWebDriver driver) { - _connection = await driver.AsBiDiConnectionAsync(); - _permissions = await PermissionsModule.AttachAsync(_connection); - var bidi = await BiDi.AttachAsync(_connection); - await _connection.ConnectAsync(default); - return bidi; - } - - [TearDown] - public async Task TearDown() - { - if (_connection is not null) - { - await _connection.DisposeAsync(); - } + return await driver + .AsBiDiBuilder() + .AddExtension(PermissionsModule.Attach, out _permissions) + .BuildAsync(); } [Test]