18using System.Collections.Generic;
22using System.Threading.Tasks;
23using DocumentFormat.OpenXml.Office2019.Drawing.Diagram11;
57 private readonly List<Action<RESTClient>> _workflows =
new List<Action<RESTClient>>();
58 private readonly List<(
string Endpoint,
object Parameters,
string HttpMethod,
string NextResultName)?> _workflowStates =
new List<(
string,
object,
string,
string)?>();
59 private bool _customEndpoint =
false;
60 private string _endpoint;
61 private object _parameters;
62 private string _httpMethod =
"GET";
63 internal ContentEncoding _contentEncoding = ContentEncoding.Json;
65 private string _saveFile {
get;
set; }
66 private string _nextResultName;
67 private readonly List<(
string Name,
object Result,
int Iteration)> _executionResults =
new List<(
string Name,
object Result,
int Iteration)>();
68 private RESTHelper _helper;
69 private int _currentIteration;
70 internal Dictionary<string, string> _headers =
new Dictionary<string, string>();
73 get => _helper.StatusCode;
78 get => _helper.RetryAfterSeconds;
81 internal Dictionary<string, (
string[] Mandatory,
string[] Optional, Func<IDictionary<string, object>,
bool> CustomValidation)>
82 openApiParamRules =
new Dictionary<
string, (
string[] Mandatory,
string[] Optional, Func<IDictionary<string, object>,
bool> CustomValidation)>(StringComparer.OrdinalIgnoreCase);
84 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)>
86 [ApiEndpoint.Back] = (
new string[] { },
new string[] { },
null),
87 [ApiEndpoint.CaptureVisibleTab] = (
new string[] { },
new string[] {
"windowId",
"imageFormat" },
null),
88 [ApiEndpoint.CastDesktop] = (
new[] {
"sinkName" },
new string[] { },
null),
89 [ApiEndpoint.CastTab] = (
new[] {
"sinkName" },
new string[] { },
null),
90 [ApiEndpoint.CheckNetworkIdle] = (
91 Mandatory:
new string[] { },
92 Optional:
new[] {
"maxConnections",
"timeoutMs",
"pruneMs",
"sessionToken" },
93 CustomValidation: null
95 [ApiEndpoint.CheckStatus] = (
new string[] { },
new string[] { },
null),
96 [ApiEndpoint.ClearReferrer] = (
new string[] { },
new string[] { },
null),
97 [ApiEndpoint.CloseBrowser] = (
98 Mandatory:
new string[] { },
99 Optional:
new string[] { },
100 CustomValidation:
null
102 [ApiEndpoint.CloseTab] = (
103 Mandatory:
new string[] { },
104 Optional:
new[] {
"tabId",
"url" },
105 CustomValidation: null
107 [ApiEndpoint.CloseWindow] = (
108 Mandatory:
new string[] { },
109 Optional:
new[] {
"windowId",
"url" },
110 CustomValidation:
null
120 [ApiEndpoint.DeleteStorage] = (
new[] {
"storageType" },
new[] {
"domain",
"path",
"key",
"storeName" },
null),
121 [ApiEndpoint.DragAndDrop] = (
new[] {
"deltaX",
"deltaY" },
new[] {
"css",
"xpath",
"elementId",
"offsetX",
"offsetY" },
null),
122 [ApiEndpoint.Evaluate] = (
new string[] { },
new string[] {
"xpath",
"elementId" }, dict =>
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId")),
123 [ApiEndpoint.EvaluateAll] = (
new string[] { },
new string[] {
"xpath",
"elementId" }, dict =>
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId")),
124 [ApiEndpoint.EvaluatePersistent] = (
new string[] { },
new string[] {
"xpath",
"elementId" }, dict =>
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId")),
125 [ApiEndpoint.EvaluateAllPersistent] = (
new string[] { },
new string[] {
"xpath",
"elementId" }, dict =>
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId")),
128 [ApiEndpoint.ExecuteJavaScript] = (
new string[] { },
new[] {
"script",
"expression",
"parameters" }, dict =>
true == dict.ContainsKey(
"script") ||
true == dict.ContainsKey(
"expression")),
129 [ApiEndpoint.Fetch] = (
new[] {
"url" },
new[] {
"method",
"body",
"contentType",
"headers",
"bytes" },
null),
130 [ApiEndpoint.FillInAppend] = (
new[] {
"text" },
new string[] {
"css",
"xpath",
"elementId",
"gpalElements",
"typingDelay" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
131 [ApiEndpoint.FillInInsert] = (
new[] {
"text" },
new string[] {
"css",
"xpath",
"elementId",
"gpalElements",
"typingDelay" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
132 [ApiEndpoint.FillInOverwrite] = (
new[] {
"text" },
new string[] {
"css",
"xpath",
"elementId",
"gpalElements",
"typingDelay" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
133 [ApiEndpoint.FireChangeEvent] = (
new string[] { },
new string[] {
"css",
"xpath",
"elementId",
"gpalElements" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
134 [ApiEndpoint.Focus] = (
new string[] { },
new string[] {
"css",
"xpath",
"elementId",
"gpalElements" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
135 [ApiEndpoint.Forward] = (
new string[] { },
new string[] { },
null),
136 [ApiEndpoint.FullScreen] = (
new string[] { },
new string[] { },
null),
137 [ApiEndpoint.GetAttribute] = (
new[] {
"attribute" },
new string[] {
"css",
"xpath",
"elementId",
"gpalElements" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
138 [ApiEndpoint.GetBoundingClientRect] = (
new string[] { },
new string[] {
"css",
"xpath",
"elementId",
"gpalElements" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
139 [ApiEndpoint.ElementFromPoint] = (
new[] {
"x",
"y" },
new string[] {
"css",
"xpath",
"elementId",
"gpalElements" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
140 [ApiEndpoint.GetBrowserSettings] = (
new string[] { },
new string[] { },
null),
141 [ApiEndpoint.GetCssAttributes] = (
new string[] { },
new string[] {
"css",
"xpath",
"elementId",
"gpalElements" },
null),
142 [ApiEndpoint.GetContentAndCss] = (
new string[] { },
new string[] {
"css",
"xpath",
"elementId",
"gpalElements" },
null),
143 [ApiEndpoint.GetCurrentUrl] = (
new string[] { },
new string[] { },
null),
144 [ApiEndpoint.GetCurrentWindow] = (
new string[] { },
new string[] { },
null),
145 [ApiEndpoint.GetDocumentStamp] = (
new string[] { },
new string[] { },
null),
146 [ApiEndpoint.GetHydrationScripts] = (
new string[] { },
new string[] { },
null),
147 [ApiEndpoint.GetDomAttributes] = (
new string[] { },
new string[] {
"css",
"xpath",
"elementId",
"gpalElements" },
null),
148 [ApiEndpoint.GetDomProperties] = (
new string[] { },
new string[] {
"css",
"xpath",
"elementId",
"gpalElements" },
null),
149 [ApiEndpoint.GetElementAttributeHash] = (
new string[] { },
new string[] {
"css",
"xpath",
"elementId",
"gpalElements" },
null),
150 [ApiEndpoint.GetGpalSettings] = (
new string[] { },
new string[] { },
null),
151 [ApiEndpoint.GetPageSource] = (
new string[] { },
new string[] { },
null),
152 [ApiEndpoint.GetParentNode] = (
new string[] { },
new string[] {
"css",
"xpath",
"elementId",
"gpalElements" },
null),
153 [ApiEndpoint.GetReadyStatus] = (
new string[] { },
new string[] {
"sessionToken" },
null),
154 [ApiEndpoint.GetSettings] = (
new string[] { },
new string[] { },
null),
155 [ApiEndpoint.GetShadowRoot] = (
new string[] { },
new string[] {
"css",
"xpath",
"elementId" },
null),
156 [ApiEndpoint.GetStorage] = (
new[] {
"storageType" },
new[] {
"domain",
"path",
"key",
"storeName" },
null),
157 [ApiEndpoint.GetLanguages] = (
new string[] { },
new string[] { },
null),
158 [ApiEndpoint.CaptureCalls] = (
new string[] { },
new[] {
"capture",
"filter",
"clear" },
null),
159 [ApiEndpoint.GetCapturedCalls] = (
new string[] { },
new string[] { },
null),
160 [ApiEndpoint.GetUserAgent] = (
new string[] { },
new string[] { },
null),
161 [ApiEndpoint.GetWorkflow] = (
new string[] { },
new string[] { },
null),
162 [ApiEndpoint.GoTo] = (
new[] {
"url" },
new string[] { },
null),
163 [ApiEndpoint.GoToTab] = (
164 Mandatory:
new string[] { },
165 Optional:
new[] {
"tabId",
"url" },
166 CustomValidation: dict =>
true == dict.ContainsKey(
"tabId") ||
true == dict.ContainsKey(
"url")
168 [ApiEndpoint.GoToWindow] = (
169 Mandatory:
new string[] { },
170 Optional:
new[] {
"url",
"windowId" },
171 CustomValidation: dict => dict.ContainsKey(
"url") != dict.ContainsKey(
"windowId")
173 [ApiEndpoint.GetWindowRectangle] = (
new string[] { },
new string[] { },
null),
174 [ApiEndpoint.HideElement] = (
new string[] { },
new string[] {
"css",
"xpath",
"elementId",
"gpalElements" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
175 [ApiEndpoint.Hover] = (
new string[] { },
new string[] {
"css",
"xpath",
"elementId",
"gpalElements" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
176 [ApiEndpoint.InjectScript] = (
new[] {
"script" },
new string[] { },
null),
177 [ApiEndpoint.ClearInjectedScripts] = (
new string[] { },
new string[] { },
null),
178 [ApiEndpoint.IsClickable] = (
new string[] { },
new string[] {
"css",
"xpath",
"elementId",
"gpalElements" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
179 [ApiEndpoint.IsDisplayed] = (
new string[] { },
new string[] {
"css",
"xpath",
"elementId",
"gpalElements" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
180 [ApiEndpoint.IsEnabled] = (
new string[] { },
new string[] {
"css",
"xpath",
"elementId",
"gpalElements" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
181 [ApiEndpoint.IsEndOfPage] = (
new string[] { },
new string[] { },
null),
182 [ApiEndpoint.IsVisibleInViewport] = (
new string[] { },
new string[] {
"css",
"xpath",
"elementId",
"gpalElements" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
183 [ApiEndpoint.LeftClick] = (
new string[] { },
new string[] {
"css",
"xpath",
"elementId",
"gpalElements",
"modifiers" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
184 [ApiEndpoint.LeftClickAndDownload] = (
new[] {
"downloadPath" },
new string[] {
"css",
"xpath",
"elementId",
"gpalElements",
"modifiers" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
185 [ApiEndpoint.LeftDoubleClick] = (
new string [] { },
new string[] {
"css",
"xpath",
"elementId",
"gpalElements" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
186 [ApiEndpoint.Maximize] = (
new string[] { },
new string[] { },
null),
187 [ApiEndpoint.MiddleClick] = (
new string[] { },
new string[] {
"css",
"xpath",
"elementId",
"gpalElements",
"modifiers" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
188 [ApiEndpoint.Minimize] = (
new string[] { },
new string[] { },
null),
189 [ApiEndpoint.MoveTo] = (
new string[] { },
new string[] {
"css",
"xpath",
"elementId",
"gpalElements" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
190 [ApiEndpoint.NewTab] = (
new string[] { },
new[] {
"url" },
null),
191 [ApiEndpoint.NextTab] = (
new string[] { },
new string[] { },
null),
192 [ApiEndpoint.NextWindow] = (
new string[] { },
new string[] { },
null),
193 [ApiEndpoint.Normal] = (
new string[] { },
new string[] { },
null),
194 [ApiEndpoint.OpenWindow] = (
new string[] { },
new[] {
"url" },
null),
195 [ApiEndpoint.OverrideReferrer] = (
new[] {
"url" },
new string[] { },
null),
196 [ApiEndpoint.PageDown] = (
new string[] { },
new string[] {
"pagesToScroll" },
null),
197 [ApiEndpoint.PageEnd] = (
new string[] { },
new string[] { },
null),
198 [ApiEndpoint.PageTop] = (
new string[] { },
new string[] { },
null),
199 [ApiEndpoint.PageUp] = (
new string[] { },
new string[] {
"pagesToScroll" },
null),
200 [ApiEndpoint.PressModifierKey] = (
new[] {
"modifierKeys" },
new string[] { },
null),
201 [ApiEndpoint.PreviousTab] = (
new string[] { },
new string[] { },
null),
202 [ApiEndpoint.PreviousWindow] = (
new string[] { },
new string[] { },
null),
203 [ApiEndpoint.QuerySelector] = (
new string[] { },
new string[] {
"css",
"elementId" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId")),
204 [ApiEndpoint.QuerySelectors] = (
new string[] { },
new string[] {
"css",
"elementId" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId")),
205 [ApiEndpoint.QueryPersistentSelector] = (
new string[] { },
new string[] {
"css",
"elementId" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId")),
206 [ApiEndpoint.QueryPersistentSelectors] = (
new string[] { },
new string[] {
"css",
"elementId" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"elementId")),
207 [ApiEndpoint.Refresh] = (
new string[] { },
new string[] { },
null),
208 [ApiEndpoint.ReleaseModifierKey] = (
new[] {
"modifierKeys" },
new string[] { },
null),
209 [ApiEndpoint.Restore] = (
new string[] { },
new string[] { },
null),
210 [ApiEndpoint.RightClick] = (
new string[] { },
new string[] {
"css",
"xpath",
"elementId",
"gpalElements",
"modifiers" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
211 [ApiEndpoint.ScrollWindowByHorizontal] = (
new[] {
"hPixels" },
new string[] {
"vPixels" },
null),
212 [ApiEndpoint.ScrollWindowByVertical] = (
new[] {
"vPixels" },
new string[] {
"hPixels" },
null),
213 [ApiEndpoint.ScrollElement] = (
214 Mandatory:
new string[] { },
215 Optional:
new string[] {
"css",
"xpath",
"elementId",
"gpalElements",
"hPixels",
"vPixels" },
216 CustomValidation: null
218 [ApiEndpoint.ScrollIntoView] = (
new string[] { },
new string[] {
"css",
"xpath",
"elementId",
"gpalElements" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
219 [ApiEndpoint.ScrollWindow] = (
220 Mandatory:
new string[] { },
221 Optional:
new[] {
"hPixels",
"vPixels" },
222 CustomValidation: null
224 [ApiEndpoint.SelectClick] = (
new string[] { },
new[] {
"css",
"xpath",
"elementId",
"gpalElements",
"selectIndex",
"selectValue" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements") ||
true == dict.ContainsKey(
"selectIndex") ||
true == dict.ContainsKey(
"selectValue")),
225 [ApiEndpoint.SendKey] = (
new [] {
"key",
"code",
"vk" },
new string[] { },
null),
226 [ApiEndpoint.SendString] = (
new[] {
"text" },
new[] {
"typingDelay" },
null),
227 [ApiEndpoint.SetAttribute] = (
new[] {
"attribute",
"value" },
new string[] {
"css",
"xpath",
"elementId" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId")),
228 [ApiEndpoint.SetDownloadFilename] = (
new[] {
"downloadPath" },
new string[] { },
null),
229 [ApiEndpoint.SetRange] = (
new[] {
"rangeValue" },
new string[] {
"css",
"xpath",
"elementId" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId")),
230 [ApiEndpoint.SetStorage] = (
new[] {
"storageType",
"key",
"data" },
new[] {
"domain",
"path",
"storeName" },
null),
231 [ApiEndpoint.SetStorageCache] = (
new[] {
"storageType",
"key",
"data",
"storeName" },
new[] {
"domain",
"path" },
null),
232 [ApiEndpoint.SetStorageIndexedDb] = (
new[] {
"storageType",
"key",
"data",
"path",
"storeName" },
new[] {
"domain" },
null),
233 [ApiEndpoint.SetUserAgent] = (
new[] {
"userAgent" },
new string[] { },
null),
234 [ApiEndpoint.SetValueFromElement] = (
new[] {
"destSelector" },
new string[] {
"css",
"xpath",
"elementId",
"gpalElements" },
null),
235 [ApiEndpoint.SetGoogleReferrer] = (
new string[] { },
new string[] { },
null),
236 [ApiEndpoint.StopCasting] = (
new string[] { },
new string[] { },
null),
237 [ApiEndpoint.SwitchToDefaultContent] = (
new string[] { },
new string[] { },
null),
238 [ApiEndpoint.SwitchToElement] = (
new string[] { },
new string[] {
"css",
"xpath",
"elementId" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId")),
239 [ApiEndpoint.SwitchToFrame] = (
new string[] { },
new string[] {
"css",
"xpath",
"elementId" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId")),
240 [ApiEndpoint.SwitchToShadowRoot] = (
new string[] { },
new string[] {
"css",
"xpath",
"elementId" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId")),
241 [ApiEndpoint.TabCount] = (
new string[] { },
new string[] { },
null),
242 [ApiEndpoint.TopBrowser] = (
new string[] { },
new string[] { },
null),
243 [ApiEndpoint.MoveToPoint] = (
new[] {
"x",
"y" },
new string[] { },
null),
246 [ApiEndpoint.ClickPoint] = (
new[] {
"x",
"y" },
new string[] {
"clickType",
"modifiers" },
null),
247 [ApiEndpoint.TrustedLeftClick] = (
new[] {
"x",
"y" },
new string[] {
"holdMs" },
null),
248 [ApiEndpoint.TrustedMiddleClick] = (
new[] {
"x",
"y" },
new string[] {
"holdMs" },
null),
249 [ApiEndpoint.Upload] = (
new string[] { },
new string[] {
"css",
"xpath",
"elementId",
"gpalElements",
"uploadPath",
"uploadPaths" }, dict =>
true == dict.ContainsKey(
"css") ||
true == dict.ContainsKey(
"xpath") ||
true == dict.ContainsKey(
"elementId") ||
true == dict.ContainsKey(
"gpalElements")),
250 [ApiEndpoint.WindowInnerHeight] = (
new string[] { },
new string[] { },
null),
251 [ApiEndpoint.WindowInnerWidth] = (
new string[] { },
new string[] { },
null),
252 [ApiEndpoint.WindowOuterHeight] = (
new string[] { },
new string[] { },
null),
253 [ApiEndpoint.WindowOuterWidth] = (
new string[] { },
new string[] { },
null),
254 [ApiEndpoint.WindowPageOffsetX] = (
new string[] { },
new string[] { },
null),
255 [ApiEndpoint.WindowPageOffsetY] = (
new string[] { },
new string[] { },
null),
256 [ApiEndpoint.WindowScreenLeft] = (
new string[] { },
new string[] { },
null),
257 [ApiEndpoint.WindowScreenTop] = (
new string[] { },
new string[] { },
null),
261 internal RESTClient()
271 internal set => _name = value;
281 _helper =
new RESTHelper(url,
this);
295 _helper =
new RESTHelper(url,
this, httpTimeout);
306 _endpoint = endpoint;
307 _customEndpoint =
true;
321 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}RESTHelper not initialized. Call WithAPIBase first.",
322 null, GPALObjectType.None);
325 else if (
false == RESTHelper.Endpoints.ContainsKey(endpoint))
328 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}API endpoint [{endpoint}] not found in Endpoints dictionary. Using empty string.",
329 null, GPALObjectType.None);
334 _endpoint = RESTHelper.Endpoints[endpoint];
341 if (
string.IsNullOrWhiteSpace(yamlOrUrl))
343 GPAL.
PublishSimpleEvent(GPALEventType.ERROR,
"LoadOpenAPIMap: yamlOrUrl is empty",
null, GPALObjectType.Other);
348 string chosenBaseUrl =
null;
350 if (yamlOrUrl.StartsWith(
"http", StringComparison.OrdinalIgnoreCase))
355 using var http =
new HttpClient();
356 yamlContent = http.GetStringAsync(yamlOrUrl).GetAwaiter().GetResult();
357 chosenBaseUrl = ExtractBestServerUrl(yamlContent);
361 GPAL.PublishSimpleEvent(GPALEventType.ERROR,
362 $
"Failed to download OpenAPI spec from [{yamlOrUrl}]", ex.Message, GPALObjectType.Other, ex);
369 yamlContent = yamlOrUrl;
370 chosenBaseUrl = ExtractBestServerUrl(yamlContent);
374 if (!
string.IsNullOrWhiteSpace(chosenBaseUrl))
376 _helper =
new RESTHelper(chosenBaseUrl,
this);
377 GPAL.PublishSimpleEvent(GPALEventType.INFO,
378 $
"LoadOpenAPIMap set API base to: [{chosenBaseUrl}]",
null, GPALObjectType.Other);
382 GPAL.PublishSimpleEvent(GPALEventType.WARNING,
383 "LoadOpenAPIMap could not determine API base from servers section",
null, GPALObjectType.Other);
387 LoadOpenApiRulesInternal(yamlContent);
392 public IAllowRESTEndpointDetails LoadOpenAPIMap(GPALFile openApiMapFile)
397 string yamlContent = File.ReadAllText(openApiMapFile.
Filename);
398 return LoadOpenAPIMap(yamlContent);
402 GPAL.PublishSimpleEvent(GPALEventType.ERROR,
403 $
"Failed to read OpenAPI file [{openApiMapFile.Filename}]", ex.Message, GPALObjectType.Other, ex);
408 public void LoadOpenApiRulesInternal(
string yamlContent)
412 var reader =
new Microsoft.OpenApi.Readers.OpenApiStreamReader();
413 using var stream =
new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(yamlContent));
414 var document = reader.Read(stream, out var diagnostic);
416 if (diagnostic.Errors.Any())
418 GPAL.PublishSimpleEvent(GPALEventType.WARNING,
419 $
"OpenAPI parse issues: [{diagnostic.Errors.Count}] [{string.Join(",
",diagnostic.Errors)}]", diagnostic, GPALObjectType.Other);
422 openApiParamRules.Clear();
424 foreach (var pathItem
in document.Paths)
426 foreach (var opKv
in pathItem.Value.Operations)
428 var method = opKv.Key.ToString().ToUpperInvariant();
429 var path = pathItem.Key.TrimStart(
'/');
430 var ruleKey = $
"{method} {path}";
432 var mandatory =
new List<string>();
433 var optional =
new List<string>();
435 foreach (var param
in opKv.Value.Parameters)
438 mandatory.Add(param.Name);
440 optional.Add(param.Name);
443 if (opKv.Value.RequestBody?.Required ==
true)
444 mandatory.Add(
"body");
446 openApiParamRules[ruleKey] = (
447 Mandatory: mandatory.ToArray(),
448 Optional: optional.ToArray(),
449 CustomValidation:
null
454 GPAL.PublishSimpleEvent(GPALEventType.INFO,
455 $
"Loaded OpenAPI rules for [{openApiParamRules.Count}] operations from spec",
456 null, GPALObjectType.Other);
460 GPAL.PublishSimpleEvent(GPALEventType.EXCEPTION,
461 "Failed to load OpenAPI parameter rules", yamlContent?.Length ?? 0, GPALObjectType.Other, ex);
465 public IAllowRESTEndpointDetails ListOpenAPIEndPoints()
467 foreach (var key
in openApiParamRules.Keys)
468 GPAL.PublishSimpleEvent(GPALEventType.INFO, key);
480 _nextResultName = name;
491 _parameters =
new { url };
503 if (0 > resultIndex || resultIndex >= _executionResults.Count)
506 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result index [{resultIndex}] is out of range for WithUrlFromResult. Using empty string.",
507 null, GPALObjectType.None);
510 var previousResult = _executionResults[resultIndex].Result;
511 var url =
null == previousResult ?
"" : previousResult.ToString();
522 var resultEntry = _executionResults.LastOrDefault(entry => entry.Name == name);
523 if (
null == resultEntry.Result)
526 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result name [{name}] not found for WithUrlFromResult. Using empty string.",
527 null, GPALObjectType.None);
530 var previousResult = resultEntry.Result;
531 var url =
null == previousResult ?
"" : previousResult.ToString();
542 _parameters =
new { tabId };
554 if (0 > resultIndex || resultIndex >= _executionResults.Count)
557 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result index [{resultIndex}] is out of range for WithTabIdFromResult. Using 0.",
558 null, GPALObjectType.None);
561 var previousResult = _executionResults[resultIndex].Result;
562 var tabId = previousResult is
int i ? i : 0;
573 var resultEntry = _executionResults.LastOrDefault(entry => entry.Name == name);
574 if (
null == resultEntry.Result)
577 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result name [{name}] not found for WithTabIdFromResult. Using 0.",
578 null, GPALObjectType.None);
581 var previousResult = resultEntry.Result;
582 var tabId = previousResult is
int i ? i : 0;
593 _parameters =
new { script, parameters = _parameters };
605 _parameters =
null == _parameters
607 : MergeParameters(_parameters,
new { key });
620 if (0 > resultIndex || resultIndex >= _executionResults.Count)
623 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result index [{resultIndex}] is out of range for WithKeyFromResult. Using empty string.",
624 null, GPALObjectType.None);
627 var previousResult = _executionResults[resultIndex].Result;
628 var key =
null == previousResult ?
"" : previousResult.ToString();
639 var resultEntry = _executionResults.LastOrDefault(entry => entry.Name == name);
640 if (
null == resultEntry.Result)
643 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result name [{name}] not found for WithKeyFromResult. Using empty string.",
644 null, GPALObjectType.None);
647 var previousResult = resultEntry.Result;
648 var key =
null == previousResult ?
"" : previousResult.ToString();
670 _parameters =
null == _parameters
672 : MergeParameters(_parameters,
new { css });
684 if (0 > resultIndex || resultIndex >= _executionResults.Count)
687 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result index [{resultIndex}] is out of range for WithCssFromResult. Using empty string.",
688 null, GPALObjectType.None);
691 var previousResult = _executionResults[resultIndex].Result;
692 var css =
null == previousResult ?
"" : previousResult.ToString();
703 var resultEntry = _executionResults.LastOrDefault(entry => entry.Name == name);
704 if (
null == resultEntry.Result)
707 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result name [{name}] not found for WithCssFromResult. Using empty string.",
708 null, GPALObjectType.None);
711 var previousResult = resultEntry.Result;
712 var css =
null == previousResult ?
"" : previousResult.ToString();
723 List<GPALElement> gpalElements =
new List<GPALElement>() { (
GPALElement)gPALElement };
725 _parameters =
null == _parameters
726 ?
new { gpalElements }
727 : MergeParameters(_parameters,
new { gpalElements });
739 if (0 > resultIndex || resultIndex >= _executionResults.Count)
742 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result index [{resultIndex}] is out of range for WithElementFromResult. Using empty string.",
743 null, GPALObjectType.None);
746 var previousResult = _executionResults[resultIndex].Result;
750 if (previousResult is IEnumerable<object> enumerable &&
false == (previousResult is
string))
752 elementId =
null == enumerable.FirstOrDefault() ?
"" : enumerable.FirstOrDefault().ToString();
756 elementId =
null == previousResult ?
"" : previousResult.ToString();
768 var resultEntry = _executionResults.LastOrDefault(entry => entry.Name == name);
769 if (
null == resultEntry.Result)
772 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result name [{name}] not found for WithElementFromResult. Using empty string.",
773 null, GPALObjectType.None);
776 var previousResult = resultEntry.Result;
780 if (previousResult is IEnumerable<object> enumerable &&
false == (previousResult is
string))
782 elementId =
null == enumerable.FirstOrDefault() ?
"" : enumerable.FirstOrDefault().ToString();
786 elementId =
null == previousResult ?
"" : previousResult.ToString();
798 _parameters =
null == _parameters
800 : MergeParameters(_parameters,
new { timeoutMs });
812 _parameters =
null == _parameters
814 : MergeParameters(_parameters,
new { pruneMs });
826 _parameters =
null == _parameters
827 ?
new { maxConnections }
828 : MergeParameters(_parameters,
new { maxConnections });
840 _parameters =
null == _parameters
842 : MergeParameters(_parameters,
new { uploadPath });
854 _parameters =
null == _parameters
855 ?
new { uploadPaths }
856 : MergeParameters(_parameters,
new { uploadPaths });
868 _parameters =
null == _parameters
870 : MergeParameters(_parameters,
new { xpath });
882 if (0 > resultIndex || resultIndex >= _executionResults.Count)
885 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result index [{resultIndex}] is out of range for WithXPathFromResult. Using empty string.",
886 null, GPALObjectType.None);
889 var previousResult = _executionResults[resultIndex].Result;
890 var xpath =
null == previousResult ?
"" : previousResult.ToString();
901 var resultEntry = _executionResults.LastOrDefault(entry => entry.Name == name);
902 if (
null == resultEntry.Result)
905 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result name [{name}] not found for WithXPathFromResult. Using empty string.",
906 null, GPALObjectType.None);
909 var previousResult = resultEntry.Result;
910 var xpath =
null == previousResult ?
"" : previousResult.ToString();
921 _parameters =
null == _parameters
923 : MergeParameters(_parameters, parameters);
935 _parameters =
null == _parameters
937 : MergeParameters(_parameters, parameters);
949 if (0 > resultIndex || resultIndex >= _executionResults.Count)
952 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result index [{resultIndex}] is out of range for WithParametersFromResult. Using null.",
953 null, GPALObjectType.None);
958 _parameters = _executionResults[resultIndex].Result;
971 var resultEntry = _executionResults.LastOrDefault(entry => entry.Name == name);
972 if (
null == resultEntry.Result)
975 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result name [{name}] not found for WithParametersFromResult. Using null.",
976 null, GPALObjectType.None);
981 _parameters = resultEntry.Result;
994 _parameters =
null == _parameters
996 : MergeParameters(_parameters,
new { data });
1009 _parameters =
null == _parameters
1011 : MergeParameters(_parameters,
new { storeName });
1024 _parameters =
null == _parameters
1026 : MergeParameters(_parameters,
new { domain });
1039 _parameters =
null == _parameters
1041 : MergeParameters(_parameters,
new { path });
1054 _parameters =
null == _parameters
1055 ?
new { storageType = storageType.ToString() }
1056 : MergeParameters(_parameters,
new { storageType = storageType.ToString() });
1069 _parameters =
null == _parameters
1071 : MergeParameters(_parameters,
new { key });
1079 _parameters =
null == _parameters
1080 ?
new { crossOrigin }
1081 : MergeParameters(_parameters,
new { crossOrigin });
1094 _parameters =
null == _parameters
1096 : MergeParameters(_parameters,
new { pixels });
1108 if (0 > resultIndex || resultIndex >= _executionResults.Count)
1111 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result index [{resultIndex}] is out of range for WithPixelsFromResult. Using 0.",
1112 null, GPALObjectType.None);
1115 var previousResult = _executionResults[resultIndex].Result;
1116 var pixels = previousResult is
int i ? i : 0;
1127 var resultEntry = _executionResults.LastOrDefault(entry => entry.Name == name);
1128 if (
null == resultEntry.Result)
1131 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result name [{name}] not found for WithPixelsFromResult. Using 0.",
1132 null, GPALObjectType.None);
1135 var previousResult = resultEntry.Result;
1136 var pixels = previousResult is
int i ? i : 0;
1147 _parameters =
null == _parameters
1149 : MergeParameters(_parameters,
new { url });
1161 if (0 > resultIndex || resultIndex >= _executionResults.Count)
1164 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result index [{resultIndex}] is out of range. Using empty string.",
1165 null, GPALObjectType.None);
1168 var previousResult = _executionResults[resultIndex].Result;
1169 var referrer =
null == previousResult ?
"" : previousResult.ToString();
1180 var resultEntry = _executionResults.LastOrDefault(entry => entry.Name == name);
1181 if (
null == resultEntry.Result)
1184 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result name [{name}] not found. Using empty string.",
1185 null, GPALObjectType.None);
1188 var previousResult = resultEntry.Result;
1189 var referrer =
null == previousResult ?
"" : previousResult.ToString();
1200 _parameters =
null == _parameters
1202 : MergeParameters(_parameters,
new { text });
1214 if (0 > resultIndex || resultIndex >= _executionResults.Count)
1217 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result index [{resultIndex}] is out of range for WithTextFromResult. Using empty string.",
1218 null, GPALObjectType.None);
1221 var previousResult = _executionResults[resultIndex].Result;
1222 var text =
null == previousResult ?
"" : previousResult.ToString();
1233 var resultEntry = _executionResults.LastOrDefault(entry => entry.Name == name);
1234 if (
null == resultEntry.Result)
1237 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result name [{name}] not found for WithTextFromResult. Using empty string.",
1238 null, GPALObjectType.None);
1241 var previousResult = resultEntry.Result;
1242 var text =
null == previousResult ?
"" : previousResult.ToString();
1257 if (
null == downloadPath ||
null == downloadPath.
Filenames || 0 == downloadPath.
Filenames.Count)
1259 GPAL.
PublishSimpleEvent(GPALEventType.ERROR,
"DownloadTo requires a valid GPALFile with at least one filename.",
null, GPALObjectType.None);
1263 _parameters =
null == _parameters
1264 ?
new { downloadPath }
1265 : MergeParameters(_parameters,
new { downloadPath });
1280 GPAL.
PublishSimpleEvent(GPALEventType.ERROR,
"SaveResultsTo requires a valid GPALFile with at least one filename.",
null, GPALObjectType.None);
1294 _httpMethod =
null == method ?
"GET" : method;
1305 string imageFormat = format.ToString();
1306 _parameters =
null == _parameters
1307 ?
new { imageFormat }
1308 : MergeParameters(_parameters,
new { imageFormat });
1320 _parameters =
null == _parameters
1322 : MergeParameters(_parameters,
new { index });
1334 _parameters =
null == _parameters
1336 : MergeParameters(_parameters,
new { sinkName });
1349 if (
null == _helper)
1351 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 on an engine that runs one, which OttoMagicClient only is on the OttoMagic engines.";
1355 throw new GPALException($
"{GPAL.MyMethodName()}: {noBase}");
1358 GPALEventType publishToConsole =
GPAL.GPALSettings.ConsoleEvents;
1359 GPALEventType publishToDebug =
GPAL.GPALSettings.DebugEvents;
1363 bool customApiPassedValidation = _customEndpoint;
1365 if (
true == _customEndpoint && 0 < openApiParamRules.Count())
1367 string ruleKey = GetOpenApiRuleKey(_httpMethod, _endpoint);
1368 customApiPassedValidation = (
false ==
string.IsNullOrEmpty(ruleKey) &&
true == openApiParamRules.ContainsKey(ruleKey) &&
true == ValidateOpenApiParameters(ruleKey));
1371 if (
true == customApiPassedValidation ||
true == ValidateParameters(RESTHelper.Endpoints.FirstOrDefault(kvp => kvp.Value == _endpoint).Key))
1373 if (
false == publishEvent)
1375 GPAL.GPALSettings.ConsoleEvents = GPALEventType.NONE;
1376 GPAL.GPALSettings.DebugEvents = GPALEventType.NONE;
1379 var result = _helper.Call(_endpoint, _parameters, _httpMethod, _contentEncoding).Result;
1381 _executionResults.Add((_nextResultName, result, _currentIteration));
1382 _nextResultName =
null;
1387 if (
null != _saveFile)
1389 SaveResponseToFile(result, _saveFile);
1403 catch (AggregateException ex)
1405 if (
true == publishEvent)
1407 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Execution failed synchronously for endpoint [{_endpoint}].",
1408 null, GPALObjectType.None, ex.InnerException);
1412 throw ex.InnerException;
1418 GPAL.GPALSettings.ConsoleEvents = publishToConsole;
1419 GPAL.GPALSettings.DebugEvents = publishToDebug;
1432 if (
null == _helper)
1434 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 on an engine that runs one, which OttoMagicClient only is on the OttoMagic engines.";
1438 throw new GPALException($
"{GPAL.MyMethodName()}: {noBase}");
1441 GPALEventType publishToConsole =
GPAL.GPALSettings.ConsoleEvents;
1442 GPALEventType publishToDebug =
GPAL.GPALSettings.DebugEvents;
1447 bool customApiPassedValidation = _customEndpoint;
1449 if (
true == _customEndpoint && 0 < openApiParamRules.Count())
1451 string ruleKey = GetOpenApiRuleKey(_httpMethod, _endpoint);
1452 customApiPassedValidation = (
false ==
string.IsNullOrEmpty(ruleKey) &&
true == openApiParamRules.ContainsKey(ruleKey) &&
true == ValidateOpenApiParameters(ruleKey));
1455 if (
true == customApiPassedValidation ||
true == ValidateParameters(RESTHelper.Endpoints.FirstOrDefault(kvp => kvp.Value == _endpoint).Key))
1457 if (
false == publishEvent)
1459 GPAL.GPALSettings.ConsoleEvents = GPALEventType.NONE;
1460 GPAL.GPALSettings.DebugEvents = GPALEventType.NONE;
1469 result = _helper.CallAndDeserialize<T>(_endpoint, _parameters, _httpMethod, _contentEncoding).Result;
1471 catch (AggregateException ex)
1473 if (
true == publishEvent)
1475 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Execution failed synchronously for endpoint [{_endpoint}].",
1476 null, GPALObjectType.None, ex.InnerException);
1480 throw ex.InnerException;
1485 while (
null == result && 0 < --retry);
1487 _executionResults.Add((_nextResultName, result, _currentIteration));
1488 _nextResultName =
null;
1494 if (_saveFile !=
null)
1509 GPAL.GPALSettings.ConsoleEvents = publishToConsole;
1510 GPAL.GPALSettings.DebugEvents = publishToDebug;
1520 var result =
Execute(publishEvent);
1521 _executionResults.Add((_nextResultName, result, _currentIteration));
1534 _executionResults.Add((_nextResultName, result, _currentIteration));
1548 if (
null == _helper)
1550 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 on an engine that runs one, which OttoMagicClient only is on the OttoMagic engines.";
1554 throw new GPALException($
"{GPAL.MyMethodName()}: {noBase}");
1557 GPALEventType publishToConsole =
GPAL.GPALSettings.ConsoleEvents;
1558 GPALEventType publishToDebug =
GPAL.GPALSettings.DebugEvents;
1562 bool customApiPassedValidation = _customEndpoint;
1564 if (
true == _customEndpoint && 0 < openApiParamRules.Count())
1566 string ruleKey = GetOpenApiRuleKey(_httpMethod, _endpoint);
1567 customApiPassedValidation = (
false ==
string.IsNullOrEmpty(ruleKey) &&
true == openApiParamRules.ContainsKey(ruleKey) &&
true == ValidateOpenApiParameters(ruleKey));
1570 if (
true == customApiPassedValidation ||
true == ValidateParameters(RESTHelper.Endpoints.FirstOrDefault(kvp => kvp.Value == _endpoint).Key))
1572 if (
false == publishEvent)
1574 GPAL.GPALSettings.ConsoleEvents = GPALEventType.NONE;
1575 GPAL.GPALSettings.DebugEvents = GPALEventType.NONE;
1578 var result = await _helper.Call(_endpoint, _parameters, _httpMethod, _contentEncoding);
1579 _executionResults.Add((_nextResultName, result, _currentIteration));
1580 _nextResultName =
null;
1597 catch (AggregateException ex)
1599 if (
true == publishEvent)
1601 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Execution failed asynchronously for endpoint [{_endpoint}].",
1602 null, GPALObjectType.None, ex.InnerException);
1606 throw ex.InnerException;
1612 GPAL.GPALSettings.ConsoleEvents = publishToConsole;
1613 GPAL.GPALSettings.DebugEvents = publishToDebug;
1626 if (
null == _helper)
1628 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 on an engine that runs one, which OttoMagicClient only is on the OttoMagic engines.";
1632 throw new GPALException($
"{GPAL.MyMethodName()}: {noBase}");
1635 GPALEventType publishToConsole =
GPAL.GPALSettings.ConsoleEvents;
1636 GPALEventType publishToDebug =
GPAL.GPALSettings.DebugEvents;
1640 bool customApiPassedValidation = _customEndpoint;
1642 if (
true == _customEndpoint && 0 < openApiParamRules.Count())
1644 string ruleKey = GetOpenApiRuleKey(_httpMethod, _endpoint);
1645 customApiPassedValidation = (
false ==
string.IsNullOrEmpty(ruleKey) &&
true == openApiParamRules.ContainsKey(ruleKey) &&
true == ValidateOpenApiParameters(ruleKey));
1648 if (
true == customApiPassedValidation ||
true == ValidateParameters(RESTHelper.Endpoints.FirstOrDefault(kvp => kvp.Value == _endpoint).Key))
1650 if (
false == publishEvent)
1652 GPAL.GPALSettings.ConsoleEvents = GPALEventType.NONE;
1653 GPAL.GPALSettings.DebugEvents = GPALEventType.NONE;
1656 T result = await _helper.CallAndDeserialize<T>(_endpoint, _parameters, _httpMethod, _contentEncoding);
1657 _executionResults.Add((_nextResultName, result, _currentIteration));
1658 _nextResultName =
null;
1664 if (_saveFile !=
null)
1677 catch (Exception ex)
1679 if (
true == publishEvent)
1681 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Execution failed asynchronously for endpoint [{_endpoint}].",
1682 null, GPALObjectType.None, ex);
1687 GPAL.GPALSettings.ConsoleEvents = publishToConsole;
1688 GPAL.GPALSettings.DebugEvents = publishToDebug;
1716 _workflowStates.Clear();
1729 _executionResults.Clear();
1748 return GetExecutionResults().GetAllResults(name);
1759 if (
null == workflow)
1762 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Workflow cannot be null.",
1763 null, GPALObjectType.None);
1767 _workflowStates.Add((_endpoint, _parameters, _httpMethod, _nextResultName));
1768 _workflows.Add(workflow);
1780 if (0 == _workflows.Count)
1783 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}No workflows defined for While loop.",
1784 null, GPALObjectType.None);
1790 const int maxIterations = 1000;
1792 while (condition() && iteration < maxIterations)
1794 _currentIteration = iteration;
1795 for (
int i = 0; i < _workflows.Count; i++)
1797 var initialState = _workflowStates[i];
1798 if (initialState.HasValue)
1800 (_endpoint, _parameters, _httpMethod, _nextResultName) = initialState.Value;
1806 _workflows[i](
this);
1811 if (maxIterations <= iteration)
1814 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}While loop reached maximum iterations [{maxIterations}].",
1815 null, GPALObjectType.None);
1819 _currentIteration = 0;
1830 if (0 == _workflows.Count)
1833 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}No workflows defined for Until loop.",
1834 null, GPALObjectType.None);
1840 const int maxIterations = 1000;
1842 while (
false == condition() && iteration < maxIterations)
1844 _currentIteration = iteration;
1845 for (
int i = 0; i < _workflows.Count; i++)
1847 var initialState = _workflowStates[i];
1848 if (initialState.HasValue)
1850 (_endpoint, _parameters, _httpMethod, _nextResultName) = initialState.Value;
1856 _workflows[i](
this);
1861 if (maxIterations <= iteration)
1864 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Until loop reached maximum iterations [{maxIterations}].",
1865 null, GPALObjectType.None);
1869 _currentIteration = 0;
1880 _parameters =
null == _parameters
1882 : MergeParameters(_parameters,
new { elementId });
1894 _contentEncoding = encoding;
1897 internal static string GetContentType(ContentEncoding encoding)
1899 return encoding
switch
1901 ContentEncoding.UrlEncoded =>
"application/x-www-form-urlencoded",
1902 ContentEncoding.Json =>
"application/json",
1903 _ =>
"application/json"
1915 if (!
string.IsNullOrEmpty(name) && !
string.IsNullOrEmpty(value))
1917 _headers[name] = value;
1920 GPAL.
PublishSimpleEvent(GPALEventType.WARNING, $
"Invalid name [{name}] or value [{value}], nothing added to the header.",
null, GPALObjectType.None);
1949 if (
null == _helper)
1951 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}No API base to set a timeout on. Call WithAPIBase first, or take a client from ContinueAsRESTClient",
1952 null, GPALObjectType.None);
1954 _helper.HttpTimeout = httpTimeout;
1966 if (0 > resultIndex || resultIndex >= _executionResults.Count)
1969 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result index [{resultIndex}] out of range. Using empty values.",
1970 null, GPALObjectType.None);
1973 var result = _executionResults[resultIndex].Result?.ToString().Split(
new[] {
':' }, 2);
1974 var name = result?.Length > 0 ? result[0] :
"";
1975 var value = result?.Length > 1 ? result[1] :
"";
1986 var resultEntry = _executionResults.LastOrDefault(entry => entry.Name == name);
1987 if (
null == resultEntry.Result)
1990 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result name [{name}] not found. Using empty values.",
1991 null, GPALObjectType.None);
1994 var result = resultEntry.Result?.ToString().Split(
new[] {
':' }, 2);
1995 var headerName = result?.Length > 0 ? result[0] :
"";
1996 var headerValue = result?.Length > 1 ? result[1] :
"";
2007 _parameters =
null == _parameters
2009 : MergeParameters(_parameters,
new { deltaX });
2021 _parameters =
null == _parameters
2023 : MergeParameters(_parameters,
new { deltaY });
2035 _parameters =
null == _parameters
2037 : MergeParameters(_parameters,
new { offsetX });
2049 _parameters =
null == _parameters
2051 : MergeParameters(_parameters,
new { offsetY });
2063 _parameters =
null == _parameters
2065 : MergeParameters(_parameters,
new { hPixels });
2077 if (0 > resultIndex || resultIndex >= _executionResults.Count)
2080 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result index [{resultIndex}] is out of range for WithHPixelsFromResult. Using 0.",
2081 null, GPALObjectType.None);
2084 var previousResult = _executionResults[resultIndex].Result;
2085 var hPixels = previousResult is
int i ? i : 0;
2096 var resultEntry = _executionResults.LastOrDefault(entry => entry.Name == name);
2097 if (
null == resultEntry.Result)
2100 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result name [{name}] not found for WithHPixelsFromResult. Using 0.",
2101 null, GPALObjectType.None);
2104 var previousResult = resultEntry.Result;
2105 var hPixels = previousResult is
int i ? i : 0;
2116 _parameters =
null == _parameters
2118 : MergeParameters(_parameters,
new { vPixels });
2130 if (0 > resultIndex || resultIndex >= _executionResults.Count)
2133 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result index [{resultIndex}] is out of range for WithVPixelsFromResult. Using 0.",
2134 null, GPALObjectType.None);
2137 var previousResult = _executionResults[resultIndex].Result;
2138 var vPixels = previousResult is
int i ? i : 0;
2149 var resultEntry = _executionResults.LastOrDefault(entry => entry.Name == name);
2150 if (
null == resultEntry.Result)
2153 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result name [{name}] not found for WithVPixelsFromResult. Using 0.",
2154 null, GPALObjectType.None);
2157 var previousResult = resultEntry.Result;
2158 var vPixels = previousResult is
int i ? i : 0;
2167 WithImageFormat(imageFormat);
2186 return WithDownloadFile(downloadPath);
2192 _parameters =
null == _parameters
2193 ?
new { downloadPath }
2194 : MergeParameters(_parameters,
new { downloadPath });
2219 WithEndpoint(ApiEndpoint.EvaluateAll).WithXPath(xpath);
2231 WithEndpoint(ApiEndpoint.EvaluatePersistent).WithXPath(xpath);
2243 WithEndpoint(ApiEndpoint.EvaluateAllPersistent).WithXPath(xpath);
2266 WithEndpoint(ApiEndpoint.FireChangeEvent).WithElementId(elementId);
2278 WithEndpoint(ApiEndpoint.Focus).WithElementId(elementId);
2290 WithEndpoint(ApiEndpoint.GetBoundingClientRect).WithElementId(elementId);
2304 WithEndpoint(ApiEndpoint.ElementFromPoint).WithElementId(elementId);
2306 _parameters =
null == _parameters
2308 : MergeParameters(_parameters,
new { x, y });
2327 object point = 0 < holdMs ? (object)
new { x, y, holdMs } :
new { x, y };
2329 _parameters =
null == _parameters
2331 : MergeParameters(_parameters, point);
2353 object point = 0 < holdMs ? (object)
new { x, y, holdMs } :
new { x, y };
2355 _parameters =
null == _parameters
2357 : MergeParameters(_parameters, point);
2372 _parameters =
null == _parameters
2374 : MergeParameters(_parameters,
new { elementId });
2378 public IAllowRESTExecution GetCssAttributes(
string elementId)
2381 _parameters =
null == _parameters
2383 : MergeParameters(_parameters,
new { elementId });
2387 public IAllowRESTExecution GetDomAttributes(
string elementId)
2390 _parameters =
null == _parameters
2392 : MergeParameters(_parameters,
new { elementId });
2396 public IAllowRESTExecution GetDomProperties(
string elementId)
2399 _parameters =
null == _parameters
2401 : MergeParameters(_parameters,
new { elementId });
2412 WithEndpoint(ApiEndpoint.GetElementAttributeHash).WithElementId(elementId);
2423 WithEndpoint(ApiEndpoint.SwitchToElement).WithElementId(elementId).AndThen().WithCss(
"option");
2439 WithEndpoint(ApiEndpoint.GetParentNode).WithElementId(elementId);
2451 WithEndpoint(ApiEndpoint.HideElement).WithElementId(elementId);
2463 WithEndpoint(ApiEndpoint.IsClickable).WithElementId(elementId);
2475 WithEndpoint(ApiEndpoint.IsDisplayed).WithElementId(elementId);
2487 WithEndpoint(ApiEndpoint.IsEnabled).WithElementId(elementId);
2510 WithEndpoint(ApiEndpoint.IsVisibleInViewport).WithElementId(elementId);
2522 WithEndpoint(ApiEndpoint.LeftClick).WithElementId(elementId);
2534 WithEndpoint(ApiEndpoint.LeftDoubleClick).WithElementId(elementId);
2545 WithEndpoint(ApiEndpoint.MiddleClick).WithElementId(elementId);
2581 WithEndpoint(ApiEndpoint.QueryPersistentSelector).WithCss(css);
2593 WithEndpoint(ApiEndpoint.QueryPersistentSelectors).WithCss(css);
2605 WithEndpoint(ApiEndpoint.RightClick).WithElementId(elementId);
2617 WithEndpoint(ApiEndpoint.ScrollIntoView).WithElementId(elementId);
2630 WithEndpoint(ApiEndpoint.ScrollElement).WithHPixels(hPixels).WithVPixels(vPixels);
2642 WithEndpoint(ApiEndpoint.GetAttribute).WithElementId(elementId);
2654 WithEndpoint(ApiEndpoint.SetAttribute).WithElementId(elementId);
2676 _parameters =
null == _parameters
2678 : MergeParameters(_parameters,
new { attribute });
2691 WithEndpoint(ApiEndpoint.SetRange).WithElementId(elementId);
2703 _parameters =
null == _parameters
2704 ?
new { rangeValue = rangeValue.ToString() }
2705 : MergeParameters(_parameters,
new { rangeValue = rangeValue.ToString() });
2718 _parameters =
null == _parameters
2720 : MergeParameters(_parameters,
new { value });
2780 _parameters =
null == _parameters
2782 : MergeParameters(_parameters,
new { url });
2796 _parameters =
null == _parameters
2798 : MergeParameters(_parameters,
new { method });
2811 _parameters =
null == _parameters
2813 : MergeParameters(_parameters,
new { body });
2826 _parameters =
null == _parameters
2827 ?
new { contentType }
2828 : MergeParameters(_parameters,
new { contentType });
2841 _parameters =
null == _parameters
2843 : MergeParameters(_parameters,
new { headers });
2857 _parameters =
null == _parameters
2859 : MergeParameters(_parameters,
new { bytes });
2916 WithEndpoint(ApiEndpoint.Hover).WithElementId(elementId);
2923 private void Reset()
2925 _customEndpoint =
false; ;
2927 _httpMethod =
"GET";
2955 WithEndpoint(ApiEndpoint.CheckNetworkIdle).WithMaxConnections(maxConnections);
2995 _parameters =
null == _parameters
2997 : MergeParameters(_parameters,
new { script });
3010 _parameters =
null == _parameters
3012 : MergeParameters(_parameters,
new { script });
3138 WithEndpoint(ApiEndpoint.GetShadowRoot).WithElementId(css);
3164 _parameters =
null == _parameters
3166 : MergeParameters(_parameters,
new { capture });
3180 _parameters =
null == _parameters
3181 ?
new { filter = urlFragment }
3182 : MergeParameters(_parameters,
new { filter = urlFragment });
3195 _parameters =
null == _parameters
3197 : MergeParameters(_parameters,
new { clear });
3244 if (
true ==
string.IsNullOrEmpty(url))
3245 url =
new GPALUrl(
"google.com");
3284 WithEndpoint(ApiEndpoint.FillInAppend).WithElementId(elementId);
3296 WithEndpoint(ApiEndpoint.FillInInsert).WithElementId(elementId);
3308 WithEndpoint(ApiEndpoint.FillInOverwrite).WithElementId(elementId);
3320 WithEndpoint(ApiEndpoint.LeftClickAndDownload).WithElementId(elementId);
3332 WithEndpoint(ApiEndpoint.Upload).WithElementId(elementId);
3366 WithEndpoint(ApiEndpoint.MoveTo).WithElementId(elementId);
3440 WithEndpoint(ApiEndpoint.OverrideReferrer).WithReferrer(referrer);
3453 _parameters =
null == _parameters
3455 : MergeParameters(_parameters,
new { userAgent });
3469 _parameters =
null == _parameters
3470 ?
new { pagesToScroll }
3471 : MergeParameters(_parameters,
new { pagesToScroll });
3507 _parameters =
null == _parameters
3508 ?
new { pagesToScroll }
3509 : MergeParameters(_parameters,
new { pagesToScroll });
3522 _parameters =
null == _parameters
3523 ?
new { modifierKeys }
3524 : MergeParameters(_parameters,
new { modifierKeys });
3570 _parameters =
null == _parameters
3571 ?
new { modifierKeys }
3572 : MergeParameters(_parameters,
new { modifierKeys });
3596 WithEndpoint(ApiEndpoint.DragAndDrop).WithElementId(elementId);
3608 WithEndpoint(ApiEndpoint.ScrollElement).WithElementId(elementId);
3614 WithEndpoint(ApiEndpoint.ScrollWindow).WithHPixels(hPixels).WithVPixels(vPixels);
3626 WithEndpoint(ApiEndpoint.ScrollWindow).WithHPixels(hPixels).WithVPixels(vPixels);
3640 WithEndpoint(ApiEndpoint.ScrollWindow).WithHPixels(hPixels).WithVPixels(vPixels);
3652 WithEndpoint(ApiEndpoint.SelectClick).WithElementId(elementId);
3664 _parameters =
null == _parameters
3665 ?
new { selectValue }
3666 : MergeParameters(_parameters,
new { selectValue });
3672 _parameters =
null == _parameters
3673 ?
new { selectIndex }
3674 : MergeParameters(_parameters,
new { selectIndex });
3692 _parameters =
null == _parameters
3694 : MergeParameters(_parameters,
new { key });
3695 _parameters = MergeParameters(_parameters,
new { code });
3696 _parameters = MergeParameters(_parameters,
new { vk = code });
3712 _parameters =
null == _parameters
3713 ?
new { text, typingDelay = delayMs }
3714 : MergeParameters(_parameters,
new { text, typingDelay = delayMs });
3730 _parameters =
null == _parameters
3731 ?
new { destSelector }
3732 : MergeParameters(_parameters,
new { destSelector });
3758 #region Window Handling
3767 _parameters =
new { windowId };
3779 if (resultIndex < 0 || resultIndex >= _executionResults.Count)
3782 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result index [{resultIndex}] is out of range for WithWindowIdFromResult. Using 0.",
3783 null, GPALObjectType.None);
3786 var previousResult = _executionResults[resultIndex].Result;
3787 var windowId = previousResult is
int i ? i : (
int.TryParse(previousResult?.ToString(), out
int parsed) ? parsed : 0);
3798 var resultEntry = _executionResults.LastOrDefault(entry => entry.Name == name);
3799 if (resultEntry.Result ==
null)
3802 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Result name [{name}] not found for WithWindowIdFromResult. Using 0.",
3803 null, GPALObjectType.None);
3806 var previousResult = resultEntry.Result;
3807 var windowId = previousResult is
int i ? i : (
int.TryParse(previousResult?.ToString(), out
int parsed) ? parsed : 0);
3818 if (
true ==
string.IsNullOrEmpty(url))
3819 url =
new GPALUrl(
"google.com");
3833 WithEndpoint(ApiEndpoint.GoToWindow).WithUrl(url?.Url);
3845 WithEndpoint(ApiEndpoint.GoToWindow).WithWindowId(windowId);
3884 WithEndpoint(ApiEndpoint.CloseWindow).WithWindowId(windowId);
3895 WithEndpoint(ApiEndpoint.DeleteStorage).WithStorageType(storageType);
3907 WithEndpoint(ApiEndpoint.GetStorage).WithStorageType(storageType);
3919 WithEndpoint(ApiEndpoint.SetStorage).WithStorageType(storageType);
3933 #endregion Window Handling
3943 _parameters =
null == _parameters
3945 : MergeParameters(_parameters,
new { elementId });
3959 _parameters =
null == _parameters
3961 : MergeParameters(_parameters,
new { elementId });
3975 _parameters =
null == _parameters
3977 : MergeParameters(_parameters,
new { elementId });
3988 private object MergeParameters(
object existing,
object additional)
3990 var dict = existing is IDictionary<string, object> existingDict
3991 ?
new Dictionary<string, object>(existingDict)
3992 : existing.GetType().GetProperties()
3993 .ToDictionary(p => p.
Name, p => p.GetValue(existing));
3995 if (
null != additional)
3997 var additionalDict = additional is IDictionary<string, object> addDict
3999 : additional?.GetType().GetProperties()
4000 .ToDictionary(p => p.Name, p => p.GetValue(additional));
4002 foreach (var kvp
in additionalDict)
4004 dict[kvp.Key] = kvp.Value;
4011 internal bool ValidateParameters(ApiEndpoint endpoint, IDictionary<string, object> parmsToValidate =
null)
4015 var internalParms = _parameters as IDictionary<string, object>
4016 ?? (
null != _parameters ? _parameters.GetType().GetProperties().ToDictionary(p => p.Name, p => p.GetValue(_parameters))
4017 :
new Dictionary<string, object>());
4019 var paramsDict = parmsToValidate ?? internalParms;
4021 if (
false == paramRules.ContainsKey(endpoint))
4023 GPAL.PublishSimpleEvent(GPALEventType.WARNING,
4024 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}No validation rules defined for endpoint [{endpoint}].",
4025 null, GPALObjectType.None);
4029 var (mandatory, optional, customValidation) = paramRules[endpoint];
4031 if (ApiEndpoint.SetStorage == endpoint)
4033 var storageType = paramsDict.ContainsKey(
"storageType") ? paramsDict[
"storageType"]?.ToString() :
"";
4034 if (
true ==
"cache".Equals(storageType))
4035 (mandatory, optional, customValidation) = paramRules[ApiEndpoint.SetStorageCache];
4036 else if (
true ==
"indexedDb".Equals(storageType))
4037 (mandatory, optional, customValidation) = paramRules[ApiEndpoint.SetStorageIndexedDb];
4040 var missingMandatory = mandatory.Where(p =>
false == paramsDict.ContainsKey(p)).ToArray();
4042 if (
true == missingMandatory.Any())
4044 GPAL.PublishSimpleEvent(GPALEventType.WARNING,
4045 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Missing required parameters for [{endpoint}]: [{string.Join(",
", missingMandatory)}].",
4046 null, GPALObjectType.None);
4050 if (
null != customValidation &&
false == customValidation(paramsDict))
4052 GPAL.PublishSimpleEvent(GPALEventType.WARNING,
4053 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Custom validation failed for [{endpoint}].",
4054 null, GPALObjectType.None);
4059 var allowedParams = mandatory.Concat(optional).ToHashSet();
4060 var invalidParams = paramsDict.Keys.Where(k =>
false == allowedParams.Contains(k)).ToArray();
4061 if (
true == invalidParams.Any())
4063 GPAL.PublishSimpleEvent(GPALEventType.WARNING,
4064 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Invalid parameters for [{endpoint}]: [{string.Join(",
", invalidParams)}].",
4065 null, GPALObjectType.None);
4069 catch (Exception ex)
4071 GPAL.PublishSimpleEvent(GPALEventType.EXCEPTION, $
"Unable to validate [{endpoint}]",
this, GPALObjectType.RestClient, ex);
4077 internal bool ValidateOpenApiParameters(
string ruleKey, IDictionary<string, object> parmsToValidate =
null)
4081 var internalParms = _parameters as IDictionary<string, object>
4082 ?? (
null != _parameters ? _parameters.GetType().GetProperties().ToDictionary(p => p.Name, p => p.GetValue(_parameters))
4083 :
new Dictionary<string, object>());
4085 var paramsDict = parmsToValidate ?? internalParms;
4087 if (
false == openApiParamRules.ContainsKey(ruleKey))
4089 GPAL.PublishSimpleEvent(GPALEventType.WARNING,
4090 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}No OpenAPI validation rules defined for [{ruleKey}].",
4091 null, GPALObjectType.None);
4095 var (mandatory, optional, customValidation) = openApiParamRules[ruleKey];
4097 var missingMandatory = mandatory.Where(p =>
false == paramsDict.ContainsKey(p)).ToArray();
4099 if (
true == missingMandatory.Any())
4101 GPAL.PublishSimpleEvent(GPALEventType.WARNING,
4102 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Missing required parameters for [{ruleKey}]: [{string.Join(",
", missingMandatory)}].",
4103 null, GPALObjectType.None);
4107 if (
null != customValidation &&
false == customValidation(paramsDict))
4109 GPAL.PublishSimpleEvent(GPALEventType.WARNING,
4110 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Custom validation failed for OpenAPI endpoint [{ruleKey}].",
4111 null, GPALObjectType.None);
4116 var allowedParams = mandatory.Concat(optional).ToHashSet(StringComparer.OrdinalIgnoreCase);
4117 var invalidParams = paramsDict.Keys.Where(k =>
false == allowedParams.Contains(k)).ToArray();
4119 if (
true == invalidParams.Any())
4121 GPAL.PublishSimpleEvent(GPALEventType.WARNING,
4122 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Invalid parameters for [{ruleKey}]: [{string.Join(",
", invalidParams)}].",
4123 null, GPALObjectType.None);
4127 catch (Exception ex)
4129 GPAL.PublishSimpleEvent(GPALEventType.EXCEPTION,
4130 $
"Unable to validate OpenAPI endpoint [{ruleKey}]",
this, GPALObjectType.RestClient, ex);
4141 private string GetOpenApiRuleKey(
string httpMethod,
string endpoint)
4143 if (
string.IsNullOrWhiteSpace(httpMethod) ||
string.IsNullOrWhiteSpace(endpoint))
4146 var path = endpoint.TrimStart(
'/');
4147 return $
"{httpMethod.ToUpperInvariant()} {path}";
4155 private string ExtractBestServerUrl(
string yamlContent)
4159 var reader =
new Microsoft.OpenApi.Readers.OpenApiStreamReader();
4160 using var stream =
new MemoryStream(System.Text.Encoding.UTF8.GetBytes(yamlContent));
4161 var document = reader.Read(stream, out _);
4163 if (document.Servers ==
null || document.Servers.Count == 0)
4167 var remote = document.Servers.FirstOrDefault(s =>
4168 s.Url.StartsWith(
"https://", StringComparison.OrdinalIgnoreCase));
4171 return remote.Url.TrimEnd(
'/');
4174 return document.Servers[0].Url.TrimEnd(
'/');
4181 internal static void SaveResponseToFile(
string response,
string filePath)
4186 if (response.StartsWith(
"data:"))
4189 var base64Part = response.Substring(response.IndexOf(
",") + 1);
4190 var bytes = Convert.FromBase64String(base64Part);
4191 System.IO.File.WriteAllBytes(filePath, bytes);
4192 GPAL.PublishSimpleEvent(GPALEventType.INFO, $
"Saved base64 response to [{filePath}]",
null, GPALObjectType.None);
4194 else if (Uri.TryCreate(response, UriKind.Absolute, out var uri))
4197 using (var client =
new HttpClient())
4198 using (var stream = client.GetStreamAsync(uri).Result)
4199 using (var fileStream = System.IO.File.Create(filePath))
4201 stream.CopyTo(fileStream);
4203 GPAL.PublishSimpleEvent(GPALEventType.INFO, $
"Downloaded response to [{filePath}]",
null, GPALObjectType.None);
4207 GPAL.PublishSimpleEvent(GPALEventType.WARNING, $
"Unsupported response format for saving to [{filePath}]",
null, GPALObjectType.None);
4210 catch (Exception ex)
4212 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...
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 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.
int StatusCode
The HTTP status code the last call came back with.
int RetryAfterSeconds
The seconds the last call was asked to wait before asking again, zero when it was not asked.
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[]>();.
IAllowRESTStorageOptions WithStorageType(WebsiteStorageType storageType)
Sets the storage path parameter.
IAllowRESTParametersOrExecution SetValueFrom(string destSelector)
Sets the value of the destination element identified by destSelector from the source element identif...
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 TrustedLeftClick(int x, int y, int holdMs=0)
Clicks a viewport point through the browser's own input pipeline, so the page reads the event as trus...
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).
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....
IAllowRESTExecution SetGoogleReferrer()
Overrides referrer stealthily - sets to google.com client.SetGoogleReferrer().Execute();.
IAllowRESTEndpointDetails WithName(string name)
Sets the client name.
IAllowRESTExecution GetOptions(string elementId)
Get the options in a Select manue.
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")....
IAllowRESTExecution TrustedMiddleClick(int x, int y, int holdMs=0)
Middle clicks a viewport point through the browser's own input pipeline, so the page reads the event ...
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 GetHydrationScripts()
Gets the page title, the NEXT_DATA payload and any React Flight chunks, read from the document rather...
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.
IReadOnlyList< object > GetExecutionResults(string name)
Every result stored under name , in the order it was stored, so a loop that ran five times answers wi...
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 WithTimeout(TimeSpan httpTimeout)
How long one attempt is given before it is abandoned. Said after the base url, so a client handed a s...
IAllowRESTExecution MiddleClick(string elementId)
Performs a left click on an element by ID client.LeftClick("element123").Execute();.
IAllowRESTExecution ClearResults()
Empties what WithResultName has stored, so GetExecutionResults answers about what has happened since ...
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.
IAllowRESTWorkflow ClearWorkflows()
Gets the execution results.
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.
IAllowRESTEndpointDetails WithAPIBase(string url, TimeSpan httpTimeout)
Sets the API base URL and how long one attempt is given before it is abandoned.
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.
IAllowRESTExecution GetDocumentStamp()
Gets the current URL and the document identity in one call. A form posting to itself and a route rew...
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.