Skip to content

Commit

Permalink
Merge branch 'trunk' into renovate/io.lettuce-lettuce-core-6.x
Browse files Browse the repository at this point in the history
  • Loading branch information
VietND96 authored Feb 9, 2025
2 parents 57b1c12 + e639050 commit 48cd353
Show file tree
Hide file tree
Showing 94 changed files with 1,158 additions and 920 deletions.
60 changes: 37 additions & 23 deletions dotnet/src/webdriver/BiDi/Communication/Broker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ internal Broker(BiDi bidi, ITransport transport)
{
new BrowsingContextConverter(_bidi),
new BrowserUserContextConverter(bidi),
new BrowserClientWindowConverter(),
new NavigationConverter(),
new InterceptConverter(_bidi),
new RequestConverter(_bidi),
Expand All @@ -82,6 +83,7 @@ internal Broker(BiDi bidi, ITransport transport)
new DateTimeOffsetConverter(),
new PrintPageRangeConverter(),
new InputOriginConverter(),
new SubscriptionConverter(),
new JsonStringEnumConverter(JsonNamingPolicy.CamelCase),

// https://github.com/dotnet/runtime/issues/72604
Expand All @@ -97,6 +99,7 @@ internal Broker(BiDi bidi, ITransport transport)
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(),
}
};
Expand All @@ -109,15 +112,17 @@ public async Task ConnectAsync(CancellationToken cancellationToken)
await _transport.ConnectAsync(cancellationToken).ConfigureAwait(false);

_receiveMessagesCancellationTokenSource = new CancellationTokenSource();
_receivingMessageTask = _myTaskFactory.StartNew(async () => await ReceiveMessagesAsync(_receiveMessagesCancellationTokenSource.Token), TaskCreationOptions.LongRunning).Unwrap();
_eventEmitterTask = _myTaskFactory.StartNew(async () => await ProcessEventsAwaiterAsync(), TaskCreationOptions.LongRunning).Unwrap();
_receivingMessageTask = _myTaskFactory.StartNew(async () => await ReceiveMessagesAsync(_receiveMessagesCancellationTokenSource.Token)).Unwrap();
_eventEmitterTask = _myTaskFactory.StartNew(ProcessEventsAwaiterAsync).Unwrap();
}

private async Task ReceiveMessagesAsync(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
var message = await _transport.ReceiveAsJsonAsync<Message>(_jsonSerializerContext, cancellationToken);
var data = await _transport.ReceiveAsync(cancellationToken).ConfigureAwait(false);

var message = JsonSerializer.Deserialize(new ReadOnlySpan<byte>(data), _jsonSerializerContext.Message);

switch (message)
{
Expand Down Expand Up @@ -177,21 +182,21 @@ private async Task ProcessEventsAwaiterAsync()
}

public async Task<TResult> ExecuteCommandAsync<TCommand, TResult>(TCommand command, CommandOptions? options)
where TCommand: Command
where TCommand : Command
{
var jsonElement = await ExecuteCommandCoreAsync(command, options).ConfigureAwait(false);

return (TResult)jsonElement.Deserialize(typeof(TResult), _jsonSerializerContext)!;
}

public async Task ExecuteCommandAsync<TCommand>(TCommand command, CommandOptions? options)
where TCommand: Command
where TCommand : Command
{
await ExecuteCommandCoreAsync(command, options).ConfigureAwait(false);
}

private async Task<JsonElement> ExecuteCommandCoreAsync<TCommand>(TCommand command, CommandOptions? options)
where TCommand: Command
where TCommand : Command
{
command.Id = Interlocked.Increment(ref _currentCommandId);

Expand All @@ -205,7 +210,9 @@ private async Task<JsonElement> ExecuteCommandCoreAsync<TCommand>(TCommand comma

_pendingCommands[command.Id] = tcs;

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

await _transport.SendAsync(data, cts.Token).ConfigureAwait(false);

return await tcs.Task.ConfigureAwait(false);
}
Expand All @@ -217,23 +224,23 @@ public async Task<Subscription> SubscribeAsync<TEventArgs>(string eventName, Act

if (options is BrowsingContextsSubscriptionOptions browsingContextsOptions)
{
await _bidi.SessionModule.SubscribeAsync([eventName], new() { Contexts = browsingContextsOptions.Contexts }).ConfigureAwait(false);
var subscribeResult = await _bidi.SessionModule.SubscribeAsync([eventName], new() { Contexts = browsingContextsOptions.Contexts }).ConfigureAwait(false);

var eventHandler = new SyncEventHandler<TEventArgs>(eventName, action, browsingContextsOptions?.Contexts);

handlers.Add(eventHandler);

return new Subscription(this, eventHandler);
return new Subscription(subscribeResult.Subscription, this, eventHandler);
}
else
{
await _bidi.SessionModule.SubscribeAsync([eventName]).ConfigureAwait(false);
var subscribeResult = await _bidi.SessionModule.SubscribeAsync([eventName]).ConfigureAwait(false);

var eventHandler = new SyncEventHandler<TEventArgs>(eventName, action);

handlers.Add(eventHandler);

return new Subscription(this, eventHandler);
return new Subscription(subscribeResult.Subscription, this, eventHandler);
}
}

Expand All @@ -244,44 +251,51 @@ public async Task<Subscription> SubscribeAsync<TEventArgs>(string eventName, Fun

if (options is BrowsingContextsSubscriptionOptions browsingContextsOptions)
{
await _bidi.SessionModule.SubscribeAsync([eventName], new() { Contexts = browsingContextsOptions.Contexts }).ConfigureAwait(false);
var subscribeResult = await _bidi.SessionModule.SubscribeAsync([eventName], new() { Contexts = browsingContextsOptions.Contexts }).ConfigureAwait(false);

var eventHandler = new AsyncEventHandler<TEventArgs>(eventName, func, browsingContextsOptions.Contexts);

handlers.Add(eventHandler);

return new Subscription(this, eventHandler);
return new Subscription(subscribeResult.Subscription, this, eventHandler);
}
else
{
await _bidi.SessionModule.SubscribeAsync([eventName]).ConfigureAwait(false);
var subscribeResult = await _bidi.SessionModule.SubscribeAsync([eventName]).ConfigureAwait(false);

var eventHandler = new AsyncEventHandler<TEventArgs>(eventName, func);

handlers.Add(eventHandler);

return new Subscription(this, eventHandler);
return new Subscription(subscribeResult.Subscription, this, eventHandler);
}
}

public async Task UnsubscribeAsync(EventHandler eventHandler)
public async Task UnsubscribeAsync(Modules.Session.Subscription subscription, EventHandler eventHandler)
{
var eventHandlers = _eventHandlers[eventHandler.EventName];

eventHandlers.Remove(eventHandler);

if (eventHandler.Contexts is not null)
if (subscription is not null)
{
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 _bidi.SessionModule.UnsubscribeAsync([subscription]).ConfigureAwait(false);
}
else
{
if (!eventHandlers.Any(h => h.Contexts is not null) && !eventHandlers.Any(h => h.Contexts is null))
if (eventHandler.Contexts is not null)
{
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);
}
}
else
{
await _bidi.SessionModule.UnsubscribeAsync([eventHandler.EventName]).ConfigureAwait(false);
if (!eventHandlers.Any(h => h.Contexts is not null) && !eventHandlers.Any(h => h.Contexts is null))
{
await _bidi.SessionModule.UnsubscribeAsync([eventHandler.EventName]).ConfigureAwait(false);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,20 @@ namespace OpenQA.Selenium.BiDi.Communication.Json;
[JsonSerializable(typeof(Modules.Session.NewResult))]
[JsonSerializable(typeof(Modules.Session.EndCommand))]
[JsonSerializable(typeof(Modules.Session.SubscribeCommand))]
[JsonSerializable(typeof(Modules.Session.UnsubscribeCommand))]
[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))]
[JsonSerializable(typeof(Modules.Browser.GetUserContextsResult))]
[JsonSerializable(typeof(Modules.Browser.RemoveUserContextCommand))]
[JsonSerializable(typeof(Modules.Browser.GetClientWindowsCommand))]
[JsonSerializable(typeof(Modules.Browser.GetClientWindowsResult))]
[JsonSerializable(typeof(Modules.Browser.UserContextInfo))]
[JsonSerializable(typeof(IReadOnlyList<Modules.Browser.UserContextInfo>))]
[JsonSerializable(typeof(IReadOnlyList<Modules.Browser.ClientWindowInfo>))]


[JsonSerializable(typeof(Modules.BrowsingContext.ActivateCommand))]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// <copyright file="BrowserClientWindowConverter.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>

using OpenQA.Selenium.BiDi.Modules.Browser;
using System;
using System.Text.Json;
using System.Text.Json.Serialization;

#nullable enable

namespace OpenQA.Selenium.BiDi.Communication.Json.Converters;

internal class BrowserClientWindowConverter : JsonConverter<ClientWindow>
{
public override ClientWindow? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var id = reader.GetString();

return new ClientWindow(id!);
}

public override void Write(Utf8JsonWriter writer, ClientWindow value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.Id);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// <copyright file="GetClientWindowsResultConverter.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>

using OpenQA.Selenium.BiDi.Modules.Browser;
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;

#nullable enable

namespace OpenQA.Selenium.BiDi.Communication.Json.Converters.Enumerable;

internal class GetClientWindowsResultConverter : JsonConverter<GetClientWindowsResult>
{
public override GetClientWindowsResult Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
using var doc = JsonDocument.ParseValue(ref reader);
var clientWindows = doc.RootElement.GetProperty("clientWindows").Deserialize<IReadOnlyList<ClientWindowInfo>>(options);

return new GetClientWindowsResult(clientWindows!);
}

public override void Write(Utf8JsonWriter writer, GetClientWindowsResult value, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ internal class GetCookiesResultConverter : JsonConverter<GetCookiesResult>
{
public override GetCookiesResult Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var doc = JsonDocument.ParseValue(ref reader);
using var doc = JsonDocument.ParseValue(ref reader);
var cookies = doc.RootElement.GetProperty("cookies").Deserialize<IReadOnlyList<Modules.Network.Cookie>>(options);
var partitionKey = doc.RootElement.GetProperty("partitionKey").Deserialize<PartitionKey>(options);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ internal class GetRealmsResultConverter : JsonConverter<GetRealmsResult>
{
public override GetRealmsResult Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var doc = JsonDocument.ParseValue(ref reader);
using var doc = JsonDocument.ParseValue(ref reader);
var realms = doc.RootElement.GetProperty("realms").Deserialize<IReadOnlyList<RealmInfo>>(options);

return new GetRealmsResult(realms!);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ internal class GetUserContextsResultConverter : JsonConverter<GetUserContextsRes
{
public override GetUserContextsResult Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var doc = JsonDocument.ParseValue(ref reader);
using var doc = JsonDocument.ParseValue(ref reader);
var userContexts = doc.RootElement.GetProperty("userContexts").Deserialize<IReadOnlyList<UserContextInfo>>(options);

return new GetUserContextsResult(userContexts!);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ internal class LocateNodesResultConverter : JsonConverter<LocateNodesResult>
{
public override LocateNodesResult Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var doc = JsonDocument.ParseValue(ref reader);
using var doc = JsonDocument.ParseValue(ref reader);
var nodes = doc.RootElement.GetProperty("nodes").Deserialize<IReadOnlyList<RemoteValue.Node>>(options);

return new LocateNodesResult(nodes!);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// <copyright file="SubscriptionConverter.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>

using System;
using System.Text.Json;
using System.Text.Json.Serialization;

#nullable enable

namespace OpenQA.Selenium.BiDi.Communication.Json.Converters;

internal class SubscriptionConverter : JsonConverter<Modules.Session.Subscription>
{
public override Modules.Session.Subscription? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var id = reader.GetString();

return new Modules.Session.Subscription(id!);
}

public override void Write(Utf8JsonWriter writer, Modules.Session.Subscription value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.Id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
using System.Threading.Tasks;
using System.Threading;
using System;
using System.Text.Json.Serialization;

#nullable enable

Expand All @@ -30,8 +29,7 @@ interface ITransport : IDisposable
{
Task ConnectAsync(CancellationToken cancellationToken);

Task<T> ReceiveAsJsonAsync<T>(JsonSerializerContext jsonSerializerContext, CancellationToken cancellationToken);
Task<byte[]> ReceiveAsync(CancellationToken cancellationToken);

Task SendAsJsonAsync<TCommand>(TCommand command, JsonSerializerContext jsonSerializerContext, CancellationToken cancellationToken)
where TCommand : Command;
Task SendAsync(byte[] data, CancellationToken cancellationToken);
}
Loading

0 comments on commit 48cd353

Please sign in to comment.