Exemplo n.º 1
0
        private IEnumerable <Element> FindElements(Selector selector, LoggingWebDriver loggingWebdriver)
        {
            var wrappers = selector.PrioritizedSearchers.Select(s => new Wrapper {
                Searcher = s
            }).ToList();
            var loopResults = Parallel.ForEach(wrappers, (wrapper, loopState) =>
            {
                var searcher = wrapper.Searcher;
                var results  = searcher.SearchIn(loggingWebdriver, Prefixes);

                SuccessfulSearchers.Add(searcher);
                loopState.Break();
                wrapper.Elements = results;
                return;
            });
            var r     = loopResults.IsCompleted;
            var index = 0;

            foreach (var w in wrappers)
            {
                if (w.Elements != null)
                {
                    if (w.Elements.Any())
                    {
                        foreach (var e in w.Elements)
                        {
                            AugmentWebElementSources(selector, e.WebElement);
                        }
                    }
                    return(w.Elements);
                }
                if (w.Exception != null)
                {
                    throw new AggregateException($"Error throw on xpath {index}", w.Exception);
                }
                index++;
            }
            return(null);
        }
Exemplo n.º 2
0
 public IEnumerable <Element> SelectMany(Selector selector)
 => RetryExecutor.RetryFor(() =>
 {
     var loggingWebdriver = new LoggingWebDriver(SeleniumDriver, MovieLogger, WebElementSourceLog);
     try
     {
         var elements = FindElements(selector, loggingWebdriver);
         if (elements != null)
         {
             return(elements);
         }
         //iframes ?
         var iframes = SeleniumDriver.FindElements(By.XPath("//iframe"));
         foreach (var iframe in iframes)
         {
             try
             {
                 loggingWebdriver.Log($"Trying iframe:{iframe}");
                 SeleniumDriver.SwitchTo().Frame(iframe);
                 elements = FindElements(selector, loggingWebdriver);
                 if (elements != null)
                 {
                     return(elements);
                 }
             }
             catch
             { }
         }
         SeleniumDriver.SwitchTo().DefaultContent();
         return(new List <Element>());
     }
     finally
     {
         if (loggingWebdriver.Screenshots.Any())
         {
             Screenshots = loggingWebdriver.Screenshots.Select(x => x.AsByteArray).ToList();
         }
     }
 }, TimeSpan.FromMilliseconds(SeleniumGridConfiguration.RetryMs));
Exemplo n.º 3
0
 public Element Select(Selector selector, TimeSpan?retryDuration = null, int?index = null)
 => RetryExecutor.RetryFor(() =>
 {
     var loggingWebdriver = new LoggingWebDriver(SeleniumDriver, MovieLogger, WebElementSourceLog);
     try
     {
         var element = FindElement(selector, loggingWebdriver, index);
         if (element != null)
         {
             return(element);
         }
         //iframes ?
         var iframes = SeleniumDriver.FindElements(By.XPath("//iframe"));
         foreach (var iframe in iframes)
         {
             try
             {
                 loggingWebdriver.Log($"Trying iframe:{iframe}");
                 SeleniumDriver.SwitchTo().Frame(iframe);
                 element = FindElement(selector, loggingWebdriver, index);
                 if (element != null)
                 {
                     return(element);
                 }
             }
             catch
             { }
         }
         SeleniumDriver.SwitchTo().DefaultContent();
         throw new Exception($"element was not found; tried:\n{loggingWebdriver.GetLogs()}, maybe try one of these identifiers {GetIdentifiers().Take(10).LogFormat()}");
     }
     finally
     {
         if (loggingWebdriver.Screenshots.Any())
         {
             Screenshots = loggingWebdriver.Screenshots.Select(x => x.AsByteArray).ToList();
         }
     }
 }, retryDuration ?? TimeSpan.FromMilliseconds(SeleniumGridConfiguration.RetryMs));
Exemplo n.º 4
0
        public TableElement GetTables(IEnumerable <string> headers, StringComparison comparison = StringComparison.CurrentCulture, int?index = null)
        => RetryExecutor.RetryFor(() =>
        {
            var loggingWebdriver = new LoggingWebDriver(SeleniumDriver, MovieLogger, WebElementSourceLog);
            try
            {
                var possilbeTables = GetTables(headers.Count()).ToList();
                Func <string, string, bool> comparer = (s1, s2) => s1.Equals(s2, comparison);

                var tableElements = possilbeTables.Where(t => headers.Where(h => !string.IsNullOrEmpty(h)).Except(t.Header.Keys,
                                                                                                                  new Core.EqualityComparer <string>(comparer)).None());

                if (tableElements.One())
                {
                    return(tableElements.First());
                }
                //Exact match overrides in case of multiples.
                if (tableElements.Where(x => headers.Count() == x.MaxColumnIndex).One())
                {
                    return(tableElements.Where(x => headers.Count() == x.MaxColumnIndex).First());
                }
                if (tableElements.Many())
                {
                    if (index == null)
                    {
                        throw new Exception($"multiple talbes matched the definition of {headers.LogFormat()}, table headers were {tableElements.LogFormat(t => $"Table: {t.Header.Keys.LogFormat()}")};");
                    }
                    if (index >= tableElements.Count())
                    {
                        throw new Exception($"only found {tableElements.Count()} tables, index of {index} is out of range. (zero based)");
                    }
                    return(tableElements.ToArray()[index.Value]);
                }
                //iframes ?
                var iframes = SeleniumDriver.FindElements(By.XPath("//iframe"));
                foreach (var iframe in iframes)
                {
                    try
                    {
                        loggingWebdriver.Log($"Trying iframe:{iframe}");
                        SeleniumDriver.SwitchTo().Frame(iframe);
                        possilbeTables = GetTables(headers.Count() - 1).ToList();

                        tableElements = possilbeTables.Where(t => headers.Where(h => !string.IsNullOrEmpty(h)).Except(t.Header.Keys,
                                                                                                                      new Core.EqualityComparer <string>(comparer)).None());

                        if (tableElements.One())
                        {
                            return(tableElements.First());
                        }
                        if (tableElements.Many())
                        {
                            if (index == null)
                            {
                                throw new Exception($"multiple talbes matched the definition of {headers.LogFormat()}, table headers were {tableElements.LogFormat(t => $"Table: {t.Header.Keys.LogFormat()}")};");
                            }
                            if (index >= tableElements.Count())
                            {
                                throw new Exception($"only found {tableElements.Count()} tables, index of {index} is out of range. (zero based)");
                            }
                            return(tableElements.ToArray()[index.Value]);
                        }
                    }
                    catch
                    { }
                }
                SeleniumDriver.SwitchTo().DefaultContent();
                throw new Exception($"table was not found");
            }
            finally
            {
                if (loggingWebdriver.Screenshots.Any())
                {
                    Screenshots = loggingWebdriver.Screenshots.Select(x => x.AsByteArray).ToList();
                }
            }
        }, TimeSpan.FromMilliseconds(SeleniumGridConfiguration.RetryMs));
Exemplo n.º 5
0
        private Element FindElement(Selector selector, LoggingWebDriver loggingWebdriver, int?index = null)
        {
            var wrappers = selector.PrioritizedSearchers.Select(s => new Wrapper {
                Searcher = s
            }).ToList();
            var loopResults = Parallel.ForEach(wrappers,
                                               //new ParallelOptions { MaxDegreeOfParallelism = 4 },
                                               (wrapper, loopState) =>
            {
                var searcher = wrapper.Searcher;

                var results = searcher.SearchIn(loggingWebdriver, Prefixes);
                if (loopState.ShouldExitCurrentIteration)
                {
                    return;
                }
                else if (results.One())
                {
                    SuccessfulSearchers.Add(searcher);
                    loopState.Break();
                    wrapper.Element = results.First();
                    return;
                }
                else if (results.Many() && index.HasValue)
                {
                    SuccessfulSearchers.Add(searcher);
                    loopState.Break();
                    var a = results.ToArray();
                    if (a.Count() <= index.Value)
                    {
                        wrapper.Exception = new Exception($"Not enough items found, found {a.Count()} and desired index {index}");
                    }
                    else
                    {
                        wrapper.Element = a[index.Value];
                    }
                    return;
                }
                else if (results.Many())
                {
                    var by = WebElementSourceLog.Get(results.First().WebElement).By;
                    if (by.IsXpath())
                    {
                        //lets find the only clickable one,
                        //if two are precisely on top of each other it will not filter that
                        //but that is unlikely to happen in real applications
                        var el = FindOnlyClickable(by.Xpath());
                        if (el != null)
                        {
                            var pos  = el.Location;
                            var rpos = results.Select(x => new { x.Location, x }).ToList();

                            var filterHidden = rpos
                                               .Where(e => e.Location == pos)
                                               .Select(x => x.x);

                            if (filterHidden.One())
                            {
                                SuccessfulSearchers.Add(searcher);
                                loopState.Break();
                                wrapper.Element = filterHidden.First();
                                return;
                            }
                        }
                    }

                    var items = results.Select(e => $"{e.Tag}@{e.Location.X},{e.Location.Y}").LogFormat();
                    loopState.Break();
                    wrapper.Exception = new Exception($"Multiple results were found using {searcher.LogFormat()}");
                    return;
                }
            });
            var r            = loopResults.IsCompleted;
            var wrapperIndex = 0;

            foreach (var w in wrappers)
            {
                if (w.Element != null)
                {
                    AugmentWebElementSources(selector, w.Element.WebElement);
                    return(w.Element);
                }
                if (w.Exception != null)
                {
                    throw new AggregateException($"Error throw on xpath {wrapperIndex}", w.Exception);
                }
                wrapperIndex++;
            }
            return(null);
        }