如何在C#中使用selenium web驱动程序检查元素是否存在

时间:2015-04-08 02:34:26

标签: c# selenium-webdriver

我对这个问题很感兴趣,但找不到更好的答案,所以......发布在这里。

我点击浏览器中的一个按钮,打开一个表单/ div(动态生成)。在我按下按钮之前,form / div元素不存在。

现在,我正在尝试检查form / div元素是否存在。我尝试使用以下代码。但是当元素存在并且在元素不存在时抛出异常(第一个方法 - 超时,第二个,驱动程序停止)时它会起作用。

方法1:

 ReadOnlyCollection<IWebElement> elements = Utility.Browser.FindElements(By.TagName("div")); // Utility.Browser is the browser instance.

 var expElement = from e in elements
                  where e.GetAttribute("id").Contains("element id")
                  select e;

  return expElement.Count() > 0;

和 方法2:

 string script = string.Format("return document.getElementById('{0}')", attValue);
 IJavaScriptExecutor js = (IJavaScriptExecutor)Utility.Browser; // Utility.Browser is the browser instance.
 var ele = js.ExecuteScript(script);

 return ele != null;

任何帮助都将受到高度赞赏。

感谢。

4 个答案:

答案 0 :(得分:2)

查看WebDriverWait。您可以定义等待特定时间以满足特定条件的等待函数。你基本上可以说“等待元素出现十秒钟”。我在手机上,确切的语法可能不正确,但它看起来像下面这样。

pulic bool ElementExist(IWebDriver driver)
{
 var value = false;

 var objWait = new WebDriverWait(driver, Timespan.FromMilliseconds(10000));
 objWait.IgnoreExceptionTypes(typeof(WebDriverTimeoutException));
 value = objWait.Until(b=>b.FindElements(By.TagName("div")).Count > 0);

 return value;
}

您可以指定要忽略的异常类型,例如ElementNotFound和StaleElement,如果发生这些异常,函数将继续等待。您还可以定义一个函数并将其作为参数传递给.Until函数。我缺乏lamda表达式和内联函数定义的技能,否则我会给出一个更好的例子,但这绝对是最可定制的方法。

答案 1 :(得分:2)

与此处已有的其他两个答案类似,我使用扩展方法来测试我的测试:

public static bool ElementExists(this IWebDriver driver, By condition, TimeSpan? timeSpan)
{
    bool isElementPresent = false;

    if (timeSpan == null)
    {
        // default to 15 seconds if timespan parameter is not passed in
        timeSpan = TimeSpan.FromMilliseconds(15000);
    }

    var driverWait = new WebDriverWait(driver, (TimeSpan)timeSpan);
    driverWait.IgnoreExceptionTypes(typeof(WebDriverTimeoutException));
    isElementPresent = driverWait.Until(x => x.FindElements(condition).Any());

    return isElementPresent;
}

然后我在代码中使用它:

var isElementPresent = _driver.ElementExists(By.ClassName("register"), TimeSpan.FromSeconds(90.00));
if (isElementPresent)
{
    // do required processing...
}

希望这有帮助

[edit] - 您当然可以重构扩展方法以返回所需的元素,如果您想在单个操作中执行所有操作,则默认值为null。

public static IWebElement FindElementAfterWait(this IWebDriver driver, By condition)
{
    bool isElementPresent = false;
    IWebElement singleElement = null;

    var driverWait = new WebDriverWait(driver, TimeSpan.FromSeconds(90));
    driverWait.IgnoreExceptionTypes(typeof(WebDriverTimeoutException));
    isElementPresent = driverWait.Until(x => x.FindElement(condition) != null);

    if (isElementPresent)
    {
        singleElement = driver.FindElement(condition);
    }

    return singleElement;
}

用法:

_driver.FindElementAfterWait(By.ClassName("register"));

也:

public static IWebElement FindElementAfterWait(this IWebDriver driver, Func<IWebDriver, IWebElement> condition)
{
    IWebElement singleElement = null;

    var driverWait = new WebDriverWait(driver, TimeSpan.FromSeconds(90));
    driverWait.IgnoreExceptionTypes(typeof(WebDriverTimeoutException));
    singleElement = driverWait.Until(condition);

    return singleElement;
}

用法:

_driver.FindElementAfterWait(ExpectedConditions.ElementIsVisible(By.Id("firstName")))

...享受

答案 2 :(得分:1)

以下函数帮助我在C#Selenium代码中测试页面上是否存在元素:

public static bool IsElementPresent(this IWebDriver driver, By by) { return driver.FindElements(by).Count > 0; }

如果有帮助,请告诉我!

答案 3 :(得分:0)

以下方法是我一直使用的方法,相信我真的做了它所说的。 如果显示指定的元素,它将返回true,否则它将返回false。 您可以使用它:IsElementDisplayedByXpathVariableWait("Xpath_Of_The_Element",5);

5 是每次检查后检查元素是否以1秒暂停显示的次数。

public static bool IsElementDisplayedByXpathVariableWait(string xpath, int iterations)
    {
bool returnVal = false;   
        int tracker = 0;
        while (tracker < iterations)
        {
            try
            {
                tracker++;
                IWebElement pageObject = _driver.FindElement(By.XPath(xpath));
                if (pageObject.Displayed)
                {
                    returnVal = true;
                    break;
                }
            }
            catch (Exception e)
            {                   
                Wait(1000);
                continue;
            }
        }           
        return returnVal;
}