/// <summary> /// Factory of Locators based on the type of the IWebElement denoted by Enum id. /// </summary> /// <param name="id">The Enum identifier containing CSS of the target IWebElement.</param> /// <param name="parent">Locator of the parent IWebElement of the target IWebElement.</param> /// <returns>Locator with behaviore matched with the type of the element.</returns> public static Locator LocatorOf(Enum id, Fragment parent) { EnumMemberAttribute usage = EnumMemberAttribute.EnumMemberAttributeOf(id); switch (usage.TagName) { case HtmlTagName.Table: return(new TableLocator(id, parent)); case HtmlTagName.Text: return(new TextLocator(id, parent)); case HtmlTagName.Radio: return(new RadioLocator(id, parent)); case HtmlTagName.Select: return(new SelectLocator(id, parent)); case HtmlTagName.Checkbox: case HtmlTagName.Check: return(new CheckboxLocator(id, parent)); default: return(new Locator(id, parent)); } }
public static EnumMemberAttribute EnumMemberAttributeOf(Enum theEnum) { if (CachedEnumMemberAttributes.ContainsKey(theEnum)) { return(CachedEnumMemberAttributes[theEnum]); } Type enumType = theEnum.GetType(); if (!EnumMemberFullNames.ContainsKey(theEnum)) { EnumMemberFullNames.Add(theEnum, string.Format("{0}.{1}", enumType.FullName, theEnum)); } //Get the Type Attribute: IsCollection, Mechanism and HtmlTag EnumTypeAttribute typeAttribute = EnumTypeAttribute.TypeAttributeOf(enumType); EnumMemberAttribute memberAttribute = null; //Try to get the EnumMemberAttribute defined in codes, especially the Meaning of theEnum var fi = enumType.GetField(theEnum.ToString()); var usageAttributes = GetCustomAttributes(fi, typeof(EnumMemberAttribute), false); int attributesCount = usageAttributes.Count(); string enumValue = null; if (attributesCount == 0) { enumValue = theEnum.DefaultValue(); memberAttribute = new EnumMemberAttribute(enumValue, false, DescriptionOf(typeAttribute, enumValue)); } else if (attributesCount == 1) { EnumMemberAttribute attr = (EnumMemberAttribute)usageAttributes[0]; enumValue = attr.Value ?? theEnum.DefaultValue(); //if (enumValue != theEnum.DoString()) // theEnum.ChangeValue(enumValue); memberAttribute = new EnumMemberAttribute(enumValue, attr.IsFragment, attr.Description ?? DescriptionOf(typeAttribute, enumValue)); } if (memberAttribute == null) { throw new Exception("Unexpected situation when memberAttribute is null."); } string css = CssSelectorOf(typeAttribute, memberAttribute, enumValue); memberAttribute = new EnumMemberAttribute(memberAttribute.Value, memberAttribute.IsFragment, memberAttribute.Description, css, typeAttribute.Mechanism, typeAttribute.IsCollection, typeAttribute.TagName); CachedEnumMemberAttributes.Add(theEnum, memberAttribute); return(memberAttribute); }
/// <summary> /// Retrieve the Index-th of the IWebElement collection located by collectionEnum. /// </summary> /// <param name="collectionEnum">The Enum identifier of a collection of IWebElement.</param> /// <param name="index">The Index number, from 0, of the concerned one within the collection.</param> /// <returns>The IWebElement whose order within the collection is identical to "Index".</returns> public IWebElement ElementByIndex(Enum collectionEnum, int index) { EnumMemberAttribute usage = EnumMemberAttribute.EnumMemberAttributeOf(collectionEnum); if (!usage.IsCollection) { throw new Exception(collectionEnum.ToString() + " shall be IsCollection=true."); } var thisElement = FindElement(); var candidates = thisElement.FindElementsByCss(usage.Css); return(candidates[index]); }
public static string Value(this Enum theEnum) { if (EnumValues.ContainsKey(theEnum)) { return(EnumValues[theEnum]); } EnumMemberAttribute memberAttribute = EnumMemberAttribute.EnumMemberAttributeOf(theEnum); if (!EnumValues.ContainsKey(theEnum)) { EnumValues.Add(theEnum, memberAttribute.Value); } return(EnumValues[theEnum]); }
public static string CssSelectorOf(EnumTypeAttribute typeAttribute, EnumMemberAttribute memberAttribute, string memberValue) { HtmlTagName tagName = typeAttribute.TagName; string tagLocator = tagName.Value(); Mechanisms mechanism = typeAttribute.Mechanism; string mechanismFormat = typeAttribute.Mechanism.Value(); string css; switch (mechanism) { case Mechanisms.ByAttr: case Mechanisms.ByAttribute: { int index = memberValue.IndexOf(EnumValueSplitter); if (index == -1) //The Value of the Enum entry shall be treated as the attribute name { string withAttr = string.Format("[{0}]", memberValue); css = string.Format(tagLocator, string.Empty, withAttr); } else { string attrString = string.Format(mechanismFormat, memberValue.Substring(0, index), memberValue.Substring(index + 1)); css = string.Format(tagLocator, string.Empty, attrString); } break; } case Mechanisms.ByOrder: case Mechanisms.ByOrderLast: case Mechanisms.ByChild: case Mechanisms.ByChildLast: { string[] pair = memberValue.Split(EnumValueSplitter); string attrString = null; switch (pair.Count()) { case 2: attrString = string.Format(mechanismFormat, string.Empty, pair[1]).Trim(); css = string.Format(tagLocator, pair[0], attrString); break; case 1: attrString = string.Format(mechanismFormat, string.Empty, memberValue).TrimStart(); css = string.Format(tagLocator, string.Empty, attrString); break; default: throw new InvalidEnumArgumentException(mechanismFormat + " expects one item or two items seperated by '='."); } break; } case Mechanisms.ByText: case Mechanisms.ByTag: { //Notice: this is not preferrable with CSS Locator. //The value of the Enum member shall be used afterwards css = string.Format(tagLocator, string.Empty, string.Empty); break; } case Mechanisms.ByCustom: { css = memberValue; break; } case Mechanisms.ByAdjacent: case Mechanisms.ByAncestor: case Mechanisms.ByParent: case Mechanisms.BySibling: { string[] pair = memberValue.Split(EnumValueSplitter); string attrString = null; switch (pair.Count()) { case 2: attrString = string.Format(mechanismFormat, pair[0], string.Empty); css = string.Format(tagLocator, attrString, pair[1]); break; case 1: attrString = string.Format(mechanismFormat, memberValue, string.Empty); css = string.Format(tagLocator, attrString, string.Empty); break; default: throw new InvalidEnumArgumentException(mechanismFormat + " expects one item or two items seperated by '='."); } break; } default: //case Mechanisms.ById: //case Mechanisms.ByClass: //case Mechanisms.ByUrl: //case Mechanisms.ByName: //case Mechanisms.ByValue: { string[] pair = memberValue.Split(EnumValueSplitter); string byId = string.Format(mechanismFormat, pair.Last()); css = string.Format(tagLocator, string.Empty, byId); break; } } return(css); }
public static string Css(this Enum theEnum) { EnumMemberAttribute memberAttribute = EnumMemberAttribute.EnumMemberAttributeOf(theEnum); return(memberAttribute.Css); }
public static bool IsCollection(this Enum theEnum) { EnumMemberAttribute memberAttribute = EnumMemberAttribute.EnumMemberAttributeOf(theEnum); return(memberAttribute.IsCollection); }
public static bool IsFragment(this Enum theEnum) { EnumMemberAttribute memberAttribute = EnumMemberAttribute.EnumMemberAttributeOf(theEnum); return(memberAttribute.IsFragment); }
public static string Description(this Enum theEnum) { EnumMemberAttribute memberAttribute = EnumMemberAttribute.EnumMemberAttributeOf(theEnum); return(memberAttribute.Description); }
public static Mechanisms Mechanism(this Enum theEnum) { EnumMemberAttribute memberAttribute = EnumMemberAttribute.EnumMemberAttributeOf(theEnum); return(memberAttribute.Mechanism); }
public static HtmlTagName TagName(this Enum theEnum) { EnumMemberAttribute memberAttribute = EnumMemberAttribute.EnumMemberAttributeOf(theEnum); return(memberAttribute.TagName); }