WaitForElementClickable/可见-Selenium C# [英] WaitForElementClickable/ Visible - Selenium C#

查看:39
本文介绍了WaitForElementClickable/可见-Selenium C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要实施&修改我当前的方法以同时兼顾这两个问题:

I need to implement & modify my current method to do both matters:

  • 等待可见的元素-(目前已实现,但仍使用已过时的 ExpectedCondition 可能会更改)
  • 等待可单击的元素-(运行测试时,它面临加载圆圈"的问题,我按下按钮,然后在加载窗口之前先加载1-4秒,然后再加载窗口我的目标是强制Selenium等待"XXX"时间,加载完成后再继续处理.
  • Waiting for element of being visible - (which is currently implemented but it still uses ExpectedCondition which is obsolete and might be changed)
  • Waiting for element of being clickable - (When my test are running, it's face a problems with "loading circles", I'm pressing the button and before window is loaded there is loader which takes for 1 to 4 seconds and then it disappears. My goal is to force Selenium to wait "XXX" time and when loading will finish then continue with process.

当前代码:

public static IWebElement WaitForElementVisible(this IWebDriver driver, By by, int timeoutInSeconds = 6)
    {
        IWebElement element;
        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(0);
        try
        {
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
            element = wait.Until(ExpectedConditions.ElementIsVisible(by));
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(Configuration.ElementTimeout);
            return element;

        }
        catch (WebDriverTimeoutException e)
        {
            Console.WriteLine(e.ToString());
        }
        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(Configuration.ElementTimeout);
        return null;
    }

基于不同的主题,我开始写一些东西,但不幸的是,它只是复制...

Based on different topics I've started writing something but unfortunately it's just copy...

我宁愿做一个有价值的方法,目的是检查这两件事.您能给我任何建议/提示可以添加到该特定方法中吗?

I would prefer to do one valuable method which goal would be to check both things. Could you please give me any advice's/ hints what could be added to that specific method?

//编辑

我要添加该加载程序代码的外观:

I'm adding how that loader code looks like:

    <div class="Loader__background" style="display: block; position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); z-index: 10;">
   <div class="Loader__foreground" style="display: table; width: 100%; height: 100%; text-align: center; z-index: 20; color: white;">
      <div class="Loader__message" style="display: table-cell; vertical-align: middle;">
         <div mode="indeterminate" value="0" min="0" max="100" style="position: relative; display: inline-block; width: 280px; height: 280px;">
            <div style="width: 280px; height: 280px; display: inline-block; transition: transform 10s linear 0ms; transform: rotate(1800deg);">
               <svg viewBox="0 0 280 280" style="width: 280px; height: 280px; position: relative;">
                  <circle cx="140" cy="140" r="137.5" fill="none" stroke-width="5" stroke-miterlimit="20" style="stroke: rgb(0, 188, 212); stroke-linecap: round; transition: all 750ms ease-in-out 0ms; stroke-dasharray: 604.757, 863.938; stroke-dashoffset: -259.181;"></circle>
               </svg>
            </div>
         </div>
      </div>
   </div>
</div>

我还将@sers Java建议转移到了C#中:

I've also transferred @sers Java advice into C#:

public static IWebElement WaitForElementClickable(this IWebDriver driver, By by, int timeoutInSeconds)
    {
        new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds)).Until(d =>
        {
            Boolean ajaxComplete;
            Boolean jsReady;
            Boolean loaderHidden = false;

            IJavaScriptExecutor js = (IJavaScriptExecutor)d;
            jsReady = (Boolean)js.ExecuteScript("return (document.readyState == \"complete\" || document.readyState == \"interactive\")"); ;

            try
            {
                ajaxComplete = (Boolean)js.ExecuteScript("var result = true; try { result = (typeof jQuery != 'undefined') ? jQuery.active == 0 : true } catch (e) {}; return result;");
            }
            catch (Exception)
            {
                ajaxComplete = true;
            }
            try
            {
                loaderHidden = !d.FindElement(by).Displayed;
            }
            catch (Exception) { }

            return ajaxComplete && jsReady && loaderHidden;
        });
    }

推荐答案

据我了解,当在屏幕上加载元素但将元素覆盖时,您的元素是可见且可单击的,也许您还需要等待javascript完成才能成功单击.

As I understood your element is visible and clickable when loading element on the screen but overlaying you element, also maybe you need to wait javascript to complete to click successfully.

您需要获取加载圈子"定位器.对于打开的chrome devtools,触发加载圈子"出现并按F8(暂停),然后您可以找到加载元素的html.

You need get "loading circles" locator. For that open chrome devtools trigger "loading circles" to appear and press F8(pause) then you can find html of loading element.

等待直到加载元素消失:

Wait until loading element is disappeared:

var wait = new WebDriverWait(Driver.Instance, TimeSpan.FromSeconds(8));
wait.until(ExpectedConditions.invisibilityOfElementLocated(loadingElementLocator);

您还可以检查javascript是否完整:

Also you can check if javascript is complete :

IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
bool jsLoaded = (bool)js.ExecuteScript("return (document.readyState == \"complete\" || document.readyState == \"interactive\")");

这里是Java示例:

new WebDriverWait(driver, timeoutSec).until(d ->
{
    boolean ajaxComplete;
    boolean jsReady;
    boolean loaderHidden = false;

    JavascriptExecutor js = (JavascriptExecutor) d;
    jsReady = (boolean) js.executeScript("return (document.readyState == \"complete\" || document.readyState == \"interactive\")");;

    try {
        ajaxComplete = (boolean) js.executeScript("var result = true; try { result = (typeof jQuery != 'undefined') ? jQuery.active == 0 : true } catch (e) {}; return result;");
    } catch (Exception ignored) {
        ajaxComplete = true;
    }

    try {
        loaderHidden = !d.findElement(loadElementLocator).isDisplayed();
    } catch (Exception ignored) {}

    return ajaxComplete && jsReady && loaderHidden;
});

这是您的更新代码:

public static void WaitForLoading(IWebDriver driver, int timeoutInSeconds)
    {
        new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds)).Until(d =>
        {
            Boolean ajaxComplete;
            Boolean jsReady;
            Boolean loaderHidden = false;

            IJavaScriptExecutor js = (IJavaScriptExecutor)d;
            jsReady = (Boolean)js.ExecuteScript("return (document.readyState == \"complete\" || document.readyState == \"interactive\")"); ;

            try
            {
                ajaxComplete = (Boolean)js.ExecuteScript("var result = true; try { result = (typeof jQuery != 'undefined') ? jQuery.active == 0 : true } catch (e) {}; return result;");
            }
            catch (Exception)
            {
                ajaxComplete = true;
            }
            try
            {
                loaderHidden = !d.FindElement(By.ClassName("Loader__background")).Displayed;
            }
            catch (Exception) { }

            return ajaxComplete && jsReady && loaderHidden;
        });
    }

使用方法:

WaitForLoading(driver, 10);
myButton.Click();

这篇关于WaitForElementClickable/可见-Selenium C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆