Webdriver 如何等待元素在 webdriver C# 中可点击

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16057031/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 23:51:21  来源:igfitidea点击:

Webdriver How to wait until the element is clickable in webdriver C#

c#webdriverselenium-webdriver

提问by Anand S

There is a block Ui which covers all the elements for a few seconds after the Element have been generated in the browser because of this i facing a problem ,Since element has come into existence the web-driver try to click the element but the click is received by Block UI . I have tried to use the wait Until but i did not help ,Since i can find isClickAble in C# webdriver

在浏览器中生成元素后,有一个块 Ui 覆盖了所有元素几秒钟,因为我面临一个问题,因为元素已经存在,网络驱动程序尝试点击该元素,但点击是由 Block UI 接收。我曾尝试使用等待直到但我没有帮助,因为我可以在 C# webdriver 中找到 isClickAble

   var example = _wait.Until<IWebElement>((d) => d.FindElement(By.XPath("Example")));
   var example2 = _wait.Until<IWebElement>(ExpectedConditions.ElementIsVisible(By.XPath("Example")));
example.click();
example2.click();

Is there C# equivalent for isClickAble ,Thanks in advance

是否有等效于 isClickAble 的 C#,提前致谢

采纳答案by Arran

Well taking a look into the Java source, tells me it is basically doing two things to determine if it's 'clickable':

看看 Java 源代码,告诉我它基本上做了两件事来确定它是否“可点击”:

https://code.google.com/p/selenium/source/browse/java/client/src/org/openqa/selenium/support/ui/ExpectedConditions.java

https://code.google.com/p/selenium/source/browse/java/client/src/org/openqa/selenium/support/ui/ExpectedConditions.java

Firstly, it'll check if it's 'visible' by using the standard ExpectedConditions.visibilityOfElementLocated, it'll then simply check if the element.isEnabled()is trueor not.

首先,它会通过使用标准来检查它是否“可见” ExpectedConditions.visibilityOfElementLocated,然后它会简单地检查是否element.isEnabled()true

This can be condensed slightly, this basically means (simplified, in C#):

这可以稍微浓缩,这基本上意味着(简化,在 C# 中):

  1. Wait until the element is returned from the DOM
  2. Wait until the element's .Displayedproperty is true (which is essentially what visibilityOfElementLocatedis checking for).
  3. Wait until the element's .Enabledproperty is true (which is essentially what the elementToBeClickableis checking for).
  1. 等待元素从 DOM 返回
  2. 等到元素的.Displayed属性为真(本质上就是visibilityOfElementLocated要检查的内容)。
  3. 等到元素的.Enabled属性为真(这本质上elementToBeClickable是检查的内容)。

I would implement this like so (adding onto the current set of ExpectedConditions, but there are multiple ways of doing it:

我会像这样实现它(添加到当前的 集合中ExpectedConditions,但有多种方法可以做到:

/// <summary>
/// An expectation for checking whether an element is visible.
/// </summary>
/// <param name="locator">The locator used to find the element.</param>
/// <returns>The <see cref="IWebElement"/> once it is located, visible and clickable.</returns>
public static Func<IWebDriver, IWebElement> ElementIsClickable(By locator)
{
    return driver =>
    {
        var element = driver.FindElement(locator);
        return (element != null && element.Displayed && element.Enabled) ? element : null;
    };
}

Usable in something like:

可用于类似的东西:

var wait = new WebDriverWait(driver, TimeSpan.FromMinutes(1));
var clickableElement = wait.Until(ExpectedConditions.ElementIsClickable(By.Id("id")));

However, you might have a different idea of what clickablemight mean, in which case, this solution may not work - but it is a direct translation of what the Java code is doing.

但是,您可能对可点击的含义有不同的看法,在这种情况下,此解决方案可能不起作用 - 但它是对 Java 代码正在执行的操作的直接翻译。

回答by Phil Hudson

Here's the code I use to check if it's clickable, else go to another URL.

这是我用来检查它是否可点击的代码,否则转到另一个 URL。

if (logOutLink.Exists() && ExpectedConditions.ElementToBeClickable(logOutLink).Equals(true))
            {
                logOutLink.Click();
            }
            else
            {
                Browser.Goto("/");
            }

回答by tetenal

If you are having an issue such as "Another element would receive the click", a way around this is to use a while loop that waits for that overlay box to go away.

如果您遇到诸如“另一个元素会收到点击”之类的问题,解决此问题的方法是使用 while 循环等待该覆盖框消失。

//The below code waits 2 times in order for the problem element to go away.
int attempts = 2;
var elementsWeWantGone = WebDriver.FindElements(By.Id("id"));
while (attempts > 0 && elementsWeWantGone.Count > 0)
{
    Thread.Sleep(500);
    elementsWeWantGone = WebDriver.FindElements(By.Id("id"));
}

回答by Developer63

On our slower test runner computers it seemed the input element would be findable first, but still not clickable by the time that the script tried to send keys or a click to the input control. Waiting for "ElementToBeClickable" helped. Faster, more powerful test runner systems did not have this problem nearly as much.

在我们较慢的测试运行器计算机上,似乎可以首先找到输入元素,但在脚本尝试向输入控件发送键或单击时仍然无法单击。等待“ElementToBeClickable”有帮助。更快、更强大的测试运行器系统几乎没有这个问题。

Here is code with a bit of context that seems to have improved things on my C# based Selenium tests. Also using SpecFlow and xUnit. We are using IE11 and IEDriverServer.exe.

这是带有一些上下文的代码,似乎在我基于 C# 的 Selenium 测试中有所改进。还使用 SpecFlow 和 xUnit。我们正在使用 IE11 和 IEDriverServer.exe。

As of May 2019, the NuGet package containing this is DotNetSeleniumExtras.WaitHelpers.

截至 2019 年 5 月,包含此内容的 NuGet 包是 DotNetSeleniumExtras.WaitHelpers。

The key line is this one:

关键是这一行:

wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(By...

wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(By...

Do this for the first input field on a new page, using a selector that points to the first input field you want to interact with. (By.XPath("")

使用指向您要与之交互的第一个输入字段的选择器,对新页面上的第一个输入字段执行此操作。(By.XPath("")

[Given(@"I have selected the link to the OrgPlus application")]
public void GivenIHaveSelectedTheLinkToTheOrgPlusApplication()
{
    _driver.Navigate().GoToUrl("http://orgplus.myorg.org/ope?footer");
}

[Given(@"I have selected the link to the OrgPlus Directory lookup")]
public void GivenIHaveSelectedTheLinkToTheOrgPlusDirectoryLookup()
{
    var wait = new WebDriverWait(_driver, new TimeSpan(0, 0, 30));
    var element = wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(By.XPath("//*[@id=\"lnkDir\"]")));
    IWebElement btnSearch = _driver.FindElement(By.XPath("//*[@id=\"lnkDir\"]"));
    btnSearch.SendKeys(Keys.Enter);
}