37 private readonly List<Action<PuppeteerClient>> _workflows =
new List<Action<PuppeteerClient>>();
41 private List<(
string Endpoint,
object Parameters,
string NextResultName)?> _workflowStates {
get;
set; } =
new List<(string, object, string)?>();
45 private bool _customEndpoint {
get;
set; } =
false;
49 private ApiEndpoint _apiEndpoint;
53 private string _endpoint {
get;
set; }
57 private object _parameters {
get;
set; }
61 internal ContentEncoding _contentEncoding = ContentEncoding.Json;
65 private string _name {
get;
set; }
69 private string _nextResultName {
get;
set; }
73 private string _saveFile {
get;
set; }
78 private readonly List<(
string Name,
object Result,
int Iteration,
string TargetId)> _executionResults =
new List<(
string Name,
object Result,
int Iteration,
string TargetId)>();
86 private int _currentIteration {
get;
set; }
90 internal Dictionary<string, string> _headers =
new Dictionary<string, string>();
94 private int _timeoutMs = 30000;
98 private int _pruneMs = 3_000;
102 private int _maxConnections {
get;
set; }
106 private int _hPixels {
get;
set; }
110 private int _vPixels {
get;
set; }
114 private string _attribute {
get;
set; }
118 private string _value {
get;
set; }
122 private string _text {
get;
set; }
130 internal string _currentTargetId {
get;
set; }
134 private Dictionary<string, Func<PuppeteerCommunicator, IDictionary<string, object>, string, Task<object>>> endpointMap {
get;
set; }
145 private int _whileLoopTimeoutMs {
get;
set; }
149 private int _whileLoopMaxIterations {
get;
set; }
156 internal PuppeteerClient()
167 endpointMap =
new Dictionary<string, Func<PuppeteerCommunicator, IDictionary<string, object>, string, Task<object>>>
169 [RESTHelper.Endpoints[ApiEndpoint.Back]] = async (c, p, s) =>
171 return await c.Back(s).ConfigureAwait(
false);
173 [RESTHelper.Endpoints[ApiEndpoint.CaptureVisibleTab]] = async (c, p, s) =>
175 var parameters =
new Dictionary<string, object> { {
"format",
"jpeg" } };
176 if (p.ContainsKey(
"clip"))
178 dynamic format = p.ContainsKey(
"imageFormat") ? p[
"imageFormat"] :
"JPEG";
179 var clip = p[
"clip"] as IDictionary<string, object>;
182 double x = clip.ContainsKey(
"x") ? Convert.ToDouble(clip[
"x"]) : 0;
183 double y = clip.ContainsKey(
"y") ? Convert.ToDouble(clip[
"y"]) : 0;
184 double width = clip.ContainsKey(
"width") ? Convert.ToDouble(clip[
"width"]) :
Puppeteer.GetScreenWidthInt();
185 double height = clip.ContainsKey(
"height") ? Convert.ToDouble(clip[
"height"]) :
Puppeteer.GetScreenHeightInt();
186 double scale = clip.ContainsKey(
"scale") ? Convert.ToDouble(clip[
"scale"]) : 1.0;
188 if (width > 0 && height > 0 && x >= 0 && y >= 0)
190 parameters =
new Dictionary<string, object>
192 {
"format", format },
194 "clip",
new Dictionary<string, object>
199 {
"height", height },
207 GPAL.
PublishSimpleEvent(GPALEventType.WARNING, $
"Invalid clip parameters: x=[{x}], y=[{y}], width=[{width}], height=[{height}]. Using viewport.",
this, GPALObjectType.PuppeteerClient);
211 JObject retData = await c.SendCommand(DevToolsMethods.PageCaptureScreenshot, parameters, s).ConfigureAwait(
false);
212 string base64 = retData[
"data"]?.ToString();
216 [RESTHelper.Endpoints[ApiEndpoint.CastDesktop]] = async (c, p, s) =>
218 string sinkName = p.ContainsKey(
"sinkName") ? p[
"sinkName"]?.ToString() :
null;
219 await c.CastDesktop(sinkName, s).ConfigureAwait(
false);
222 [RESTHelper.Endpoints[ApiEndpoint.CastTab]] = async (c, p, s) =>
224 string sinkName = p.ContainsKey(
"sinkName") ? p[
"sinkName"]?.ToString() :
null;
225 await c.CastTab(sinkName, s).ConfigureAwait(
false);
228 [RESTHelper.Endpoints[ApiEndpoint.CheckNetworkIdle]] = async (c, p, s) =>
230 string sessionToken = Guid.NewGuid().ToString();
231 return await c.CheckNetworkIdle(s, _maxConnections, _timeoutMs, _pruneMs, sessionToken).ConfigureAwait(
false);
233 [RESTHelper.Endpoints[ApiEndpoint.ClearReferrer]] = async (c, p, s) =>
235 return await c.SendCommand(DevToolsMethods.NetworkSetExtraHTTPHeaders,
new Dictionary<string, object> { {
"headers", new Dictionary<string, object> { {
"Referer",
"" } } } }, s).ConfigureAwait(
false);
237 [RESTHelper.Endpoints[ApiEndpoint.CloseTab]] = async (c, p, s) =>
239 string targetId =
null;
240 if (p.ContainsKey(
"tabId"))
242 int tabId =
int.Parse(p[
"tabId"]?.ToString());
243 var queueArray = c.CurrentSessions.ToArray();
244 if (tabId >= 0 && tabId < queueArray.Length)
246 targetId = queueArray[tabId].Key;
251 targetId = c.GetCurrentTargetId();
254 if (targetId !=
null)
256 await c.CloseTab(targetId, s).ConfigureAwait(
false);
261 [RESTHelper.Endpoints[ApiEndpoint.CloseWindow]] = async (c, p, s) =>
263 string targetId =
null;
264 string windowId = p.ContainsKey(
"windowId") ? p[
"windowId"]?.ToString() :
null;
265 string url = p.ContainsKey(
"url") ? p[
"url"]?.ToString() :
null;
267 if (!
string.IsNullOrEmpty(windowId))
271 else if (!
string.IsNullOrEmpty(url))
273 targetId = await c.GetTargetWindowIdByUrl(url).ConfigureAwait(
false);
274 if (targetId !=
null)
277 int windowIndex = c.GetCurrentWindowIndex(targetId);
278 if (windowIndex >= 0)
280 c.SetActiveWindowIndex(windowIndex);
286 targetId = c.GetCurrentWindowTargetId();
289 if (!
string.IsNullOrEmpty(targetId))
291 await c.CloseWindow(targetId, s).ConfigureAwait(
false);
295 GPAL.
PublishSimpleEvent(GPALEventType.ERROR, $
"Unable to find window for targetId [{targetId}] or URL [{url}]", c, GPALObjectType.Puppeteer);
298 [RESTHelper.Endpoints[ApiEndpoint.DeleteStorage]] = async (c, p, s) =>
300 var storageType = p.ContainsKey(
"storageType") ? p[
"storageType"]?.ToString() :
"";
301 var domain = p.ContainsKey(
"domain") ? p[
"domain"]?.ToString() :
"";
302 var path = p.ContainsKey(
"path") ? p[
"path"]?.ToString() :
"";
303 var key = p.ContainsKey(
"key") ? p[
"key"]?.ToString() :
"";
304 var storeName = p.ContainsKey(
"storeName") ? p[
"storeName"]?.ToString() :
"";
306 return await c.DeleteStorage(storageType, s, domain, storeName, path, key).ConfigureAwait(
false);
308 [RESTHelper.Endpoints[ApiEndpoint.DragAndDrop]] = async (c, p, s) =>
310 dynamic parm = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
311 List<GPALElement> elems = p.ContainsKey(
"gpalElements") ? p[
"gpalElements"] : await _puppeteerCommunicator.EvaluateSelector(parm).ConfigureAwait(
false);
312 var deltaX = p.ContainsKey(
"deltaX") ? Convert.ToInt32(p[
"deltaX"]) : 0;
313 var deltaY = p.ContainsKey(
"deltaY") ? Convert.ToInt32(p[
"deltaY"]) : 0;
314 var offsetX = p.ContainsKey(
"offsetX") ? Convert.ToInt32(p[
"offsetX"]) : 0;
315 var offsetY = p.ContainsKey(
"offsetY") ? Convert.ToInt32(p[
"offsetY"]) : 0;
316 List<dynamic> responses =
new List<dynamic>();
320 await c.ScrollIntoView(elem, s).ConfigureAwait(
false);
321 await c.DragAndDrop(elem, s, responses, deltaX, deltaY, offsetX, offsetY).ConfigureAwait(
false);
324 return (responses, elems);
326 [RESTHelper.Endpoints[ApiEndpoint.Evaluate]] = async (c, p, s) =>
328 var xpath = p.ContainsKey(
"xpath") ? p[
"xpath"]?.ToString() :
"";
329 xpath = xpath.Replace(
"'",
"\\'");
330 List<GPALElement> elems = await _puppeteerCommunicator.EvaluateSelector(xpath, s).ConfigureAwait(
false);
338 [RESTHelper.Endpoints[ApiEndpoint.EvaluateAll]] = async (c, p, s) =>
340 var xpath = p.ContainsKey(
"xpath") ? p[
"xpath"]?.ToString() :
"";
342 xpath = xpath.Replace(
"'",
"\\'");
343 return await _puppeteerCommunicator.EvaluateSelector(xpath, s).ConfigureAwait(
false);
406 [RESTHelper.Endpoints[ApiEndpoint.Fetch]] = async (c, p, s) =>
408 return await c.Fetch(
409 p.ContainsKey(
"url") ? p[
"url"]?.ToString() :
null,
410 p.ContainsKey(
"method") ? p[
"method"]?.ToString() :
null,
411 p.ContainsKey(
"body") ? p[
"body"]?.ToString() :
null,
412 p.ContainsKey(
"contentType") ? p[
"contentType"]?.ToString() :
null,
413 p.ContainsKey(
"headers") ? p[
"headers"] as
string[] :
null,
414 p.ContainsKey(
"bytes") &&
true == Convert.ToBoolean(p[
"bytes"]),
415 s).ConfigureAwait(
false);
417 [RESTHelper.Endpoints[ApiEndpoint.ExecuteJavaScript]] = async (c, p, s) =>
419 var expression = p.ContainsKey(
"expression") ? p[
"expression"]?.ToString() : p[
"script"]?.ToString();
420 return await c.SendCommand<
object>(DevToolsMethods.RuntimeEvaluate,
new
423 returnByValue =
true,
425 }, s).ConfigureAwait(
false);
427 [RESTHelper.Endpoints[ApiEndpoint.FillInAppend]] = async (c, p, s) =>
429 List<dynamic> responses =
new List<dynamic>();
431 List<GPALElement> elems = (List<GPALElement>)(p.ContainsKey(
"gpalElements") ? p[
"gpalElements"] :
null);
432 var text = p.ContainsKey(
"text") ? p[
"text"]?.ToString() :
"";
433 var typingDelay = p.ContainsKey(
"typingDelay") ? Convert.ToInt32(p[
"typingDelay"]) : 0;
435 dynamic parm = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
437 if (
null == elems &&
null != parm)
438 elems = await _puppeteerCommunicator.EvaluateSelector(parm).ConfigureAwait(
false);
442 await c.ScrollIntoView(element, s).ConfigureAwait(
false);
446 await c.FocusElement(element.ElementHandle, s).ConfigureAwait(
false);
447 responses.Add(await c.FillIn(element.ElementHandle, element.
Value + text, typingDelay, s).ConfigureAwait(
false));
480 return new { responses, elems };
482 [RESTHelper.Endpoints[ApiEndpoint.FillInInsert]] = async (c, p, s) =>
484 List<dynamic> responses =
new List<dynamic>();
485 List<GPALElement> elems = (List<GPALElement>)(p.ContainsKey(
"gpalElements") ? p[
"gpalElements"] :
null);
486 var text = p.ContainsKey(
"text") ? p[
"text"]?.ToString() :
"";
487 var typingDelay = p.ContainsKey(
"typingDelay") ? Convert.ToInt32(p[
"typingDelay"]) : 0;
489 dynamic parm = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
491 if (
null == elems &&
null != parm)
492 elems = await _puppeteerCommunicator.EvaluateSelector(parm).ConfigureAwait(
false);
496 await c.ScrollIntoView(element, s).ConfigureAwait(
false);
500 await c.FocusElement(element.ElementHandle, s).ConfigureAwait(
false);
501 responses.Add(await c.FillIn(element.ElementHandle, text + element.
Value, typingDelay, s).ConfigureAwait(
false));
534 return new { responses, elems };
536 [RESTHelper.Endpoints[ApiEndpoint.FillInOverwrite]] = async (c, p, s) =>
538 List<dynamic> responses =
new List<dynamic>();
539 List<GPALElement> elems = (List<GPALElement>)(p.ContainsKey(
"gpalElements") ? p[
"gpalElements"] :
null);
540 var text = p.ContainsKey(
"text") ? p[
"text"]?.ToString() :
"";
541 var typingDelay = p.ContainsKey(
"typingDelay") ? Convert.ToInt32(p[
"typingDelay"]) : 0;
543 dynamic parm = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
545 if (
null == elems &&
null != parm)
546 elems = await _puppeteerCommunicator.EvaluateSelector(parm).ConfigureAwait(
false);
550 await c.ScrollIntoView(element, s).ConfigureAwait(
false);
554 await c.FocusElement(element.ElementHandle, s).ConfigureAwait(
false);
555 responses.Add(await c.FillIn(element.ElementHandle, text, typingDelay, s).ConfigureAwait(
false));
557 return new { responses, elems };
559 [RESTHelper.Endpoints[ApiEndpoint.FireChangeEvent]] = async (c, p, s) =>
561 dynamic selector = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
562 return await c.SendCommand<
object>(DevToolsMethods.RuntimeEvaluate,
new
564 expression = $
"document.querySelector('{selector.Replace("'", "\\'")}').dispatchEvent(new Event('change'))",
566 }, s).ConfigureAwait(
false);
568 [RESTHelper.Endpoints[ApiEndpoint.Focus]] = async (c, p, s) =>
570 dynamic parm = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
572 List<GPALElement> elems = p.ContainsKey(
"gpalElements") ? p[
"gpalElements"] : await _puppeteerCommunicator.EvaluateSelector(parm).ConfigureAwait(
false);
576 var requestNodeResult = await c.SendCommand<
object>(DevToolsMethods.DOMRequestNode,
new { objectId = elem.ElementHandle }, s).ConfigureAwait(
false);
578 if (requestNodeResult?.nodeId !=
null)
580 return await c.SendCommand<
object>(DevToolsMethods.DOMFocus,
new { nodeId = (int)requestNodeResult.nodeId }, s).ConfigureAwait(
false);
592 [RESTHelper.Endpoints[ApiEndpoint.Forward]] = async (c, p, s) =>
594 return await c.Forward(s).ConfigureAwait(
false);
596 [RESTHelper.Endpoints[ApiEndpoint.FullScreen]] = async (c, p, s) =>
598 var windowId = await c.GetCurrentWindow(s).ConfigureAwait(
false);
599 return await c.SendCommand(DevToolsMethods.BrowserSetWindowBounds,
new
602 bounds = new { windowState =
"fullscreen" }
603 }, s).ConfigureAwait(
false);
605 [RESTHelper.Endpoints[ApiEndpoint.GetAttribute]] = async (c, p, s) =>
607 dynamic parm = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
608 var attribute = p.ContainsKey(
"attribute") ? p[
"attribute"]?.ToString() :
"";
609 List<GPALElement> elems = p.ContainsKey(
"gpalElements") ? p[
"gpalElements"] : await _puppeteerCommunicator.EvaluateSelector(parm).ConfigureAwait(
false);
616 [RESTHelper.Endpoints[ApiEndpoint.GetBoundingClientRect]] = async (c, p, s) =>
618 dynamic parm = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
620 return await c.GetBoundingClientRect(Int32.Parse(parm)).ConfigureAwait(
false);
622 [RESTHelper.Endpoints[ApiEndpoint.GetContentAndCss]] = async (c, p, s) =>
624 var selector = p.ContainsKey(
"elementId") ? p[
"elementId"]?.ToString() :
"";
625 return await c.SendCommand<
object>(DevToolsMethods.RuntimeEvaluate,
new
627 expression = $
"(() => {{ const el = document.querySelector('{selector.Replace("'", "\\'")}'); return {{ text: el.textContent, css: window.getComputedStyle(el).cssText }}; }})()",
629 }, s).ConfigureAwait(
false);
631 [RESTHelper.Endpoints[ApiEndpoint.GetCssAttributes]] = async (c, p, s) =>
633 string backendNodeId = p.ContainsKey(
"elementId") ? p[
"elementId"]?.ToString() :
null;
635 return await c.GetCssAttributes(Int32.Parse(backendNodeId), s).ConfigureAwait(
false);
637 [RESTHelper.Endpoints[ApiEndpoint.GetCurrentUrl]] = async (c, p, s) =>
639 return await c.GetCurrentUrl(s).ConfigureAwait(
false);
641 [RESTHelper.Endpoints[ApiEndpoint.GetCurrentWindow]] = async (c, p, s) =>
643 return await c.GetCurrentWindow(s).ConfigureAwait(
false);
645 [RESTHelper.Endpoints[ApiEndpoint.GetDomAttributes]] = async (c, p, s) =>
647 string backendNodeId = p.ContainsKey(
"elementId") ? p[
"elementId"]?.ToString() :
null;
649 return await c.GetDomAttributes(Int32.Parse(backendNodeId), s).ConfigureAwait(
false);
651 [RESTHelper.Endpoints[ApiEndpoint.GetDomProperties]] = async (c, p, s) =>
653 string backendNodeId = p.ContainsKey(
"elementId") ? p[
"elementId"]?.ToString() :
null;
655 return await c.GetDomProperties(Int32.Parse(backendNodeId), s).ConfigureAwait(
false);
657 [RESTHelper.Endpoints[ApiEndpoint.GetElementAttributeHash]] = async (c, p, s) =>
659 dynamic parm = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
660 var text = p.ContainsKey(
"text") ? p[
"text"]?.ToString() :
"";
661 var attribute = p.ContainsKey(
"attribute") ? p[
"attribute"]?.ToString() :
"";
662 List<GPALElement> elems = p.ContainsKey(
"gpalElements") ? p[
"gpalElements"] : await _puppeteerCommunicator.EvaluateSelector(parm).ConfigureAwait(
false);
669 [RESTHelper.Endpoints[ApiEndpoint.GetPageSource]] = async (c, p, s) =>
671 return await c.GetPageSource(s).ConfigureAwait(
false);
673 [RESTHelper.Endpoints[ApiEndpoint.GetParentNode]] = async (c, p, s) =>
675 dynamic parm = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
676 List<GPALElement> elems = p.ContainsKey(
"gpalElements") ? p[
"gpalElements"] : await _puppeteerCommunicator.EvaluateSelector(parm).ConfigureAwait(
false);
682 if (!
string.IsNullOrEmpty(elem.ElementHandle))
685 var parentResult = await c.SendCommand<
object>(
686 DevToolsMethods.RuntimeCallFunctionOn,
689 objectId = elem.ElementHandle,
690 functionDeclaration =
"function() { return this.parentElement; }",
691 returnByValue =
false,
694 s).ConfigureAwait(
false);
696 if (parentResult?.result?.objectId !=
null)
698 string parentObjectId = parentResult.result.objectId;
701 var parentElems = await c.EvaluateSelector(parentObjectId).ConfigureAwait(
false);
703 return parentElems[0];
709 [RESTHelper.Endpoints[ApiEndpoint.GetReadyStatus]] = async (c, p, s) =>
711 dynamic sessionToken = p.ContainsKey(
"sessionToken") ? p[
"sessionToken"] :
null;
712 return await c.GetReadyStatus(s, sessionToken).ConfigureAwait(
false);
714 [RESTHelper.Endpoints[ApiEndpoint.GetShadowRoot]] = async (c, p, s) =>
717 dynamic parm = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
718 List<GPALElement> elems = p.ContainsKey(
"gpalElements") ? p[
"gpalElements"] : await _puppeteerCommunicator.EvaluateSelector(parm).ConfigureAwait(
false);
724 [RESTHelper.Endpoints[ApiEndpoint.GetStorage]] = async (c, p, s) =>
726 var storageType = p.ContainsKey(
"storageType") ? p[
"storageType"]?.ToString() :
null;
727 var domain = p.ContainsKey(
"domain") ? p[
"domain"]?.ToString() :
null;
728 var path = p.ContainsKey(
"path") ? p[
"path"]?.ToString() :
null;
729 var key = p.ContainsKey(
"key") ? p[
"key"]?.ToString() :
null;
730 var storeName = p.ContainsKey(
"storeName") ? p[
"storeName"]?.ToString() :
null;
732 return await c.GetStorage(storageType, s, domain, storeName, path, key).ConfigureAwait(
false);
734 [RESTHelper.Endpoints[ApiEndpoint.GetLanguages]] = async (c, p, s) =>
736 var languages = await c.SendCommand<
object>(DevToolsMethods.RuntimeEvaluate,
new
738 expression =
"navigator.languages.join(',')",
740 }, s).ConfigureAwait(
false);
741 return (
string)languages.result.value;
743 [RESTHelper.Endpoints[ApiEndpoint.GetUserAgent]] = async (c, p, s) =>
745 var result = await c.SendCommand<
object>(DevToolsMethods.RuntimeEvaluate,
new
747 expression =
"navigator.userAgent",
749 }, s).ConfigureAwait(
false);
750 return (
string)result.result.value;
752 [RESTHelper.Endpoints[ApiEndpoint.GoTo]] = async (c, p, s) =>
762 var url = p.ContainsKey(
"url") ? p[
"url"]?.ToString() :
"about:blank";
763 return await c.GoTo(url, s).ConfigureAwait(
false);
765 [RESTHelper.Endpoints[ApiEndpoint.GoToTab]] = async (c, p, s) =>
767 string tabId = p.ContainsKey(
"tabId") ? p[
"tabId"]?.ToString() :
null;
768 string url = p.ContainsKey(
"url") ? p[
"url"]?.ToString() :
null;
769 int? index = p.TryGetValue(
"index", out
object value) &&
int.TryParse(value?.ToString(), out
int parsed) ? (
int?)parsed :
null;
771 object tabIdOrUrlOrIndex = tabId ?? url ?? (object)index;
772 if (tabIdOrUrlOrIndex ==
null)
774 GPAL.
PublishSimpleEvent(GPALEventType.WARNING,
"No valid input provided for GoToTab (tabId, url, or index required)", c, GPALObjectType.PuppeteerCommunicator);
778 string targetId = await c.GoToTab(tabIdOrUrlOrIndex, s).ConfigureAwait(
false);
779 if (targetId ==
null)
781 GPAL.
PublishSimpleEvent(GPALEventType.WARNING, $
"Failed to switch to tab for input [{tabIdOrUrlOrIndex}]", c, GPALObjectType.PuppeteerCommunicator);
785 return new { targetId };
787 [RESTHelper.Endpoints[ApiEndpoint.GoToWindow]] = async (c, p, s) =>
789 var tabIdOrUrl = p.ContainsKey(
"tabId") ? (object)Convert.ToInt32(p[
"tabId"])
790 : (object)(p.ContainsKey(
"url") ? p[
"url"]?.ToString() :
null);
792 if (tabIdOrUrl ==
null)
795 var targetId = await c.GoToWindow(tabIdOrUrl, s).ConfigureAwait(
false);
797 if (!
string.IsNullOrEmpty(targetId))
799 _currentTargetId = targetId;
800 return new { targetId };
803 return new { targetId };
805 [RESTHelper.Endpoints[ApiEndpoint.HideElement]] = async (c, p, s) =>
807 dynamic parm = p.ContainsKey(
"elementId") ? p[
"elementId"] :
808 p.ContainsKey(
"css") ? p[
"css"] :
809 p.ContainsKey(
"xpath") ? p[
"xpath"] :
null;
810 List<GPALElement> elems = p.ContainsKey(
"gpalElements") ? p[
"gpalElements"] as List<GPALElement> :
811 await c.EvaluateSelector(parm).ConfigureAwait(
false);
812 if (elems ==
null || !elems.Any())
814 GPAL.
PublishSimpleEvent(GPALEventType.WARNING,
"No elements resolved for HideElement", c, GPALObjectType.Puppeteer);
818 List<dynamic> responses =
new List<dynamic>();
821 responses.Add(await c.HideElement(elem.ElementBackendNodeId, s).ConfigureAwait(
false));
824 return (responses, elems);
826 [RESTHelper.Endpoints[ApiEndpoint.Hover]] = async (c, p, s) =>
828 dynamic parm = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
829 List<GPALElement> elems = p.ContainsKey(
"gpalElements") ? p[
"gpalElements"] : await _puppeteerCommunicator.EvaluateSelector(parm).ConfigureAwait(
false);
830 List<dynamic> responses =
new List<dynamic>();
832 await c.MoveTo(elems, s, responses).ConfigureAwait(
false);
834 return (responses, elems);
836 [RESTHelper.Endpoints[ApiEndpoint.ClickPoint]] = async (c, p, s) =>
838 var x = p.ContainsKey(
"x") ? Convert.ToInt32(p[
"x"]) : 0;
839 var y = p.ContainsKey(
"y") ? Convert.ToInt32(p[
"y"]) : 0;
840 var clickType = p.ContainsKey(
"clickType") ? (ClickType)Convert.ToInt32(p[
"clickType"]) : ClickType.LeftClick;
841 var modifiers = p.ContainsKey(
"modifiers") ? Convert.ToInt32(p[
"modifiers"]) : 0;
842 List<dynamic> responses =
new List<dynamic>();
844 await c.ClickElement(x, y, s, responses, clickType, modifiers).ConfigureAwait(
false);
847 [RESTHelper.Endpoints[ApiEndpoint.MoveToPoint]] = async (c, p, s) =>
849 var x = p.ContainsKey(
"x") ? Convert.ToInt32(p[
"x"]) : 0;
850 var y = p.ContainsKey(
"y") ? Convert.ToInt32(p[
"y"]) : 0;
852 await c.MoveTo(x, y, s).ConfigureAwait(
false);
855 [RESTHelper.Endpoints[ApiEndpoint.InjectScript]] = async (c, p, s) =>
857 var script = p.ContainsKey(
"script") ? p[
"script"]?.ToString() :
"";
858 await c.InjectScript(script, s).ConfigureAwait(
false);
861 [RESTHelper.Endpoints[ApiEndpoint.ClearInjectedScripts]] = async (c, p, s) =>
863 await c.ClearInjectedScripts(s).ConfigureAwait(
false);
866 [RESTHelper.Endpoints[ApiEndpoint.SwitchToDefaultContent]] = async (c, p, s) =>
869 await c.SwitchToDefaultContent(s).ConfigureAwait(
false);
872 [RESTHelper.Endpoints[ApiEndpoint.SwitchToShadowRoot]] = (c, p, s) =>
877 [RESTHelper.Endpoints[ApiEndpoint.IsClickable]] = async (c, p, s) =>
881 dynamic parm = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
882 List<GPALElement> elems = p.ContainsKey(
"gpalElements") ? p[
"gpalElements"] : await _puppeteerCommunicator.EvaluateSelector(parm).ConfigureAwait(
false);
883 List<bool> isClickables =
new List<bool>();
889 return isClickables.All(isClickAble =>
true == isClickAble);
891 [RESTHelper.Endpoints[ApiEndpoint.IsDisplayed]] = async (c, p, s) =>
895 dynamic parm = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
896 List<GPALElement> elems = p.ContainsKey(
"gpalElements") ? p[
"gpalElements"] : await _puppeteerCommunicator.EvaluateSelector(parm).ConfigureAwait(
false);
898 bool isDisplayed =
true;
905 [RESTHelper.Endpoints[ApiEndpoint.IsEnabled]] = async (c, p, s) =>
909 dynamic parm = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
910 List<GPALElement> elems = p.ContainsKey(
"gpalElements") ? p[
"gpalElements"] : await _puppeteerCommunicator.EvaluateSelector(parm).ConfigureAwait(
false);
912 bool isDisabled =
false;
919 [RESTHelper.Endpoints[ApiEndpoint.IsEndOfPage]] = async (c, p, s) =>
921 return await c.IsEndOfPage(s).ConfigureAwait(
false);
923 [RESTHelper.Endpoints[ApiEndpoint.IsVisibleInViewport]] = async (c, p, s) =>
927 dynamic parm = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
928 List<GPALElement> elems = (List<GPALElement>)(p.ContainsKey(
"gpalElements") ? p[
"gpalElements"] :
null);
931 return await c.IsVisibleInViewport(elems, s).ConfigureAwait(
false);
933 return await c.IsVisibleInViewport(parm, s).ConfigureAwait(
false);
935 [RESTHelper.Endpoints[ApiEndpoint.LeftClick]] = async (c, p, s) =>
937 dynamic parm = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
938 List<GPALElement> elems = p.ContainsKey(
"gpalElements") ? p[
"gpalElements"] : await _puppeteerCommunicator.EvaluateSelector(parm).ConfigureAwait(
false);
939 int modifiers = p.ContainsKey(
"modifiers") ? Convert.ToInt32(p[
"modifiers"]) : 0;
940 List<dynamic> responses =
new List<dynamic>();
944 await c.ScrollIntoView(element, s).ConfigureAwait(
false);
945 await c.ClickElement(element, s, responses, ClickType.LeftClick, modifiers).ConfigureAwait(
false);
948 return (responses, elems);
950 [RESTHelper.Endpoints[ApiEndpoint.LeftDoubleClick]] = async (c, p, s) =>
952 dynamic parm = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
953 List<GPALElement> elems = p.ContainsKey(
"gpalElements") ? p[
"gpalElements"] : await _puppeteerCommunicator.EvaluateSelector(parm).ConfigureAwait(
false);
954 int modifiers = p.ContainsKey(
"modifiers") ? Convert.ToInt32(p[
"modifiers"]) : 0;
955 List<dynamic> responses =
new List<dynamic>();
959 await c.ScrollIntoView(element, s).ConfigureAwait(
false);
960 await c.ClickElement(element, s, responses, ClickType.LeftDoubleClick, modifiers).ConfigureAwait(
false);
963 return (responses, elems);
965 [RESTHelper.Endpoints[ApiEndpoint.LeftClickAndDownload]] = async (c, p, s) =>
967 string downloadPath = p.ContainsKey(
"downloadPath") ? p[
"downloadPath"]?.ToString() :
"";
968 dynamic elementId = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
969 int modifiers = p.ContainsKey(
"modifiers") ? Convert.ToInt32(p[
"modifiers"]) : 0;
971 List<GPALElement> elems = p.ContainsKey(
"gpalElements") ? p[
"gpalElements"] : await _puppeteerCommunicator.EvaluateSelector(elementId).ConfigureAwait(
false);
972 List<dynamic> responses =
new List<dynamic>();
976 await c.LeftClickAndDownload(elems, downloadPath, modifiers, s, responses).ConfigureAwait(
false);
981 return (responses, elems);
983 [RESTHelper.Endpoints[ApiEndpoint.Upload]] = async (c, p, s) =>
985 GPALFile uploadPaths = p.ContainsKey(
"uploadPaths") ? (
GPALFile)p[
"uploadPaths"] :
null;
986 string uploadPath = p.ContainsKey(
"uploadPath") ? p[
"uploadPath"]?.ToString() :
"";
987 dynamic elementId = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
988 int modifiers = p.ContainsKey(
"modifiers") ? Convert.ToInt32(p[
"modifiers"]) : 0;
990 List<GPALElement> elems = p.ContainsKey(
"gpalElements") ? p[
"gpalElements"] : await _puppeteerCommunicator.EvaluateSelector(elementId).ConfigureAwait(
false);
991 List<dynamic> responses =
new List<dynamic>();
995 if (0 < uploadPaths?.Count)
996 await c.LeftClickAndUpload(elems, uploadPaths, modifiers, s, responses).ConfigureAwait(
false);
998 await c.LeftClickAndUpload(elems, uploadPath, modifiers, s, responses).ConfigureAwait(
false);
1003 return (responses, elems);
1005 [RESTHelper.Endpoints[ApiEndpoint.LeftDoubleClick]] = async (c, p, s) =>
1007 dynamic parm = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
1008 List<GPALElement> elems = p.ContainsKey(
"gpalElements") ? p[
"gpalElements"] : await _puppeteerCommunicator.EvaluateSelector(parm).ConfigureAwait(
false);
1009 int modifiers = p.ContainsKey(
"modifiers") ? Convert.ToInt32(p[
"modifiers"]) : 0;
1011 List<dynamic> responses =
new List<dynamic>();
1015 await c.ScrollIntoView(element, s).ConfigureAwait(
false);
1016 await c.ClickElement(element, s, responses, ClickType.LeftDoubleClick, modifiers).ConfigureAwait(
false);
1018 return (responses, elems);
1020 [RESTHelper.Endpoints[ApiEndpoint.MiddleClick]] = async (c, p, s) =>
1022 dynamic parm = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
1023 List<GPALElement> elems = p.ContainsKey(
"gpalElements") ? p[
"gpalElements"] : await _puppeteerCommunicator.EvaluateSelector(parm).ConfigureAwait(
false);
1024 int modifiers = p.ContainsKey(
"modifiers") ? Convert.ToInt32(p[
"modifiers"]) : 0;
1025 List<dynamic> responses =
new List<dynamic>();
1029 await c.ScrollIntoView(element, s).ConfigureAwait(
false);
1030 await c.ClickElement(element, s, responses, ClickType.
MiddleClick, modifiers).ConfigureAwait(
false);
1033 return (responses, elems);
1035 [RESTHelper.Endpoints[ApiEndpoint.Maximize]] = async (c, p, s) =>
1037 return await c.Maximize(s).ConfigureAwait(
false);
1039 [RESTHelper.Endpoints[ApiEndpoint.Minimize]] = async (c, p, s) =>
1041 return await c.Minimize(s).ConfigureAwait(
false);
1043 [RESTHelper.Endpoints[ApiEndpoint.MoveTo]] = async (c, p, s) =>
1045 dynamic parm = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
1046 List<GPALElement> elems = p.ContainsKey(
"gpalElements") ? p[
"gpalElements"] : await _puppeteerCommunicator.EvaluateSelector(parm).ConfigureAwait(
false);
1047 List<dynamic> responses =
new List<dynamic>();
1049 return await c.MoveTo(elems, s, responses).ConfigureAwait(
false);
1051 [RESTHelper.Endpoints[ApiEndpoint.NewTab]] = async (c, p, s) =>
1053 var url = p.ContainsKey(
"url") ? p[
"url"]?.ToString() :
"https://google.com";
1054 var targetId = await c.NewTab(url, s).ConfigureAwait(
false);
1056 if (!
string.IsNullOrEmpty(targetId))
1057 _currentTargetId = targetId;
1060 "NewTab: Failed to open a new tab",
1061 this, GPALObjectType.Puppeteer);
1063 return _currentTargetId;
1065 [RESTHelper.Endpoints[ApiEndpoint.NextTab]] = async (c, p, s) =>
1067 var tmp = _currentTargetId;
1069 _currentTargetId = await c.NextTab(_currentTargetId).ConfigureAwait(
false);
1071 return _currentTargetId;
1073 [RESTHelper.Endpoints[ApiEndpoint.NextWindow]] = async (c, p, s) =>
1075 _currentTargetId = await c.NextWindow(_currentTargetId).ConfigureAwait(
false);
1077 return _currentTargetId;
1079 [RESTHelper.Endpoints[ApiEndpoint.Normal]] = async (c, p, s) =>
1081 return await c.Normal(s).ConfigureAwait(
false);
1083 [RESTHelper.Endpoints[ApiEndpoint.OpenWindow]] = async (c, p, s) =>
1085 var url = p.ContainsKey(
"url") ? p[
"url"]?.ToString() :
"about:blank";
1087 _currentTargetId = await c.OpenWindow(url, s).ConfigureAwait(
false);
1089 return _currentTargetId;
1091 [RESTHelper.Endpoints[ApiEndpoint.OverrideReferrer]] = async (c, p, s) =>
1093 var referrer = p.ContainsKey(
"referrer") ? p[
"referrer"]?.ToString() :
"";
1094 return await c.SendCommand<
object>(DevToolsMethods.NetworkSetExtraHTTPHeaders,
new
1096 headers =
new Dictionary<string, object> { {
"Referer", referrer } }
1097 }, s).ConfigureAwait(
false);
1099 [RESTHelper.Endpoints[ApiEndpoint.SetUserAgent]] = async (c, p, s) =>
1101 var userAgent = p.ContainsKey(
"userAgent") ? p[
"userAgent"]?.ToString() :
"";
1102 return await c.SetUserAgent(userAgent, s).ConfigureAwait(
false);
1104 [RESTHelper.Endpoints[ApiEndpoint.PageDown]] = async (c, p, s) =>
1106 int pagesToScroll = p.ContainsKey(
"pagesToScroll") ? Convert.ToInt32(p[
"pagesToScroll"]) : 1;
1107 return await c.ScrollPageAsync(
"down", pagesToScroll, s).ConfigureAwait(
false);
1109 [RESTHelper.Endpoints[ApiEndpoint.PageEnd]] = async (c, p, s) =>
1111 return await c.ScrollToPositionAsync(
"end", s).ConfigureAwait(
false);
1113 [RESTHelper.Endpoints[ApiEndpoint.PageTop]] = async (c, p, s) =>
1115 return await c.ScrollToPositionAsync(
"top", s).ConfigureAwait(
false);
1117 [RESTHelper.Endpoints[ApiEndpoint.PageUp]] = async (c, p, s) =>
1119 int pagesToScroll = p.ContainsKey(
"pagesToScroll") ? Convert.ToInt32(p[
"pagesToScroll"]) : 1;
1120 return await c.ScrollPageAsync(
"up", pagesToScroll, s).ConfigureAwait(
false);
1122 [RESTHelper.Endpoints[ApiEndpoint.PressModifierKey]] = async (c, p, s) =>
1124 var modifier = p.ContainsKey(
"modifier") ? Convert.ToInt32(p[
"modifier"]) : 0;
1125 return await c.SendCommand<
object>(DevToolsMethods.InputDispatchKeyEvent,
new
1128 modifiers = modifier
1129 }, s).ConfigureAwait(
false);
1131 [RESTHelper.Endpoints[ApiEndpoint.PreviousTab]] = async (c, p, s) =>
1133 _currentTargetId = await c.PreviousTab(_currentTargetId).ConfigureAwait(
false);
1135 return _currentTargetId;
1137 [RESTHelper.Endpoints[ApiEndpoint.PreviousWindow]] = async (c, p, s) =>
1139 _currentTargetId = await c.PreviousWindow(_currentTargetId).ConfigureAwait(
false);
1141 return _currentTargetId;
1143 [RESTHelper.Endpoints[ApiEndpoint.QuerySelector]] = async (c, p, s) =>
1145 var selector = p.ContainsKey(
"css") ? p[
"css"]?.ToString() :
"";
1146 List<GPALElement> elems = await _puppeteerCommunicator.EvaluateSelector(selector, s).ConfigureAwait(
false);
1148 if (0 < elems.Count)
1155 [RESTHelper.Endpoints[ApiEndpoint.QuerySelectors]] = async (c, p, s) =>
1157 var selector = p.ContainsKey(
"css") ? p[
"css"]?.ToString() :
"";
1158 return await _puppeteerCommunicator.EvaluateSelector(selector, s).ConfigureAwait(
false);
1160 [RESTHelper.Endpoints[ApiEndpoint.Refresh]] = async (c, p, s) =>
1162 return await c.SendCommand(DevToolsMethods.PageReload,
new { }, s).ConfigureAwait(
false);
1164 [RESTHelper.Endpoints[ApiEndpoint.ReleaseModifierKey]] = async (c, p, s) =>
1166 var modifier = p.ContainsKey(
"modifier") ? Convert.ToInt32(p[
"modifier"]) : 0;
1167 return await c.SendCommand<
object>(DevToolsMethods.InputDispatchKeyEvent,
new
1170 modifiers = modifier
1171 }, s).ConfigureAwait(
false);
1173 [RESTHelper.Endpoints[ApiEndpoint.Restore]] = async (c, p, s) =>
1175 return await c.Restore(s).ConfigureAwait(
false);
1177 [RESTHelper.Endpoints[ApiEndpoint.RightClick]] = async (c, p, s) =>
1179 dynamic parm = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
1180 List<dynamic> responses =
new List<dynamic>();
1181 List<GPALElement> elems = p.ContainsKey(
"gpalElements") ? p[
"gpalElements"] : await _puppeteerCommunicator.EvaluateSelector(parm).ConfigureAwait(
false);
1185 await c.ScrollIntoView(element, s).ConfigureAwait(
false);
1186 await c.ClickElement(element, s, responses, ClickType.RightClick).ConfigureAwait(
false);
1190 [RESTHelper.Endpoints[ApiEndpoint.ScrollElement]] = async (c, p, s) =>
1192 dynamic parm = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
1193 List<GPALElement> elems = p.ContainsKey(
"gpalElements") ? p[
"gpalElements"] : await _puppeteerCommunicator.EvaluateSelector(parm).ConfigureAwait(
false);
1194 bool isObjectId = System.Text.RegularExpressions.Regex.IsMatch(parm,
@"^-?\d+\.\d+\.\d+$");
1195 var hPixels = p.ContainsKey(
"hPixels") ? Convert.ToInt32(p[
"hPixels"]) : 0;
1196 var vPixels = p.ContainsKey(
"vPixels") ? Convert.ToInt32(p[
"vPixels"]) : 0;
1197 List<dynamic> responses =
new List<dynamic>();
1202 (function(selector, hPixels, vPixels) {{
1203 function evaluateSelector(selector) {{
1205 let type = 'unknown';
1207 nodes = Array.from(document.querySelectorAll(selector));
1208 if (nodes.length > 0) return nodes;
1212 const result = document.evaluate(selector, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
1213 nodes = Array.from({{ length: result.snapshotLength }}, (_, i) => result.snapshotItem(i));
1214 if (nodes.length > 0) return nodes;
1220 const elements = evaluateSelector(selector);
1221 elements.forEach(el => {{
1222 if (el.scrollBy) el.scrollBy(hPixels, vPixels);
1224 return elements.length; // optional: return number of elements scrolled
1225 }})('{(true == isObjectId ? (elem.Css ?? elem.Xpath) : parm).Replace("'", "\\'")}', {hPixels}, {vPixels})";
1227 responses.Add(await c.SendCommand<
object>(DevToolsMethods.RuntimeEvaluate,
new
1229 expression = jsFunc,
1230 returnByValue = true
1231 }, s).ConfigureAwait(
false));
1233 return (responses, elems);
1235 [RESTHelper.Endpoints[ApiEndpoint.ScrollIntoView]] = async (c, p, s) =>
1237 dynamic parm = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
1238 List<GPALElement> elems = p.ContainsKey(
"gpalElements") ? p[
"gpalElements"] : await _puppeteerCommunicator.EvaluateSelector(parm).ConfigureAwait(
false);
1239 List<dynamic> responses =
new List<dynamic>();
1243 responses.Add(await c.ScrollIntoView(elem, s).ConfigureAwait(
false));
1245 return (responses, elems);
1247 [RESTHelper.Endpoints[ApiEndpoint.ScrollWindow]] = async (c, p, s) =>
1249 var hPixels = p.ContainsKey(
"hPixels") ? Convert.ToInt32(p[
"hPixels"]) : 0;
1250 var vPixels = p.ContainsKey(
"vPixels") ? Convert.ToInt32(p[
"vPixels"]) : 0;
1251 return await c.ScrollWindowByPixelsAsync(hPixels, vPixels, s).ConfigureAwait(
false);
1258 [RESTHelper.Endpoints[ApiEndpoint.SelectClick]] = async (c, p, s) =>
1261 dynamic elementHandle = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
1262 string selectValue = p.ContainsKey(
"selectValue") ? p[
"selectValue"]?.ToString() :
null;
1263 int? selectIndex = p.ContainsKey(
"selectIndex") &&
int.TryParse(p[
"selectIndex"]?.ToString(), out
int idx) ? idx : (
int?)
null;
1264 bool result =
false;
1266 if (selectIndex.HasValue)
1268 result = await c.SelectByIndex(elementHandle, selectIndex.Value, s).ConfigureAwait(
false);
1272 string safeValue = selectValue.Replace(
"'",
"\\'");
1273 result = await c.SelectByValue(elementHandle, safeValue, s).ConfigureAwait(
false);
1278 [RESTHelper.Endpoints[ApiEndpoint.SendKey]] = async (c, p, s) =>
1280 var key = p.ContainsKey(
"key") ? p[
"key"]?.ToString() :
"Unidentified";
1281 var code = p.ContainsKey(
"code") ? p[
"code"]?.ToString() :
"Unidentified";
1282 var vk = p.ContainsKey(
"vk") ? Convert.ToInt32(p[
"vk"]) : 0;
1284 return await c.SendKey(key, code, vk).ConfigureAwait(
false);
1287 [RESTHelper.Endpoints[ApiEndpoint.SendString]] = async (c, p, s) =>
1289 var text = p.ContainsKey(
"text") ? p[
"text"]?.ToString() :
"";
1290 var typingDelay = p.ContainsKey(
"typingDelay") ? Convert.ToInt32(p[
"typingDelay"]) : 0;
1291 await c.SendString(text, typingDelay, s).ConfigureAwait(
false);
1294 [RESTHelper.Endpoints[ApiEndpoint.SetAttribute]] = async (c, p, s) =>
1296 List<dynamic> responses =
new List<dynamic>();
1297 List<GPALElement> elems =
null;
1299 dynamic parm = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
1302 var value = p.ContainsKey(
"value") ? p[
"value"]?.ToString() :
string.Empty;
1303 var attribute = p.ContainsKey(
"attribute") ? p[
"attribute"] :
"";
1304 bool isObjectId = System.Text.RegularExpressions.Regex.IsMatch(parm,
@"^-?\d+\.\d+\.\d+$");
1305 elems = p.ContainsKey(
"gpalElements") ? p[
"gpalElements"] : await _puppeteerCommunicator.EvaluateSelector(parm).ConfigureAwait(
false);
1310 (function(selector, attribute, value) {{
1311 function evaluateSelector(selector) {{
1313 let type = 'unknown';
1315 nodes = Array.from(document.querySelectorAll(selector));
1316 if (nodes.length > 0) return nodes;
1320 const result = document.evaluate(selector, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
1321 nodes = Array.from({{ length: result.snapshotLength }}, (_, i) => result.snapshotItem(i));
1322 if (nodes.length > 0) return nodes;
1328 const elements = evaluateSelector(selector);
1329 elements.forEach(el => {{
1330 el.setAttribute(attribute, value);
1332 return elements.length; // optional: return number of elements scrolled
1333 }})('{(true == isObjectId ? (elem.Css ?? elem.Xpath) : parm).Replace("'", "\\'")}', {attribute}, {value})";
1335 responses.Add(await c.SendCommand<
object>(DevToolsMethods.RuntimeEvaluate,
new
1337 expression = jsFunc,
1338 returnByValue = true
1339 }, s).ConfigureAwait(
false));
1340 elem.
Attributes[attribute.ToString()] = value;
1343 return (responses, elems);
1345 [RESTHelper.Endpoints[ApiEndpoint.SetDownloadFilename]] = async (c, p, s) =>
1347 var filename = p.ContainsKey(
"filename") ? p[
"filename"]?.ToString() :
"";
1348 return await c.SendCommand<
object>(DevToolsMethods.PageSetDownloadBehavior,
new
1351 downloadPath = filename
1352 }, s).ConfigureAwait(
false);
1354 [RESTHelper.Endpoints[ApiEndpoint.SetRange]] = async (c, p, s) =>
1356 dynamic parm = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
1357 List<GPALElement> elems = p.ContainsKey(
"gpalElements") ? p[
"gpalElements"] : await _puppeteerCommunicator.EvaluateSelector(parm).ConfigureAwait(
false);
1358 string rangeValue = (string)(p.ContainsKey(
"rangeValue") ? p[
"rangeValue"] :
"0xdeadbeef");
1359 List<dynamic> responses =
new List<dynamic>();
1361 if (
"0xdeadbeef" != rangeValue)
1363 responses.Add(await c.SetRange(elem.
Css, rangeValue, s).ConfigureAwait(
false));
1367 [RESTHelper.Endpoints[ApiEndpoint.SetValueFromElement]] = async (c, p, s) =>
1369 dynamic parm = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
1370 List<GPALElement> elems = p.ContainsKey(
"gpalElements") ? p[
"gpalElements"] : await _puppeteerCommunicator.EvaluateSelector(parm).ConfigureAwait(
false);
1371 string destSelector = p.ContainsKey(
"destSelector") ? p[
"destSelector"]?.ToString() :
null;
1372 List<dynamic> responses =
new List<dynamic>();
1374 if (
false ==
string.IsNullOrEmpty(destSelector))
1376 responses.Add(await c.SetValueFromElement(elem.
Css, destSelector, s).ConfigureAwait(
false));
1380 [RESTHelper.Endpoints[ApiEndpoint.SetStorage]] = async (c, p, s) =>
1382 var storageType = p.ContainsKey(
"storageType") ? p[
"storageType"]?.ToString() :
"";
1383 var domain = p.ContainsKey(
"domain") ? p[
"domain"]?.ToString() :
"";
1384 var storeName = p.ContainsKey(
"storeName") ? p[
"storeName"]?.ToString() :
null;
1385 var path = p.ContainsKey(
"path") ? p[
"path"]?.ToString() :
"";
1386 var key = p.ContainsKey(
"key") ? p[
"key"]?.ToString() :
"";
1387 var data = p.ContainsKey(
"data") ? p[
"data"]?.ToString() :
"";
1389 return await c.SetStorage(storageType, s, domain, key, data, storeName, path).ConfigureAwait(
false);
1391 [RESTHelper.Endpoints[ApiEndpoint.SetGoogleReferrer]] = async (c, p, s) =>
1393 return await c.SendCommand<
object>(DevToolsMethods.NetworkSetExtraHTTPHeaders,
new
1395 headers =
new Dictionary<string, object> { {
"Referer",
"https://www.google.com" } }
1396 }, s).ConfigureAwait(
false);
1398 [RESTHelper.Endpoints[ApiEndpoint.StopCasting]] = async (c, p, s) =>
1400 return await c.StopCasting(s).ConfigureAwait(
false);
1402 [RESTHelper.Endpoints[ApiEndpoint.SwitchToDefaultContent]] = async (c, p, s) =>
1405 await c.SwitchToDefaultContent(s).ConfigureAwait(
false);
1408 [RESTHelper.Endpoints[ApiEndpoint.SwitchToElement]] = async (c, p, s) =>
1410 dynamic selector = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
1411 await c.SwitchToElement(selector).ConfigureAwait(
false);
1414 [RESTHelper.Endpoints[ApiEndpoint.SwitchToFrame]] = async (c, p, s) =>
1416 dynamic selector = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
1417 await c.SwitchToFrame(selector).ConfigureAwait(
false);
1420 [RESTHelper.Endpoints[ApiEndpoint.SwitchToShadowRoot]] = async (c, p, s) =>
1422 dynamic selector = p.ContainsKey(
"elementId") ? p[
"elementId"] :
null;
1423 await c.SwitchToShadowDom(selector).ConfigureAwait(
false);
1426 [RESTHelper.Endpoints[ApiEndpoint.TopBrowser]] = async (c, p, s) =>
1428 await c.TopBrowser().ConfigureAwait(
false);
1431 [RESTHelper.Endpoints[ApiEndpoint.WindowInnerHeight]] = async (c, p, s) =>
1433 var result = await c.SendCommand<
object>(DevToolsMethods.RuntimeEvaluate,
new
1435 expression =
"window.innerHeight",
1436 returnByValue =
true
1438 }, c.GetCurrentSessionId()).ConfigureAwait(
false);
1439 return (
int)result.result.value;
1441 [RESTHelper.Endpoints[ApiEndpoint.WindowInnerWidth]] = async (c, p, s) =>
1443 var result = await c.SendCommand<
object>(DevToolsMethods.RuntimeEvaluate,
new
1445 expression =
"window.innerWidth",
1446 returnByValue =
true
1448 }, c.GetCurrentSessionId()).ConfigureAwait(
false);
1449 return (
int)result.result.value;
1451 [RESTHelper.Endpoints[ApiEndpoint.WindowOuterHeight]] = async (c, p, s) =>
1453 var result = await c.SendCommand<
object>(DevToolsMethods.RuntimeEvaluate,
new
1455 expression =
"window.outerHeight",
1456 returnByValue =
true
1458 }, c.GetCurrentSessionId()).ConfigureAwait(
false);
1459 return (
int)result.result.value;
1461 [RESTHelper.Endpoints[ApiEndpoint.WindowOuterWidth]] = async (c, p, s) =>
1463 var result = await c.SendCommand<
object>(DevToolsMethods.RuntimeEvaluate,
new
1465 expression =
"window.outerWidth",
1466 returnByValue =
true
1468 }, c.GetCurrentSessionId()).ConfigureAwait(
false);
1469 return (
int)result.result.value;
1471 [RESTHelper.Endpoints[ApiEndpoint.WindowPageOffsetX]] = async (c, p, s) =>
1473 var result = await c.SendCommand<
object>(DevToolsMethods.RuntimeEvaluate,
new
1475 expression =
"window.pageXOffset",
1476 returnByValue =
true
1477 }, s).ConfigureAwait(
false);
1478 return (
int)result.result.value;
1480 [RESTHelper.Endpoints[ApiEndpoint.WindowPageOffsetY]] = async (c, p, s) =>
1482 var result = await c.SendCommand<
object>(DevToolsMethods.RuntimeEvaluate,
new
1484 expression =
"window.pageYOffset",
1485 returnByValue =
true
1486 }, s).ConfigureAwait(
false);
1487 return (
int)result.result.value;
1489 [RESTHelper.Endpoints[ApiEndpoint.WindowScreenLeft]] = async (c, p, s) =>
1491 var result = await c.SendCommand<
object>(DevToolsMethods.RuntimeEvaluate,
new
1493 expression =
"window.screenLeft",
1494 returnByValue =
true
1496 }, c.GetCurrentSessionId()).ConfigureAwait(
false);
1497 return (
int)result.result.value;
1499 [RESTHelper.Endpoints[ApiEndpoint.WindowScreenTop]] = async (c, p, s) =>
1501 var result = await c.SendCommand<
object>(DevToolsMethods.RuntimeEvaluate,
new
1503 expression =
"window.screenTop",
1504 returnByValue =
true
1506 }, c.GetCurrentSessionId()).ConfigureAwait(
false);
1507 return (
int)result.result.value;
1536 _puppeteerCommunicator = communicator;
1547 _endpoint = endpoint;
1548 _customEndpoint =
true;
1560 _apiEndpoint = endpoint;
1561 _endpoint = RESTHelper.Endpoints.TryGetValue(endpoint, out var ep) ? ep :
"";
1572 _nextResultName = name;
1576 public IAllowPuppeteerEndpointDetails WithSaveFile(
GPALFile file)
1589 SetParameter(
"sessionToken", sessionToken);
1611 SetParameter(
"url", url);
1622 SetParameter(
"imageFormat", imageFormat.ToString());
1633 var url = GetResultFromIndex(resultIndex)?.ToString() ??
"";
1644 var url = GetResultFromName(name)?.ToString() ??
"";
1655 SetParameter(
"tabId", tabId);
1666 var tabId = GetResultFromIndex(resultIndex) is
int i ? i : 0;
1677 var tabId = GetResultFromName(name) is
int i ? i : 0;
1688 SetParameter(
"windowId", windowId);
1699 var windowId = GetResultFromIndex(resultIndex) is
int i ? i : 0;
1710 var windowId = GetResultFromName(name) is
int i ? i : 0;
1721 SetParameter(
"domain", domain);
1731 SetParameter(
"path", path);
1741 SetParameter(
"key", key);
1751 SetParameter(
"storeName", storeName);
1761 SetParameter(
"data", data);
1771 SetParameter(
"crossOrigin", trueOrFalse);
1781 SetParameter(
"key", key);
1792 var key = GetResultFromIndex(resultIndex)?.ToString() ??
"";
1803 var key = GetResultFromName(name)?.ToString() ??
"";
1814 SetParameter(
"css", css);
1825 var css = GetResultFromIndex(resultIndex)?.ToString() ??
"";
1836 var css = GetResultFromName(name)?.ToString() ??
"";
1847 SetParameter(
"gpalElements", gpalElements);
1858 var elementId = GetResultFromIndex(resultIndex)?.ToString() ??
"";
1869 var elementId = GetResultFromName(name)?.ToString() ??
"";
1879 _currentIteration = iteration > 0 ? iteration : 1;
1889 SetParameter(
"xpath", xpath);
1900 var xpath = GetResultFromIndex(resultIndex)?.ToString() ??
"";
1911 var xpath = GetResultFromName(name)?.ToString() ??
"";
1922 SetParameter(
"pixels", pixels);
1933 var pixels = GetResultFromIndex(resultIndex) is
int i ? i : 0;
1944 var pixels = GetResultFromName(name) is
int i ? i : 0;
1955 SetParameter(
"referrer", referrer);
1966 var referrer = GetResultFromIndex(resultIndex)?.ToString() ??
"";
1977 var referrer = GetResultFromName(name)?.ToString() ??
"";
1989 SetParameter(
"text", text);
2000 var text = GetResultFromIndex(resultIndex)?.ToString() ??
"";
2011 var text = GetResultFromName(name)?.ToString() ??
"";
2025 SetParameter(
"downloadPath", file.
Filename);
2033 private List<GPALElement> GetElements(
string selector)
2035 return _puppeteerCommunicator.EvaluateSelector(selector).Result;
2044 bool isObjectId = System.Text.RegularExpressions.Regex.IsMatch(selector,
@"^-?\d+\.\d+\.\d+$");
2048 SetParameter(
"elementId", selector);
2065 var elementId = GetResultFromIndex(resultIndex)?.ToString() ??
"";
2076 var elementId = GetResultFromName(name)?.ToString() ??
"";
2087 _hPixels = GetResultFromIndex(resultIndex) is
int i ? i : 0;
2088 SetParameter(
"hPixels", _hPixels);
2099 _hPixels = GetResultFromName(name) is
int i ? i : 0;
2100 SetParameter(
"hPixels", _hPixels);
2109 public IAllowPuppeteerParametersOrExecution WithVPixelsFromResult(
int resultIndex)
2111 _vPixels = GetResultFromIndex(resultIndex) is
int i ? i : 0;
2112 SetParameter(
"vPixels", _vPixels);
2123 _vPixels = GetResultFromName(name) is
int i ? i : 0;
2124 SetParameter(
"vPixels", _vPixels);
2132 public string Execute()
2134 return Task.Run(async () => await
ExecuteAsync().ConfigureAwait(
false)).GetAwaiter().GetResult();
2137 public T Execute<T>()
2141 Task<T> task = ExecuteAsync<T>();
2146 return Task.Run(async () => await task.ConfigureAwait(
false)).GetAwaiter().GetResult();
2154 catch (Exception ex)
2156 GPAL.PublishSimpleEvent(GPALEventType.EXCEPTION, $
"Failed to execute synchronously for type [{typeof(T).Name}].",
this, GPALObjectType.PuppeteerClient, ex);
2165 public IPuppeteerClient AndThen()
2171 public IPuppeteerClient AndThen<T>()
2181 public async Task<string> ExecuteAsync()
2183 var result = await ExecuteInternalAsync().ConfigureAwait(
false);
2189 return result?.ToString() ??
"";
2192 public async Task<T> ExecuteAsync<T>()
2194 dynamic result = await ExecuteInternalAsync().ConfigureAwait(
false);
2202 GPAL.PublishSimpleEvent(GPALEventType.EXCEPTION,
"ExecuteInternalAsync returned null.",
this, GPALObjectType.PuppeteerClient,
null);
2206 if (typeof(T) == typeof(JObject))
2208 if (result is JObject)
2210 return (T)(object)result;
2212 GPAL.PublishSimpleEvent(GPALEventType.EXCEPTION, $
"Expected JObject but got [{result.GetType().Name}].",
this, GPALObjectType.PuppeteerClient,
null);
2223 if (result is JToken)
2225 return JsonConvert.DeserializeObject<T>(result.ToString());
2235 if (result is JObject jObject)
2237 JToken resultToken = jObject[
"result"];
2238 if (resultToken ==
null)
2240 GPAL.PublishSimpleEvent(GPALEventType.EXCEPTION,
"Result object is missing 'result' property.",
this, GPALObjectType.PuppeteerClient,
null);
2244 JToken valueToken = resultToken[
"value"];
2245 if (valueToken !=
null)
2248 if (typeof(T) == typeof(
string) && valueToken.Type == JTokenType.String)
2250 return (T)(object)valueToken.ToString();
2255 return JsonConvert.DeserializeObject<T>(valueToken.ToString());
2257 catch (Exception ex)
2259 GPAL.
PublishSimpleEvent(GPALEventType.EXCEPTION, $
"Failed to deserialize result.value [{valueToken.ToString()}] to type [{typeof(T).Name}].",
this, GPALObjectType.PuppeteerClient, ex);
2266 return JsonConvert.DeserializeObject<T>(resultToken.ToString());
2268 catch (Exception ex)
2270 GPAL.
PublishSimpleEvent(GPALEventType.EXCEPTION, $
"Failed to deserialize result [{resultToken.ToString()}] to type [{typeof(T).Name}].",
this, GPALObjectType.PuppeteerClient, ex);
2275 GPAL.
PublishSimpleEvent(GPALEventType.EXCEPTION, $
"Unsupported result type [{result.GetType().Name}] for type [{typeof(T).Name}].",
this, GPALObjectType.PuppeteerClient,
null);
2294 _workflowStates.Clear();
2307 _executionResults.Clear();
2318 return new ResultCollection(_executionResults.Select(entry => (entry.Name, entry.Result, entry.Iteration)).ToList(), _name);
2342 _headers[name] = value;
2353 SetParameter(
"parameters", parameters);
2364 SetParameter(
"parameters", parameters);
2375 SetParameter(
"parameters", GetResultFromIndex(resultIndex));
2386 SetParameter(
"parameters", GetResultFromName(name));
2397 _contentEncoding = encoding;
2406 public IAllowPuppeteerWorkflow WithWorkflow(Action<PuppeteerClient> workflow)
2410 _workflowStates.Add((_endpoint, _parameters, _nextResultName));
2411 _workflows.Add(workflow);
2421 public IAllowPuppeteerWorkflow WhileLoopTimeout(
int timeoutMs)
2423 _whileLoopTimeoutMs = timeoutMs;
2432 public IAllowPuppeteerWorkflow WhileLoopMaxIterations(
int maxIterations)
2434 _whileLoopMaxIterations = maxIterations;
2450 private void RunWorkflowLoop(Func<bool> condition,
bool until)
2452 if (0 == _workflows.Count)
2454 GPAL.PublishSimpleEvent(GPALEventType.WARNING,
2455 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}No workflow steps declared for the {(true == until ? "Until
" : "While
")} loop.",
2456 this, GPALObjectType.PuppeteerClient);
2464 int maxIterations = 0 < _whileLoopMaxIterations ? _whileLoopMaxIterations : 1000;
2465 int timeoutMs = 0 < _whileLoopTimeoutMs ? _whileLoopTimeoutMs :
int.MaxValue;
2468 Func<bool> anotherPass =
true == until ? () =>
false == condition() : condition;
2471 DateTime started = DateTime.UtcNow;
2473 while (
true == anotherPass()
2474 && maxIterations > iteration
2475 && timeoutMs > (DateTime.UtcNow - started).TotalMilliseconds)
2477 _currentIteration = iteration;
2479 for (
int step = 0; step < _workflows.Count; step++)
2481 (
string Endpoint,
object Parameters,
string NextResultName)? declaredAs = _workflowStates[step];
2483 if (
true == declaredAs.HasValue)
2484 (_endpoint, _parameters, _nextResultName) = declaredAs.Value;
2488 _workflows[step](
this);
2494 if (maxIterations <= iteration)
2496 $
"{(string.IsNullOrEmpty(_name) ? "" : $"[{_name}]
")}Loop stopped at its maximum of [{maxIterations}] passes.",
2497 this, GPALObjectType.PuppeteerClient);
2501 _currentIteration = 1;
2505 RunWorkflowLoop(condition,
false);
2517 RunWorkflowLoop(condition,
true);
2529 _timeoutMs = timeoutMs;
2551 _maxConnections = maxConnections;
2573 SetParameter(
"hPixels", hPixels);
2584 SetParameter(
"vPixels", vPixels);
2595 SetParameter(
"deltaX", deltaX);
2606 SetParameter(
"deltaY", deltaY);
2617 SetParameter(
"offsetX", offsetX);
2628 SetParameter(
"offsetY", offsetY);
2639 _attribute = attribute;
2640 SetParameter(
"attribute", attribute);
2652 SetParameter(
"value", value);
2663 SetParameter(
"destElementId", destElementId);
2674 SetParameter(
"sinkName", sinkName);
2695 WithImageFormat(imageFormat);
2707 WithEndpoint(ApiEndpoint.CastDesktop).WithDeviceName(deviceNameOrId);
2718 WithEndpoint(ApiEndpoint.CastTab).WithDeviceName(deviceNameOrId);
2730 if (url !=
null)
WithUrl(url.Url);
2754 if (url !=
null)
WithUrl(url.Url);
2778 SetParameter(
"storageType", storageType.ToString());
2791 SetParameter(
"expression", script);
2804 SetParameter(
"url", url);
2815 SetParameter(
"method", method);
2826 SetParameter(
"body", body);
2837 SetParameter(
"contentType", contentType);
2848 SetParameter(
"headers", headers);
2860 SetParameter(
"bytes", asBytes);
2876 else if (elementOrelementId is List<GPALElement> elements)
2881 SetParameter(
"typingDelay", delayMs);
2897 else if (elementOrelementId is List<GPALElement> elements)
2898 WithElements(elements);
2900 WithElementId(elementOrelementId);
2902 SetParameter(
"typingDelay", delayMs);
2914 WithEndpoint(ApiEndpoint.FillInOverwrite);
2917 WithElements(
new List<GPALElement>() { element });
2918 else if (elementOrelementId is List<GPALElement> elements)
2919 WithElements(elements);
2921 WithElementId(elementOrelementId);
2923 SetParameter(
"typingDelay", delayMs);
2967 if (
false ==
string.IsNullOrEmpty(sessionToken))
3024 WithEndpoint(ApiEndpoint.GetStorage);
3025 SetParameter(
"storageType", storageType.ToString());
3036 WithEndpoint(ApiEndpoint.GetLanguages);
3046 WithEndpoint(ApiEndpoint.GetUserAgent);
3057 url.
ForUrl(
MagicHelper.GetFullUrl(url?.
Url, _puppeteerCommunicator.Browser, out _puppeteerCommunicator.Browser._areRobotsAllowed));
3059 if (
false == _puppeteerCommunicator.Browser.AreRobotsAllowed &&
true == _puppeteerCommunicator.Browser.BrowserSettings.ObeyRobotsTxt)
3061 GPAL.
PublishSimpleEvent(GPALEventType.ERROR, $
"[{url?.Url}] not allowed to robots and your honoring robots.txt. Not going to URL. Workflow will fail.",
this, GPALObjectType.PuppeteerClient);
3064 WithEndpoint(ApiEndpoint.GoTo);
3157 WithEndpoint(ApiEndpoint.Maximize);
3190 WithEndpoint(ApiEndpoint.NewTab);
3192 url?.
ForUrl(
MagicHelper.GetFullUrl(url?.Url, _puppeteerCommunicator.Browser, out _puppeteerCommunicator.Browser._areRobotsAllowed));
3194 if (
false == _puppeteerCommunicator.Browser.AreRobotsAllowed &&
true == _puppeteerCommunicator.Browser.BrowserSettings.ObeyRobotsTxt)
3196 GPAL.
PublishSimpleEvent(GPALEventType.ERROR, $
"[{url.Url}] not allowed to robots and your honoring robots.txt. Not going to URL. Workflow will fail.",
this, GPALObjectType.PuppeteerClient);
3197 url.
ForUrl(
"https://google.com");
3208 public IAllowPuppeteerExecution NextTab()
3210 WithEndpoint(ApiEndpoint.NextTab);
3220 WithEndpoint(ApiEndpoint.NextWindow);
3243 url.
ForUrl(
MagicHelper.GetFullUrl(url?.
Url, _puppeteerCommunicator.Browser, out _puppeteerCommunicator.Browser._areRobotsAllowed));
3245 if (
false == _puppeteerCommunicator.Browser.AreRobotsAllowed &&
true == _puppeteerCommunicator.Browser.BrowserSettings.ObeyRobotsTxt)
3247 GPAL.
PublishSimpleEvent(GPALEventType.ERROR, $
"[{url?.Url}] not allowed to robots and your honoring robots.txt. Not going to URL. Workflow will fail.",
this, GPALObjectType.PuppeteerClient);
3248 url.
ForUrl(
"https://google.com");
3275 SetParameter(
"userAgent", userAgent);
3287 SetParameter(
"pagesToScroll", pagesToScroll);
3297 WithEndpoint(ApiEndpoint.PageEnd);
3307 WithEndpoint(ApiEndpoint.PageTop);
3319 SetParameter(
"pagesToScroll", pagesToScroll);
3349 WithEndpoint(ApiEndpoint.Refresh);
3386 if (modifierKeys.HasFlag(ModifierKeys.Alt))
3388 if (modifierKeys.HasFlag(ModifierKeys.Control))
3390 if (modifierKeys.HasFlag(ModifierKeys.Windows))
3392 if (modifierKeys.HasFlag(ModifierKeys.Shift))
3401 public string GetModifiersString(
int bitmask)
3403 var modifiers =
new List<string>();
3405 if ((bitmask & 1) != 0)
3406 modifiers.Add(
"Alt");
3407 if ((bitmask & 2) != 0)
3408 modifiers.Add(
"Control");
3409 if ((bitmask & 4) != 0)
3410 modifiers.Add(
"Windows");
3411 if ((bitmask & 8) != 0)
3412 modifiers.Add(
"Shift");
3414 return modifiers.Count > 0 ?
string.Join(
"+", modifiers) :
"None";
3445 WithEndpoint(ApiEndpoint.ScrollWindowByHorizontal);
3446 SetParameter(
"hPixels", pixels);
3458 SetParameter(
"vPixels", pixels);
3472 SetParameter(
"typingDelay", delayMs);
3486 SetParameter(
"key", key);
3487 SetParameter(
"code", code);
3488 SetParameter(
"vk", (
int)vkcode);
3499 WithEndpoint(ApiEndpoint.OverrideReferrer).WithReferrer(
"https://www.google.com");
3567 SetParameter(
"script", script);
3591 SetParameter(
"downloadPath", downloadPath);
3767 WithEndpoint(ApiEndpoint.IsEndOfPage);
3779 SetParameter(
"gpalElements",
new List<GPALElement>() { (
GPALElement)element });
3790 WithEndpoint(ApiEndpoint.IsVisibleInViewport);
3791 WithElementId(backendNodeId);
3802 if (elementOrelementId is System.Drawing.Point point)
3803 return WithClickPoint(point, ClickType.LeftClick);
3809 else if (elementOrelementId is List<GPALElement> elements)
3824 if (elementOrelementId is System.Drawing.Point point)
3825 return WithClickPoint(point, ClickType.MiddleClick);
3831 else if (elementOrelementId is List<GPALElement> elements)
3846 if (elementOrelementId is System.Drawing.Point point)
3847 return WithClickPoint(point, ClickType.LeftDoubleClick);
3853 else if (elementOrelementId is List<GPALElement> elements)
3854 WithElements(elements);
3856 WithElementId(elementOrelementId);
3868 if (elementOrelementId is System.Drawing.Point point)
3869 return WithClickPoint(point, ClickType.RightClick);
3875 else if (elementOrelementId is List<GPALElement> elements)
3876 WithElements(elements);
3878 WithElementId(elementOrelementId);
3888 public IAllowPuppeteerSelectOptions SelectClick(
string elementHandle)
3902 SetParameter(
"selectValue", value);
3912 SetParameter(
"selectIndex", index);
3926 else if (elementOrelementId is List<GPALElement> elements)
3970 WithEndpoint(ApiEndpoint.WindowOuterWidth);
3980 WithEndpoint(ApiEndpoint.WindowPageOffsetX);
3988 public IAllowPuppeteerExecution WindowPageOffsetY()
3990 WithEndpoint(ApiEndpoint.WindowPageOffsetY);
3998 public IAllowPuppeteerExecution WindowScreenLeft()
4010 WithEndpoint(ApiEndpoint.WindowScreenTop);
4036 SetParameter(
"x", point.X);
4037 SetParameter(
"y", point.Y);
4038 SetParameter(
"clickType", (
int)clickType);
4051 SetParameter(
"x", point.X);
4052 SetParameter(
"y", point.Y);
4159 WithEndpoint(ApiEndpoint.SetRange);
4171 SetParameter(
"rangeValue", rangeValue.ToString());
4181 WithEndpoint(ApiEndpoint.ScrollElement);
4194 WithEndpoint(ApiEndpoint.ScrollElement);
4208 public IAllowPuppeteerExecution SetValueFrom(
string destSelector)
4210 WithEndpoint(ApiEndpoint.SetValueFromElement);
4211 SetParameter(
"destSelector", destSelector);
4219 public IAllowPuppeteerExecution TopBrowser()
4221 WithEndpoint(ApiEndpoint.TopBrowser);
4242 private object GetResultFromIndex(
int index)
4244 if (index < 0 || index >= _executionResults.Count)
return null;
4245 return _executionResults[index].Result;
4254 private object GetResultFromName(
string name)
4256 return _executionResults.LastOrDefault(entry => entry.Name == name).Result;
4264 private void SetParameter(
string key,
object value)
4266 if (_parameters ==
null) _parameters =
new Dictionary<string, object>();
4267 ((Dictionary<string, object>)_parameters)[key] = value;
4275 public IAllowPuppeteerStorageOptions SetStorage(WebsiteStorageType storageType)
4277 WithEndpoint(ApiEndpoint.SetStorage);
4278 SetParameter(
"storageType", storageType.ToString());
4285 private void Reset()
4289 _customEndpoint =
false;
4290 _nextResultName =
null;
4291 _timeoutMs = 30_000;
4293 _maxConnections = 0;
4299 _currentIteration = 1;
4300 _whileLoopTimeoutMs = 0;
4301 _whileLoopMaxIterations = 0;
4308 private async Task<object> ExecuteInternalAsync()
4310 if (
true == _puppeteerCommunicator._windowSessionsQueue.IsEmpty)
4312 GPAL.PublishSimpleEvent(GPALEventType.WARNING, $
"No browser windows open. Cannot call endpoint [{_endpoint}]",
null, GPALObjectType.None);
4316 if (
string.IsNullOrEmpty(_endpoint))
4318 GPAL.PublishSimpleEvent(GPALEventType.WARNING, $
"[{_name}] No endpoint specified",
null, GPALObjectType.None);
4322 var parameters = _parameters as IDictionary<string, object> ??
4323 (_parameters?.GetType().GetProperties().ToDictionary(p => p.Name, p => p.GetValue(_parameters)) ??
new Dictionary<string, object>());
4325 if (!_customEndpoint && !restClient.ValidateParameters(_apiEndpoint, parameters))
4330 object result = await ExecuteEndpoint(_endpoint, parameters).ConfigureAwait(
false);
4332 if (!
string.IsNullOrEmpty(_saveFile))
4334 SaveResponseToFile(result?.ToString(), _saveFile);
4337 if (!
string.IsNullOrEmpty(_nextResultName))
4339 _executionResults.Add((_nextResultName, result, _executionResults.Where(r => r.Name == _nextResultName && r.TargetId == _currentTargetId).Select(r => r.Iteration).DefaultIfEmpty(0).Max() + 1, _currentTargetId));
4340 _workflowStates.Add((_endpoint, _parameters, _nextResultName));
4344 string valueStr = (result as JObject)?[
"result"]?[
"value"]?.Value<string>();
4345 if (!
string.IsNullOrEmpty(valueStr))
4350 statusCode = (int) JObject.Parse(valueStr)[
"status"]?.Value<
int>();
4356 _puppeteerCommunicator.ServerResponseCode = statusCode;
4357 if (statusCode < 200 || statusCode >= 300)
4358 GPAL.PublishSimpleEvent(GPALEventType.WARNING, $
"[{_name}] Endpoint [{_endpoint}] returned HTTP [{statusCode}]",
null, GPALObjectType.None);
4363 _whileLoopTimeoutMs = 0;
4364 _whileLoopMaxIterations = 0;
4375 private async Task<object> ExecuteEndpoint(
string endpoint, IDictionary<string, object> parameters)
4377 if (endpointMap.TryGetValue(endpoint, out var handler))
4380 var sessionId = _puppeteerCommunicator.GetEffectiveSessionId();
4381 if (sessionId ==
null)
4383 GPAL.
PublishSimpleEvent(GPALEventType.ERROR,
"No active session for execution. Using null.",
this, GPALObjectType.Puppeteer);
4386 return await handler(_puppeteerCommunicator, parameters, sessionId).ConfigureAwait(
false);