Skip to content

Commit 69eff0d

Browse files
Merge branch 'trunk' into fix-numbercoercer-overflow
2 parents adc1f7e + 8a4e7cf commit 69eff0d

96 files changed

Lines changed: 1796 additions & 435 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

common/repositories.bzl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ js_library(
5050

5151
http_archive(
5252
name = "linux_beta_firefox",
53-
url = "https://ftp.mozilla.org/pub/firefox/releases/149.0b2/linux-x86_64/en-US/firefox-149.0b2.tar.xz",
54-
sha256 = "14057fe24b65ef64125d04bde3507f48e489464b9f22cda832d34db92dede817",
53+
url = "https://ftp.mozilla.org/pub/firefox/releases/149.0b4/linux-x86_64/en-US/firefox-149.0b4.tar.xz",
54+
sha256 = "57539691f99f49124487846e1ed30b2c3c1e5413a68a4838644d9f35fcd22ec6",
5555
build_file_content = """
5656
load("@aspect_rules_js//js:defs.bzl", "js_library")
5757
package(default_visibility = ["//visibility:public"])
@@ -72,8 +72,8 @@ js_library(
7272

7373
dmg_archive(
7474
name = "mac_beta_firefox",
75-
url = "https://ftp.mozilla.org/pub/firefox/releases/149.0b2/mac/en-US/Firefox%20149.0b2.dmg",
76-
sha256 = "cc697fd73992e677e7249be2a42d7e6e9fe1373841ecefe7009acfad113566fb",
75+
url = "https://ftp.mozilla.org/pub/firefox/releases/149.0b4/mac/en-US/Firefox%20149.0b4.dmg",
76+
sha256 = "69b90c44f1757f0ba0799e82767e38bac8cad4762de76113a14237190f9c4212",
7777
build_file_content = """
7878
load("@aspect_rules_js//js:defs.bzl", "js_library")
7979
package(default_visibility = ["//visibility:public"])

dotnet/src/webdriver/BiDi/BiDi.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ namespace OpenQA.Selenium.BiDi;
2727
public sealed class BiDi : IBiDi
2828
{
2929
private readonly ConcurrentDictionary<Type, Module> _modules = new();
30+
private bool _disposed;
3031

3132
private Broker Broker { get; set; } = null!;
3233

@@ -83,6 +84,13 @@ public Task<EndResult> EndAsync(EndOptions? options = null, CancellationToken ca
8384

8485
public async ValueTask DisposeAsync()
8586
{
87+
if (_disposed)
88+
{
89+
return;
90+
}
91+
92+
_disposed = true;
93+
8694
await Broker.DisposeAsync().ConfigureAwait(false);
8795
GC.SuppressFinalize(this);
8896
}

dotnet/src/webdriver/BiDi/Json/Converters/BrowserUserContextConverter.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
// under the License.
1818
// </copyright>
1919

20+
using System.Collections.Concurrent;
21+
using System.Runtime.CompilerServices;
2022
using System.Text.Json;
2123
using System.Text.Json.Serialization;
2224
using OpenQA.Selenium.BiDi.Browser;
@@ -25,11 +27,15 @@ namespace OpenQA.Selenium.BiDi.Json.Converters;
2527

2628
internal class BrowserUserContextConverter(IBiDi bidi) : JsonConverter<UserContext>
2729
{
30+
private static readonly ConditionalWeakTable<IBiDi, ConcurrentDictionary<string, UserContext>> s_cache = new();
31+
2832
public override UserContext? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
2933
{
3034
var id = reader.GetString();
3135

32-
return new UserContext(id!) { BiDi = bidi };
36+
var sessionCache = s_cache.GetValue(bidi, _ => new ConcurrentDictionary<string, UserContext>());
37+
38+
return sessionCache.GetOrAdd(id!, key => new UserContext(bidi, key));
3339
}
3440

3541
public override void Write(Utf8JsonWriter writer, UserContext value, JsonSerializerOptions options)

dotnet/src/webdriver/BiDi/Json/Converters/BrowsingContextConverter.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,24 @@
1717
// under the License.
1818
// </copyright>
1919

20+
using System.Collections.Concurrent;
21+
using System.Runtime.CompilerServices;
2022
using System.Text.Json;
2123
using System.Text.Json.Serialization;
2224

2325
namespace OpenQA.Selenium.BiDi.Json.Converters;
2426

2527
internal class BrowsingContextConverter(IBiDi bidi) : JsonConverter<BrowsingContext.BrowsingContext>
2628
{
27-
private readonly IBiDi _bidi = bidi;
29+
private static readonly ConditionalWeakTable<IBiDi, ConcurrentDictionary<string, BrowsingContext.BrowsingContext>> s_cache = new();
2830

2931
public override BrowsingContext.BrowsingContext? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
3032
{
3133
var id = reader.GetString();
3234

33-
return new BrowsingContext.BrowsingContext(id!) { BiDi = _bidi };
35+
var sessionCache = s_cache.GetValue(bidi, _ => new ConcurrentDictionary<string, BrowsingContext.BrowsingContext>());
36+
37+
return sessionCache.GetOrAdd(id!, key => new BrowsingContext.BrowsingContext(bidi, key));
3438
}
3539

3640
public override void Write(Utf8JsonWriter writer, BrowsingContext.BrowsingContext value, JsonSerializerOptions options)

dotnet/src/webdriver/BiDi/Script/RemoteValue.cs

Lines changed: 82 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -54,49 +54,101 @@ namespace OpenQA.Selenium.BiDi.Script;
5454
[JsonConverter(typeof(RemoteValueConverter))]
5555
public abstract record RemoteValue
5656
{
57-
public static implicit operator double(RemoteValue remoteValue) => (double)((NumberRemoteValue)remoteValue).Value;
57+
public static implicit operator bool(RemoteValue remoteValue) => remoteValue.ConvertTo<bool>();
58+
public static implicit operator double(RemoteValue remoteValue) => remoteValue.ConvertTo<double>();
59+
public static implicit operator float(RemoteValue remoteValue) => remoteValue.ConvertTo<float>();
60+
public static implicit operator int(RemoteValue remoteValue) => remoteValue.ConvertTo<int>();
61+
public static implicit operator long(RemoteValue remoteValue) => remoteValue.ConvertTo<long>();
62+
public static implicit operator string?(RemoteValue remoteValue) => remoteValue.ConvertTo<string>();
5863

59-
public static implicit operator int(RemoteValue remoteValue) => (int)(double)remoteValue;
60-
public static implicit operator long(RemoteValue remoteValue) => (long)(double)remoteValue;
61-
62-
public static implicit operator string?(RemoteValue remoteValue)
63-
{
64-
return remoteValue switch
64+
public TResult? ConvertTo<TResult>()
65+
=> (this, typeof(TResult)) switch
6566
{
66-
StringRemoteValue stringValue => stringValue.Value,
67-
NullRemoteValue => null,
68-
_ => throw new InvalidCastException($"Cannot convert {remoteValue} to string")
67+
(_, Type t) when t.IsAssignableFrom(GetType())
68+
=> (TResult)(object)this,
69+
(BooleanRemoteValue b, Type t) when t == typeof(bool)
70+
=> (TResult)(object)b.Value,
71+
(NullRemoteValue, Type t) when !t.IsValueType || Nullable.GetUnderlyingType(t) is not null
72+
=> default,
73+
(NumberRemoteValue n, Type t) when t == typeof(byte)
74+
=> (TResult)(object)Convert.ToByte(n.Value),
75+
(NumberRemoteValue n, Type t) when t == typeof(sbyte)
76+
=> (TResult)(object)Convert.ToSByte(n.Value),
77+
(NumberRemoteValue n, Type t) when t == typeof(short)
78+
=> (TResult)(object)Convert.ToInt16(n.Value),
79+
(NumberRemoteValue n, Type t) when t == typeof(ushort)
80+
=> (TResult)(object)Convert.ToUInt16(n.Value),
81+
(NumberRemoteValue n, Type t) when t == typeof(int)
82+
=> (TResult)(object)Convert.ToInt32(n.Value),
83+
(NumberRemoteValue n, Type t) when t == typeof(uint)
84+
=> (TResult)(object)Convert.ToUInt32(n.Value),
85+
(NumberRemoteValue n, Type t) when t == typeof(long)
86+
=> (TResult)(object)Convert.ToInt64(n.Value),
87+
(NumberRemoteValue n, Type t) when t == typeof(ulong)
88+
=> (TResult)(object)Convert.ToUInt64(n.Value),
89+
(NumberRemoteValue n, Type t) when t == typeof(double)
90+
=> (TResult)(object)n.Value,
91+
(NumberRemoteValue n, Type t) when t == typeof(float)
92+
=> (TResult)(object)Convert.ToSingle(n.Value),
93+
(NumberRemoteValue n, Type t) when t == typeof(decimal)
94+
=> (TResult)(object)Convert.ToDecimal(n.Value),
95+
(StringRemoteValue s, Type t) when t == typeof(string)
96+
=> (TResult)(object)s.Value,
97+
(ArrayRemoteValue a, Type t) when t.IsArray
98+
=> ConvertRemoteValuesToArray<TResult>(a.Value, t.GetElementType()!),
99+
(ArrayRemoteValue a, Type t) when t.IsGenericType && t.IsAssignableFrom(typeof(List<>).MakeGenericType(t.GetGenericArguments()[0]))
100+
=> ConvertRemoteValuesToGenericList<TResult>(a.Value, typeof(List<>).MakeGenericType(t.GetGenericArguments()[0])),
101+
102+
(_, Type t) when Nullable.GetUnderlyingType(t) is { } underlying
103+
=> ConvertToNullable<TResult>(underlying),
104+
105+
_ => throw new InvalidCastException($"Cannot convert {GetType().Name} to {typeof(TResult).FullName}")
69106
};
70-
}
71107

72-
// TODO: extend types
73-
public TResult? ConvertTo<TResult>()
108+
private TResult ConvertToNullable<TResult>(Type underlyingType)
74109
{
75-
var type = typeof(TResult);
110+
var convertMethod = typeof(RemoteValue).GetMethod(nameof(ConvertTo))!.MakeGenericMethod(underlyingType);
111+
var value = convertMethod.Invoke(this, null);
112+
return (TResult)value!;
113+
}
76114

77-
if (typeof(RemoteValue).IsAssignableFrom(type)) // handle native derived types
78-
{
79-
return (TResult)(this as object);
80-
}
81-
if (type == typeof(bool))
82-
{
83-
return (TResult)(Convert.ToBoolean(((BooleanRemoteValue)this).Value) as object);
84-
}
85-
if (type == typeof(int))
115+
private static TResult ConvertRemoteValuesToArray<TResult>(IEnumerable<RemoteValue>? remoteValues, Type elementType)
116+
{
117+
if (remoteValues is null)
86118
{
87-
return (TResult)(Convert.ToInt32(((NumberRemoteValue)this).Value) as object);
119+
return (TResult)(object)Array.CreateInstance(elementType, 0);
88120
}
89-
else if (type == typeof(string))
121+
122+
var convertMethod = typeof(RemoteValue).GetMethod(nameof(ConvertTo))!.MakeGenericMethod(elementType);
123+
var items = remoteValues.ToList();
124+
var array = Array.CreateInstance(elementType, items.Count);
125+
126+
for (int i = 0; i < items.Count; i++)
90127
{
91-
return (TResult)(((StringRemoteValue)this).Value as object);
128+
var convertedItem = convertMethod.Invoke(items[i], null);
129+
array.SetValue(convertedItem, i);
92130
}
93-
else if (type is object)
131+
132+
return (TResult)(object)array;
133+
}
134+
135+
private static TResult ConvertRemoteValuesToGenericList<TResult>(IEnumerable<RemoteValue>? remoteValues, Type listType)
136+
{
137+
var elementType = listType.GetGenericArguments()[0];
138+
var list = (System.Collections.IList)Activator.CreateInstance(listType)!;
139+
140+
if (remoteValues is not null)
94141
{
95-
// :)
96-
return (TResult)new object();
142+
var convertMethod = typeof(RemoteValue).GetMethod(nameof(ConvertTo))!.MakeGenericMethod(elementType);
143+
144+
foreach (var item in remoteValues)
145+
{
146+
var convertedItem = convertMethod.Invoke(item, null);
147+
list.Add(convertedItem);
148+
}
97149
}
98150

99-
throw new BiDiException("Cannot convert .....");
151+
return (TResult)list;
100152
}
101153
}
102154

0 commit comments

Comments
 (0)