| // <copyright file="Command.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.Internal; |
| using System; |
| using System.Collections.Generic; |
| using System.Text.Json; |
| using System.Text.Json.Serialization; |
| using System.Text.Json.Serialization.Metadata; |
| |
| namespace OpenQA.Selenium; |
| |
| /// <summary> |
| /// Provides a way to send commands to the remote server |
| /// </summary> |
| public class Command |
| { |
| private readonly static JsonSerializerOptions s_jsonSerializerOptions = new() |
| { |
| TypeInfoResolverChain = |
| { |
| CommandJsonSerializerContext.Default, |
| new DefaultJsonTypeInfoResolver() |
| }, |
| Converters = { new ResponseValueJsonConverter() } |
| }; |
| |
| /// <summary> |
| /// Initializes a new instance of the <see cref="Command"/> class using a command name and a JSON-encoded string for the parameters. |
| /// </summary> |
| /// <param name="name">Name of the command</param> |
| /// <param name="jsonParameters">Parameters for the command as a JSON-encoded string.</param> |
| public Command(string name, string jsonParameters) |
| : this(null, name, ConvertParametersFromJson(jsonParameters)) |
| { |
| } |
| |
| /// <summary> |
| /// Initializes a new instance of the <see cref="Command"/> class for a Session |
| /// </summary> |
| /// <param name="sessionId">Session ID the driver is using</param> |
| /// <param name="name">Name of the command</param> |
| /// <param name="parameters">Parameters for that command</param> |
| /// <exception cref="ArgumentNullException">If <paramref name="name"/> is <see langword="null"/>.</exception> |
| public Command(SessionId? sessionId, string name, Dictionary<string, object?>? parameters) |
| { |
| this.SessionId = sessionId; |
| this.Parameters = parameters ?? new Dictionary<string, object?>(); |
| this.Name = name ?? throw new ArgumentNullException(nameof(name)); |
| } |
| |
| /// <summary> |
| /// Gets the SessionID of the command |
| /// </summary> |
| [JsonPropertyName("sessionId")] |
| public SessionId? SessionId { get; } |
| |
| /// <summary> |
| /// Gets the command name |
| /// </summary> |
| [JsonPropertyName("name")] |
| public string Name { get; } |
| |
| /// <summary> |
| /// Gets the parameters of the command |
| /// </summary> |
| [JsonPropertyName("parameters")] |
| public Dictionary<string, object?> Parameters { get; } |
| |
| /// <summary> |
| /// Gets the parameters of the command as a JSON-encoded string. |
| /// </summary> |
| public string ParametersAsJsonString |
| { |
| get |
| { |
| if (this.Parameters != null && this.Parameters.Count > 0) |
| { |
| return JsonSerializer.Serialize(this.Parameters, s_jsonSerializerOptions); |
| } |
| else |
| { |
| return "{}"; |
| } |
| } |
| } |
| |
| /// <summary> |
| /// Returns a string of the Command object |
| /// </summary> |
| /// <returns>A string representation of the Command Object</returns> |
| public override string ToString() |
| { |
| return string.Concat("[", this.SessionId, "]: ", this.Name, " ", this.ParametersAsJsonString); |
| } |
| |
| /// <summary> |
| /// Gets the command parameters as a <see cref="Dictionary{K, V}"/>, with a string key, and an object value. |
| /// </summary> |
| /// <param name="value">The JSON-encoded string representing the command parameters.</param> |
| /// <returns>A <see cref="Dictionary{K, V}"/> with a string keys, and an object value. </returns> |
| /// <exception cref="JsonException">If <paramref name="value"/> is not a JSON object.</exception> |
| /// <exception cref="ArgumentNullException">If <paramref name="value"/> is <see langword="null"/>.</exception> |
| private static Dictionary<string, object?>? ConvertParametersFromJson(string value) |
| { |
| Dictionary<string, object?>? parameters = JsonSerializer.Deserialize<Dictionary<string, object?>>(value, CommandJsonSerializerContext.Default.DictionaryStringObject!); |
| return parameters; |
| } |
| } |
| |
| // Built-in types |
| [JsonSerializable(typeof(bool))] |
| [JsonSerializable(typeof(byte))] |
| [JsonSerializable(typeof(sbyte))] |
| [JsonSerializable(typeof(char))] |
| [JsonSerializable(typeof(decimal))] |
| [JsonSerializable(typeof(double))] |
| [JsonSerializable(typeof(float))] |
| [JsonSerializable(typeof(int))] |
| [JsonSerializable(typeof(uint))] |
| [JsonSerializable(typeof(nint))] |
| [JsonSerializable(typeof(nuint))] |
| [JsonSerializable(typeof(long))] |
| [JsonSerializable(typeof(ulong))] |
| [JsonSerializable(typeof(short))] |
| [JsonSerializable(typeof(ushort))] |
| [JsonSerializable(typeof(string))] |
| |
| // Selenium WebDriver types |
| [JsonSerializable(typeof(char[]))] |
| [JsonSerializable(typeof(byte[]))] |
| [JsonSerializable(typeof(Chromium.ChromiumNetworkConditions))] |
| [JsonSerializable(typeof(Cookie))] |
| [JsonSerializable(typeof(ReturnedCookie))] |
| [JsonSerializable(typeof(Proxy))] |
| |
| // Selenium Dictionaries, primarily used in Capabilities |
| [JsonSerializable(typeof(Dictionary<string, object>))] |
| [JsonSerializable(typeof(Dictionary<string, bool>))] |
| [JsonSerializable(typeof(Dictionary<string, byte>))] |
| [JsonSerializable(typeof(Dictionary<string, sbyte>))] |
| [JsonSerializable(typeof(Dictionary<string, char>))] |
| [JsonSerializable(typeof(Dictionary<string, decimal>))] |
| [JsonSerializable(typeof(Dictionary<string, double>))] |
| [JsonSerializable(typeof(Dictionary<string, float>))] |
| [JsonSerializable(typeof(Dictionary<string, int>))] |
| [JsonSerializable(typeof(Dictionary<string, uint>))] |
| [JsonSerializable(typeof(Dictionary<string, nint>))] |
| [JsonSerializable(typeof(Dictionary<string, nuint>))] |
| [JsonSerializable(typeof(Dictionary<string, long>))] |
| [JsonSerializable(typeof(Dictionary<string, ulong>))] |
| [JsonSerializable(typeof(Dictionary<string, short>))] |
| [JsonSerializable(typeof(Dictionary<string, ushort>))] |
| [JsonSerializable(typeof(Dictionary<string, string>))] |
| [JsonSourceGenerationOptions(Converters = [typeof(ResponseValueJsonConverter)])] |
| internal partial class CommandJsonSerializerContext : JsonSerializerContext; |