/// <summary>
        ///
        /// </summary>
        /// <param name="retryTimes"></param>
        /// <param name="interval"></param>
        /// <param name="throwIfFail"></param>
        /// <param name="function"></param>
        private void RetryFunction(int retryTimes, string interval, bool throwIfFail, DelgFunction function)
        {
            var functionName = function.GetMethodInfo().Name;

            _log.Info("Run retry function: " + functionName);
            var sleepTime = String.Empty;

            for (int retryTimeCount = 0; retryTimeCount <= retryTimes; retryTimeCount++)
            {
                try
                {
                    function();
                    break;
                }
                catch (Exception e)
                {
                    if (retryTimeCount.Equals(retryTimes))
                    {
                        var gg = DateTime.Now.ToString("MMddHHmmss.ffff");
                        if (throwIfFail)
                        {
                            SnapshotServices.SnapShotProcess($"[{gg}]" + e.Message.Replace(".", "_"));
                            throw new Exception($"[{gg}]_IT_HAD_RETRY_{retryTimeCount}_SECONDS " + e.Message, e);
                        }
                        break;
                    }
                    if (interval.Equals(""))
                    {
                        //Default sleep time: 1.0s
                        var defaultSleepTime = ConfigManager.Settings.DefaultRetryTimeBySeconds;

                        sleepTime = defaultSleepTime.ToString(CultureInfo.InvariantCulture);
                    }
                    else
                    {
                        _log.Info("Every " + interval + " seconds retry the function : " + function.GetMethodInfo().Name);
                        sleepTime = interval;
                    }

                    var delay = TimerService.SetTimeBySecond(sleepTime);
                    _log.Info("[System Setting] Round " + retryTimeCount + ", interval time WILL setup adds " + delay.ToString() + " delay each time on " + function.GetMethodInfo().Name);
                    Thread.Sleep(delay);
                }
            }
        }
        //Wait Until JavaScript loading Completed.
        public void WaitUntilJSReady()
        {
            _log.Info("Start Waiting Until JS Ready");
            var webDriver          = WebDriverHelper._webDriver;
            var timeCount          = 0;
            IJavaScriptExecutor js = webDriver as IJavaScriptExecutor;
            var sleepTime          = TimerService.SetTimeBySecond("1");
            var script             = "return document.readyState";
            var state = "complete";

            while (true)
            {
                if (js == null)
                {
                    var ex = new ArgumentException("Element", "The element must wrap a web driver that supports javascript execution.");
                    _log.Error(ex.Message);
                    throw ex;
                }

                var untilJsReady = js.ExecuteScript(script).ToString().Equals(state);
                if (untilJsReady)
                {
                    //Wait JQuery Ready
                    WaitUntilJQueryReady();
                    //Wait JQuery Load
                    WaitForJQueryLoad();
                    break;
                }
                else
                {
                    //1 sec
                    _log.Error($"THIS IS PAGE SOURCE ========================= {webDriver.PageSource}");
                    Thread.Sleep(sleepTime);
                }
            }

            _log.Info($"End waiting until JS ready, this process document.ready spends: {timeCount} .");
        }
        private TimeSpan SetTimeBySecond(string assignSecond)
        {
            var timeValue = TimerService.SetTimeBySecond(assignSecond);

            return(timeValue);
        }