18using System.Collections.Generic;
22using System.Threading.Tasks;
27using System.Windows.Automation;
29using System.Reflection;
43 internal class SmallSelectorNode
45 public InteractionType InteractionType {
get;
internal set; }
46 public int OffsetX {
get;
internal set; }
47 public int OffsetY {
get;
internal set; }
48 public int DeltaX {
get;
internal set; }
49 public int DeltaY {
get;
internal set; }
58 internal SelectorSettings selectorSettings =
null;
59 public SelectorSettings SelectorSettings
63 return selectorSettings;
67 selectorSettings = value;
71 public SelectorType SelectorType
75 return SelectorSettings.SelectorType;
80 selectorSettings.SelectorType = value;
85 public Selector ToGPALObject()
99 public delegate CallIfStatus
webMatchingFunction(List<IGPALElement> foundElements, out List<IGPALElement> matchedElements, out
bool matchedAll, Selector selector,
bool ExactMatch =
true);
110 public delegate CallIfStatus
appMatchingFunction(List<GPALAutomationElement> foundElements, out List<GPALAutomationElement> matchedElements, out
bool matchedAll, Selector selector,
bool ExactMatch =
true);
113 internal Selector(
Browser.Browser browser, Selector selector)
115 SelectorSettings =
new SelectorSettings();
118 selectorSettings = ObjectCopier.DeepCopyObject(selector.SelectorSettings, selectorSettings, DeepCopy.FieldsAndProperties);
119 if (
true ==
string.IsNullOrEmpty(selector.
Name))
120 Name = $
"Selector{browser.CurrentUOW.WithSelectorList.Count}";
130 Name = $
"Selector{browser.CurrentUOW.WithSelectorList.Count}";
135 SelectorSettings =
new SelectorSettings();
137 MyApplication = application;
138 selectorSettings = ObjectCopier.DeepCopyObject(selector.SelectorSettings, selectorSettings, DeepCopy.FieldsAndProperties);
139 if (
true ==
string.IsNullOrEmpty(selector.
Name))
140 Name = $
"Selector{application.CurrentUOW.WithSelectorList.Count}";
146 internal Selector(Application.Application application)
148 MyApplication = application;
149 SelectorSettings =
new SelectorSettings();
150 Name = $
"Selector{application.CurrentUOW.WithSelectorList.Count}";
154 SelectorSettings =
new SelectorSettings();
156 internal bool AnyMatchCriteria()
158 return 0 < MatchCriteria.Count;
161 #region <Fluent Settings>
171 SelectorSettings.SelectorPaths.Add(selectorPathEntry);
183 SelectorSettings.SelectorPaths.Add(selectorPathEntry);
195 SelectorSettings.SelectorPaths.Add(selectorPathEntry);
207 SelectorSettings.SelectorPaths.Add(selectorPathEntry);
219 SelectorSettings.SelectorPaths.Add(selectorPathEntry);
231 SelectorSettings.SelectorPaths.Add(selectorPathEntry);
243 SelectorSettings.SelectorPaths.Add(selectorPathEntry);
255 SelectorSettings.SelectorPaths.Add(selectorPathEntry);
271 SelectorSettings.SelectorPaths.Add(selectorPathEntry);
289 SelectorSettings.SelectorPaths.Add(selectorPathEntry);
298 [SingleUse(Description =
"Search inside the element this selector already found rather than the whole page")]
301 SelectorSettings.SearchForSelector = searchForElement;
310 [SingleUse(Description =
"A name for this selector, used as the column header when its data is saved and in the events it publishes")]
313 SelectorSettings.Name = name;
321 [SingleUse(Description =
"How far to drag horizontally from where the element was grabbed, in pixels")]
324 SelectorSettings.DeltaX = deltaX;
332 [SingleUse(Description =
"How far to drag vertically from where the element was grabbed, in pixels")]
335 SelectorSettings.DeltaY = deltaY;
343 [SingleUse(Description =
"Where to click inside the element, in pixels right of its left edge. Unset clicks the centre")]
346 SelectorSettings.OffsetX = offsetX;
354 [SingleUse(Description =
"Where to click inside the element, in pixels down from its top edge. Unset clicks the centre")]
357 SelectorSettings.OffsetY = offsetY;
365 [SingleUse(Description =
"Move the pointer to the element along a curve rather than jumping straight there")]
368 SelectorSettings.SimulateMouse = moveWithArc;
373 [SingleUse(Description =
"Read this attribute from the element instead of its text when data is retrieved")]
376 SelectorSettings.AttributeName = attributeName;
386 SelectorSettings.MatchCriteriaEntry matchCriteriaEntry =
new SelectorSettings.MatchCriteriaEntry { MatchType = MatchType.Custom, AppMatchingFunction = matchingFunction };
387 SelectorSettings.MatchCriteria.Add(matchCriteriaEntry);
397 SelectorSettings.MatchCriteriaEntry matchCriteriaEntry =
new SelectorSettings.MatchCriteriaEntry { MatchType = MatchType.Custom, WebMatchingFunction = matchingFunction };
398 SelectorSettings.MatchCriteria.Add(matchCriteriaEntry);
408 SelectorSettings.MatchCriteriaEntry matchCriteriaEntry =
new SelectorSettings.MatchCriteriaEntry { MatchType = MatchType.Attribute, StringToMatch = attributeToMatch };
409 SelectorSettings.MatchCriteria.Add(matchCriteriaEntry);
419 SelectorSettings.MatchCriteriaEntry matchCriteriaEntry =
new SelectorSettings.MatchCriteriaEntry { MatchType = MatchType.Regex | MatchType.Attribute, StringToMatch = attributeToMatch };
420 SelectorSettings.MatchCriteria.Add(matchCriteriaEntry);
430 SelectorSettings.MatchCriteriaEntry matchCriteriaEntry =
new SelectorSettings.MatchCriteriaEntry { MatchType = MatchType.Href, StringToMatch = hrefToMatch };
431 SelectorSettings.MatchCriteria.Add(matchCriteriaEntry);
441 SelectorSettings.MatchCriteriaEntry matchCriteriaEntry =
new SelectorSettings.MatchCriteriaEntry { MatchType = MatchType.Regex | MatchType.Href, StringToMatch = hrefToMatch };
442 SelectorSettings.MatchCriteria.Add(matchCriteriaEntry);
452 SelectorSettings.MatchCriteriaEntry matchCriteriaEntry =
new SelectorSettings.MatchCriteriaEntry { MatchType = MatchType.Placeholder, StringToMatch = placeholderToMatch };
453 SelectorSettings.MatchCriteria.Add(matchCriteriaEntry);
463 SelectorSettings.MatchCriteriaEntry matchCriteriaEntry =
new SelectorSettings.MatchCriteriaEntry { MatchType = MatchType.Regex | MatchType.Placeholder, StringToMatch = placeholderToMatch };
464 SelectorSettings.MatchCriteria.Add(matchCriteriaEntry);
474 SelectorSettings.MatchCriteriaEntry matchCriteriaEntry =
new SelectorSettings.MatchCriteriaEntry { MatchType = MatchType.Src, StringToMatch = srcToMatch };
475 SelectorSettings.MatchCriteria.Add(matchCriteriaEntry);
485 SelectorSettings.MatchCriteriaEntry matchCriteriaEntry =
new SelectorSettings.MatchCriteriaEntry { MatchType = MatchType.Regex | MatchType.Src, StringToMatch = srcToMatch };
486 SelectorSettings.MatchCriteria.Add(matchCriteriaEntry);
496 SelectorSettings.MatchCriteriaEntry matchCriteriaEntry =
new SelectorSettings.MatchCriteriaEntry { MatchType = MatchType.Text, StringToMatch = textToMatch };
497 SelectorSettings.MatchCriteria.Add(matchCriteriaEntry);
507 SelectorSettings.MatchCriteriaEntry matchCriteriaEntry =
new SelectorSettings.MatchCriteriaEntry { MatchType = MatchType.Regex | MatchType.Text, StringToMatch = textToMatch };
508 SelectorSettings.MatchCriteria.Add(matchCriteriaEntry);
518 SelectorSettings.MatchCriteriaEntry matchCriteriaEntry =
new SelectorSettings.MatchCriteriaEntry { MatchType = MatchType.Value, StringToMatch = valueToMatch };
519 SelectorSettings.MatchCriteria.Add(matchCriteriaEntry);
529 SelectorSettings.MatchCriteriaEntry matchCriteriaEntry =
new SelectorSettings.MatchCriteriaEntry { MatchType = MatchType.Regex | MatchType.Value, StringToMatch = valueToMatch };
530 SelectorSettings.MatchCriteria.Add(matchCriteriaEntry);
557 SelectorSettings.StopOnNotFound = stopOnNotFound;
567 SelectorSettings.CallIfNotFound.Add(callIfNotFound);
580 foreach (
string filename
in imageToFindPath.Filenames)
583 SelectorSettings.SelectorPaths.Add(selectorPathEntry);
597 SelectorSettings.MatchCriteriaEntry matchCriteriaEntry =
new SelectorSettings.MatchCriteriaEntry { MatchType = MatchType.Href, StringToMatch = HRefFullOrPartial };
598 matchCriteriaEntry.ExactMatch =
false;
599 SelectorSettings.MatchCriteria.Add(matchCriteriaEntry);
602 #endregion <Fluent Settings>
604 #region <Getter/Setters>
629 SelectorSettings.RequestedInteractionType =
InteractionType.JavaScript;
654 return SelectorSettings.ElementsFoundAndMatchedCount;
658 SelectorSettings.ElementsFoundAndMatchedCount = value;
661 internal CallIfStatus AppCallIfFoundHandled
669 SelectorSettings.AppCallIfFoundHandled = value;
672 internal CallIfStatus AppCallIfNotFoundHandled
676 return SelectorSettings.AppCallIfNotFoundHandled;
680 SelectorSettings.AppCallIfNotFoundHandled = value;
683 internal CallIfStatus CallIfFoundHandled
687 return SelectorSettings.CallIfFoundHandled;
691 SelectorSettings.CallIfFoundHandled = value;
694 internal CallIfStatus CallIfNotFoundHandled
698 return SelectorSettings.CallIfNotFoundHandled;
702 SelectorSettings.CallIfNotFoundHandled = value;
705 internal Application.Application Application
709 return MyApplication;
713 MyApplication = value;
716 internal List<Application.Application.CallIfDelegate> AppCallIfFound
720 return SelectorSettings.AppCallIfFound;
723 internal List<Application.Application.CallIfDelegate> AppCallIfNotFound
727 return SelectorSettings.AppCallIfNotFound;
730 internal string AttributeName
734 return SelectorSettings.AttributeName;
746 return SelectorSettings.InteractionType;
750 SelectorSettings.InteractionType = value;
769 return SelectorSettings.SelectorPaths[0].SelectorPath;
780 return SelectorSettings.SelectorPaths;
798 return SelectorSettings.SearchForSelector;
810 return SelectorSettings.OffsetX;
814 SelectorSettings.OffsetX = value;
826 return SelectorSettings.OffsetY;
830 SelectorSettings.OffsetY = value;
841 return SelectorSettings.DeltaX;
845 SelectorSettings.DeltaX = value;
856 return SelectorSettings.DeltaY;
860 SelectorSettings.DeltaY = value;
873 return SelectorSettings.Name;
878 SelectorSettings.Name = value;
884 internal bool DeleteMe
892 SelectorSettings.DeleteMe = value;
900 internal List<
Browser.Browser.CallIfDelegate> RemovedMethods
904 return SelectorSettings.RemovedMethods;
908 SelectorSettings.RemovedMethods = value;
921 return SelectorSettings.RequestedInteractionType;
925 SelectorSettings.RequestedInteractionType = value;
936 return SelectorSettings.SimulateMouse;
947 return SelectorSettings.StopOnNotFound;
951 public List<GPALElement> WebSelectorFoundResults
956 if (
null != selectorPathEntry.WebSelectorFoundResults)
957 return selectorPathEntry.WebSelectorFoundResults;
964 selectorPathEntry.WebSelectorFoundResults = value;
967 public List<GPALElement> WebSelectorMatchedResults
972 if (
null != selectorPathEntry.WebSelectorMatchedResults)
973 return selectorPathEntry.WebSelectorMatchedResults;
980 selectorPathEntry.WebSelectorMatchedResults = value;
984 #endregion <Getter/Setters>
986 #region Implicit String Conversion, so wherever Selector parameter is expected, a string can be used directly
988 public static implicit
operator string(Selector sel) => sel.
Name;
990 private static int implicitCount = 0;
994 public static implicit
operator Selector(
string selectorString)
996 var sel =
new Selector();
998 if (
string.IsNullOrWhiteSpace(selectorString))
1001 GPAL.PublishSimpleEvent(
1002 GPALEventType.WARNING,
1003 "Invalid selector path treating as empty selector (no paths added).",
1005 GPALObjectType.Selector
1009 sel.WithSelectorName($
"EmptySelector{implicitCount++}");
1018 sel.WithXPath(selectorString);
1019 sel.WithCSS(selectorString);
1024 sel.WithCSS(selectorString);
1025 sel.WithXPath(selectorString);
1029 sel.WithSelectorName($
"Implicit{implicitCount++}.{(looksLikeXPath ? "XPath
" : "CSS
")}.{Shorten(selectorString, 10)}");
1032 GPAL.PublishSimpleEvent(GPALEventType.DEBUG, $
"Implicit selector [{sel.Name}] created for [{selectorString}]");
1035 if (1 == implicitCount)
1036 GPAL.PublishSimpleEvent(GPALEventType.DEBUG, $
"Implicit selector conversions lack equality, even if paths match. Create instance using GPAL.Selector for reuse.", sel, GPALObjectType.Selector);
1042 private static string Shorten(
string s,
int maxLen)
1044 if (s.Length <= maxLen)
return s;
1045 return s.Substring(0, maxLen - 3) +
"...";
1056 if (
string.IsNullOrWhiteSpace(s))
return false;
1060 if (s.StartsWith(
"/") || s.StartsWith(
".//") || s.StartsWith(
"//") || s.StartsWith(
"id("))
1064 if (
char.IsLetter(s[0]) && s.Contains(
"/") && s.Contains(
"["))
1068 if (s.Contains(
"::") ||
1069 s.Contains(
"/following") ||
1070 s.Contains(
"/preceding") ||
1071 s.Contains(
"/ancestor") ||
1072 s.Contains(
"/parent") ||
1073 s.Contains(
"/child") ||
1074 s.Contains(
"position()") ||
1075 s.Contains(
"last()") ||
1076 s.Contains(
"normalize-space") ||
1077 s.Contains(
"contains(text()") ||
1078 (s.Contains(
"@") && s.Contains(
"=") && !s.Contains(
"[")))
1084 if (s.Contains(
"@") && !s.Contains(
"["))
1088 if (s.StartsWith(
"#") ||
1089 s.StartsWith(
".") ||
1093 s.Contains(
":not(") ||
1094 s.Contains(
":nth-child") ||
1095 s.Contains(
":nth-of-type"))
1101 if (s.Contains(
"[") && !s.Contains(
":") && !s.Contains(
"#") && !s.Contains(
"."))
1111 SelectorSettings.MatchCriteriaEntry matchCriteriaEntry =
new SelectorSettings.MatchCriteriaEntry { MatchType = MatchType.Attribute, StringToMatch = attributeToMatch };
1112 matchCriteriaEntry.ExactMatch =
false;
1113 SelectorSettings.MatchCriteria.Add(matchCriteriaEntry);
1117 public IAllowSelectorSettings ContainsHRef(
string hrefToMatch)
1119 SelectorSettings.MatchCriteriaEntry matchCriteriaEntry =
new SelectorSettings.MatchCriteriaEntry { MatchType = MatchType.Href, StringToMatch = hrefToMatch };
1120 matchCriteriaEntry.ExactMatch =
false;
1121 SelectorSettings.MatchCriteria.Add(matchCriteriaEntry);
1125 public IAllowSelectorSettings ContainsPlaceholder(
string placeholderToMatch)
1127 SelectorSettings.MatchCriteriaEntry matchCriteriaEntry =
new SelectorSettings.MatchCriteriaEntry { MatchType = MatchType.Placeholder, StringToMatch = placeholderToMatch };
1128 matchCriteriaEntry.ExactMatch =
false;
1129 SelectorSettings.MatchCriteria.Add(matchCriteriaEntry);
1133 public IAllowSelectorSettings ContainsSrc(
string srcToMatch)
1135 SelectorSettings.MatchCriteriaEntry matchCriteriaEntry =
new SelectorSettings.MatchCriteriaEntry { MatchType = MatchType.Src, StringToMatch = srcToMatch };
1136 matchCriteriaEntry.ExactMatch =
false;
1137 SelectorSettings.MatchCriteria.Add(matchCriteriaEntry);
1141 public IAllowSelectorSettings ContainsText(
string textToMatch)
1143 SelectorSettings.MatchCriteriaEntry matchCriteriaEntry =
new SelectorSettings.MatchCriteriaEntry { MatchType = MatchType.Text, StringToMatch = textToMatch };
1144 matchCriteriaEntry.ExactMatch =
false;
1145 SelectorSettings.MatchCriteria.Add(matchCriteriaEntry);
1149 public IAllowSelectorSettings ContainsValue(
string valueToMatch)
1151 SelectorSettings.MatchCriteriaEntry matchCriteriaEntry =
new SelectorSettings.MatchCriteriaEntry { MatchType = MatchType.Value, StringToMatch = valueToMatch };
1152 matchCriteriaEntry.ExactMatch =
false;
1153 SelectorSettings.MatchCriteria.Add(matchCriteriaEntry);
Application object that contains the fluent methods to create your Application workflow....
Browser object that contains the fluent methods to create your Browser workflow. Instatiated using G...
GPAL File object instantied with GPAL.File Used to load tokens into a GPALGrid [rows/columns].
Provides comprehensive image capture, conversion, and matching capabilities for automation scenarios....
static Image Base64ToImage(string base64String)
Converts a Base64 string (with or without data URI prefix) to a System.Drawing.Image.
GPAL Selector used to locate Application and Browser elements. Instantiated with GPAL....
IAllowSelectorSettings WithSelectorName(string name)
A common name for this selector. Used in Information and Exception channel messages.
string SelectorPath
Returns the first defined selector path string.
int DeltaX
Drag-and-drop deltaX to move from the elemenet.X + OffsetX.
IAllowSelectorSettings MatchText(string textToMatch)
Found elements must match the text supplied in order to interact with them.
IAllowSelectorSettings WithJavaScript
Interact with this element using javascript injected into the page.
IAllowSelectorSettings MatchValueRegex(string valueToMatch)
Found elements must match the value regular expression supplied in order to interact with them.
IAllowSelectorSettings MatchTextRegex(string textToMatch)
Found elements must match the text regular expression supplied in order to interact with them.
IAllowSelectorSettings MatchAttribute(string attributeToMatch)
Found elements must have attribute supplied in order to interact with them.
Browser.Browser Browser
Browser associated with this selector.
IAllowSelectorSettings WithDeltaY(int deltaY)
Define the y offset from the Top Left corner to perform clicks.
IAllowSelectorSettings WithImage(Image image)
Define an image to match on-screen. The top left corner is used as the start of the element....
bool StopOnNotFound
Stop the workflow if no elements are found for this selector.
void Remove()
Remove this selector from the current Unit of Work.
IAllowSelectorSettings WithPlaceholder(string placeholder)
Define the placeholder used to find elements, matched in full against the placeholder attribute....
IAllowSelectorSettings WithText(string text)
Define Text used to find elements by text attribute. Browser only.
IAllowSelectorSettings WithDeltaX(int deltaX)
Define the x offset from the Top Left corner to perform clicks.
IAllowSelectorSettings MatchPlaceholder(string placeholderToMatch)
Found elements must match the placeholder supplied in order to interact with them.
bool SearchForSelector
Search for elements on the page.
IAllowSelectorSettings MatchFunction(Selector.appMatchingFunction matchingFunction)
Your custom application element matching function to examine found elements and return only those you...
IAllowSelectorSettings MatchSrc(string srcToMatch)
Found elements must match the src supplied in order to interact with them.
int DeltaY
Drag-and-drop deltaY to move from the elemenet.Y + OffsetY.
int OffsetY
Y offset fromm the top left corner to interact with the element, image match included....
IAllowSelectorSettings MatchFunction(Selector.webMatchingFunction matchingFunction)
Your custom web element matching function to examine found elements and return only those you 'match'...
IAllowSelectorSettings WithClassName(string className)
Define Name used to find elements by name attribute. Application only.
IAllowSelectorSettings MatchAttributeRegex(string attributeToMatch)
Found elements must have the attribute specified by regular expression in order to interact with them...
int ElementsFoundAndMatchedCount
Count of elements found for this selector (after match).
InteractionType InteractionType
Defined method to interact with this element. NOTE: This can be overridden in the workflow.
IAllowSelectorSettings WithSelenium
Interact with this element using Selenium [default].
IAllowSelectorSettings WithValue(string value)
Define Value used to find elements by value attribute. Browser only.
IAllowSelectorSettings WithName(string name)
Define Name used to find elements by name attribute. Application only.
IAllowSelectorSettings WithXPath(string xPath)
Define XPath used to find elements Both.
IAllowSelectorSettings WithImage(GPALFile imageToFindPath)
Define an image to match on-screen. The top left corner is used as the start of the element....
IAllowSelectorSettings MatchHRefRegex(string hrefToMatch)
Found elements must match the HRef regular expression supplied in order to interact with them.
IAllowSelectorSettings MatchValue(string valueToMatch)
Found elements must match the value supplied in order to interact with them.
delegate CallIfStatus webMatchingFunction(List< IGPALElement > foundElements, out List< IGPALElement > matchedElements, out bool matchedAll, Selector selector, bool ExactMatch=true)
Custom matching function, must return all matched elements and an indicator as to whether all element...
static bool IsLikelyXPath(string s)
Rudimentary but reasonably effective guess: is this string more likely an XPath than a CSS selector?
IAllowSelectorSettings WithSimulateMouse(bool moveWithArc)
Simulate a human moving the mouse when interacting with this element. Implies hardware input.
IAllowSelectorSettings WithAutomationID(string automationID)
Define Name used to find elements by name attribute. Application only.
IAllowSelectorSettings WithOffsetX(int offsetX)
Define the x offset from the Top Left corner to perform clicks.
delegate CallIfStatus appMatchingFunction(List< GPALAutomationElement > foundElements, out List< GPALAutomationElement > matchedElements, out bool matchedAll, Selector selector, bool ExactMatch=true)
Custom matching function, must return all matched elements and an indicator as to whether all element...
IAllowSelectorSettings MatchPlaceholderRegex(string placeholderToMatch)
Found elements must match the placeholder regular expression supplied in order to interact with them.
IAllowSelectorSettings WithImage(string base64String)
Define an image to match on-screen. The top left corner is used as the start of the element....
List< SelectorSettings.SelectorPathEntry > SelectorPaths
The selector paths defined to locate elements.
IAllowSelectorSettings MatchHRef(string hrefToMatch)
Found elements must match the HRef supplied in order to interact with them.
IAllowSelectorSettings WithCSS(string css)
Define CSS used to find elements. Browser only.
bool SimulateMouse
Simulate moving the mouse to interact with this element?
IAllowSelectorSettings WithOffsetY(int offsetY)
Define the y offset from the Top Left corner to perform clicks.
IAllowSelectorSettings WithHRef(string HRefFullOrPartial)
Found elements must carry this href, in full or in part, in order to interact with them....
IAllowSelectorSettings WithSearchForSelector(bool searchForElement)
Search for a matching image when using hardware emulation or image matching. Finding an element on p...
IAllowSelectorSettings MatchSrcRegex(string srcToMatch)
Found elements must match the src regular expression supplied in order to interact with them.
string Name
The name you gave this selector, or one assigned by GPAL [selector1, selector2...] Used in Informati...
IAllowSelectorSettings WithStopOnNotFound(bool stopOnNotFound)
Stop the workflow if this selector is not found.
int OffsetX
X offset from the top left corner to interact with the element, image match included....
IAllowSelectorSettings WithHardware
Interact with this element using hardware emulation.
An entry defining a selector locator, a selector path.
Settings for the current selector. Use this only for debugging.