18using System.Collections.Generic;
22using System.Threading.Tasks;
23using DocumentFormat.OpenXml.Office2019.Drawing.Diagram11;
26using static OpenCvSharp.LineIterator;
58 private readonly List<Action<RESTClient>> _workflows =
new List<Action<RESTClient>>();
59 private readonly List<(
string Endpoint,
object Parameters,
string HttpMethod,
string NextResultName)?> _workflowStates =
new List<(
string,
object,
string,
string)?>();
60 private bool _customEndpoint =
false;
61 private string _endpoint;
62 private object _parameters;
63 private string _httpMethod =
"GET";
64 internal ContentEncoding _contentEncoding = ContentEncoding.Json;
66 private string _saveFile {
get;
set; }
67 private string _nextResultName;
68 private readonly List<(
string Name,
object Result,
int Iteration)> _executionResults =
new List<(
string Name,
object Result,
int Iteration)>();
69 private RESTHelper _helper;
70 private int _currentIteration;
71 internal Dictionary<string, string> _headers =
new Dictionary<string, string>();
74 get => _helper.StatusCode;
77 internal Dictionary<string, (
string[] Mandatory,
string[] Optional, Func<IDictionary<string, object>,
bool> CustomValidation)>
78 openApiParamRules =
new Dictionary<
string, (
string[] Mandatory,
string[] Optional, Func<IDictionary<string, object>,
bool> CustomValidation)>(StringComparer.OrdinalIgnoreCase);
80 Dictionary<ApiEndpoint, (
string[] Mandatory,
string[] Optional, Func<IDictionary<string, object>,
bool> CustomValidation)> paramRules =
new Dictionary<ApiEndpoint, (
string[] Mandatory,
string[] Optional, Func<IDictionary<string, object>,
bool> CustomValidation)>
82 [ApiEndpoint.Back] = (
new string[] { },
new string[] { },
null),
83 [ApiEndpoint.CaptureVisibleTab] = (
new string[] { },
new string[] {
"windowId",
"imageFormat" },
null),
84 [ApiEndpoint.CastDesktop] = (
new[] {
"sinkName" },
new string[] { },
null),
85 [ApiEndpoint.CastTab] = (
new[] {
"sinkName" },
new string[] { },
null),
86 [ApiEndpoint.CheckNetworkIdle] = (
87 Mandatory:
new string[] { },
88 Optional:
new[] {
"maxConnections",
"timeoutMs",
"pruneMs",
"sessionToken" },
89 CustomValidation: null
91 [ApiEndpoint.CheckStatus] = (
new string[] { },
new string[] { },
null),
92 [ApiEndpoint.ClearReferrer] = (
new string[] { },
new string[] { },
null),
93 [ApiEndpoint.CloseBrowser] = (
94 Mandatory:
new string[] { },
95 Optional:
new string[] { },
96 CustomValidation:
null
98 [ApiEndpoint.CloseTab] = (
99 Mandatory:
new string[] { },
100 Optional:
new[] {
"tabId",
"url" },
101 CustomValidation: null
103 [ApiEndpoint.CloseWindow] = (
104 Mandatory:
new string[] { },
105 Optional:
new[] {
"windowId",
"url" },
106 CustomValidation:
null
116 [ApiEndpoint.DeleteStorage] = (
new[] {
"storageType" },
new[] {
"domain",
"path",
"key",
"storeName" },
null),
117 [ApiEndpoint.DragAndDrop] = (
new[] {
"deltaX",
"deltaY" },
new[] {
"css",
"elementId",
"offsetX",
"offsetY" },
null),
118 [ApiEndpoint.Evaluate] = (
new string[] { },
new string[] {
"xpath",
"elementId" }, dict =>
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId")),
119 [ApiEndpoint.EvaluateAll] = (
new string[] { },
new string[] {
"xpath",
"elementId" }, dict =>
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId")),
120 [ApiEndpoint.EvaluatePersistent] = (
new string[] { },
new string[] {
"xpath",
"elementId" }, dict =>
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId")),
121 [ApiEndpoint.EvaluateAllPersistent] = (
new string[] { },
new string[] {
"xpath",
"elementId" }, dict =>
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId")),
122 [ApiEndpoint.ExecuteJavaScript] = (
new[] {
"script" },
new[] {
"parameters" },
null),
123 [ApiEndpoint.Fetch] = (
new[] {
"url" },
new[] {
"method",
"body",
"contentType",
"headers",
"bytes" },
null),
124 [ApiEndpoint.FillInAppend] = (
new[] {
"text" },
new string[] {
"css",
"elementId",
"gpalElements",
"typingDelay" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
125 [ApiEndpoint.FillInInsert] = (
new[] {
"text" },
new string[] {
"css",
"elementId",
"gpalElements",
"typingDelay" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
126 [ApiEndpoint.FillInOverwrite] = (
new[] {
"text" },
new string[] {
"css",
"elementId",
"gpalElements",
"typingDelay" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
127 [ApiEndpoint.FireChangeEvent] = (
new string[] { },
new string[] {
"css",
"elementId",
"gpalElements" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
128 [ApiEndpoint.Focus] = (
new string[] { },
new string[] {
"css",
"elementId",
"gpalElements" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
129 [ApiEndpoint.Forward] = (
new string[] { },
new string[] { },
null),
130 [ApiEndpoint.FullScreen] = (
new string[] { },
new string[] { },
null),
131 [ApiEndpoint.GetAttribute] = (
new[] {
"attribute" },
new string[] {
"css",
"elementId",
"gpalElements" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
132 [ApiEndpoint.GetBoundingClientRect] = (
new string[] { },
new string[] {
"css",
"elementId",
"gpalElements" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
133 [ApiEndpoint.ElementFromPoint] = (
new[] {
"x",
"y" },
new string[] {
"css",
"elementId",
"gpalElements" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
134 [ApiEndpoint.GetBrowserSettings] = (
new string[] { },
new string[] { },
null),
135 [ApiEndpoint.GetCssAttributes] = (
new string[] { },
new string[] {
"css",
"elementId",
"gpalElements" },
null),
136 [ApiEndpoint.GetContentAndCss] = (
new string[] { },
new string[] {
"elementId",
"gpalElements" },
null),
137 [ApiEndpoint.GetCurrentUrl] = (
new string[] { },
new string[] { },
null),
138 [ApiEndpoint.GetCurrentWindow] = (
new string[] { },
new string[] { },
null),
139 [ApiEndpoint.GetDomAttributes] = (
new string[] { },
new string[] {
"css",
"elementId",
"gpalElements" },
null),
140 [ApiEndpoint.GetDomProperties] = (
new string[] { },
new string[] {
"css",
"elementId",
"gpalElements" },
null),
141 [ApiEndpoint.GetElementAttributeHash] = (
new string[] { },
new string[] {
"css",
"elementId",
"gpalElements" },
null),
142 [ApiEndpoint.GetGpalSettings] = (
new string[] { },
new string[] { },
null),
143 [ApiEndpoint.GetPageSource] = (
new string[] { },
new string[] { },
null),
144 [ApiEndpoint.GetParentNode] = (
new string[] { },
new string[] {
"css",
"elementId",
"gpalElements" },
null),
145 [ApiEndpoint.GetReadyStatus] = (
new string[] { },
new string[] {
"sessionToken" },
null),
146 [ApiEndpoint.GetSettings] = (
new string[] { },
new string[] { },
null),
147 [ApiEndpoint.GetShadowRoot] = (
new string[] { },
new string[] {
"css",
"elementId" },
null),
148 [ApiEndpoint.GetStorage] = (
new[] {
"storageType" },
new[] {
"domain",
"path",
"key",
"storeName" },
null),
149 [ApiEndpoint.GetLanguages] = (
new string[] { },
new string[] { },
null),
150 [ApiEndpoint.CaptureCalls] = (
new string[] { },
new[] {
"capture",
"filter",
"clear" },
null),
151 [ApiEndpoint.GetCapturedCalls] = (
new string[] { },
new string[] { },
null),
152 [ApiEndpoint.GetUserAgent] = (
new string[] { },
new string[] { },
null),
153 [ApiEndpoint.GetWorkflow] = (
new string[] { },
new string[] { },
null),
154 [ApiEndpoint.GoTo] = (
new[] {
"url" },
new string[] { },
null),
155 [ApiEndpoint.GoToTab] = (
156 Mandatory:
new string[] { },
157 Optional:
new[] {
"tabId",
"url" },
158 CustomValidation: dict =>
true == dict.ContainsKey(
"tabId") ||
true == dict.ContainsKey(
"url")
160 [ApiEndpoint.GoToWindow] = (
161 Mandatory:
new string[] { },
162 Optional:
new[] {
"url",
"windowId" },
163 CustomValidation: dict => dict.ContainsKey(
"url") != dict.ContainsKey(
"windowId")
165 [ApiEndpoint.GetWindowRectangle] = (
new string[] { },
new string[] { },
null),
166 [ApiEndpoint.HideElement] = (
new string[] { },
new string[] {
"css",
"elementId",
"gpalElements" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
167 [ApiEndpoint.Hover] = (
new string[] { },
new string[] {
"css",
"elementId",
"gpalElements" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
168 [ApiEndpoint.InjectScript] = (
new[] {
"script" },
new string[] { },
null),
169 [ApiEndpoint.ClearInjectedScripts] = (
new string[] { },
new string[] { },
null),
170 [ApiEndpoint.IsClickable] = (
new string[] { },
new string[] {
"css",
"elementId",
"gpalElements" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
171 [ApiEndpoint.IsDisplayed] = (
new string[] { },
new string[] {
"css",
"elementId",
"gpalElements" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
172 [ApiEndpoint.IsEnabled] = (
new string[] { },
new string[] {
"css",
"elementId",
"gpalElements" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
173 [ApiEndpoint.IsEndOfPage] = (
new string[] { },
new string[] { },
null),
174 [ApiEndpoint.IsVisibleInViewport] = (
new string[] { },
new string[] {
"css",
"elementId",
"gpalElements" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
175 [ApiEndpoint.LeftClick] = (
new string[] { },
new string[] {
"css",
"elementId",
"gpalElements",
"modifiers" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements") ||
true == dict.ContainsKey(
"modifiers")),
176 [ApiEndpoint.LeftClickAndDownload] = (
new[] {
"downloadPath" },
new string[] {
"css",
"elementId",
"gpalElements",
"modifiers" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements") ||
true == dict.ContainsKey(
"modifiers")),
177 [ApiEndpoint.LeftDoubleClick] = (
new string [] { },
new string[] {
"css",
"elementId",
"gpalElements",
"modifiers" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements") ||
true == dict.ContainsKey(
"modifiers")),
178 [ApiEndpoint.Maximize] = (
new string[] { },
new string[] { },
null),
179 [ApiEndpoint.MiddleClick] = (
new string[] { },
new string[] {
"css",
"elementId",
"gpalElements",
"modifiers" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements") ||
true == dict.ContainsKey(
"modifiers")),
180 [ApiEndpoint.Minimize] = (
new string[] { },
new string[] { },
null),
181 [ApiEndpoint.MoveTo] = (
new string[] { },
new string[] {
"css",
"elementId",
"gpalElements" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
182 [ApiEndpoint.NewTab] = (
new string[] { },
new[] {
"url" },
null),
183 [ApiEndpoint.NextTab] = (
new string[] { },
new string[] { },
null),
184 [ApiEndpoint.NextWindow] = (
new string[] { },
new string[] { },
null),
185 [ApiEndpoint.Normal] = (
new string[] { },
new string[] { },
null),
186 [ApiEndpoint.OpenWindow] = (
new string[] { },
new[] {
"url" },
null),
187 [ApiEndpoint.OverrideReferrer] = (
new[] {
"url" },
new string[] { },
null),
188 [ApiEndpoint.PageDown] = (
new string[] { },
new string[] {
"pagesToScroll" },
null),
189 [ApiEndpoint.PageEnd] = (
new string[] { },
new string[] { },
null),
190 [ApiEndpoint.PageTop] = (
new string[] { },
new string[] { },
null),
191 [ApiEndpoint.PageUp] = (
new string[] { },
new string[] {
"pagesToScroll" },
null),
192 [ApiEndpoint.PressModifierKey] = (
new[] {
"modifierKeys" },
new string[] { },
null),
193 [ApiEndpoint.PreviousTab] = (
new string[] { },
new string[] { },
null),
194 [ApiEndpoint.PreviousWindow] = (
new string[] { },
new string[] { },
null),
195 [ApiEndpoint.QuerySelector] = (
new string[] { },
new string[] {
"css",
"elementId" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId")),
196 [ApiEndpoint.QuerySelectors] = (
new string[] { },
new string[] {
"css",
"elementId" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId")),
197 [ApiEndpoint.QueryPersistentSelector] = (
new string[] { },
new string[] {
"css",
"elementId" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId")),
198 [ApiEndpoint.QueryPersistentSelectors] = (
new string[] { },
new string[] {
"css",
"elementId" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId")),
199 [ApiEndpoint.Refresh] = (
new string[] { },
new string[] { },
null),
200 [ApiEndpoint.ReleaseModifierKey] = (
new[] {
"modifierKeys" },
new string[] { },
null),
201 [ApiEndpoint.Restore] = (
new string[] { },
new string[] { },
null),
202 [ApiEndpoint.RightClick] = (
new string[] { },
new string[] {
"css",
"elementId",
"gpalElements",
"modifiers" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements") ||
true == dict.ContainsKey(
"modifiers")),
203 [ApiEndpoint.RightClickAndDownload] = (
new[] {
"downloadPath" },
new string[] {
"modifiers" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId")),
204 [ApiEndpoint.ScrollWindowByHorizontal] = (
new[] {
"hPixels" },
new string[] {
"vPixels" },
null),
205 [ApiEndpoint.ScrollWindowByVertical] = (
new[] {
"vPixels" },
new string[] {
"hPixels" },
null),
206 [ApiEndpoint.ScrollElement] = (
207 Mandatory:
new string[] { },
208 Optional:
new string[] { },
209 CustomValidation: dict =>
true == (dict.ContainsKey(
"hPixels") ||
true == dict.ContainsKey(
"vPixels")) && (
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId"))
211 [ApiEndpoint.ScrollIntoView] = (
new string[] { },
new string[] {
"css",
"elementId",
"gpalElements" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
212 [ApiEndpoint.ScrollWindow] = (
213 Mandatory:
new string[] { },
214 Optional:
new[] {
"hPixels",
"vPixels" },
215 CustomValidation: dict =>
true == dict.ContainsKey(
"hPixels") ||
true == dict.ContainsKey(
"vPixels")
217 [ApiEndpoint.SelectClick] = (
new string[] { },
new[] {
"elementId",
"gpalElements",
"selectIndex",
"selectValue" }, dict =>
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements") ||
true == dict.ContainsKey(
"index") ||
true == dict.ContainsKey(
"value")),
218 [ApiEndpoint.SendKey] = (
new [] {
"key",
"code",
"vk" },
new string[] { },
null),
219 [ApiEndpoint.SendString] = (
new[] {
"text" },
new[] {
"typingDelay" },
null),
220 [ApiEndpoint.SetAttribute] = (
new[] {
"attribute",
"value" },
new string[] { }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId")),
221 [ApiEndpoint.SetDownloadFilename] = (
new[] {
"downloadPath" },
new string[] { },
null),
222 [ApiEndpoint.SetRange] = (
new[] {
"elementId",
"rangeValue" },
new string[] { },
null),
223 [ApiEndpoint.SetStorage] = (
new[] {
"storageType",
"key",
"data" },
new[] {
"domain",
"path",
"storeName" },
null),
224 [ApiEndpoint.SetStorageCache] = (
new[] {
"storageType",
"key",
"data",
"storeName" },
new[] {
"domain",
"path" },
null),
225 [ApiEndpoint.SetStorageIndexedDb] = (
new[] {
"storageType",
"key",
"data",
"path",
"storeName" },
new[] {
"domain" },
null),
226 [ApiEndpoint.SetUserAgent] = (
new[] {
"userAgent" },
new string[] { },
null),
227 [ApiEndpoint.SetValueFromElement] = (
new[] {
"destSelector" },
new string[] {
"css",
"elementId",
"gpalElements" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
228 [ApiEndpoint.StealthOverrideReferrer] = (
new string[] { },
new string[] { },
null),
229 [ApiEndpoint.StopCasting] = (
new string[] { },
new string[] { },
null),
230 [ApiEndpoint.SubmitForm] = (
new string[] { },
new string[] {
"css",
"elementId",
"gpalElements" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
231 [ApiEndpoint.SwitchToDefaultContent] = (
new string[] { },
new string[] { },
null),
232 [ApiEndpoint.SwitchToElement] = (
new string[] { },
new string[] {
"css",
"elementId" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId")),
233 [ApiEndpoint.SwitchToFrame] = (
new string[] { },
new string[] {
"css",
"elementId" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId")),
234 [ApiEndpoint.SwitchToShadowRoot] = (
new string[] { },
new string[] {
"css",
"elementId" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId")),
235 [ApiEndpoint.TabCount] = (
new string[] { },
new string[] { },
null),
236 [ApiEndpoint.TopBrowser] = (
new string[] { },
new string[] { },
null),
237 [ApiEndpoint.MoveToPoint] = (
new[] {
"x",
"y" },
new string[] { },
null),
238 [ApiEndpoint.ClickPoint] = (
new[] {
"x",
"y" },
new string[] {
"clickType",
"modifiers" },
null),
239 [ApiEndpoint.TrustedLeftClick] = (
new string[] { },
new string[] {
"css",
"elementId",
"gpalElements",
"modifiers",
"holdMs" },
null),
240 [ApiEndpoint.Upload] = (
new[] {
"elementId" },
new string[] {
"css",
"elementId",
"gpalElements",
"modifiers",
"uploadPath",
"uploadPaths" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements") ||
true == dict.ContainsKey(
"modifiers")),
241 [ApiEndpoint.WindowInnerHeight] = (
new string[] { },
new string[] { },
null),
242 [ApiEndpoint.WindowInnerWidth] = (
new string[] { },
new string[] { },
null),
243 [ApiEndpoint.WindowOuterHeight] = (
new string[] { },
new string[] { },
null),
244 [ApiEndpoint.WindowOuterWidth] = (
new string[] { },
new string[] { },
null),
245 [ApiEndpoint.WindowPageOffsetX] = (
new string[] { },
new string[] { },
null),
246 [ApiEndpoint.WindowPageOffsetY] = (
new string[] { },
new string[] { },
null),
247 [ApiEndpoint.WindowScreenLeft] = (
new string[] { },
new string[] { },
null),
248 [ApiEndpoint.WindowScreenTop] = (
new string[] { },
new string[] { },
null),
252 internal RESTClient()
262 internal set => _name = value;
272 _helper =
new RESTHelper(url,
this);
278 _helper =
new RESTHelper(url,
this, httpTimeout);
290 _endpoint = endpoint;
291 _customEndpoint =
true;
306 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}RESTHelper not initialized. Call WithAPIBase first.",
307 null, GPALObjectType.None);
310 else if (
false == RESTHelper.Endpoints.ContainsKey(endpoint))
313 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}API endpoint [{endpoint}] not found in Endpoints dictionary. Using empty string.",
314 null, GPALObjectType.None);
319 _endpoint = RESTHelper.Endpoints[endpoint];
326 if (
string.IsNullOrWhiteSpace(yamlOrUrl))
328 GPAL.
PublishSimpleEvent(GPALEventType.ERROR,
"LoadOpenAPIMap: yamlOrUrl is empty",
null, GPALObjectType.Other);
333 string chosenBaseUrl =
null;
335 if (yamlOrUrl.StartsWith(
"http", StringComparison.OrdinalIgnoreCase))
340 using var http =
new HttpClient();
341 yamlContent = http.GetStringAsync(yamlOrUrl).GetAwaiter().GetResult();
342 chosenBaseUrl = ExtractBestServerUrl(yamlContent);
346 GPAL.PublishSimpleEvent(GPALEventType.ERROR,
347 $
"Failed to download OpenAPI spec from [{yamlOrUrl}]", ex.Message, GPALObjectType.Other, ex);
354 yamlContent = yamlOrUrl;
355 chosenBaseUrl = ExtractBestServerUrl(yamlContent);
359 if (!
string.IsNullOrWhiteSpace(chosenBaseUrl))
361 _helper =
new RESTHelper(chosenBaseUrl,
this);
362 GPAL.PublishSimpleEvent(GPALEventType.INFO,
363 $
"LoadOpenAPIMap set API base to: [{chosenBaseUrl}]",
null, GPALObjectType.Other);
367 GPAL.PublishSimpleEvent(GPALEventType.WARNING,
368 "LoadOpenAPIMap could not determine API base from servers section",
null, GPALObjectType.Other);
372 LoadOpenApiRulesInternal(yamlContent);
377 public IAllowRESTEndpointDetails LoadOpenAPIMap(GPALFile openApiMapFile)
382 string yamlContent = File.ReadAllText(openApiMapFile.
Filename);
383 return LoadOpenAPIMap(yamlContent);
387 GPAL.PublishSimpleEvent(GPALEventType.ERROR,
388 $
"Failed to read OpenAPI file [{openApiMapFile.Filename}]", ex.Message, GPALObjectType.Other, ex);
393 public void LoadOpenApiRulesInternal(
string yamlContent)
397 var reader =
new Microsoft.OpenApi.Readers.OpenApiStreamReader();
398 using var stream =
new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(yamlContent));
399 var document = reader.Read(stream, out var diagnostic);
401 if (diagnostic.Errors.Any())
403 GPAL.PublishSimpleEvent(GPALEventType.WARNING,
404 $
"OpenAPI parse issues: [{diagnostic.Errors.Count}] [{string.Join(",
",diagnostic.Errors)}]", diagnostic, GPALObjectType.Other);
407 openApiParamRules.Clear();
409 foreach (var pathItem
in document.Paths)
411 foreach (var opKv
in pathItem.Value.Operations)
413 var method = opKv.Key.ToString().ToUpperInvariant();
414 var path = pathItem.Key.TrimStart(
'/');
415 var ruleKey = $
"{method} {path}";
417 var mandatory =
new List<string>();
418 var optional =
new List<string>();
420 foreach (var param
in opKv.Value.Parameters)
423 mandatory.Add(param.Name);
425 optional.Add(param.Name);
428 if (opKv.Value.RequestBody?.Required ==
true)
429 mandatory.Add(
"body");
431 openApiParamRules[ruleKey] = (
432 Mandatory: mandatory.ToArray(),
433 Optional: optional.ToArray(),
434 CustomValidation:
null
439 GPAL.PublishSimpleEvent(GPALEventType.INFO,
440 $
"Loaded OpenAPI rules for [{openApiParamRules.Count}] operations from spec",
441 null, GPALObjectType.Other);
445 GPAL.PublishSimpleEvent(GPALEventType.EXCEPTION,
446 "Failed to load OpenAPI parameter rules", yamlContent?.Length ?? 0, GPALObjectType.Other, ex);
450 public IAllowRESTEndpointDetails ListOpenAPIEndPoints()
452 foreach (var key
in openApiParamRules.Keys)
453 GPAL.PublishSimpleEvent(GPALEventType.INFO, key);
465 _nextResultName = name;
476 _parameters =
new { url };
488 if (0 > resultIndex || resultIndex >= _executionResults.Count)
491 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result index [{resultIndex}] is out of range for WithUrlFromResult. Using empty string.",
492 null, GPALObjectType.None);
495 var previousResult = _executionResults[resultIndex].Result;
496 var url =
null == previousResult ?
"" : previousResult.ToString();
507 var resultEntry = _executionResults.LastOrDefault(entry => entry.Name == name);
508 if (
null == resultEntry.Result)
511 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result name [{name}] not found for WithUrlFromResult. Using empty string.",
512 null, GPALObjectType.None);
515 var previousResult = resultEntry.Result;
516 var url =
null == previousResult ?
"" : previousResult.ToString();
527 _parameters =
new { tabId };
539 if (0 > resultIndex || resultIndex >= _executionResults.Count)
542 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result index [{resultIndex}] is out of range for WithTabIdFromResult. Using 0.",
543 null, GPALObjectType.None);
546 var previousResult = _executionResults[resultIndex].Result;
547 var tabId = previousResult is
int i ? i : 0;
558 var resultEntry = _executionResults.LastOrDefault(entry => entry.Name == name);
559 if (
null == resultEntry.Result)
562 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result name [{name}] not found for WithTabIdFromResult. Using 0.",
563 null, GPALObjectType.None);
566 var previousResult = resultEntry.Result;
567 var tabId = previousResult is
int i ? i : 0;
578 _parameters =
new { script, parameters = _parameters };
590 _parameters =
null == _parameters
592 : MergeParameters(_parameters,
new { key });
605 if (0 > resultIndex || resultIndex >= _executionResults.Count)
608 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result index [{resultIndex}] is out of range for WithKeyFromResult. Using empty string.",
609 null, GPALObjectType.None);
612 var previousResult = _executionResults[resultIndex].Result;
613 var key =
null == previousResult ?
"" : previousResult.ToString();
624 var resultEntry = _executionResults.LastOrDefault(entry => entry.Name == name);
625 if (
null == resultEntry.Result)
628 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result name [{name}] not found for WithKeyFromResult. Using empty string.",
629 null, GPALObjectType.None);
632 var previousResult = resultEntry.Result;
633 var key =
null == previousResult ?
"" : previousResult.ToString();
655 _parameters =
null == _parameters
657 : MergeParameters(_parameters,
new { css });
669 if (0 > resultIndex || resultIndex >= _executionResults.Count)
672 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result index [{resultIndex}] is out of range for WithCssFromResult. Using empty string.",
673 null, GPALObjectType.None);
676 var previousResult = _executionResults[resultIndex].Result;
677 var css =
null == previousResult ?
"" : previousResult.ToString();
688 var resultEntry = _executionResults.LastOrDefault(entry => entry.Name == name);
689 if (
null == resultEntry.Result)
692 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result name [{name}] not found for WithCssFromResult. Using empty string.",
693 null, GPALObjectType.None);
696 var previousResult = resultEntry.Result;
697 var css =
null == previousResult ?
"" : previousResult.ToString();
708 List<GPALElement> gpalElements =
new List<GPALElement>() { (
GPALElement)gPALElement };
710 _parameters =
null == _parameters
711 ?
new { gpalElements }
712 : MergeParameters(_parameters,
new { gpalElements });
724 if (0 > resultIndex || resultIndex >= _executionResults.Count)
727 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result index [{resultIndex}] is out of range for WithElementFromResult. Using empty string.",
728 null, GPALObjectType.None);
731 var previousResult = _executionResults[resultIndex].Result;
735 if (previousResult is IEnumerable<object> enumerable &&
false == (previousResult is
string))
737 elementId =
null == enumerable.FirstOrDefault() ?
"" : enumerable.FirstOrDefault().ToString();
741 elementId =
null == previousResult ?
"" : previousResult.ToString();
753 var resultEntry = _executionResults.LastOrDefault(entry => entry.Name == name);
754 if (
null == resultEntry.Result)
757 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result name [{name}] not found for WithElementFromResult. Using empty string.",
758 null, GPALObjectType.None);
761 var previousResult = resultEntry.Result;
765 if (previousResult is IEnumerable<object> enumerable &&
false == (previousResult is
string))
767 elementId =
null == enumerable.FirstOrDefault() ?
"" : enumerable.FirstOrDefault().ToString();
771 elementId =
null == previousResult ?
"" : previousResult.ToString();
783 _parameters =
null == _parameters
785 : MergeParameters(_parameters,
new { timeoutMs });
797 _parameters =
null == _parameters
799 : MergeParameters(_parameters,
new { pruneMs });
811 _parameters =
null == _parameters
812 ?
new { maxConnections }
813 : MergeParameters(_parameters,
new { maxConnections });
825 _parameters =
null == _parameters
827 : MergeParameters(_parameters,
new { uploadPath });
839 _parameters =
null == _parameters
840 ?
new { uploadPaths }
841 : MergeParameters(_parameters,
new { uploadPaths });
853 _parameters =
null == _parameters
855 : MergeParameters(_parameters,
new { xpath });
867 if (0 > resultIndex || resultIndex >= _executionResults.Count)
870 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result index [{resultIndex}] is out of range for WithXPathFromResult. Using empty string.",
871 null, GPALObjectType.None);
874 var previousResult = _executionResults[resultIndex].Result;
875 var xpath =
null == previousResult ?
"" : previousResult.ToString();
886 var resultEntry = _executionResults.LastOrDefault(entry => entry.Name == name);
887 if (
null == resultEntry.Result)
890 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result name [{name}] not found for WithXPathFromResult. Using empty string.",
891 null, GPALObjectType.None);
894 var previousResult = resultEntry.Result;
895 var xpath =
null == previousResult ?
"" : previousResult.ToString();
906 _parameters =
null == _parameters
908 : MergeParameters(_parameters, parameters);
920 _parameters =
null == _parameters
922 : MergeParameters(_parameters, parameters);
934 if (0 > resultIndex || resultIndex >= _executionResults.Count)
937 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result index [{resultIndex}] is out of range for WithParametersFromResult. Using null.",
938 null, GPALObjectType.None);
943 _parameters = _executionResults[resultIndex].Result;
956 var resultEntry = _executionResults.LastOrDefault(entry => entry.Name == name);
957 if (
null == resultEntry.Result)
960 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result name [{name}] not found for WithParametersFromResult. Using null.",
961 null, GPALObjectType.None);
966 _parameters = resultEntry.Result;
979 _parameters =
null == _parameters
981 : MergeParameters(_parameters,
new { data });
994 _parameters =
null == _parameters
996 : MergeParameters(_parameters,
new { storeName });
1009 _parameters =
null == _parameters
1011 : MergeParameters(_parameters,
new { domain });
1024 _parameters =
null == _parameters
1026 : MergeParameters(_parameters,
new { path });
1039 _parameters =
null == _parameters
1040 ?
new { storageType = storageType.ToString() }
1041 : MergeParameters(_parameters,
new { storageType = storageType.ToString() });
1054 _parameters =
null == _parameters
1056 : MergeParameters(_parameters,
new { key });
1064 _parameters =
null == _parameters
1065 ?
new { crossOrigin }
1066 : MergeParameters(_parameters,
new { crossOrigin });
1079 _parameters =
null == _parameters
1081 : MergeParameters(_parameters,
new { pixels });
1093 if (0 > resultIndex || resultIndex >= _executionResults.Count)
1096 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result index [{resultIndex}] is out of range for WithPixelsFromResult. Using 0.",
1097 null, GPALObjectType.None);
1100 var previousResult = _executionResults[resultIndex].Result;
1101 var pixels = previousResult is
int i ? i : 0;
1112 var resultEntry = _executionResults.LastOrDefault(entry => entry.Name == name);
1113 if (
null == resultEntry.Result)
1116 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result name [{name}] not found for WithPixelsFromResult. Using 0.",
1117 null, GPALObjectType.None);
1120 var previousResult = resultEntry.Result;
1121 var pixels = previousResult is
int i ? i : 0;
1132 _parameters =
null == _parameters
1134 : MergeParameters(_parameters,
new { url });
1146 if (0 > resultIndex || resultIndex >= _executionResults.Count)
1149 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result index [{resultIndex}] is out of range. Using empty string.",
1150 null, GPALObjectType.None);
1153 var previousResult = _executionResults[resultIndex].Result;
1154 var referrer =
null == previousResult ?
"" : previousResult.ToString();
1165 var resultEntry = _executionResults.LastOrDefault(entry => entry.Name == name);
1166 if (
null == resultEntry.Result)
1169 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result name [{name}] not found. Using empty string.",
1170 null, GPALObjectType.None);
1173 var previousResult = resultEntry.Result;
1174 var referrer =
null == previousResult ?
"" : previousResult.ToString();
1185 _parameters =
null == _parameters
1187 : MergeParameters(_parameters,
new { text });
1199 if (0 > resultIndex || resultIndex >= _executionResults.Count)
1202 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result index [{resultIndex}] is out of range for WithTextFromResult. Using empty string.",
1203 null, GPALObjectType.None);
1206 var previousResult = _executionResults[resultIndex].Result;
1207 var text =
null == previousResult ?
"" : previousResult.ToString();
1218 var resultEntry = _executionResults.LastOrDefault(entry => entry.Name == name);
1219 if (
null == resultEntry.Result)
1222 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result name [{name}] not found for WithTextFromResult. Using empty string.",
1223 null, GPALObjectType.None);
1226 var previousResult = resultEntry.Result;
1227 var text =
null == previousResult ?
"" : previousResult.ToString();
1242 if (
null == downloadPath ||
null == downloadPath.
Filenames || 0 == downloadPath.
Filenames.Count)
1244 GPAL.
PublishSimpleEvent(GPALEventType.ERROR,
"DownloadTo requires a valid GPALFile with at least one filename.",
null, GPALObjectType.None);
1248 _parameters =
null == _parameters
1249 ?
new { downloadPath }
1250 : MergeParameters(_parameters,
new { downloadPath });
1265 GPAL.
PublishSimpleEvent(GPALEventType.ERROR,
"SaveResultsTo requires a valid GPALFile with at least one filename.",
null, GPALObjectType.None);
1279 _httpMethod =
null == method ?
"GET" : method;
1290 string imageFormat = format.ToString();
1291 _parameters =
null == _parameters
1292 ?
new { imageFormat }
1293 : MergeParameters(_parameters,
new { imageFormat });
1305 _parameters =
null == _parameters
1307 : MergeParameters(_parameters,
new { index });
1319 _parameters =
null == _parameters
1321 : MergeParameters(_parameters,
new { sinkName });
1334 if (
null == _helper)
1336 string noBase = $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}No API base is set for endpoint [{_endpoint}]. A browser's own client has one once the browser is launched.";
1340 throw new GPALException($
"{GPAL.MyMethodName()}: {noBase}");
1343 GPALEventType publishToConsole =
GPAL.GPALSettings.ConsoleEvents;
1344 GPALEventType publishToDebug =
GPAL.GPALSettings.DebugEvents;
1348 bool customApiPassedValidation = _customEndpoint;
1350 if (
true == _customEndpoint && 0 < openApiParamRules.Count())
1352 string ruleKey = GetOpenApiRuleKey(_httpMethod, _endpoint);
1353 customApiPassedValidation = (
false ==
string.IsNullOrEmpty(ruleKey) &&
true == openApiParamRules.ContainsKey(ruleKey) &&
true == ValidateOpenApiParameters(ruleKey));
1356 if (
true == customApiPassedValidation ||
true == ValidateParameters(RESTHelper.Endpoints.FirstOrDefault(kvp => kvp.Value == _endpoint).Key))
1358 if (
false == publishEvent)
1360 GPAL.GPALSettings.ConsoleEvents = GPALEventType.NONE;
1361 GPAL.GPALSettings.DebugEvents = GPALEventType.NONE;
1364 var result = _helper.Call(_endpoint, _parameters, _httpMethod, _contentEncoding).Result;
1366 _executionResults.Add((_nextResultName, result, _currentIteration));
1367 _nextResultName =
null;
1368 if (
null != _saveFile)
1370 SaveResponseToFile(result, _saveFile);
1377 catch (AggregateException ex)
1379 if (
true == publishEvent)
1381 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Execution failed synchronously for endpoint [{_endpoint}].",
1382 null, GPALObjectType.None, ex.InnerException);
1386 throw ex.InnerException;
1392 GPAL.GPALSettings.ConsoleEvents = publishToConsole;
1393 GPAL.GPALSettings.DebugEvents = publishToDebug;
1406 if (
null == _helper)
1408 string noBase = $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}No API base is set for endpoint [{_endpoint}]. A browser's own client has one once the browser is launched.";
1412 throw new GPALException($
"{GPAL.MyMethodName()}: {noBase}");
1415 GPALEventType publishToConsole =
GPAL.GPALSettings.ConsoleEvents;
1416 GPALEventType publishToDebug =
GPAL.GPALSettings.DebugEvents;
1421 bool customApiPassedValidation = _customEndpoint;
1423 if (
true == _customEndpoint && 0 < openApiParamRules.Count())
1425 string ruleKey = GetOpenApiRuleKey(_httpMethod, _endpoint);
1426 customApiPassedValidation = (
false ==
string.IsNullOrEmpty(ruleKey) &&
true == openApiParamRules.ContainsKey(ruleKey) &&
true == ValidateOpenApiParameters(ruleKey));
1429 if (
true == customApiPassedValidation ||
true == ValidateParameters(RESTHelper.Endpoints.FirstOrDefault(kvp => kvp.Value == _endpoint).Key))
1431 if (
false == publishEvent)
1433 GPAL.GPALSettings.ConsoleEvents = GPALEventType.NONE;
1434 GPAL.GPALSettings.DebugEvents = GPALEventType.NONE;
1443 result = _helper.CallAndDeserialize<T>(_endpoint, _parameters, _httpMethod, _contentEncoding).Result;
1445 catch (AggregateException ex)
1447 if (
true == publishEvent)
1449 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Execution failed synchronously for endpoint [{_endpoint}].",
1450 null, GPALObjectType.None, ex.InnerException);
1454 throw ex.InnerException;
1459 while (
null == result && 0 < --retry);
1461 _executionResults.Add((_nextResultName, result, _currentIteration));
1462 _nextResultName =
null;
1464 if (_saveFile !=
null)
1474 GPAL.GPALSettings.ConsoleEvents = publishToConsole;
1475 GPAL.GPALSettings.DebugEvents = publishToDebug;
1485 var result =
Execute(publishEvent);
1486 _executionResults.Add((_nextResultName, result, _currentIteration));
1499 _executionResults.Add((_nextResultName, result, _currentIteration));
1513 if (
null == _helper)
1515 string noBase = $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}No API base is set for endpoint [{_endpoint}]. A browser's own client has one once the browser is launched.";
1519 throw new GPALException($
"{GPAL.MyMethodName()}: {noBase}");
1522 GPALEventType publishToConsole =
GPAL.GPALSettings.ConsoleEvents;
1523 GPALEventType publishToDebug =
GPAL.GPALSettings.DebugEvents;
1527 bool customApiPassedValidation = _customEndpoint;
1529 if (
true == _customEndpoint && 0 < openApiParamRules.Count())
1531 string ruleKey = GetOpenApiRuleKey(_httpMethod, _endpoint);
1532 customApiPassedValidation = (
false ==
string.IsNullOrEmpty(ruleKey) &&
true == openApiParamRules.ContainsKey(ruleKey) &&
true == ValidateOpenApiParameters(ruleKey));
1535 if (
true == customApiPassedValidation ||
true == ValidateParameters(RESTHelper.Endpoints.FirstOrDefault(kvp => kvp.Value == _endpoint).Key))
1537 if (
false == publishEvent)
1539 GPAL.GPALSettings.ConsoleEvents = GPALEventType.NONE;
1540 GPAL.GPALSettings.DebugEvents = GPALEventType.NONE;
1543 var result = await _helper.Call(_endpoint, _parameters, _httpMethod, _contentEncoding);
1544 _executionResults.Add((_nextResultName, result, _currentIteration));
1545 _nextResultName =
null;
1551 catch (AggregateException ex)
1553 if (
true == publishEvent)
1555 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Execution failed asynchronously for endpoint [{_endpoint}].",
1556 null, GPALObjectType.None, ex.InnerException);
1560 throw ex.InnerException;
1566 GPAL.GPALSettings.ConsoleEvents = publishToConsole;
1567 GPAL.GPALSettings.DebugEvents = publishToDebug;
1580 if (
null == _helper)
1582 string noBase = $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}No API base is set for endpoint [{_endpoint}]. A browser's own client has one once the browser is launched.";
1586 throw new GPALException($
"{GPAL.MyMethodName()}: {noBase}");
1589 GPALEventType publishToConsole =
GPAL.GPALSettings.ConsoleEvents;
1590 GPALEventType publishToDebug =
GPAL.GPALSettings.DebugEvents;
1594 bool customApiPassedValidation = _customEndpoint;
1596 if (
true == _customEndpoint && 0 < openApiParamRules.Count())
1598 string ruleKey = GetOpenApiRuleKey(_httpMethod, _endpoint);
1599 customApiPassedValidation = (
false ==
string.IsNullOrEmpty(ruleKey) &&
true == openApiParamRules.ContainsKey(ruleKey) &&
true == ValidateOpenApiParameters(ruleKey));
1602 if (
true == customApiPassedValidation ||
true == ValidateParameters(RESTHelper.Endpoints.FirstOrDefault(kvp => kvp.Value == _endpoint).Key))
1604 if (
false == publishEvent)
1606 GPAL.GPALSettings.ConsoleEvents = GPALEventType.NONE;
1607 GPAL.GPALSettings.DebugEvents = GPALEventType.NONE;
1610 T result = await _helper.CallAndDeserialize<T>(_endpoint, _parameters, _httpMethod, _contentEncoding);
1611 _executionResults.Add((_nextResultName, result, _currentIteration));
1612 _nextResultName =
null;
1614 if (_saveFile !=
null)
1622 catch (Exception ex)
1624 if (
true == publishEvent)
1626 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Execution failed asynchronously for endpoint [{_endpoint}].",
1627 null, GPALObjectType.None, ex);
1632 GPAL.GPALSettings.ConsoleEvents = publishToConsole;
1633 GPAL.GPALSettings.DebugEvents = publishToDebug;
1663 if (
null == workflow)
1666 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Workflow cannot be null.",
1667 null, GPALObjectType.None);
1671 _workflowStates.Add((_endpoint, _parameters, _httpMethod, _nextResultName));
1672 _workflows.Add(workflow);
1684 if (0 == _workflows.Count)
1687 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}No workflows defined for While loop.",
1688 null, GPALObjectType.None);
1694 const int maxIterations = 1000;
1696 while (condition() && iteration < maxIterations)
1698 _currentIteration = iteration;
1699 for (
int i = 0; i < _workflows.Count; i++)
1701 var initialState = _workflowStates[i];
1702 if (initialState.HasValue)
1704 (_endpoint, _parameters, _httpMethod, _nextResultName) = initialState.Value;
1710 _workflows[i](
this);
1715 if (maxIterations <= iteration)
1718 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}While loop reached maximum iterations [{maxIterations}].",
1719 null, GPALObjectType.None);
1723 _currentIteration = 0;
1734 if (0 == _workflows.Count)
1737 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}No workflows defined for Until loop.",
1738 null, GPALObjectType.None);
1744 const int maxIterations = 1000;
1746 while (
false == condition() && iteration < maxIterations)
1748 _currentIteration = iteration;
1749 for (
int i = 0; i < _workflows.Count; i++)
1751 var initialState = _workflowStates[i];
1752 if (initialState.HasValue)
1754 (_endpoint, _parameters, _httpMethod, _nextResultName) = initialState.Value;
1760 _workflows[i](
this);
1765 if (maxIterations <= iteration)
1768 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Until loop reached maximum iterations [{maxIterations}].",
1769 null, GPALObjectType.None);
1773 _currentIteration = 0;
1784 _parameters =
null == _parameters
1786 : MergeParameters(_parameters,
new { elementId });
1798 _contentEncoding = encoding;
1801 internal static string GetContentType(ContentEncoding encoding)
1803 return encoding
switch
1805 ContentEncoding.UrlEncoded =>
"application/x-www-form-urlencoded",
1806 ContentEncoding.Json =>
"application/json",
1807 _ =>
"application/json"
1819 if (!
string.IsNullOrEmpty(name) && !
string.IsNullOrEmpty(value))
1821 _headers[name] = value;
1824 GPAL.
PublishSimpleEvent(GPALEventType.WARNING, $
"Invalid name [{name}] or value [{value}], nothing added to the header.",
null, GPALObjectType.None);
1836 if (0 > resultIndex || resultIndex >= _executionResults.Count)
1839 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result index [{resultIndex}] out of range. Using empty values.",
1840 null, GPALObjectType.None);
1843 var result = _executionResults[resultIndex].Result?.ToString().Split(
new[] {
':' }, 2);
1844 var name = result?.Length > 0 ? result[0] :
"";
1845 var value = result?.Length > 1 ? result[1] :
"";
1856 var resultEntry = _executionResults.LastOrDefault(entry => entry.Name == name);
1857 if (
null == resultEntry.Result)
1860 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result name [{name}] not found. Using empty values.",
1861 null, GPALObjectType.None);
1864 var result = resultEntry.Result?.ToString().Split(
new[] {
':' }, 2);
1865 var headerName = result?.Length > 0 ? result[0] :
"";
1866 var headerValue = result?.Length > 1 ? result[1] :
"";
1877 _parameters =
null == _parameters
1879 : MergeParameters(_parameters,
new { deltaX });
1891 _parameters =
null == _parameters
1893 : MergeParameters(_parameters,
new { deltaY });
1905 _parameters =
null == _parameters
1907 : MergeParameters(_parameters,
new { offsetX });
1919 _parameters =
null == _parameters
1921 : MergeParameters(_parameters,
new { offsetY });
1933 _parameters =
null == _parameters
1935 : MergeParameters(_parameters,
new { hPixels });
1947 if (0 > resultIndex || resultIndex >= _executionResults.Count)
1950 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result index [{resultIndex}] is out of range for WithHPixelsFromResult. Using 0.",
1951 null, GPALObjectType.None);
1954 var previousResult = _executionResults[resultIndex].Result;
1955 var hPixels = previousResult is
int i ? i : 0;
1966 var resultEntry = _executionResults.LastOrDefault(entry => entry.Name == name);
1967 if (
null == resultEntry.Result)
1970 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result name [{name}] not found for WithHPixelsFromResult. Using 0.",
1971 null, GPALObjectType.None);
1974 var previousResult = resultEntry.Result;
1975 var hPixels = previousResult is
int i ? i : 0;
1986 _parameters =
null == _parameters
1988 : MergeParameters(_parameters,
new { vPixels });
2000 if (0 > resultIndex || resultIndex >= _executionResults.Count)
2003 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result index [{resultIndex}] is out of range for WithVPixelsFromResult. Using 0.",
2004 null, GPALObjectType.None);
2007 var previousResult = _executionResults[resultIndex].Result;
2008 var vPixels = previousResult is
int i ? i : 0;
2019 var resultEntry = _executionResults.LastOrDefault(entry => entry.Name == name);
2020 if (
null == resultEntry.Result)
2023 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result name [{name}] not found for WithVPixelsFromResult. Using 0.",
2024 null, GPALObjectType.None);
2027 var previousResult = resultEntry.Result;
2028 var vPixels = previousResult is
int i ? i : 0;
2037 WithImageFormat(imageFormat);
2056 return WithDownloadFile(downloadPath);
2062 _parameters =
null == _parameters
2063 ?
new { downloadPath }
2064 : MergeParameters(_parameters,
new { downloadPath });
2089 WithEndpoint(ApiEndpoint.EvaluateAll).WithXPath(xpath);
2101 WithEndpoint(ApiEndpoint.EvaluatePersistent).WithXPath(xpath);
2113 WithEndpoint(ApiEndpoint.EvaluateAllPersistent).WithXPath(xpath);
2136 WithEndpoint(ApiEndpoint.FireChangeEvent).WithElementId(elementId);
2148 WithEndpoint(ApiEndpoint.Focus).WithElementId(elementId);
2160 WithEndpoint(ApiEndpoint.GetBoundingClientRect).WithElementId(elementId);
2174 WithEndpoint(ApiEndpoint.ElementFromPoint).WithElementId(elementId);
2176 _parameters =
null == _parameters
2178 : MergeParameters(_parameters,
new { x, y });
2190 _parameters =
null == _parameters
2192 : MergeParameters(_parameters,
new { elementId });
2196 public IAllowRESTExecution GetCssAttributes(
string elementId)
2199 _parameters =
null == _parameters
2201 : MergeParameters(_parameters,
new { elementId });
2205 public IAllowRESTExecution GetDomAttributes(
string elementId)
2208 _parameters =
null == _parameters
2210 : MergeParameters(_parameters,
new { elementId });
2214 public IAllowRESTExecution GetDomProperties(
string elementId)
2217 _parameters =
null == _parameters
2219 : MergeParameters(_parameters,
new { elementId });
2230 WithEndpoint(ApiEndpoint.GetElementAttributeHash).WithElementId(elementId);
2241 WithEndpoint(ApiEndpoint.SwitchToElement).WithElementId(elementId).AndThen().WithCss(
"option");
2257 WithEndpoint(ApiEndpoint.GetParentNode).WithElementId(elementId);
2269 WithEndpoint(ApiEndpoint.HideElement).WithElementId(elementId);
2281 WithEndpoint(ApiEndpoint.IsClickable).WithElementId(elementId);
2293 WithEndpoint(ApiEndpoint.IsDisplayed).WithElementId(elementId);
2305 WithEndpoint(ApiEndpoint.IsEnabled).WithElementId(elementId);
2328 WithEndpoint(ApiEndpoint.IsVisibleInViewport).WithElementId(elementId);
2340 WithEndpoint(ApiEndpoint.LeftClick).WithElementId(elementId);
2352 WithEndpoint(ApiEndpoint.LeftDoubleClick).WithElementId(elementId);
2363 WithEndpoint(ApiEndpoint.MiddleClick).WithElementId(elementId);
2399 WithEndpoint(ApiEndpoint.QueryPersistentSelector).WithCss(css);
2411 WithEndpoint(ApiEndpoint.QueryPersistentSelectors).WithCss(css);
2423 WithEndpoint(ApiEndpoint.RightClick).WithElementId(elementId);
2435 WithEndpoint(ApiEndpoint.ScrollIntoView).WithElementId(elementId);
2448 WithEndpoint(ApiEndpoint.ScrollElement).WithHPixels(hPixels).WithVPixels(vPixels);
2460 WithEndpoint(ApiEndpoint.GetAttribute).WithElementId(elementId);
2472 WithEndpoint(ApiEndpoint.SetAttribute).WithElementId(elementId);
2494 _parameters =
null == _parameters
2496 : MergeParameters(_parameters,
new { attribute });
2509 WithEndpoint(ApiEndpoint.SetRange).WithElementId(elementId);
2521 _parameters =
null == _parameters
2522 ?
new { rangeValue = rangeValue.ToString() }
2523 : MergeParameters(_parameters,
new { rangeValue = rangeValue.ToString() });
2536 _parameters =
null == _parameters
2538 : MergeParameters(_parameters,
new { value });
2598 _parameters =
null == _parameters
2600 : MergeParameters(_parameters,
new { url });
2614 _parameters =
null == _parameters
2616 : MergeParameters(_parameters,
new { method });
2629 _parameters =
null == _parameters
2631 : MergeParameters(_parameters,
new { body });
2644 _parameters =
null == _parameters
2645 ?
new { contentType }
2646 : MergeParameters(_parameters,
new { contentType });
2659 _parameters =
null == _parameters
2661 : MergeParameters(_parameters,
new { headers });
2675 _parameters =
null == _parameters
2677 : MergeParameters(_parameters,
new { bytes });
2734 WithEndpoint(ApiEndpoint.Hover).WithElementId(elementId);
2741 private void Reset()
2743 _customEndpoint =
false; ;
2745 _httpMethod =
"GET";
2777 WithEndpoint(ApiEndpoint.CheckNetworkIdle).WithMaxConnections(maxConnections);
2817 _parameters =
null == _parameters
2819 : MergeParameters(_parameters,
new { script });
2832 _parameters =
null == _parameters
2834 : MergeParameters(_parameters,
new { script });
2935 WithEndpoint(ApiEndpoint.GetShadowRoot).WithElementId(css);
2961 _parameters =
null == _parameters
2963 : MergeParameters(_parameters,
new { capture });
2977 _parameters =
null == _parameters
2978 ?
new { filter = urlFragment }
2979 : MergeParameters(_parameters,
new { filter = urlFragment });
2992 _parameters =
null == _parameters
2994 : MergeParameters(_parameters,
new { clear });
3041 if (
true ==
string.IsNullOrEmpty(url))
3042 url =
new GPALUrl(
"google.com");
3081 WithEndpoint(ApiEndpoint.FillInAppend).WithElementId(elementId);
3093 WithEndpoint(ApiEndpoint.FillInInsert).WithElementId(elementId);
3105 WithEndpoint(ApiEndpoint.FillInOverwrite).WithElementId(elementId);
3117 WithEndpoint(ApiEndpoint.LeftClickAndDownload).WithElementId(elementId);
3129 WithEndpoint(ApiEndpoint.Upload).WithElementId(elementId);
3163 WithEndpoint(ApiEndpoint.MoveTo).WithElementId(elementId);
3237 WithEndpoint(ApiEndpoint.OverrideReferrer).WithReferrer(referrer);
3250 _parameters =
null == _parameters
3252 : MergeParameters(_parameters,
new { userAgent });
3266 _parameters =
null == _parameters
3267 ?
new { pagesToScroll }
3268 : MergeParameters(_parameters,
new { pagesToScroll });
3304 _parameters =
null == _parameters
3305 ?
new { pagesToScroll }
3306 : MergeParameters(_parameters,
new { pagesToScroll });
3319 _parameters =
null == _parameters
3320 ?
new { modifierKeys }
3321 : MergeParameters(_parameters,
new { modifierKeys });
3367 _parameters =
null == _parameters
3368 ?
new { modifierKeys }
3369 : MergeParameters(_parameters,
new { modifierKeys });
3393 WithEndpoint(ApiEndpoint.DragAndDrop).WithElementId(elementId);
3405 WithEndpoint(ApiEndpoint.RightClickAndDownload).WithElementId(elementId);
3417 WithEndpoint(ApiEndpoint.ScrollElement).WithElementId(elementId);
3423 WithEndpoint(ApiEndpoint.ScrollWindow).WithHPixels(hPixels).WithVPixels(vPixels);
3435 WithEndpoint(ApiEndpoint.ScrollWindow).WithHPixels(hPixels).WithVPixels(vPixels);
3449 WithEndpoint(ApiEndpoint.ScrollWindow).WithHPixels(hPixels).WithVPixels(vPixels);
3461 WithEndpoint(ApiEndpoint.SelectClick).WithElementId(elementId);
3473 _parameters =
null == _parameters
3474 ?
new { selectValue }
3475 : MergeParameters(_parameters,
new { selectValue });
3481 _parameters =
null == _parameters
3482 ?
new { selectIndex }
3483 : MergeParameters(_parameters,
new { selectIndex });
3501 _parameters =
null == _parameters
3503 : MergeParameters(_parameters,
new { key });
3504 _parameters = MergeParameters(_parameters,
new { code });
3505 _parameters = MergeParameters(_parameters,
new { vk = code });
3521 _parameters =
null == _parameters
3522 ?
new { text, typingDelay = delayMs }
3523 : MergeParameters(_parameters,
new { text, typingDelay = delayMs });
3539 _parameters =
null == _parameters
3540 ?
new { destSelector }
3541 : MergeParameters(_parameters,
new { destSelector });
3566 _parameters =
null == _parameters
3568 : MergeParameters(_parameters,
new { elementId });
3583 #region Window Handling
3592 _parameters =
new { windowId };
3604 if (resultIndex < 0 || resultIndex >= _executionResults.Count)
3607 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result index [{resultIndex}] is out of range for WithWindowIdFromResult. Using 0.",
3608 null, GPALObjectType.None);
3611 var previousResult = _executionResults[resultIndex].Result;
3612 var windowId = previousResult is
int i ? i : (
int.TryParse(previousResult?.ToString(), out
int parsed) ? parsed : 0);
3623 var resultEntry = _executionResults.LastOrDefault(entry => entry.Name == name);
3624 if (resultEntry.Result ==
null)
3627 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result name [{name}] not found for WithWindowIdFromResult. Using 0.",
3628 null, GPALObjectType.None);
3631 var previousResult = resultEntry.Result;
3632 var windowId = previousResult is
int i ? i : (
int.TryParse(previousResult?.ToString(), out
int parsed) ? parsed : 0);
3643 if (
true ==
string.IsNullOrEmpty(url))
3644 url =
new GPALUrl(
"google.com");
3658 WithEndpoint(ApiEndpoint.GoToWindow).WithUrl(url?.Url);
3670 WithEndpoint(ApiEndpoint.GoToWindow).WithWindowId(windowId);
3709 WithEndpoint(ApiEndpoint.CloseWindow).WithWindowId(windowId);
3720 WithEndpoint(ApiEndpoint.DeleteStorage).WithStorageType(storageType);
3732 WithEndpoint(ApiEndpoint.GetStorage).WithStorageType(storageType);
3744 WithEndpoint(ApiEndpoint.SetStorage).WithStorageType(storageType);
3758 #endregion Window Handling
3768 _parameters =
null == _parameters
3770 : MergeParameters(_parameters,
new { elementId });
3784 _parameters =
null == _parameters
3786 : MergeParameters(_parameters,
new { elementId });
3800 _parameters =
null == _parameters
3802 : MergeParameters(_parameters,
new { elementId });
3813 private object MergeParameters(
object existing,
object additional)
3815 var dict = existing is IDictionary<string, object> existingDict
3816 ?
new Dictionary<string, object>(existingDict)
3817 : existing.GetType().GetProperties()
3818 .ToDictionary(p => p.
Name, p => p.GetValue(existing));
3820 if (
null != additional)
3822 var additionalDict = additional is IDictionary<string, object> addDict
3824 : additional?.GetType().GetProperties()
3825 .ToDictionary(p => p.Name, p => p.GetValue(additional));
3827 foreach (var kvp
in additionalDict)
3829 dict[kvp.Key] = kvp.Value;
3836 internal bool ValidateParameters(ApiEndpoint endpoint, IDictionary<string, object> parmsToValidate =
null)
3840 var internalParms = _parameters as IDictionary<string, object>
3841 ?? (
null != _parameters ? _parameters.GetType().GetProperties().ToDictionary(p => p.Name, p => p.GetValue(_parameters))
3842 :
new Dictionary<string, object>());
3844 var paramsDict = parmsToValidate ?? internalParms;
3846 if (
false == paramRules.ContainsKey(endpoint))
3848 GPAL.PublishSimpleEvent(GPALEventType.WARNING,
3849 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}No validation rules defined for endpoint [{endpoint}].",
3850 null, GPALObjectType.None);
3854 var (mandatory, optional, customValidation) = paramRules[endpoint];
3856 if (ApiEndpoint.SetStorage == endpoint)
3858 var storageType = paramsDict.ContainsKey(
"storageType") ? paramsDict[
"storageType"]?.ToString() :
"";
3859 if (
true ==
"cache".Equals(storageType))
3860 (mandatory, optional, customValidation) = paramRules[ApiEndpoint.SetStorageCache];
3861 else if (
true ==
"indexedDb".Equals(storageType))
3862 (mandatory, optional, customValidation) = paramRules[ApiEndpoint.SetStorageIndexedDb];
3865 var missingMandatory = mandatory.Where(p =>
false == paramsDict.ContainsKey(p)).ToArray();
3867 if (
true == missingMandatory.Any())
3869 GPAL.PublishSimpleEvent(GPALEventType.WARNING,
3870 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Missing required parameters for [{endpoint}]: [{string.Join(",
", missingMandatory)}].",
3871 null, GPALObjectType.None);
3875 if (
null != customValidation &&
false == customValidation(paramsDict))
3877 GPAL.PublishSimpleEvent(GPALEventType.WARNING,
3878 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Custom validation failed for [{endpoint}].",
3879 null, GPALObjectType.None);
3884 var allowedParams = mandatory.Concat(optional).ToHashSet();
3885 var invalidParams = paramsDict.Keys.Where(k =>
false == allowedParams.Contains(k)).ToArray();
3886 if (
true == invalidParams.Any())
3888 GPAL.PublishSimpleEvent(GPALEventType.WARNING,
3889 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Invalid parameters for [{endpoint}]: [{string.Join(",
", invalidParams)}].",
3890 null, GPALObjectType.None);
3894 catch (Exception ex)
3896 GPAL.PublishSimpleEvent(GPALEventType.EXCEPTION, $
"Unable to validate [{endpoint}]",
this, GPALObjectType.RestClient, ex);
3902 internal bool ValidateOpenApiParameters(
string ruleKey, IDictionary<string, object> parmsToValidate =
null)
3906 var internalParms = _parameters as IDictionary<string, object>
3907 ?? (
null != _parameters ? _parameters.GetType().GetProperties().ToDictionary(p => p.Name, p => p.GetValue(_parameters))
3908 :
new Dictionary<string, object>());
3910 var paramsDict = parmsToValidate ?? internalParms;
3912 if (
false == openApiParamRules.ContainsKey(ruleKey))
3914 GPAL.PublishSimpleEvent(GPALEventType.WARNING,
3915 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}No OpenAPI validation rules defined for [{ruleKey}].",
3916 null, GPALObjectType.None);
3920 var (mandatory, optional, customValidation) = openApiParamRules[ruleKey];
3922 var missingMandatory = mandatory.Where(p =>
false == paramsDict.ContainsKey(p)).ToArray();
3924 if (
true == missingMandatory.Any())
3926 GPAL.PublishSimpleEvent(GPALEventType.WARNING,
3927 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Missing required parameters for [{ruleKey}]: [{string.Join(",
", missingMandatory)}].",
3928 null, GPALObjectType.None);
3932 if (
null != customValidation &&
false == customValidation(paramsDict))
3934 GPAL.PublishSimpleEvent(GPALEventType.WARNING,
3935 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Custom validation failed for OpenAPI endpoint [{ruleKey}].",
3936 null, GPALObjectType.None);
3941 var allowedParams = mandatory.Concat(optional).ToHashSet(StringComparer.OrdinalIgnoreCase);
3942 var invalidParams = paramsDict.Keys.Where(k =>
false == allowedParams.Contains(k)).ToArray();
3944 if (
true == invalidParams.Any())
3946 GPAL.PublishSimpleEvent(GPALEventType.WARNING,
3947 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Invalid parameters for [{ruleKey}]: [{string.Join(",
", invalidParams)}].",
3948 null, GPALObjectType.None);
3952 catch (Exception ex)
3954 GPAL.PublishSimpleEvent(GPALEventType.EXCEPTION,
3955 $
"Unable to validate OpenAPI endpoint [{ruleKey}]",
this, GPALObjectType.RestClient, ex);
3966 private string GetOpenApiRuleKey(
string httpMethod,
string endpoint)
3968 if (
string.IsNullOrWhiteSpace(httpMethod) ||
string.IsNullOrWhiteSpace(endpoint))
3971 var path = endpoint.TrimStart(
'/');
3972 return $
"{httpMethod.ToUpperInvariant()} {path}";
3980 private string ExtractBestServerUrl(
string yamlContent)
3984 var reader =
new Microsoft.OpenApi.Readers.OpenApiStreamReader();
3985 using var stream =
new MemoryStream(System.Text.Encoding.UTF8.GetBytes(yamlContent));
3986 var document = reader.Read(stream, out _);
3988 if (document.Servers ==
null || document.Servers.Count == 0)
3992 var remote = document.Servers.FirstOrDefault(s =>
3993 s.Url.StartsWith(
"https://", StringComparison.OrdinalIgnoreCase));
3996 return remote.Url.TrimEnd(
'/');
3999 return document.Servers[0].Url.TrimEnd(
'/');
4006 internal static void SaveResponseToFile(
string response,
string filePath)
4011 if (response.StartsWith(
"data:"))
4014 var base64Part = response.Substring(response.IndexOf(
",") + 1);
4015 var bytes = Convert.FromBase64String(base64Part);
4016 System.IO.File.WriteAllBytes(filePath, bytes);
4017 GPAL.PublishSimpleEvent(GPALEventType.INFO, $
"Saved base64 response to [{filePath}]",
null, GPALObjectType.None);
4019 else if (Uri.TryCreate(response, UriKind.Absolute, out var uri))
4022 using (var client =
new HttpClient())
4023 using (var stream = client.GetStreamAsync(uri).Result)
4024 using (var fileStream = System.IO.File.Create(filePath))
4026 stream.CopyTo(fileStream);
4028 GPAL.PublishSimpleEvent(GPALEventType.INFO, $
"Downloaded response to [{filePath}]",
null, GPALObjectType.None);
4032 GPAL.PublishSimpleEvent(GPALEventType.WARNING, $
"Unsupported response format for saving to [{filePath}]",
null, GPALObjectType.None);
4035 catch (Exception ex)
4037 GPAL.PublishSimpleEvent(GPALEventType.EXCEPTION, $
"Failed to save response to [{filePath}]",
null, GPALObjectType.None, ex);
Represents a URL with optional pre-navigation storage cleanup / inspection actions....
string Url
Gets the target URL string.
Pseudo element used in Applications and Browser workflows for image matching and unified automation....
Thrown where GPAL deliberately ends the workflow, such as a CallIf handler returning CallIfStatus....
GPAL File object instantied with GPAL.File Used to load tokens into a GPALGrid [rows/columns].
List< string > Filenames
Get the list of filenames.
string Filename
We have only one file, accessing it.
Everything starts here, all the GPAL controls and global settings using fluent syntax are here....
static IAllowConverterInput Converter
New GPAL Convertor.
static void PublishSimpleEvent(GPALEventType gPALEventType, string msg, dynamic gPALObject=null, Enums.GPALObjectType gPALObjectType=GPALObjectType.None, Exception ex=null)
Publish a message to either the information channel or exception channel (if exception passed in) Pub...
IAllowRESTExecution SetValueFrom(string destSelector)
Sets the value of the destination element identified by destSelector from the source element identif...
IAllowRESTParametersOrExecution WithWindowIdFromResult(string name)
Sets the window ID from a result by name client.GoToWindow().WithWindowIdFromResult("windowResult")....
IAllowRESTExecution WindowScreenLeft()
Gets the window screen left position client.WindowScreenLeft().Execute<int>();.
IAllowRESTParametersOrExecution WithUrl(string url)
Sets the URL parameter.
IAllowRESTStorageOptions WithStoragePath(string path)
Sets the storage path parameter.
IAllowRESTParametersOrExecution WithKeyFromResult(int resultIndex)
Sets the key from a result by index.
IAllowRESTStorageOptions DeleteStorage(WebsiteStorageType storageType)
Delete the specified storage type.
IAllowRESTExecution ScrollIntoView(string elementId)
Scrolls an element into view by ID client.ScrollIntoView("element123").Execute();.
IAllowRESTParametersOrExecution WithResultName(string name)
Sets the result name for the next execution.
IAllowRESTParametersOrExecution WithElementIdFromResult(int resultIndex)
Sets the element from a result by index.
IAllowRESTParametersOrExecution WithCss(string css)
Sets the CSS parameter.
IAllowRESTParametersOrExecution WithXPath(string xpath)
Sets the XPath parameter.
IAllowRESTExecution WindowInnerWidth()
Gets the window inner width client.WindowInnerWidth().Execute<int>();.
IAllowRESTExecution Back()
Navigates browser history back client.Back().Execute();.
IAllowRESTExecution SubmitForm(string elementId)
Submits a form client.SubmitForm("form123").Execute();.
IAllowRESTExecution HideElement(string elementId)
Hides an element by ID client.HideElement("element123").Execute();.
IAllowRESTCaptureOptions WithClearCalls(bool clear=true)
Forgets what was already recorded before starting, so a second capture is not read as the first.
IAllowRESTParametersOrExecution WithCssFromResult(string name)
Sets the CSS from a result by name.
IAllowRESTParametersOrExecution WithKeyFromResult(string name)
Sets the key from a result by name.
IAllowRESTExecution WithTextFromResult(string name)
Sets the text from a result by name.
IAllowRESTParametersOrExecution WithUrlFromResult(string name)
Sets the URL from a result by name.
IAllowRESTExecution SwitchToElement(string elementId)
Switches to an element to search for selectors contained client.SwitchToElement("div123")....
IAllowRESTExecution GetBrowserSettings()
Gets browser settings client.GetBrowserSettings().Execute();.
IAllowRESTExecution Maximize()
Maximizes the browser window client.Maximize().Execute();.
IAllowRESTExecution CloseTab(int tabId)
Closes a tab by tab ID client.CloseTab(1).Execute();.
IAllowRESTParametersOrExecution WithEncoding(ContentEncoding encoding)
Specifiy the encoiding type for posted parameters: json or urlencoded.
IAllowRESTParametersOrExecution WithBytes(bool bytes)
True to bring the fetched response body back base64 encoded, which is what a file needs....
IAllowRESTParametersOrExecution WithCssFromResult(int resultIndex)
Sets the CSS from a result by index.
IAllowRESTExecution WithRangeValue(int rangeValue)
Specifies the value for SetRange operation client.SetRange("element123").WithRangeValue(63)....
IAllowRESTExecution PreviousWindow()
Switches to the next window client.NextTab().Execute();.
IAllowRESTScrollElement ScrollElement(string elementId)
Starts scrolling an element by ID client.ScrollElement("element123").WithHPixels(100)....
IAllowRESTExecution IsVisibleInViewport(string elementId)
Checks if an element is visible in viewport by ID client.IsVisibleInViewport("element123")....
IAllowRESTExecution ScrollElement(int hPixels, int vPixels)
Scrolls an element by horizontal and vertical pixels client.ScrollElement(100, 200)....
IAllowRESTExecution CloseWindow(int windowId)
Closes a window by window ID, optionally switching to the main window client.CloseWindow(123)....
IAllowRESTExecution GetLanguages()
Gets the browser's preferred languages, most preferred first client.GetLanguages()....
IAllowRESTParametersOrExecution WithTabIdFromResult(string name)
Sets the tab ID from a result by name.
IAllowRESTParametersOrExecution WithParametersFromResult(int resultIndex)
Sets parameters from a result by index.
IAllowRESTStorageOptions WithData(string data)
Sets the set storage data parameter.
IAllowRESTParametersOrExecution WithTabIdFromResult(int resultIndex)
Sets the tab ID from a result by index.
IAllowRESTExecution RightClick(string elementId)
Performs a right click on an element by ID client.RightClick("element123").Execute();.
IAllowRESTStorageOptions SetStorage(WebsiteStorageType storageType)
Set data for the specified storage type.
IAllowRESTExecution NextTab()
Switches to the next tab client.NextTab().Execute();.
IAllowCheckNetworkIdleOrExecution WithPruneMs(int pruneMs)
Sets the prune interval in milliseconds.
IAllowRESTStorageOptions WithStorageDomain(string domain)
Sets the storage domain parameter.
IAllowRESTExecution WithHttpMethod(string method)
Sets the HTTP method.
string Execute(bool publishEvent=true)
Executes the request synchronously.
IAllowRESTExecution LeftDoubleClick(string elementId)
Performs a left double click on an element by ID client.LeftDoubleClick("element123")....
IAllowRESTExecution GetUserAgent()
Gets the user agent client.GetUserAgent().Execute<string>();.
IAllowRESTParametersOrExecution WithReferrerFromResult(int resultIndex)
Sets the referrer from a result by index.
IAllowRESTInputText FillInInsert(string elementId)
Appends text to an element client.FillInAppend("input123").WithText("Hello").Execute();.
IAllowRESTDragAndDrop WithOffsetX(int offsetX)
Sets the horizontal grab offset within the element for a drag-and-drop operation.
IAllowRESTExecution SwitchToDefaultContent()
Switches to default content client.SwitchToDefaultContent().Execute();.
IAllowRESTScrollElement WithVPixelsFromResult(string name)
Sets the vertical pixels from a result by name.
IAllowRESTExecution SwitchToFrame(string elementId)
Switches to a frame client.SwitchToFrame("frame123").Execute();.
IAllowRESTExecution GoTo(GPALUrl url)
Navigates to a URL client.Goto("https://example.com").Execute();.
IAllowRESTExecution CloseTab(GPALUrl url=null)
Closes a tab by URL client.CloseTab("https://example.com").Execute();.
IAllowRESTExecution WindowOuterHeight()
Gets the window outer height client.WindowOuterHeight().Execute<int>();.
IAllowRESTParametersOrExecution WithXPathFromResult(string name)
Sets the XPath from a result by name.
async Task< string > ExecuteAsync(bool publishEvent=true)
Executes the request asynchronously and returns the raw response await client.ExecuteAsync();.
IAllowRESTExecution WindowInnerHeight()
Gets the window inner height client.WindowInnerHeight().Execute<int>();.
IAllowRESTExecution QuerySelectors(string css)
Queries multiple elements using a CSS selector client.QuerySelectors(".class").Execute<string[]>();.
IAllowRESTWithDownloadFilename RightClickAndDownload(string elementId)
Performs a right click and download on an element client.RightClickAndDownload("element123")....
IAllowRESTStorageOptions WithStorageType(WebsiteStorageType storageType)
Sets the storage path parameter.
IAllowRESTExecution IsEndOfPage()
Checks if the page is at the end client.IsEndOfPage().Execute<bool>();.
IAllowRESTScrollElement WithVPixelsFromResult(int resultIndex)
Sets the vertical pixels from a result by index.
IAllowRESTExecution IsClickable(string elementId)
Checks if an element is clickable by ID client.IsClickAble("element123").Execute<bool>();.
IAllowRESTParametersOrExecution WithParametersFromResult(string name)
Sets parameters from a result by name.
IRESTClient AndThen< T >(bool publishEvent=true)
Executes and chains the request with type.
IAllowRESTExecution ScrollWindowByHorizontal(int hPixels)
Scrolls the window horizontally by pixels client.ScrollWindowByHorizontal(100).Execute();.
IAllowRESTExecution EvaluatePersistent(string xpath)
Evaluates an XPath expression client.Evaluate("//div").Execute();.
IAllowRESTExecution OpenWindow(GPALUrl url)
Opens a new window with the specified URL client.OpenWindow("https://example.com")....
IAllowRESTWithUploadFilename LeftClickAndUpload(string elementId)
Purely headless mode, attaches the file to the input[type=file] client.LeftClickAndUpload("element123...
IAllowRESTExecution GetBoundingClientRect(string elementId)
Gets the bounding client rect of an element by ID client.GetBoundingClientRect("element123")....
T Execute< T >(bool publishEvent=true)
Executes the request synchronously with type.
IAllowRESTExecution GetElementAttributeHash(string elementId)
Gets the attribute hash of an element client.GetElementAttributeHash().Execute<string>();.
IAllowRESTParametersOrExecution WithBody(string body)
Sets the body of the request being fetched. client.Fetch(url).WithVerb("POST").WithBody(json)....
IAllowRESTExecution WithHeaderFromResult(string name)
Sets the header from a result by name.
IAllowRESTParametersOrExecution WithParameters(params object[] parameters)
Sets parameters as a variable argument list.
IAllowRESTAttribute WithValue(string value)
Specifies the value for set operation client.SetAttribute("element123").WithAttribute("disabled")....
IAllowRESTExecution PreviousTab()
Switches to the previous tab client.PreviousTab().Execute();.
IAllowRESTExecution WithUploadFiles(GPALFile uploadPaths)
Sets the timeout in milliseconds.
IAllowRESTParametersOrExecution While(Func< bool > condition)
Executes workflows while condition holds client.While(() => someCondition).Execute();.
IAllowRESTParametersOrExecution Fetch(string url)
Issue an API request from inside the page, so it carries the session the browser has already earned: ...
IAllowRESTParametersOrExecution WithWindowIdFromResult(int resultIndex)
Sets the window ID from a result by index client.GoToWindow().WithWindowIdFromResult(0)....
IAllowRESTParametersOrExecution WithScript(string script)
Sets the script parameter.
IAllowRESTExecution GoToWindow(int windowId)
Switches to a window by window ID client.GoToWindow(123).Execute<WindowTuple>();.
IAllowRESTExecution GetCurrentWindow()
Gets the current window's ID and URL client.GetCurrentWindow().Execute<WindowTuple>();.
IAllowRESTExecution Focus(string elementId)
Focuses an element by ID client.Focus("element123").Execute();.
IAllowCheckNetworkIdleOrExecution WithTimeoutMs(int timeoutMs)
Sets the timeout in milliseconds.
IAllowRESTParametersOrExecution WithHeaders(string[] headers)
Sets extra headers for the request being fetched, flattened to name, value, name, value....
IAllowRESTParametersOrExecution WithUrlFromResult(int resultIndex)
Sets the URL from a result by index.
IAllowRESTExecution ReleaseModifierKey(ModifierKeys modifierKeys)
Press the modifier keys specified. Keep pressed until a release is sent.
IAllowRESTParameters ClearInjectedScripts()
Removes all scripts previously registered via InjectScript(string).
ResultCollection GetExecutionResults()
Gets the execution results.
IAllowRESTExecution PageUp(int pagesToScroll=1)
Scrolls the page up by pages client.PageUp(1).Execute();.
IAllowRESTExecution NewTab(GPALUrl url)
Opens a new tab with optional URL client.NewTab("https://example.com").Execute();.
string Name
Gets or sets the client name.
IAllowRESTExecution GetCapturedCalls()
Everything recorded so far, oldest first, as the json the extension keeps. string json = client....
IAllowRESTAttribute SetAttribute(string elementId)
Starts setting an attribute of an element by ID client.SetAttribute("element123")....
IAllowRESTExecution WithHeaderFromResult(int resultIndex)
Sets the header from a result by index.
IAllowRESTExecution ClearReferrer()
Clears the referrer client.ClearReferrer().Execute();.
IAllowRESTExecution IsEnabled(string elementId)
Checks if an element is enabled by ID client.IsEnabled("element123").Execute<bool>();.
IAllowRESTExecution PageEnd()
Scrolls to the page end client.PageEnd().Execute();.
IAllowRESTExecution Normal()
Restores the browser window to normal client.Normal().Execute();.
IAllowRESTExecution Restore()
Restores the browser window client.Restore().Execute();.
IAllowRESTExecution QueryPersistentSelectors(string css)
Queries multiple elements using a CSS selector client.QuerySelectors(".class").Execute<string[]>();.
IAllowRESTExecution TabCount()
How many tabs the browser actually has open, which is not the same as how many GPAL opened....
IAllowRESTEndpointDetails WithName(string name)
Sets the client name.
IAllowRESTExecution GetOptions(string elementId)
Get the options in a Select manue.
IAllowRESTExecution StealthOverrideReferrer()
Overrides referrer stealthily - sets to google.com client.StealthOverrideReferrer()....
IAllowRESTExecution GetReadyStatus()
Gets the ready status client.GetReadyStatus().Execute<string>();.
async Task< T > ExecuteAsync< T >(bool publishEvent=true)
Executes the request asynchronously with type.
IAllowRESTExecution GoToTab(int tabId)
Navigates to a tab by tab ID client.GotoTab(1).Execute();.
IAllowRESTExecution GetParentNode(string elementId)
Gets the parent node of an element by ID client.GetParentNode("element123").Execute<string>();.
IAllowRESTAttribute WithAttribute(string attribute)
Specifies the attribute name for get or set operation client.GetAttribute("element123")....
IAllowRESTExecution SwitchToShadowRoot(string elementId)
Switches to a shadow root client.SwitchToShadowRoot("shadow123").Execute();.
IAllowRESTExecution MoveTo(string elementId)
Moves to an element client.MoveTo("element123").Execute();.
IAllowRESTInputText FillInAppend(string elementId)
Appends text to an element client.FillInAppend("input123").WithText("Hello").Execute();.
IAllowRESTParametersOrExecution DownloadTo(GPALFile downloadPath)
Where a file the browser downloads should end up. Not SaveTo, which is GPAL writing a file it alread...
IAllowRESTParametersOrExecution WithEndpoint(ApiEndpoint endpoint)
Sets the endpoint from an ApiEndpoint enum.
IAllowRESTExecution PressModifierKey(ModifierKeys modifierKeys)
Press the modifier keys specified. Keep pressed until a release is sent.
IAllowRESTParametersOrExecution WithReferrerFromResult(string name)
Sets the referrer from a result by name.
IAllowRESTParameters ExecuteJavaScript(string script)
Executes JavaScript code client.ExecuteJavaScript("return document.title").Execute<string>();.
IAllowRESTParametersOrExecution WithElementId(string elementId)
Sets the element ID parameter.
IAllowRESTStorageOptions WithStorageStoreName(string storeName)
Sets the storage domain parameter.
IAllowRESTExecution GetSettings()
Gets settings client.GetSettings().Execute();.
IAllowRESTExecution WithHeader(string name, string value)
Adds an HTTP header to the request client.WithHeader("Authorization", "Bearer YOUR_ACCESS_TOKEN")....
IAllowRESTParametersOrExecution WithPixelsFromResult(int resultIndex)
Sets the pixels from a result by index.
IAllowRESTParametersOrExecution WithKey(string key)
Sets the key parameter.
IAllowRESTParametersOrExecution WithElementIdFromResult(string name)
Sets the element from a result by name.
IAllowRESTParametersOrExecution WithElement(IGPALElement gPALElement)
Sets the element parameter.
IAllowRESTExecution EvaluateAll(string xpath)
Evaluates an XPath expression for multiple elements client.EvaluateAll("//div").Execute<string[]>();.
IAllowRESTCaptureOptions WithCallFilter(string urlFragment)
Records only the calls whose url holds this, so a page that talks to a dozen places narrows to the on...
IAllowRESTExecution WithTextFromResult(int resultIndex)
Sets the text from a result by index.
IAllowSelectOptions SelectClick(string elementId)
Click a Select menu option.
IAllowRESTExecution CaptureVisibleTab(ImageFormat imageFormat=ImageFormat.JPEG)
Get a screenshot of the current tab visble contents.
IAllowRESTAttribute GetAttribute(string elementId)
Starts getting an attribute of an element by ID client.GetAttribute("element123")....
IAllowRESTExecution CloseWindow(GPALUrl url)
Closes a window by URL, optionally switching to the main window client.CloseWindow("https://example....
IAllowRESTParametersOrExecution WithXPathFromResult(int resultIndex)
Sets the XPath from a result by index.
IAllowRESTExecution ElementFromPoint(string elementId, int x, int y)
Asks whether a click at this viewport point would reach the element, rather than land on whatever is ...
IRESTClient AndThen(bool publishEvent=true)
Executes and chains the request.
IAllowRangeValue SetRange(string elementId)
Starts setting an attribute of an element by ID client.SetAttribute("element123")....
IAllowRESTExecution WithUploadFile(string uploadPath)
Sets the timeout in milliseconds.
IAllowRESTEndpointDetails WithAPIBase(string url)
Sets the API base URL with download path.
IAllowRESTExecution WithText(string text)
Sets the text parameter.
IAllowRESTExecution Refresh()
Refreshes the current page client.Refresh().Execute();.
IAllowRESTExecution FullScreen()
Sets browser to full screen client.FullScreen().Execute();.
IAllowRESTExecution CheckNetworkIdle(int maxConnections=0)
Checks if network is idle with max connections client.CheckNetworkIdle(5).Execute<bool>();.
IAllowRESTExecution SendString(string text, int delayMs=0)
Sends a string client.SendString("Hello").Execute();.
IAllowRESTParametersOrExecution WithPixels(int pixels)
Sets the pixels parameter.
IAllowRESTExecution NextWindow()
Switches to the next window client.NextTab().Execute();.
IAllowRESTExecution MiddleClick(string elementId)
Performs a left click on an element by ID client.LeftClick("element123").Execute();.
IAllowRESTExecution PageDown(int pagesToScroll=1)
Scrolls the page down by pages client.PageDown(1).Execute();.
IRESTClient ToGPALObject()
Converts the client to a GPAL object.
IAllowRESTExecution GetShadowRoot(string css)
Gets the shadow root for a CSS selector client.GetShadowRoot(".class").Execute();.
IAllowRESTExecution EvaluateAllPersistent(string xpath)
Evaluates an XPath expression for multiple elements client.EvaluateAll("//div").Execute<string[]>();.
IAllowRESTExecution TopBrowser()
Top the browser, bring it into focus. Used before performing any actions on the browser.
IAllowRESTExecution GetWorkflow()
Gets the workflow client.GetWorkflow().Execute();.
IAllowRESTScrollElement WithVPixels(int vPixels)
Sets the vertical pixels parameter.
IAllowRESTExecution WindowOuterWidth()
Gets the window outer width client.WindowOuterWidth().Execute<int>();.
IAllowRESTExecution GetGpalSettings()
Gets GPAL settings client.GetGpalSettings().Execute();.
IAllowRESTExecution Minimize()
Minimizes the browser window client.Minimize().Execute();.
IAllowRESTParametersOrExecution SaveResultsTo(GPALFile file)
Saves the response to a file if the endpoint returns a downloadable content client....
IAllowRESTParametersOrExecution WithReferrer(string url)
Sets the referrer parameter.
IAllowRESTParametersOrExecution WithParameters(object parameters)
Sets parameters as a single object.
IAllowRESTParametersOrExecution Until(Func< bool > condition)
Executes workflows until condition holds.
IAllowRESTExecution Evaluate(string xpath)
Evaluates an XPath expression client.Evaluate("//div").Execute();.
IAllowRESTStorageOptions WithStorageKey(string key)
Sets the storage key parameter.
IAllowRESTDragAndDrop WithOffsetY(int offsetY)
Sets the vertical grab offset within the element for a drag-and-drop operation.
IAllowRESTDragAndDrop WithDeltaX(int deltaX)
Sets the horizontal drop offset for a drag-and-drop operation.
IAllowRESTScrollElement WithHPixels(int hPixels)
Sets the horizontal pixels parameter.
IAllowRESTExecution PageTop()
Scrolls to the page top client.PageTop().Execute();.
IAllowRESTParametersOrExecution WithTabId(int tabId)
Sets the tab ID parameter.
IAllowRESTExecution CloseBrowser()
Closes every window the browser has, which is how it is asked to quit client.CloseBrowser()....
IAllowRESTExecution SetUserAgent(string userAgent)
Overrides the browser's user agent string client.SetUserAgent("Mozilla/5.0 ...").Execute();.
IAllowRESTExecution Hover(string elementId)
Hovers over an element by ID client.Hover("element123").Execute();.
IAllowRESTExecution WindowScreenTop()
Gets the window screen top position client.WindowScreenTop().Execute<int>();.
IAllowRESTExecution GetCurrentUrl()
Gets the current URL client.GetCurrentUrl().Execute<string>();.
IAllowRESTDragAndDrop DragAndDrop(string elementId)
Drags an element from its current position by the given offset and drops it client....
IAllowRESTParametersOrExecution WithVerb(string method)
Sets the verb of the request being fetched. Not .WithHttpMethod, which is the verb of the REST call i...
IAllowRESTExecution FireChangeEvent(string elementId)
Fires a change event on an element by ID client.FireChangeEvent("element123").Execute();.
IAllowRESTExecution WindowPageOffsetY()
Gets the window page offset Y client.WindowPageOffsetY().Execute<int>();.
IAllowRESTExecution WithSelectValue(string selectValue)
Set the value to choose from the Select menu.
IAllowRESTParametersOrExecution WithWindowId(int windowId)
Sets the window ID parameter client.CloseWindow(123).Execute<WindowTuple>();.
IAllowRESTExecution Forward()
Navigates browser history forward client.Forward().Execute();.
IAllowRESTExecution WithDeviceName(string sinkName)
Sets the CSS parameter.
IAllowRESTExecution SendKey(byte vkcode)
Sends a key client.SendKey("Enter").Execute();.
IAllowRESTExecution ScrollWindowByVertical(int vPixels)
Scrolls the window vertically by pixels client.ScrollWindowByVertical(100).Execute();.
IAllowRESTScrollElement WithHPixelsFromResult(int resultIndex)
Sets the horizontal pixels from a result by index.
IAllowRESTExecution QuerySelector(string css)
Queries a single element using a CSS selector client.QuerySelector(".class").Execute();.
IAllowRESTExecution GoToTab(GPALUrl url)
Navigates to a tab by URL client.GotoTab("https://example.com").Execute();.
IAllowRESTInputText FillInOverwrite(string elementId)
Appends text to an element client.FillInAppend("input123").WithText("Hello").Execute();.
IAllowRESTExecution GoToWindow(GPALUrl url)
Switches to a window by URL client.GoToWindow("https://example.com").Execute<WindowTuple>();.
IAllowRESTStorageOptions GetStorage(WebsiteStorageType storageType)
Get the specified storage type.
IAllowRESTParametersOrExecution WithContentType(string contentType)
Sets the content type of the body of the request being fetched. client.Fetch(url)....
IAllowRESTExecution LeftClick(string elementId)
Performs a left click on an element by ID client.LeftClick("element123").Execute();.
IAllowRESTParameters InjectScript(string script)
Registers a script to run on every new document load. Persists until ClearInjectedScripts is called.
IAllowRESTWithDownloadFilename LeftClickAndDownload(string elementId)
Performs a left click and download on an element client.LeftClickAndDownload("element123")....
IAllowRESTCaptureOptions CaptureCalls(bool capture=true)
Starts or stops recording what the page asks for. Narrow it with WithCallFilter and start from nothin...
IAllowRESTExecution OverrideReferrer(string referrer)
Overrides the referrer URL client.OverrideReferrr("https://google.com").Execute();.
IAllowCheckNetworkIdleOrExecution WithMaxConnections(int maxConnections)
Sets the maximum connections.
IAllowRESTParametersOrExecution WithPixelsFromResult(string name)
Sets the pixels from a result by name.
IAllowRESTWorkflow WithWorkflow(Action< RESTClient > workflow)
Adds a workflow definition client.WithWorkflow(c => c.WithEndpoint(...).Execute())....
IAllowRESTExecution WindowPageOffsetX()
Gets the window page offset X client.WindowPageOffsetX().Execute<int>();.
IAllowRESTExecution IsDisplayed(string elementId)
Checks if an element is displayed by ID client.IsDisplayed("element123").Execute<bool>();.
IAllowRESTExecution SetDownloadFilename(string downloadPath)
Sets the download filename for the current session client.SetDownloadFilename("/path/to/file")....
IAllowRESTScrollElement WithHPixelsFromResult(string name)
Sets the horizontal pixels from a result by name.
IAllowRESTParametersOrExecution WithEndpoint(string endpoint)
Sets the endpoint as a string.
IAllowRESTExecution QueryPersistentSelector(string css)
Queries a single element using a CSS selector client.QuerySelector(".class").Execute();.
IAllowRESTDragAndDrop WithDeltaY(int deltaY)
Sets the vertical drop offset for a drag-and-drop operation.
IAllowRESTAttribute WithIndex(int index)
Specifies the option index for select menu operations client.SetAttribute("element123")....
static bool TryConvertVkCodeToDomKey(byte vkCode, out string key, out string code)
Converts a Windows VK code to DOM KeyboardEvent key and code values.