Specflow NoSuchElementException By.XPath 找不到元素
Specflow NoSuchElementException Could not find element by By.XPath
我重新整理了我的 class 文件和 Webdriver 变量,这样我就可以使用上下文注入在步骤之间共享 Webdriver 变量。
在我使用不适合 BDD 的 SetupFixture、Setup 和 TearDown 之前。现在尝试使用 BeforeAllTests、BeforeTestRun 等进行上下文注入。
我使用 XPATH 的 FindElement 不工作。在我开始重新排列我的 class 文件之前它曾经工作过。
我收到错误:
OpenQA.Selenium.NoSuchElementException : Could not find element by: By.XPath: .//*[@id='twotabsearchtextbox']
错误所在的行突出显示:
Searchfield_XPATH.SendKeys(text);
XPath 定位器定义为:
[FindsBy(How = How.XPath, Using = ".//*[@id='twotabsearchtextbox']")]
private IWebElement Searchfield_XPATH { get; set; }
我的代码片段如下:
//class setup.cs:
namespace SearchTest.Setup
{
[Binding]
public class BeforeAllTests
{
private readonly IObjectContainer objectContainer;
private static SeleniumContext seleniumContext;
public BeforeAllTests(IObjectContainer container)
{
this.objectContainer = container;
}
[BeforeTestRun]
public static void RunBeforeAllTests()
{
seleniumContext = new SeleniumContext();
seleniumContext.driver.Navigate().GoToUrl("http://localhost:8080");
}
[BeforeScenario]
public void RunBeforeScenario()
{
objectContainer.RegisterInstanceAs<SeleniumContext>(seleniumContext);
}
}
}
// Class SeleniumContext.cs
namespace SearchTest.WebDriver
{
public class SeleniumContext
{
public IWebDriver driver { get; private set; }
public SeleniumContext()
{
//create the selenium context
driver = new FirefoxDriver();
}
}
}
//Class HomePage.cs
namespace SearchTest.PageObjects
{
[Binding]
public class HomePage : PageObjectBase
{
private SeleniumContext seleniumContext;
//private IWebDriver driver{ get; set; }
[FindsBy(How = How.XPath, Using = ".//TITLE")]
public IWebElement Title{ get; set; }
// search text field on the homepage
//[FindsBy(How= How.Id, Using="twotabsearchtextbox")]
//private IWebElement Searchfield_ID { get; set; }
[FindsBy(How = How.XPath, Using = ".//*[@id='twotabsearchtextbox']")]
private IWebElement Searchfield_XPATH { get; set; }
[FindsBy(How = How.Id, Using = "nav-search-submit-text")]
private IWebElement SearchButton { get; set; }
[FindsBy(How = How.XPath, Using = ".//*[@id='nav-search']/form/div[2]/div/input")]
private IWebElement searchButton_Xpath {get; set;}
// public HomePage(IWebDriver driver)
public HomePage(SeleniumContext seleniumContext) : base(seleniumContext)
{
//driver1 = new FirefoxDriver();
//Console.Out.WriteLine(driver1.Title);
//driver1.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(5)); // Set implicit wait timeouts to 5 secs
//PageFactory.InitElements(driver1, this);
this.seleniumContext = seleniumContext;
PageFactory.InitElements(seleniumContext.driver, this);
}
public void goToURL() {
//driver = new FirefoxDriver();
//driver1.Navigate().GoToUrl("http://localhost:8080");
}
public void EnterSearchText(String text)
{
Searchfield_XPATH.SendKeys(text);
}
public SearchResultsPage click_search_button() {
searchButton_Xpath.Click();
return new SearchResultsPage(seleniumContext);
}
}
}
//Class PageObjectBase.cs
namespace SearchTest.PageObjects
{
public class PageObjectBase
{
private SeleniumContext seleniumContext;
//private IWebDriver Driver { get; set; }
public PageObjectBase(SeleniumContext seleniumContext)
{
this.seleniumContext = seleniumContext;
//Driver = driver;
//Driver = new FirefoxDriver();
//Console.Out.WriteLine("From base class Driver.title = " + Driver.Title);
//if (Driver.Title != titleOfPage)
// throw new NoSuchWindowException("PageObjectBase: The Page Title doesnt match.");
}
}
}
//The HTML is:
<form class="nav-searchbar" role="search" name="site-search" method="GET" action="/s/ref=nb_sb_noss" accept-charset="utf-8">
<div class="nav-left">
<div class="nav-right">
<div class="nav-fill">
<div class="nav-search-field">
<input id="twotabsearchtextbox" class="nav-input" type="text" tabindex="21" autocomplete="off" name="field-keywords" value=""/>
</div>
<div id="nav-iss-attach"/>
</div>
</form>
我该如何解决这个问题?
我是 BDD 的新手,如果您发现我的设置有任何问题并想建议我如何改进它,请这样做。
由于添加了以下代码:
[BeforeScenario]
public void RunBeforeScenario()
{
objectContainer.RegisterInstanceAs<SeleniumContext>(seleniumContext);
// HERE INSTEAD
seleniumContext.driver.Navigate().GoToUrl("http://localhost:8080");
}
我得到的错误是:
System.ArguementNullException: Value cannot be Null.
突出显示的行在这里:objectContainer.RegisterInstanceAs<SeleniumContext>(seleniumContext);
我的代码是:
public class BeforeAllTests
{
private readonly IObjectContainer objectContainer;
private static SeleniumContext seleniumContext;
public BeforeAllTests(IObjectContainer container)
{
this.objectContainer = container;
}
//[BeforeTestRun]
// public static void RunBeforeAllTests()
// {
// seleniumContext = new SeleniumContext();
// seleniumContext.driver.Navigate().GoToUrl("http://localhost:8080");
// }
//[BeforeScenario]
//public void RunBeforeScenario()
// {
// objectContainer.RegisterInstanceAs<SeleniumContext>(seleniumContext);
//}
[BeforeScenario]
public void RunBeforeScenario()
{
objectContainer.RegisterInstanceAs<SeleniumContext>(seleniumContext);
// HERE INSTEAD
seleniumContext.driver.Navigate().GoToUrl("http://localhost:8080");
}
}
}
我猜你不想要这条线
seleniumContext.driver.Navigate().GoToUrl("http://localhost:8080");
在您标记为 [BeforeTestRun]
的方法中,因为这只会导航到那个 URL 一次,然后所有测试都是 运行(而不是在每个测试之前)。
将它放在标记为 [BeforeScenario]
的方法中可能更有意义,因为这会在每个场景执行之前将您导航到您的基地 URL。这更有可能发生,因为场景不应该相互依赖(因此,一个场景不应该依赖于另一个已经导航到特定页面的场景)。
[BeforeScenario]
public void RunBeforeScenario()
{
objectContainer.RegisterInstanceAs<SeleniumContext>(seleniumContext);
// HERE INSTEAD
seleniumContext.driver.Navigate().GoToUrl("http://localhost:8080");
}
这可以解释为什么 Selenium 无法找到该特定元素,因为当步骤定义为 运行.
时,它实际上可能不在正确的页面上
编辑:
所以 BeforeAllTests
的最终代码将是:
public class BeforeAllTests
{
private readonly IObjectContainer objectContainer;
private static SeleniumContext seleniumContext;
public BeforeAllTests(IObjectContainer container)
{
this.objectContainer = container;
}
[BeforeTestRun]
public static void RunBeforeAllTests()
{
seleniumContext = new SeleniumContext();
}
[BeforeScenario]
public void RunBeforeScenario()
{
objectContainer.RegisterInstanceAs<SeleniumContext>(seleniumContext);
seleniumContext.driver.Navigate().GoToUrl("http://localhost:8080");
}
}
我重新整理了我的 class 文件和 Webdriver 变量,这样我就可以使用上下文注入在步骤之间共享 Webdriver 变量。
在我使用不适合 BDD 的 SetupFixture、Setup 和 TearDown 之前。现在尝试使用 BeforeAllTests、BeforeTestRun 等进行上下文注入。
我使用 XPATH 的 FindElement 不工作。在我开始重新排列我的 class 文件之前它曾经工作过。
我收到错误:
OpenQA.Selenium.NoSuchElementException : Could not find element by: By.XPath: .//*[@id='twotabsearchtextbox']
错误所在的行突出显示:
Searchfield_XPATH.SendKeys(text);
XPath 定位器定义为:
[FindsBy(How = How.XPath, Using = ".//*[@id='twotabsearchtextbox']")]
private IWebElement Searchfield_XPATH { get; set; }
我的代码片段如下:
//class setup.cs:
namespace SearchTest.Setup
{
[Binding]
public class BeforeAllTests
{
private readonly IObjectContainer objectContainer;
private static SeleniumContext seleniumContext;
public BeforeAllTests(IObjectContainer container)
{
this.objectContainer = container;
}
[BeforeTestRun]
public static void RunBeforeAllTests()
{
seleniumContext = new SeleniumContext();
seleniumContext.driver.Navigate().GoToUrl("http://localhost:8080");
}
[BeforeScenario]
public void RunBeforeScenario()
{
objectContainer.RegisterInstanceAs<SeleniumContext>(seleniumContext);
}
}
}
// Class SeleniumContext.cs
namespace SearchTest.WebDriver
{
public class SeleniumContext
{
public IWebDriver driver { get; private set; }
public SeleniumContext()
{
//create the selenium context
driver = new FirefoxDriver();
}
}
}
//Class HomePage.cs
namespace SearchTest.PageObjects
{
[Binding]
public class HomePage : PageObjectBase
{
private SeleniumContext seleniumContext;
//private IWebDriver driver{ get; set; }
[FindsBy(How = How.XPath, Using = ".//TITLE")]
public IWebElement Title{ get; set; }
// search text field on the homepage
//[FindsBy(How= How.Id, Using="twotabsearchtextbox")]
//private IWebElement Searchfield_ID { get; set; }
[FindsBy(How = How.XPath, Using = ".//*[@id='twotabsearchtextbox']")]
private IWebElement Searchfield_XPATH { get; set; }
[FindsBy(How = How.Id, Using = "nav-search-submit-text")]
private IWebElement SearchButton { get; set; }
[FindsBy(How = How.XPath, Using = ".//*[@id='nav-search']/form/div[2]/div/input")]
private IWebElement searchButton_Xpath {get; set;}
// public HomePage(IWebDriver driver)
public HomePage(SeleniumContext seleniumContext) : base(seleniumContext)
{
//driver1 = new FirefoxDriver();
//Console.Out.WriteLine(driver1.Title);
//driver1.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(5)); // Set implicit wait timeouts to 5 secs
//PageFactory.InitElements(driver1, this);
this.seleniumContext = seleniumContext;
PageFactory.InitElements(seleniumContext.driver, this);
}
public void goToURL() {
//driver = new FirefoxDriver();
//driver1.Navigate().GoToUrl("http://localhost:8080");
}
public void EnterSearchText(String text)
{
Searchfield_XPATH.SendKeys(text);
}
public SearchResultsPage click_search_button() {
searchButton_Xpath.Click();
return new SearchResultsPage(seleniumContext);
}
}
}
//Class PageObjectBase.cs
namespace SearchTest.PageObjects
{
public class PageObjectBase
{
private SeleniumContext seleniumContext;
//private IWebDriver Driver { get; set; }
public PageObjectBase(SeleniumContext seleniumContext)
{
this.seleniumContext = seleniumContext;
//Driver = driver;
//Driver = new FirefoxDriver();
//Console.Out.WriteLine("From base class Driver.title = " + Driver.Title);
//if (Driver.Title != titleOfPage)
// throw new NoSuchWindowException("PageObjectBase: The Page Title doesnt match.");
}
}
}
//The HTML is:
<form class="nav-searchbar" role="search" name="site-search" method="GET" action="/s/ref=nb_sb_noss" accept-charset="utf-8">
<div class="nav-left">
<div class="nav-right">
<div class="nav-fill">
<div class="nav-search-field">
<input id="twotabsearchtextbox" class="nav-input" type="text" tabindex="21" autocomplete="off" name="field-keywords" value=""/>
</div>
<div id="nav-iss-attach"/>
</div>
</form>
我该如何解决这个问题? 我是 BDD 的新手,如果您发现我的设置有任何问题并想建议我如何改进它,请这样做。
由于添加了以下代码:
[BeforeScenario]
public void RunBeforeScenario()
{
objectContainer.RegisterInstanceAs<SeleniumContext>(seleniumContext);
// HERE INSTEAD
seleniumContext.driver.Navigate().GoToUrl("http://localhost:8080");
}
我得到的错误是:
System.ArguementNullException: Value cannot be Null.
突出显示的行在这里:objectContainer.RegisterInstanceAs<SeleniumContext>(seleniumContext);
我的代码是:
public class BeforeAllTests
{
private readonly IObjectContainer objectContainer;
private static SeleniumContext seleniumContext;
public BeforeAllTests(IObjectContainer container)
{
this.objectContainer = container;
}
//[BeforeTestRun]
// public static void RunBeforeAllTests()
// {
// seleniumContext = new SeleniumContext();
// seleniumContext.driver.Navigate().GoToUrl("http://localhost:8080");
// }
//[BeforeScenario]
//public void RunBeforeScenario()
// {
// objectContainer.RegisterInstanceAs<SeleniumContext>(seleniumContext);
//}
[BeforeScenario]
public void RunBeforeScenario()
{
objectContainer.RegisterInstanceAs<SeleniumContext>(seleniumContext);
// HERE INSTEAD
seleniumContext.driver.Navigate().GoToUrl("http://localhost:8080");
}
}
}
我猜你不想要这条线
seleniumContext.driver.Navigate().GoToUrl("http://localhost:8080");
在您标记为 [BeforeTestRun]
的方法中,因为这只会导航到那个 URL 一次,然后所有测试都是 运行(而不是在每个测试之前)。
将它放在标记为 [BeforeScenario]
的方法中可能更有意义,因为这会在每个场景执行之前将您导航到您的基地 URL。这更有可能发生,因为场景不应该相互依赖(因此,一个场景不应该依赖于另一个已经导航到特定页面的场景)。
[BeforeScenario]
public void RunBeforeScenario()
{
objectContainer.RegisterInstanceAs<SeleniumContext>(seleniumContext);
// HERE INSTEAD
seleniumContext.driver.Navigate().GoToUrl("http://localhost:8080");
}
这可以解释为什么 Selenium 无法找到该特定元素,因为当步骤定义为 运行.
时,它实际上可能不在正确的页面上编辑:
所以 BeforeAllTests
的最终代码将是:
public class BeforeAllTests
{
private readonly IObjectContainer objectContainer;
private static SeleniumContext seleniumContext;
public BeforeAllTests(IObjectContainer container)
{
this.objectContainer = container;
}
[BeforeTestRun]
public static void RunBeforeAllTests()
{
seleniumContext = new SeleniumContext();
}
[BeforeScenario]
public void RunBeforeScenario()
{
objectContainer.RegisterInstanceAs<SeleniumContext>(seleniumContext);
seleniumContext.driver.Navigate().GoToUrl("http://localhost:8080");
}
}