//<input aria-label="target"> //*[(self::a or self::button or @role='button' or @role='link' or @role='menuitem' or self::input or self::textarea or self::select) and @aria-label='{target}'] virtual protected Func <string, IEnumerable <SelectorPrefix>, IWebDriver, IEnumerable <Element> > ByNested(string elementType) => (target, prefixes, driver) => Permutate(prefixes, driver, (prefix) => $"{prefix}//*[{elementType} and (" + $"{XpathProvider.TextMatch(target)} or " + $"label[{XpathProvider.TextMatch(target)}] or " + $"((@type='button' or @type='submit' or @type='reset') and @value={target.XpathEncode()}) or " + $"@name={target.XpathEncode()} or " + $"@aria-label={target.XpathEncode()} or " + $"(@type='radio' and @value={target.XpathEncode()})" + $")]");
//<a href = "https://www.w3schools.com/html/" >target</a> //*[(self::a or self::button or @role='button' or @role='link' or @role='menuitem') and text()='{target}'] virtual protected Func <string, IEnumerable <SelectorPrefix>, IWebDriver, IEnumerable <Element> > ByText(string elementType) => (target, prefixes, driver) => Permutate(prefixes, driver, (prefix) => $"{prefix}//*[{elementType} and {XpathProvider.TextMatch(target)}]");
//label[text()[normalize-space(.)='Bob']]/*[self::input] //<label>target<input type = "text" ></ label > //label[text()='{target}']/*[self::input or self::textarea or self::select] virtual protected Func <string, IEnumerable <SelectorPrefix>, IWebDriver, IEnumerable <Element> > ByNestedInLabel(string elementType) => (target, prefixes, driver) => Permutate(prefixes, driver, (prefix) => $"{prefix}//*[(self::label or self::div) and {XpathProvider.TextMatch(target)}]/*[{elementType}]");
//<label><span><strong>target</strong></span><input type = "text" ></ label > //*[text()='{target}']/ancestor::label//*[self::input or self::textarea or self::select] virtual protected Func <string, IEnumerable <SelectorPrefix>, IWebDriver, IEnumerable <Element> > ByLabelAncestor(string elementType) => (target, prefixes, driver) => Permutate(prefixes, driver, (prefix) => $"{prefix}//*[{XpathProvider.MarkerElements} and {XpathProvider.TextMatch(target)}]/ancestor::label//*[{elementType}]");
public SelectorFactory(ElementFactory elementFactory, XpathProvider xpathProvider) { ElementFactory = elementFactory; XpathProvider = xpathProvider; Selectors = new Dictionary <string, List <Func <string, IEnumerable <SelectorPrefix>, IWebDriver, IEnumerable <Element> > > > { { SelectorNames.Settable, new List <Func <string, IEnumerable <SelectorPrefix>, IWebDriver, IEnumerable <Element> > > { ByForAttribute, ByNestedInLabel(XpathProvider.SettableElements), ByNested(XpathProvider.SettableElements), ByText(XpathProvider.SettableElements), ByLabelledBy, RadioByName, ByFollowingMarker(XpathProvider.SettableElements), ByCellBelow(XpathProvider.SettableElements), ByLabelAncestor(XpathProvider.ActiveElements), } }, { SelectorNames.Clickable, new List <Func <string, IEnumerable <SelectorPrefix>, IWebDriver, IEnumerable <Element> > > { ByForAttribute, ByNestedInLabel(XpathProvider.ClickableElements), ByNested(XpathProvider.ClickableElements), ByText(XpathProvider.ClickableElements), ByTitle, RadioByName, SpecialButtons, ByFollowingMarker(XpathProvider.ClickableElements), ByCellBelow(XpathProvider.ClickableElements), ByTypeAncestor(XpathProvider.ActiveElements), } }, { SelectorNames.Active, new List <Func <string, IEnumerable <SelectorPrefix>, IWebDriver, IEnumerable <Element> > > { ByForAttribute, ByNestedInLabel(XpathProvider.ActiveElements), ByNested(XpathProvider.ActiveElements), ByText(XpathProvider.ActiveElements), ByTitle, ByLabelledBy, RadioByName, SpecialButtons, ByFollowingMarker(XpathProvider.ActiveElements), ByCellBelow(XpathProvider.ActiveElements), ByLabelAncestor(XpathProvider.ActiveElements), ByTypeAncestor(XpathProvider.ActiveElements), } }, { SelectorNames.Content, new List <Func <string, IEnumerable <SelectorPrefix>, IWebDriver, IEnumerable <Element> > > { ByContentSelf, ByContentSelfForRow, ByContent } }, { SelectorNames.Selectable, new List <Func <string, IEnumerable <SelectorPrefix>, IWebDriver, IEnumerable <Element> > > { ByForAttribute, ByNestedInLabel(XpathProvider.SelectableElements), ByNested(XpathProvider.SelectableElements), ByText(XpathProvider.SelectableElements), ByLabelledBy, ByFollowingMarker(XpathProvider.SelectableElements), ByCellBelow(XpathProvider.SelectableElements), } }, { SelectorNames.Checkable, new List <Func <string, IEnumerable <SelectorPrefix>, IWebDriver, IEnumerable <Element> > > { ByForAttribute, ByNestedInLabel(XpathProvider.CheckableElements), ByNested(XpathProvider.CheckableElements), ByText(XpathProvider.CheckableElements), ByLabelledBy, ByFollowingMarker(XpathProvider.CheckableElements), ByCellBelow(XpathProvider.CheckableElements), } }, }; Prefixes = new Dictionary <string, List <Func <string, IEnumerable <string> > > > { { PrefixNames.Row, new List <Func <string, IEnumerable <string> > > { TableRow, DivRoleRow, } }, { PrefixNames.Under, new List <Func <string, IEnumerable <string> > > { ParrentDiv, ParrentDivWithRowRole, FollowingRow, Legend } }, { PrefixNames.Warning, new List <Func <string, IEnumerable <string> > > { } }, { PrefixNames.Error, new List <Func <string, IEnumerable <string> > > { } } }; }