19using System.Collections.Generic;
21using System.Reflection;
23using Newtonsoft.Json.Linq;
28 internal static class CdpResultExtractors
30 public static Dictionary<DevToolsMethods, Func<JObject, object>> Build(
string protocolJson)
32 if (
string.IsNullOrEmpty(protocolJson))
33 throw new ArgumentException(
"Invalid protocol JSON");
35 var protocol = JsonConvert.DeserializeObject<
ProtocolRoot>(protocolJson);
37 throw new ArgumentException(
"Failed to parse protocol JSON");
39 var commandToReturns = protocol.Domains
40 .SelectMany(d => (d.Commands ??
new List<ProtocolCommand>())
43 Key = $
"{d.Domain}.{c.Name}",
44 ReturnNames = (c.Returns ?? new List<ProtocolReturn>())
48 .ToDictionary(x => x.Key, x => x.ReturnNames, StringComparer.OrdinalIgnoreCase);
50 var enumToCommand = Enum.GetValues(typeof(DevToolsMethods))
51 .Cast<DevToolsMethods>()
56 var field = m.GetType().GetField(m.ToString());
58 return attr?.Name ?? m.ToString().Replace(
"_",
".");
60 EqualityComparer<DevToolsMethods>.Default);
62 var overrides =
new Dictionary<string, Func<JObject, object>>(StringComparer.OrdinalIgnoreCase)
64 [
"Page.getNavigationHistory"] = m =>
66 var idx = (
int?)m[
"currentIndex"] ?? -1;
67 var entries = m[
"entries"] as JArray;
68 if (entries !=
null && idx >= 0 && idx < entries.Count)
70 return entries[idx]?[
"url"]?.Value<
string>();
74 return new { CurrentIndex = m[
"currentIndex"]?.Value<
int>(), Entries = entries };
78 [
"DOM.querySelectorAll"] = m => m[
"nodeIds"]?.ToObject<
int[]>() ??
new int[0],
79 [
"Page.captureScreenshot"] = m => m[
"data"]?.Value<string>(),
80 [
"Target.createTarget"] = m => m[
"targetId"]?.Value<
string>(),
81 [
"Target.attachToTarget"] = m => m[
"sessionId"]?.Value<string>(),
82 [
"Runtime.evaluate"] = m =>
84 var result = m[
"result"];
85 if (result ==
null)
return null;
86 var ro = result[
"result"];
87 if (ro?[
"objectId"] ==
null && ro[
"value"] !=
null && ro[
"type"]?.Value<string>() !=
"undefined")
88 return ro[
"value"].ToObject<
object>();
91 [
"DOM.getDocument"] = m => m[
"root"],
92 [
"DOM.describeNode"] = m => m[
"node"],
93 [
"DOM.getAttributes"] = m => m[
"attributes"]?.ToObject<
string[]>(),
94 [
"DOM.getBoxModel"] = m => m[
"model"],
95 [
"Runtime.getProperties"] = m => m[
"result"]?.ToObject<
object[]>(),
96 [
"DOM.resolveNode"] = m => m[
"node"],
97 [
"Page.enable"] = m =>
null,
98 [
"DOM.enable"] = m =>
null,
99 [
"Network.enable"] = m =>
null,
100 [
"Emulation.setAutomationOverride"] = m =>
null,
101 [
"Input.dispatchMouseEvent"] = m =>
null,
102 [
"Input.insertText"] = m =>
null
105 var dict =
new Dictionary<DevToolsMethods, Func<JObject, object>>();
107 foreach (var kv
in enumToCommand)
110 var commandName = kv.Value;
112 if (overrides.TryGetValue(commandName, out var overrideExtractor))
114 dict[method] = overrideExtractor;
118 if (!commandToReturns.TryGetValue(commandName, out var returns) || returns.Length == 0)
120 dict[method] = m => m.ToObject<
object>();
124 if (returns.Length == 1)
126 var name = returns[0];
127 dict[method] = m => m[name]?.ToObject<
object>();
134 var result =
new Dictionary<string, object>();
135 foreach (var n
in names)
138 result[n] = m[n].ToObject<
object>();
140 return result.Count > 0 ? result : m.ToObject<
object>();
145 foreach (var kv
in enumToCommand.Where(kv => !dict.ContainsKey(kv.Key)))
147 dict[kv.Key] = m => m.ToObject<
object>();
155 [JsonProperty(
"domains")]
156 public List<ProtocolDomain> Domains {
get;
set; } =
new List<ProtocolDomain>();
161 [JsonProperty(
"domain")]
162 public string Domain {
get;
set; } =
string.Empty;
164 [JsonProperty(
"commands")]
165 public List<ProtocolCommand> Commands {
get;
set; } =
new List<ProtocolCommand>();
167 [JsonProperty(
"types")]
168 public List<ProtocolType> Types {
get;
set; } =
new List<ProtocolType>();
173 [JsonProperty(
"name")]
174 public string Name {
get;
set; } =
string.Empty;
176 [JsonProperty(
"returns")]
177 public List<ProtocolReturn> Returns {
get;
set; } =
new List<ProtocolReturn>();
182 [JsonProperty(
"name")]
183 public string Name {
get;
set; } =
string.Empty;
185 [JsonProperty(
"type")]
186 public string Type {
get;
set; } =
string.Empty;
188 [JsonProperty(
"$ref")]
189 public string Ref {
get;
set; } =
string.Empty;
195 public string Id {
get;
set; } =
string.Empty;
198 [AttributeUsage(AttributeTargets.Field)]
199 public sealed class CommandAttribute : Attribute
201 public string Name {
get; }
202 public CommandAttribute(
string name) => Name = name;