Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
7b398a1
Remove stateless converters from json options
nvborisenko Dec 3, 2025
b0f5e1e
Generated options
nvborisenko Dec 3, 2025
79f723d
Hidrate the BiDi property example
nvborisenko Dec 3, 2025
cafbba5
One more hidrate example
nvborisenko Dec 3, 2025
d7956b4
Unified hidration for top level types
nvborisenko Dec 3, 2025
aaddb1e
Fix name
nvborisenko Dec 3, 2025
25389bd
Hydrate event args
nvborisenko Dec 3, 2025
61ad320
Hydrate AddInterceptResult
nvborisenko Dec 3, 2025
2d20a43
Hydrate AddDataCollectorResult
nvborisenko Dec 3, 2025
3f482c0
Hydrate CreateResult
nvborisenko Dec 3, 2025
00d499e
Hydrate AddPreloadScriptResult
nvborisenko Dec 3, 2025
7204604
Hydrate InstallResult
nvborisenko Dec 3, 2025
a465945
Throw if not hydrated
nvborisenko Dec 3, 2025
4e487df
Fix property name for exception
nvborisenko Dec 3, 2025
1501af1
Don't hydrate primitives except BrowsingContext
nvborisenko Dec 3, 2025
d1a2fcb
High level interception is not hydratable
nvborisenko Dec 3, 2025
372fac0
Use shared json options
nvborisenko Dec 6, 2025
3aca801
Remove generated context options
nvborisenko Dec 6, 2025
125f52e
Remove hydration
nvborisenko Dec 6, 2025
713ad83
Returned back some primitives
nvborisenko Dec 6, 2025
5861966
Some oothers
nvborisenko Dec 6, 2025
542f49f
All primitive types are now hydratable
nvborisenko Dec 6, 2025
f3ed0a4
Allow public ctor for hydratable primitives
nvborisenko Dec 6, 2025
9ab3b93
Add note for converters
nvborisenko Dec 6, 2025
cb902a5
Moved WebExtensionConverter
nvborisenko Dec 6, 2025
d214de3
Moved CollectorConverter and InterceptConverter
nvborisenko Dec 6, 2025
3bd611a
Moved PreloadScriptConverter
nvborisenko Dec 6, 2025
b4354d5
Moved RealmConverter
nvborisenko Dec 6, 2025
66aa3ff
Update LogModule.cs
nvborisenko Dec 6, 2025
8235211
Moved InternalIdConverter
nvborisenko Dec 6, 2025
f3e65eb
Moved HandleConverter
nvborisenko Dec 6, 2025
1ddd37d
Moved BrowserUserContextConverter
nvborisenko Dec 6, 2025
015d863
All converters as module requires
nvborisenko Dec 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions dotnet/src/webdriver/BiDi/BiDi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public async ValueTask DisposeAsync()

public T AsModule<T>() where T : Module, new()
{
return (T)_modules.GetOrAdd(typeof(T), _ => Module.Create<T>(this, Broker, GetJsonOptions()));
return (T)_modules.GetOrAdd(typeof(T), _ => Module.Create<T>(this, Broker));
}

private Broker Broker { get; }
Expand All @@ -94,25 +94,25 @@ private JsonSerializerOptions GetJsonOptions()
{
return new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
//PropertyNameCaseInsensitive = true,
//PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
//DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,

// BiDi returns special numbers such as "NaN" as strings
// Additionally, -0 is returned as a string "-0"
NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals | JsonNumberHandling.AllowReadingFromString,
Converters =
{
new BrowsingContextConverter(this),
new BrowserUserContextConverter(this),
new CollectorConverter(this),
new InterceptConverter(this),
new HandleConverter(this),
new InternalIdConverter(this),
new PreloadScriptConverter(this),
new RealmConverter(this),
//new BrowsingContextConverter(),
//new BrowserUserContextConverter(),
//new CollectorConverter(),
//new InterceptConverter(),
//new HandleConverter(),
//new InternalIdConverter(),
//new PreloadScriptConverter(),
//new RealmConverter(),
new DateTimeOffsetConverter(),
new WebExtensionConverter(this),
//new WebExtensionConverter(),
}
};
}
Expand Down
10 changes: 10 additions & 0 deletions dotnet/src/webdriver/BiDi/Broker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,11 @@ private void ProcessReceivedMessage(byte[]? data)
var commandResult = JsonSerializer.Deserialize(ref resultReader, command.JsonResultTypeInfo)
?? throw new JsonException("Remote end returned null command result in the 'result' property.");

if (commandResult is IBiDiHydratable bidiHydratable)
{
bidiHydratable.Hydrate(_bidi);
}

command.TaskCompletionSource.SetResult((EmptyResult)commandResult);
}
catch (Exception ex)
Expand All @@ -304,6 +309,11 @@ private void ProcessReceivedMessage(byte[]? data)
{
var eventArgs = (EventArgs)JsonSerializer.Deserialize(ref paramsReader, eventInfo)!;

if (eventArgs is IBiDiHydratable bidiHydratable)
{
bidiHydratable.Hydrate(_bidi);
}

var messageEvent = (method, eventArgs);
_pendingEvents.Add(messageEvent);
}
Expand Down
17 changes: 10 additions & 7 deletions dotnet/src/webdriver/BiDi/Browser/BrowserModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@
// under the License.
// </copyright>

using System.Text.Json;
using OpenQA.Selenium.BiDi.Json.Converters;
using System.Text.Json.Serialization;
using System.Threading.Tasks;

namespace OpenQA.Selenium.BiDi.Browser;

public sealed class BrowserModule : Module
{
private BrowserJsonSerializerContext _jsonContext = null!;
private static readonly BrowserJsonSerializerContext _jsonContext = BrowserJsonSerializerContext.Default;

public async Task<CloseResult> CloseAsync(CloseOptions? options = null)
{
Expand Down Expand Up @@ -77,11 +77,6 @@ public async Task<SetDownloadBehaviorResult> SetDownloadBehaviorDeniedAsync(SetD

return await Broker.ExecuteCommandAsync(new SetDownloadBehaviorCommand(@params), options, _jsonContext.SetDownloadBehaviorCommand, _jsonContext.SetDownloadBehaviorResult).ConfigureAwait(false);
}

protected override void Initialize(JsonSerializerOptions options)
{
_jsonContext = new BrowserJsonSerializerContext(options);
}
}

[JsonSerializable(typeof(CloseCommand))]
Expand All @@ -96,4 +91,12 @@ protected override void Initialize(JsonSerializerOptions options)
[JsonSerializable(typeof(GetClientWindowsResult))]
[JsonSerializable(typeof(SetDownloadBehaviorCommand))]
[JsonSerializable(typeof(SetDownloadBehaviorResult))]

#pragma warning disable CS3016 // Arrays as attribute arguments is not CLS-compliant
[JsonSourceGenerationOptions(
PropertyNameCaseInsensitive = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase,
Converters = [typeof(DateTimeOffsetConverter)])]
#pragma warning restore CS3016 // Arrays as attribute arguments is not CLS-compliant
internal partial class BrowserJsonSerializerContext : JsonSerializerContext;
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,10 @@ public sealed class CreateUserContextOptions : CommandOptions
public Session.UserPromptHandler? UnhandledPromptBehavior { get; set; }
}

public sealed record CreateUserContextResult(UserContext UserContext) : UserContextInfo(UserContext);
public sealed record CreateUserContextResult(UserContext UserContext) : UserContextInfo(UserContext), IBiDiHydratable
{
void IBiDiHydratable.Hydrate(BiDi bidi)
{
UserContext.BiDi = bidi;
}
}
13 changes: 8 additions & 5 deletions dotnet/src/webdriver/BiDi/Browser/UserContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,29 @@
// under the License.
// </copyright>

using OpenQA.Selenium.BiDi.Json.Converters;
using System;
using System.Text.Json.Serialization;
using System.Threading.Tasks;

namespace OpenQA.Selenium.BiDi.Browser;

[JsonConverter(typeof(BrowserUserContextConverter))]
public sealed class UserContext : IEquatable<UserContext>, IAsyncDisposable
{
private readonly BiDi _bidi;

internal UserContext(BiDi bidi, string id)
internal UserContext(string id)
{
_bidi = bidi;
Id = id;
}

internal string Id { get; }

[JsonIgnore]
public BiDi BiDi { get; internal set; }

public Task RemoveAsync()
{
return _bidi.Browser.RemoveUserContextAsync(this);
return BiDi.Browser.RemoveUserContextAsync(this);
}

public async ValueTask DisposeAsync()
Expand Down
7 changes: 4 additions & 3 deletions dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,19 @@
// under the License.
// </copyright>

using OpenQA.Selenium.BiDi.Json.Converters;
using System;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;

namespace OpenQA.Selenium.BiDi.BrowsingContext;

[JsonConverter(typeof(BrowsingContextConverter))]
public sealed class BrowsingContext
{
internal BrowsingContext(BiDi bidi, string id)
internal BrowsingContext(string id)
{
BiDi = bidi;
Id = id;
}

Expand All @@ -41,7 +42,7 @@ internal BrowsingContext(BiDi bidi, string id)
internal string Id { get; }

[JsonIgnore]
public BiDi BiDi { get; }
public BiDi BiDi { get; internal set; }

[JsonIgnore]
public BrowsingContextLogModule Log => _logModule ?? Interlocked.CompareExchange(ref _logModule, new BrowsingContextLogModule(this, BiDi.Log), null) ?? _logModule;
Expand Down
17 changes: 10 additions & 7 deletions dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@
// under the License.
// </copyright>

using OpenQA.Selenium.BiDi.Json.Converters;
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;

namespace OpenQA.Selenium.BiDi.BrowsingContext;

public sealed class BrowsingContextModule : Module
{
private BrowsingContextJsonSerializerContext _jsonContext = null!;
private static readonly BrowsingContextJsonSerializerContext _jsonContext = BrowsingContextJsonSerializerContext.Default;

public async Task<CreateResult> CreateAsync(ContextType type, CreateOptions? options = null)
{
Expand Down Expand Up @@ -251,11 +251,6 @@ public async Task<Subscription> OnUserPromptClosedAsync(Action<UserPromptClosedE
{
return await Broker.SubscribeAsync("browsingContext.userPromptClosed", handler, options, _jsonContext.UserPromptClosedEventArgs).ConfigureAwait(false);
}

protected override void Initialize(JsonSerializerOptions options)
{
_jsonContext = new BrowsingContextJsonSerializerContext(options);
}
}

[JsonSerializable(typeof(ActivateCommand))]
Expand Down Expand Up @@ -292,4 +287,12 @@ protected override void Initialize(JsonSerializerOptions options)
[JsonSerializable(typeof(NavigationInfo))]
[JsonSerializable(typeof(UserPromptOpenedEventArgs))]
[JsonSerializable(typeof(UserPromptClosedEventArgs))]

#pragma warning disable CS3016 // Arrays as attribute arguments is not CLS-compliant
[JsonSourceGenerationOptions(
PropertyNameCaseInsensitive = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase,
Converters = [typeof(DateTimeOffsetConverter)])]
#pragma warning restore CS3016 // Arrays as attribute arguments is not CLS-compliant
internal partial class BrowsingContextJsonSerializerContext : JsonSerializerContext;
8 changes: 7 additions & 1 deletion dotnet/src/webdriver/BiDi/BrowsingContext/CreateCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,10 @@ public enum ContextType
Window
}

public sealed record CreateResult(BrowsingContext Context) : EmptyResult;
public sealed record CreateResult(BrowsingContext Context) : EmptyResult, IBiDiHydratable
{
void IBiDiHydratable.Hydrate(BiDi bidi)
{
Context.BiDi = bidi;
}
}
11 changes: 10 additions & 1 deletion dotnet/src/webdriver/BiDi/BrowsingContext/GetTreeCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,13 @@ public sealed record BrowsingContextGetTreeOptions
public long? MaxDepth { get; set; }
}

public sealed record GetTreeResult(IReadOnlyList<BrowsingContextInfo> Contexts) : EmptyResult;
public sealed record GetTreeResult(IReadOnlyList<BrowsingContextInfo> Contexts) : EmptyResult, IBiDiHydratable
{
void IBiDiHydratable.Hydrate(BiDi bidi)
{
foreach (var contextInfo in Contexts)
{
contextInfo.Context.BiDi = bidi;
}
}
}
17 changes: 10 additions & 7 deletions dotnet/src/webdriver/BiDi/Emulation/EmulationModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@
// under the License.
// </copyright>

using System.Text.Json;
using OpenQA.Selenium.BiDi.Json.Converters;
using System.Text.Json.Serialization;
using System.Threading.Tasks;

namespace OpenQA.Selenium.BiDi.Emulation;

public sealed class EmulationModule : Module
{
private EmulationJsonSerializerContext _jsonContext = null!;
private static readonly EmulationJsonSerializerContext _jsonContext = EmulationJsonSerializerContext.Default;

public async Task<SetTimezoneOverrideResult> SetTimezoneOverrideAsync(string? timezone, SetTimezoneOverrideOptions? options = null)
{
Expand Down Expand Up @@ -91,11 +91,6 @@ public async Task<SetGeolocationOverrideResult> SetGeolocationPositionErrorOverr

return await Broker.ExecuteCommandAsync(new SetGeolocationOverrideCommand(@params), options, _jsonContext.SetGeolocationOverrideCommand, _jsonContext.SetGeolocationOverrideResult).ConfigureAwait(false);
}

protected override void Initialize(JsonSerializerOptions options)
{
_jsonContext = new EmulationJsonSerializerContext(options);
}
}

[JsonSerializable(typeof(SetTimezoneOverrideCommand))]
Expand All @@ -112,4 +107,12 @@ protected override void Initialize(JsonSerializerOptions options)
[JsonSerializable(typeof(SetScreenOrientationOverrideResult))]
[JsonSerializable(typeof(SetGeolocationOverrideCommand))]
[JsonSerializable(typeof(SetGeolocationOverrideResult))]

#pragma warning disable CS3016 // Arrays as attribute arguments is not CLS-compliant
[JsonSourceGenerationOptions(
PropertyNameCaseInsensitive = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase,
Converters = [typeof(DateTimeOffsetConverter)])]
#pragma warning restore CS3016 // Arrays as attribute arguments is not CLS-compliant
internal partial class EmulationJsonSerializerContext : JsonSerializerContext;
7 changes: 6 additions & 1 deletion dotnet/src/webdriver/BiDi/EventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,15 @@

namespace OpenQA.Selenium.BiDi;

public abstract record EventArgs
public abstract record EventArgs : IBiDiHydratable
{
[JsonIgnore]
public BiDi BiDi { get; internal set; }

void IBiDiHydratable.Hydrate(BiDi bidi)
{
BiDi = bidi;
}
}

public abstract record BrowsingContextEventArgs(BrowsingContext.BrowsingContext Context)
Expand Down
25 changes: 25 additions & 0 deletions dotnet/src/webdriver/BiDi/IBiDiHydratable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// <copyright file="IBiDiHydratable.cs" company="Selenium Committers">
// 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.
// </copyright>

namespace OpenQA.Selenium.BiDi;

public interface IBiDiHydratable
{
internal void Hydrate(BiDi bidi);
}
17 changes: 10 additions & 7 deletions dotnet/src/webdriver/BiDi/Input/InputModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@
// under the License.
// </copyright>

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

namespace OpenQA.Selenium.BiDi.Input;

public sealed class InputModule : Module
{
private InputJsonSerializerContext _jsonContext = null!;
private static readonly InputJsonSerializerContext _jsonContext = InputJsonSerializerContext.Default;

public async Task<PerformActionsResult> PerformActionsAsync(BrowsingContext.BrowsingContext context, IEnumerable<SourceActions> actions, PerformActionsOptions? options = null)
{
Expand All @@ -48,11 +48,6 @@ public async Task<SetFilesResult> SetFilesAsync(BrowsingContext.BrowsingContext

return await Broker.ExecuteCommandAsync(new SetFilesCommand(@params), options, _jsonContext.SetFilesCommand, _jsonContext.SetFilesResult).ConfigureAwait(false);
}

protected override void Initialize(JsonSerializerOptions options)
{
_jsonContext = new InputJsonSerializerContext(options);
}
}

[JsonSerializable(typeof(PerformActionsCommand))]
Expand All @@ -65,4 +60,12 @@ protected override void Initialize(JsonSerializerOptions options)
[JsonSerializable(typeof(IEnumerable<IKeySourceAction>))]
[JsonSerializable(typeof(IEnumerable<INoneSourceAction>))]
[JsonSerializable(typeof(IEnumerable<IWheelSourceAction>))]

#pragma warning disable CS3016 // Arrays as attribute arguments is not CLS-compliant
[JsonSourceGenerationOptions(
PropertyNameCaseInsensitive = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase,
Converters = [typeof(DateTimeOffsetConverter)])]
#pragma warning restore CS3016 // Arrays as attribute arguments is not CLS-compliant
internal partial class InputJsonSerializerContext : JsonSerializerContext;
Loading
Loading