private static void WaitForJQueryIsLoaded(this IWebDriver webDriver, AbstractPageSettings pageSettings)
        {
            if (!pageSettings.PageUsesJquery)
            {
                return;
            }

            TimeSpan      timeout = new TimeSpan(0, 0, 5);
            WebDriverWait wait    = new WebDriverWait(webDriver, timeout)
            {
                Message = "JQuery was not loaded after " + timeout.Seconds + " seconds."
            };

            wait.Until(JQueryIsLoaded);
        }
        public static TResult ExecuteScript <TResult>(this IWebDriver webDriver, AbstractPageSettings pageSettings, string script, params object[] args)
        {
            WaitForJQueryIsLoaded(webDriver, pageSettings);
            dynamic objectToCast = GetJavaScriptExecutor(webDriver).ExecuteScript(script, args);

            if (objectToCast != null)
            {
                // ReSharper disable once SuspiciousTypeConversion.Global
                //The Webdriver casts Collection<object> when the list is empty but when it detects that the elements can be castet to IWebElement it will do so.
                //Therefore the ExecuteScript will give you for an empty javascript list a ReadOnlyCollection<object>
                //but a ReadOnlyCollection<IWebElements> when there is at least one element within the JavaScript array/object!
                if (objectToCast is ReadOnlyCollection <object> && objectToCast.Count == 0)
                {
                    var  genericTypeArgument = typeof(TResult).GetGenericArguments()[0];
                    Type paraType            = typeof(List <>).MakeGenericType(genericTypeArgument);
                    var  para         = Activator.CreateInstance(paraType);
                    Type readonlyType = typeof(ReadOnlyCollection <>);
                    Type result       = readonlyType.MakeGenericType(genericTypeArgument);
                    return((TResult)Activator.CreateInstance(result, para));
                }
            }
            return((TResult)objectToCast);
        }
        /// <summary>
        /// Wait for all animations to be finished.
        /// </summary>
        private static bool AllAnimationsFinished(IWebDriver driver, AbstractPageSettings pageSettings, out string errorMessage)
        {
            if (pageSettings.PageUsesJquery && pageSettings.HasEndlessJQueryAnimation)
            {
                errorMessage = "Page has a endless animation. Cannot wait for animations finished.";
                return(true);
            }

            bool jqueryIsLoaded;

            if (pageSettings.PageUsesJquery)
            {
                jqueryIsLoaded = JQueryIsLoaded(driver);
            }
            else
            {
                errorMessage = "Cannot wait for animations, page uses no JQuery. ";
                return(true);
            }
            if (jqueryIsLoaded)
            {
                TestLog.Add("Get all running JQuery animations...");
                ReadOnlyCollection <IWebElement> animatedObjects = driver.ExecuteScript <ReadOnlyCollection <IWebElement> >(pageSettings, "return $(':animated').toArray();");
                if (animatedObjects.Count != 0)
                {
                    errorMessage = "Tried to click but there were still running JQuery animations on the webpage which are not excluded from waiting for them to finish."
                                   + " || Objects still animated: " + GetAnimatedObjectMessage(animatedObjects) + " ||.";
                    return(false);
                }
                errorMessage = string.Empty;
                return(true);
            }

            errorMessage = "JQuery was not loaded. Cannot wait for Animations";
            return(false);
        }
 public static void ExecuteScript(this IWebDriver webDriver, AbstractPageSettings pageSettings, string script, params object[] args)
 {
     WaitForJQueryIsLoaded(webDriver, pageSettings);
     ExecuteScript <object>(webDriver, pageSettings, script, args);
 }
 public static TResult ExecuteJavaScriptAsync <TResult>(this IWebDriver webDriver, AbstractPageSettings pageSettings, string script, params object[] args)
 {
     WaitForJQueryIsLoaded(webDriver, pageSettings);
     return((TResult)GetJavaScriptExecutor(webDriver).ExecuteAsyncScript(script, args));
 }
        private static void ScrollIntoView(IWebDriver webDriver, IWebElement webElement, AbstractPageSettings pageSettings)
        {
            if (webElement == null || !webElement.Displayed)
            {
                return;
            }

            try
            {
                webDriver.ExecuteScript(pageSettings, "arguments[0].scrollIntoView(true);", webElement);
            }
            catch (StaleElementReferenceException)
            {
                //For the case, that the objectreference we have, is no longer valid
            }
            catch (InvalidOperationException)
            {
                //For older IE: Sometimes we get an 'Error determining if element is displayed' error, so we can go around this error.
            }
            catch (WebDriverException)
            {
                //For some cases, our node is not responding (OpenQA.Selenium.WebDriverException: No response from server for url ...)
            }
        }
        private static Func <IWebDriver, IWebElement> FindAndScrollToElement(By locator, Visibility visibilityFilter, AbstractPageSettings pageSettings)
        {
            if (TestStatusManager.IsCanceled)
            {
                throw new TaskCanceledException("Canceled test.");
            }

            return(driver =>
            {
                IWebElement webElement = Find(locator, visibilityFilter).Invoke(driver);
                if (webElement != null)
                {
                    ScrollIntoView(driver, webElement, pageSettings);
                    TimeSpan timeout = new TimeSpan(0, 0, 3);
                    WebDriverWait wait = new WebDriverWait(driver, timeout)
                    {
                        Message = "Element by " + locator + " was not present in the viewport after timeout."
                    };
                    wait.Until(d => ElementIsInViewPort(d, locator));
                    return webElement;
                }

                return null;
            });
        }