我重新安排了我的类文件和Webdriver变量,因此我可以使用Context Injection在步骤之间共享Webdriver变量。 在我使用SetupFixture,Setup和TearDown之前,这对于BDD是不正确的。现在使用BeforeAllTests,BeforeTestRun等尝试上下文注入。 使用XPATH的我的FindElement无法正常工作。在我开始重新安排课程文件之前,它曾经工作过 我收到了错误:
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");
}
}
}
答案 0 :(得分:1)
我猜你不想要这行
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");
}
}