18using System.Collections.Generic;
19using System.Collections.ObjectModel;
23using System.Threading.Tasks;
27using System.Reflection;
28using DocumentFormat.OpenXml.Spreadsheet;
41 public string Xpath {
get;
set; }
63 public class ClientRectangle
66 public float Top {
get;
set; }
68 public float Left {
get;
set; }
72 public float Right {
get;
set; }
74 public float X {
get;
set; }
76 public float Y {
get;
set; }
78 public float Width {
get;
set; }
101 return new Dictionary<string, object>
157 public Dictionary<string, object>
Attributes {
get;
set; } =
new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
159 private Dictionary<string, object> _cssAttributes;
167 if (
null == _cssAttributes)
169 GPAL.
PublishSimpleEvent(GPALEventType.DEBUG, $
"Getting Css Attributes for element [{TagName}]",
this, GPALObjectType.Other);
172 _cssAttributes =
Browser.PuppeteerClient.GetCssAttributes(ElementBackendNodeId.ToString()).Execute<Dictionary<string, object>>();
174 _cssAttributes =
Browser.MagicHelper.GetCssAttributes(
Css);
178 if (
null == _cssAttributes)
179 _cssAttributes =
new Dictionary<string, object>();
181 GPAL.
PublishSimpleEvent(GPALEventType.DEBUG, $
"Got [{_cssAttributes.Count}] Css Attributes for element [{TagName}]",
this, GPALObjectType.Other);
183 return _cssAttributes;
185 set => _cssAttributes = value;
188 private Dictionary<string, object> _domAttributes;
196 if (
null == _domAttributes)
198 GPAL.
PublishSimpleEvent(GPALEventType.DEBUG, $
"Getting Dom Attributes for element [{TagName}]",
this, GPALObjectType.Other);
201 _domAttributes =
Browser.PuppeteerClient.GetDomAttributes(ElementBackendNodeId.ToString()).Execute<Dictionary<string, object>>();
203 _domAttributes =
Browser.MagicHelper.GetDomAttributes(
Css);
207 if (
null == _domAttributes)
208 _domAttributes =
new Dictionary<string, object>();
210 GPAL.
PublishSimpleEvent(GPALEventType.DEBUG, $
"Got [{_domAttributes.Count}] Dom Attributes for element [{TagName}]",
this, GPALObjectType.Other);
212 return _domAttributes;
214 set => _domAttributes = value;
217 private Dictionary<string, object> _domProperties;
225 if (
null == _domProperties)
227 GPAL.
PublishSimpleEvent(GPALEventType.DEBUG, $
"Getting Dom Properties for element [{TagName}]",
this, GPALObjectType.Other);
230 _domProperties =
Browser.PuppeteerClient.GetDomProperties(ElementBackendNodeId.ToString()).Execute<Dictionary<string, object>>();
232 _domProperties =
Browser.MagicHelper.GetDomProperties(
Css);
236 if (
null == _domProperties)
237 _domProperties =
new Dictionary<string, object>();
239 GPAL.
PublishSimpleEvent(GPALEventType.DEBUG, $
"Got [{_domProperties.Count}] Dom Properties for element [{TagName}]",
this, GPALObjectType.Other);
241 return _domProperties;
243 set => _domProperties = value;
251 internal dynamic iWebElement;
258 internal set => iWebElement = value;
261 public string ElementHandle {
get;
set; }
262 public int ElementNodeId {
get;
set; }
263 public int ElementBackendNodeId {
get;
set; }
264 internal long? ContextId {
get;
set; }
265 internal bool IsShadowRoot {
get;
set; } =
false;
271 internal bool IsClosedShadowRoot {
get;
set; } =
false;
290 get {
return Attributes.ContainsKey(
"attributeName") ?
Attributes[
"attributeName"] as string :
null; }
333 internal CoordinateSpace CoordinateSpace
335 get {
return Attributes.ContainsKey(
"coordinateSpace") &&
Attributes[
"coordinateSpace"] is CoordinateSpace ? (CoordinateSpace)
Attributes[
"coordinateSpace"] : CoordinateSpace.Screen; }
336 set {
Attributes[
"coordinateSpace"] = value; }
351 bool visibilty =
true;
356 visibilty =
CssAttributes[
"visibility"]?.ToString() !=
"hidden";
364 bool notHidden = visibilty && display && opacity;
366 bool hasSize = BoundingRect.Width > 0 && BoundingRect.Height > 0;
368 return notHidden && hasSize;
397 get {
return Attributes.ContainsKey(
"placeholder") ?
Attributes[
"placeholder"] as string :
null; }
465 internal GPALElement(Point location,
Size size,
string text, IWebDriver webDriver,
string tagname =
"img")
469 Text = CleanText(text);
475 internal GPALElement(IWebElement webElement,
string attributeName =
"")
477 iWebElement = webElement;
479 if (webElement !=
null)
482 Text = CleanText(webElement.Text);
486 Size = webElement.Size;
488 Href = webElement.GetAttribute(
"href");
489 Src = webElement.GetAttribute(
"src");
490 Value = CleanText(webElement.GetAttribute(
"value"));
491 Placeholder = CleanText(webElement.GetAttribute(
"placeholder"));
492 Type = webElement.GetAttribute(
"type");
513 internal GPALElement(IWebElement webElement,
string attributeName, Dictionary<string, object> properties,
string pageUrl)
515 iWebElement = webElement;
518 TagName = StringOf(properties,
"tag");
519 Text = CleanText(StringOf(properties,
"text"));
520 Enabled = BoolOf(properties,
"enabled");
521 Selected = BoolOf(properties,
"selected");
522 Displayed = BoolOf(properties,
"displayed");
523 Location =
new Point(IntOf(properties,
"x"), IntOf(properties,
"y"));
524 Size =
new Size(IntOf(properties,
"w"), IntOf(properties,
"h"));
525 Href = StringOf(properties,
"href");
526 Src = StringOf(properties,
"src");
527 Value = CleanText(StringOf(properties,
"value"));
528 Placeholder = CleanText(StringOf(properties,
"placeholder"));
529 Type = StringOf(properties,
"type");
538 static string StringOf(Dictionary<string, object> properties,
string name)
540 return true == properties.TryGetValue(name, out
object value) ? value?.ToString() :
null;
546 static bool BoolOf(Dictionary<string, object> properties,
string name)
548 return true == properties.TryGetValue(name, out
object value) &&
true == Convert.ToBoolean(value);
554 static int IntOf(Dictionary<string, object> properties,
string name)
556 return true == properties.TryGetValue(name, out
object value) &&
null != value ? Convert.ToInt32(value) : 0;
559 internal GPALElement(Dictionary<string, object> attributes,
Browser.Browser browser)
562 Attributes = attributes ??
new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
569 if (iWebElement !=
null)
578 public void Click(ModifierKeys modifierKeys)
580 string currentUrl =
Browser.BrowserSettings.CurrentURL;
581 Browser.CurrentUOW.ActionCalled =
true;
584 ElementHelper.Click(
Browser,
Selector,
this, ClickType.LeftClick, modifierKeys);
586 string currentUrl2 =
Browser.GetSetCurrentUrl();
588 if (
false == UrlHelper.AreEquivalent(currentUrl, currentUrl2))
595 Click(ModifierKeys.NONE);
599 public void MiddleClick(ModifierKeys modifierKeys = ModifierKeys.NONE)
601 Browser.CurrentUOW.ActionCalled =
true;
603 ElementHelper.Click(
Browser,
Selector,
this, ClickType.MiddleClick, modifierKeys);
610 Browser.CurrentUOW.ActionCalled =
true;
611 ElementHelper.Hide(
Browser,
this);
617 if (iWebElement !=
null)
618 return iWebElement.FindElement(by);
619 throw new NoSuchElementException(
"Element not found using " + by);
625 if (iWebElement !=
null)
626 return iWebElement.FindElements(by);
627 return new ReadOnlyCollection<IWebElement>(
new List<IWebElement>());
633 string seleniumValue =
null;
635 if (iWebElement !=
null)
636 seleniumValue = iWebElement.GetAttribute(
char.ToUpper(attributeName[0]) + attributeName.Substring(1));
638 if (
null == seleniumValue)
642 if (value is Point p)
643 return string.Format(
"({0},{1})", p.X, p.Y);
645 return string.Format(
"({0},{1})", s.Width, s.Height);
647 return string.Join(
"; ", arr.Select(x =>
string.Format(
"{0} ({1})", x.Xpath, x.MatchedElements)));
649 return string.Format(
"(top={0}, left={1}, bottom={2}, right={3}, x={4}, y={5}, width={6}, height={7})",
650 r.Top, r.Left, r.Bottom, r.Right, r.X, r.Y, r.Width, r.Height);
653 return value.ToString();
656 PropertyInfo
property = GetType().GetProperty(attributeName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
657 if (property !=
null && property.CanRead)
658 return property.GetValue(
this,
null)?.ToString();
674 ElementHelper.SetAttribute(
Browser,
this, attributeName, value);
680 return iWebElement !=
null ? iWebElement.GetCssValue(propertyName) :
CssAttributes[propertyName];
686 return iWebElement !=
null ? iWebElement.GetDomAttribute(attributeName) :
DomAttributes[attributeName];
692 return iWebElement !=
null ? iWebElement.GetDomProperty(propertyName) :
DomProperties[propertyName];
699 var shadowRoot = iWebElement !=
null ? iWebElement.GetShadowRoot() :
ShadowRoot;
707 if (iWebElement !=
null)
708 iWebElement.SendKeys(text);
714 if (iWebElement !=
null)
715 iWebElement.Submit();
721 bool attrDisabled =
Attributes.ContainsKey(
"disabled") &&
Attributes[
"disabled"].ToString() ==
"true";
722 bool propDisabled =
false;
725 propDisabled =
DomProperties[
"disabled"].ToString() ==
"true";
727 return attrDisabled || propDisabled;
742 bool isClickable =
true;
744 if (
true ==
Browser.UseOttoMagic)
745 isClickable =
Browser.MagicHelper.IsClickAble(
Css);
753 Attributes.TryGetValue(
"aria-disabled", out var aria) &&
754 aria.ToString().Equals(
"true", StringComparison.OrdinalIgnoreCase);
756 bool pointerOk =
true;
757 if (
true ==
CssAttributes.TryGetValue(
"pointer-events", out var pe))
758 pointerOk = pe.ToString() !=
"none";
766 if (
false == isClickable &&
true == publishEvent)
768 GPALEventType.WARNING,
769 $
"Element [{TagName}] does not appear clickable.",
771 GPALObjectType.Other);
778 private bool disposed =
false;
785 if (disposed ||
string.IsNullOrEmpty(ElementHandle))
return;
787 if (
true ==
Browser.UsePuppeteer)
791 await
Browser.PuppeteerCommunicator.SendCommand<
object>(
792 DevToolsMethods.RuntimeReleaseObject,
793 new { objectId = ElementHandle },
801 ElementHandle =
null;
813 static string CleanText(
string str) => str is
null ? null : System.Text.RegularExpressions.Regex.Replace(str,
@"\s+",
" ").Trim();
Browser object that contains the fluent methods to create your Browser workflow. Instatiated using G...
Represents a client-side bounding rectangle (similar to DOMRect) with additional convenience properti...
float Top
Gets or sets the top coordinate.
float Right
Gets or sets the right coordinate.
float Bottom
Gets or sets the bottom coordinate.
Dictionary< string, object > ToDictionary()
Converts the rectangle properties to a dictionary for easy serialization or logging.
float Y
Gets or sets the Y coordinate.
ClientRectangle()
Creates an empty ClientRectangle.
float Height
Gets or sets the height.
Size Size
Gets or sets the Size as a System.Drawing.Size.
bool IsEmpty
Determines whether the rectangle has zero dimensions and position.
float Left
Gets or sets the left coordinate.
float Width
Gets or sets the width.
float X
Gets or sets the X coordinate.
Pseudo element used in Applications and Browser workflows for image matching and unified automation....
void MiddleClick(ModifierKeys modifierKeys=ModifierKeys.NONE)
Performs a middle mouse button click.
string Xpath
XPath used to locate this element.
bool Displayed
Whether the element is visible on the page.
async Task DisposeAsync()
Asynchronously releases resources (especially Puppeteer object handles).
bool IsClickable(bool publishEvent=true)
Determines whether the element appears clickable based on visibility, disabled state,...
bool IsDisabled()
Checks if the element is disabled via attributes or properties.
string PageURL
Current page URL when the element was captured.
string Text
Visible text content of the element.
string Placeholder
placeholder attribute.
Dictionary< string, object > Attributes
All raw attributes returned from the automation backend.
string Type
The type of the element, for input, this can be many.
string Name
Name attribute of the element.
Size Size
Dimensions of the element.
void Click(ModifierKeys modifierKeys)
Performs a click with optional keyboard modifiers.
bool IsEnabled()
Checks if the element is enabled.
IWebElement FindElement(By by)
Finds a child element using Selenium By locator.
void SendKeys(string text)
Sends keystrokes to the element.
string GetDomAttribute(string attributeName)
Gets a DOM attribute.
Dictionary< string, object > CssAttributes
CSS computed style properties for the element.
bool Selected
Whether the element is selected (e.g. checkboxes, radio buttons).
string GetCssValue(string propertyName)
Gets a computed CSS value.
string TagName
HTML tag name of the element.
void Click()
Performs a standard left click.
Browser.Browser Browser
Associated Browser instance.
string GetAttribute(string attributeName)
Gets an attribute value with fallback to internal dictionary.
void Submit()
Submits the form if the element is part of one.
Point Location
Screen coordinates of the element.
GPALElement ShadowRoot
Shadow root if the element contains one.
string Value
value attribute (inputs, textareas, etc.).
ISearchContext GetShadowRoot()
Returns the ShadowRoot if available.
void SetAttribute(string attributeName, string value)
Directly sets a DOM attribute on this element via element.setAttribute(attributeName,...
string AttributeName
Custom attribute name (used internally).
void Hide()
Hides the element via JavaScript (sets display:none).
string FullXPath
Full absolute XPath.
string Css
CSS selector used to locate this element.
ClientRectangle BoundingRect
Client bounding rectangle with detailed coordinates.
string GetDomProperty(string propertyName)
Gets a DOM property.
Dictionary< string, object > DomAttributes
DOM attributes of the element.
void Clear()
Clears the element's value (if supported by underlying element).
string Href
href attribute (for links).
Dictionary< string, object > DomProperties
DOM properties of the element.
IWebDriver WrappedDriver
The underlying Selenium WebDriver instance.
void Dispose()
Disposes the element (fire-and-forget async cleanup).
bool Enabled
Whether the element is enabled.
Selector Selector
Selector used to locate this element.
XPathInfo[] Xpaths
Array of alternative XPaths with match counts.
string Src
src attribute (for images, scripts, etc.).
dynamic WebElement
The wrapped Selenium IWebElement or internal dynamic element.
ReadOnlyCollection< IWebElement > FindElements(By by)
Finds all child elements using Selenium By locator.
Everything starts here, all the GPAL controls and global settings using fluent syntax are here....
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...
Represents XPath matching information returned by advanced selector strategies.
XPathInfo(string xpath, int matchedElements)
Creates a new XPathInfo instance.
int MatchedElements
Number of elements matched by this XPath on the page.
string Xpath
The generated XPath expression.