18

在浏览器中生成元素后,有一个块 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();

isClickAble 是否有 C# 等价物,在此先感谢

4

4 回答 4

42

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

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

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

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

  1. 等到元素从 DOM 返回
  2. 等到元素的.Displayed属性为真(本质上visibilityOfElementLocated就是检查的内容)。
  3. 等到元素的.Enabled属性为真(这本质上就是elementToBeClickable要检查的内容)。

我会这样实现(添加到当前的集合中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;
    };
}

可用于以下内容:

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

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

于 2013-04-17T10:20:29.810 回答
2

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

if (logOutLink.Exists() && ExpectedConditions.ElementToBeClickable(logOutLink).Equals(true))
            {
                logOutLink.Click();
            }
            else
            {
                Browser.Goto("/");
            }
于 2016-03-09T05:16:56.740 回答
1

如果您遇到诸如“另一个元素会收到点击”之类的问题,解决此问题的一种方法是使用等待该覆盖框消失的 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"));
}
于 2016-04-18T21:47:46.083 回答
0

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

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

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

关键是这一行:

wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(通过...

使用指向您要与之交互的第一个输入字段的选择器对新页面上的第一个输入字段执行此操作。(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);
}
于 2019-05-08T04:04:13.277 回答