public WebDriver( IWebDriver driver, Func <Uri> rootUrl, SeleniumGridConfiguration configuration, RetryExecutor retryExecutor, SelectorFactory selectorFactory, ElementFactory elementFactory, XpathProvider xpathProvider, MovieLogger movieLogger, IEnumerable <SelectorPrefix> prefixes = null) { Driver = driver; SuccessfulSearchers = new List <Searcher>(); RootUrl = rootUrl; SeleniumGridConfiguration = configuration; RetryExecutor = retryExecutor; SelectorFactory = selectorFactory; MovieLogger = movieLogger; Prefixes = prefixes?.ToList() ?? new List <SelectorPrefix>() { new EmptySelectorPrefix() }; Children = new List <WebDriver>(); Screenshots = new List <byte[]>(); ElementFactory = elementFactory; XpathProvider = xpathProvider; }
public SpecializedSelectorFactory(ElementFactory elementFactory, XpathProvider xpathProvider) : base(elementFactory, xpathProvider) { Prefixes[PrefixNames.Under].AddRange(new List <Func <string, IEnumerable <string> > > { LooseFollowingRow, ParrentRowTableLayout }); }
public TableElement(IWebElement table, IWebDriver driver, ElementFactory elementFactory, XpathProvider xpathProvider) { RootElement = table; Driver = driver; IsValid = true; Header = new Dictionary <string, int>(); ElementFactory = elementFactory; XpathProvider = xpathProvider; }
public int GetRowId(string key, string column = null) { if (String.IsNullOrWhiteSpace(column)) { var columnLimit = Header.Values.Max(); var xpath = $"{Prefix}/tr[td[{XpathProvider.TextMatch(key)}] or td/*[{XpathProvider.TextMatch(key)}] or td/*[@value = {key.XpathEncode()}] ]/preceding-sibling::tr"; var count = Driver.FindElements(By.XPath(xpath)).Count() + 1; var rowMatch = $"{Prefix}/tr[td[{XpathProvider.TextMatch(key)}] or td/*[{XpathProvider.TextMatch(key)}] or td/*/*[{XpathProvider.TextMatch(key)}] or td/*[@value = {key.XpathEncode()}]]"; var rows = Driver.FindElements(By.XPath(rowMatch)); if (rows.None()) { throw new Exception($"Unable to find the row '{key}'"); } if (rows.Many()) { for (var indexer = 1; indexer <= MaxColumnIndex; indexer++) { xpath = $"{Prefix}/tr[(td[{indexer}])[{XpathProvider.TextMatch(key)} or *[{XpathProvider.TextMatch(key)}] or *[@value = {key.XpathEncode()}]]]/preceding-sibling::tr"; count = Driver.FindElements(By.XPath(xpath)).Count() + 1; rowMatch = $"{Prefix}/tr[(td[{indexer}])[{XpathProvider.TextMatch(key)} or *[{XpathProvider.TextMatch(key)}] or */*[{XpathProvider.TextMatch(key)}] or *[@value = {key.XpathEncode()}]]]"; rows = Driver.FindElements(By.XPath(rowMatch)); if (rows.One()) { return(count); } } throw new Exception($"Unable to uniquely identify the row id '{key}', found {rows.Count()} rows that matched it"); } return(count); } else { if (!Header.ContainsKey(column)) { throw new Exception($"the column {column} is not part of the table"); } var indexer = Header[column]; var xpath = $"{Prefix}/tr[(td[{indexer}])[{XpathProvider.TextMatch(key)}] or (td[{indexer}])/*[{XpathProvider.TextMatch(key)}] or (td[{indexer}])/*[@value = {key.XpathEncode()}] ]/preceding-sibling::tr"; var count = Driver.FindElements(By.XPath(xpath)).Count() + 1; var rowMatch = $"{Prefix}/tr[(td[{indexer}])[{XpathProvider.TextMatch(key)}] or (td[{indexer}])/*[{XpathProvider.TextMatch(key)}] or (td[{indexer}])/*/*[{XpathProvider.TextMatch(key)}] or (td[{indexer}])/*[@value = {key.XpathEncode()}]]"; var rows = Driver.FindElements(By.XPath(rowMatch)); if (rows.One()) { return(count); } if (rows.Many()) { throw new Exception($"multiple matches found for row id '{key}' for column {column}"); } throw new Exception($"Unable to find the row id '{key}' for column {column}"); } }
public CustomSelectorFactory(ElementFactory elementFactory, XpathProvider xpathProvider) : base(elementFactory, xpathProvider) { /// To make the prefixes more permissable /// just append to the list Prefixes[PrefixNames.Error].AddRange(new List <Func <string, IEnumerable <string> > > { ModalError }); /// To make the selectors more permissable for a type /// just append to the list Selectors[SelectorNames.Active].AddRange(new List <Func <string, IEnumerable <SelectorPrefix>, IWebDriver, IEnumerable <Element> > > { NextCell(XpathProvider.ActiveElements), ByTTSelectable, PreviousCell(XpathProvider.ActiveElements) }); /// To make the selectors less permissive use the following pattern. /// See the source to see what selectors are included by default. Selectors[SelectorNames.Settable].Clear(); Selectors[SelectorNames.Settable].AddRange(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), }); /// DO NOT ASSUME THAT THE SELECTOR AT POSITION 4 WILL STAY AT POSITION 4 /// so clear and add them, don't try and snipe one or two from the list. }
// look in previous cell, to the left in a table layout virtual protected Func <string, IEnumerable <SelectorPrefix>, IWebDriver, IEnumerable <Element> > PreviousCell(string elementType) => (target, prefixes, driver) => Permutate(prefixes, driver, (prefix) => $"({prefix}//td[{XpathProvider.TextMatch(target)} or *[{XpathProvider.TextMatch(target)}]]/preceding-sibling::td)[1]/*[{elementType}]");