使用Selenium和C#时“没有这样的元素”异常

时间:2014-11-04 13:51:28

标签: c# selenium bdd specflow nosuchelementexception

我的网页项目“CalculatorWeb”中有一个网页,我在其中放置了一个ID为“txtNum1”的文本框

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
</head>
<body>
    <form id="frmCalc">
        <div style="padding-top:20px;">
            My Sample Text Box <br/><br/>
            <input id="txtNum1" type="text" />
        </div>
    </form>
</body>
</html>

没什么好看的,所以页面加载如下

Web Page Preview

现在我在项目“Calculator.Specs”中创建了一个功能文件“BrowserTest1.feature”。代码如下

Feature: BrowserTest1
In order to check url
As browser
I want to be see url of page

@mytag
Scenario: Go to URL
    Given I have entered 'http://localhost:58529/'
    When I go to that url
    Then there is a text box on the page with id 'txtNum1'
然后我编写了一个BrowserTest.cs文件,用于单元测试实现

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
using TechTalk.SpecFlow;

namespace Calculator.Specs
{
    [Binding]
    class BrowserTest
    {

        public string urlPath;


        [Given(@"I have entered 'http://localhost:58529/'")]
        protected void SetURL()
        {
            string URLPath = "http://localhost:58529/";
            urlPath = URLPath;
        }

        [When(@"I go to that url")]
        protected void NavigateToURL()
        {
             using (var driver = new ChromeDriver())
             {
                 driver.Navigate().GoToUrl(urlPath);
             }
        }


        [Then(@"there is a text box on the page with id 'txtNum1'")]
        protected void TxtBoxExists()
        {
            bool txtExists = false;
            using (var driver = new ChromeDriver())
            {
                IWebElement txtBox1 = driver.FindElement(By.Id("txtNum1"));

                if (txtBox1 != null)
                {
                    txtExists = true;
                }
            }
            Assert.AreEqual(true, txtExists);
        }
    }
}

据我所知,我确实拥有Visual Studio IDE到SpecFlow / Selenium集成的所有必需参考

References Section

当我运行单元测试时,网页加载正常,但是当我尝试找到ID为“txtNum1”的元素时,即使页面上存在带有该ID的文本框,我也会得到失败的测试

Exception Message

异常详情如下所示

Exception Details

任何人都可以指出我正确的方向,我缺少什么让Selenium找到ID为“txtNum1”的页面上的文本框

3 个答案:

答案 0 :(得分:1)

你的司机只需要慢一点

在每个driver.FindElement之前添加一些延迟,例如:

Thread.Sleep(2000);
IWebElement txtBox1 = driver.FindElement(By.Id("txtNum1"));

或者更好:

WebDriverWait wait = new WebDriverWait(driver, new TimeSpan(0,0,10));
wait.Until(ExpectedConditions.ElementIsVisible(By.Id("txtNum1")));
IWebElement txtBox1 = driver.FindElement(By.Id("txtNum1"));

答案 1 :(得分:1)

您需要在步骤之间使用相同的驱动程序实例,否则导航到该页面的驱动程序与您尝试从该驱动程序获取该元素的驱动程序不同。

你有几个选择。最简单的方法是为驱动程序实例创建一个字段,并在所有步骤中使用该字段。只要您的所有步骤都在同一个文件中,这将有效。

另一个选项是将驱动程序对象存储在ScenarioContext.Current(或FeatureContext.Current)中。这些是字典,所以你可以这样做:

ScenarioContext.Current["webDriver"] = driver;

这样可以正常工作,但每次你得到驱动程序时都必须进行转换,因为字典只需要对象,但是你可以在步骤之间共享你的驱动程序实例,而不管它们是哪个文件在。。

第三个(和IMHO最佳)选项是创建一个WebDriverContext类并在步骤类构造函数中接受它。在那里创建驱动程序(在其构造函数中),然后每个步骤都可以使用WebDriverContext实例来访问共享驱动程序。

answer here

中可以看到设置此项的示例

答案 2 :(得分:0)

经过一些代码检查后找到答案。此问题与代码中的多个ChromeDriver实例有关。所以第一个实例是加载页面但是当我试图在页面上找到一个项目时,我正在使用页面的新实例而不是已经用于加载页面的实例。所以这个没有加载页面的chrome驱动程序的第二个实例总是返回异常而没有找到任何项目,因为这个chrome驱动程序实例上没有加载页面