我正在尝试使用C#
中的Selenium设置页面工厂模型框架我已经使用Selenium运行我的测试但是想要从框架中分离我的测试。
在我对元素执行任何操作之前,有几个测试要求我等待元素可见。在我的其他版本的Selenium测试中,我会做类似的事情
By selector = By.XPath("/html/body/header/div/div[4]/div/div/div[2]/div[1]/form/div[2]/span[2]");
new WebDriverWait(driver.Instance, TimeSpan.FromSeconds(5)).Until(ExpectedConditions.ElementIsVisible(selector));
但是我无法使Element Is Visible工作,所以在我的扩展方法(下面的代码)中使用了Wait Until Visible。
当我运行我的测试时,即使使用Wait Until Visible Selenium也没有等待Element继续显示。当我调试测试时,它在WaitUntilVisible步骤中使用stackOverflow失败。
当我正常运行测试时,我收到的消息没有显示错误,但它显示(我可以在屏幕上看到它)。我从在我的替代框架中运行此测试的经验知道,这仅仅是因为测试在元素出现之前正在寻找元素。
我已经在我的浏览器工厂类中运行了ImplicitWait。
我是否理解并在页面工厂模型中正确使用我的等待?
测试我正在运行
[Test]
public void Framework_Invalid_Location()
{
BrowserFactory.InitBrowser("Chrome");
BrowserFactory.LoadApplication("xxxxxxxxxxxxxx");
Page.HomePage.SearchForRestaurant("CFYUGHGYHYTDFD");
Assert.That(Page.HomePage.InvalidPostcode(), Is.EqualTo("Please enter a valid location or postcode"), "message does not show");
BrowserFactory.CloseAllDrivers();
}
HomePage Class
private IWebDriver driver;
[FindsBy(How = How.CssSelector, Using = "#js-postcode")]
[CacheLookup]
private IWebElement PostcodeInput { get; set; }
[FindsBy(How = How.XPath, Using = "/html/body/header/div/div[4]/div/div/div[2]/div[1]/form/div[2]/span[2]")]
[CacheLookup]
private IWebElement ErrorMessageInvalidEntry { get; set; }
public void SearchForRestaurant(string Postcode)
{
PostcodeInput.SendKeys(Postcode);
SearchButton.ClickOnIt("SearchButton");
public string InvalidPostcode()
{
ErrorMessageInvalidEntry.WaitUntilVisible(10);
return ErrorMessageInvalidEntry.Text;
}
元素扩展功能我正在呼唤我的等待。从评论和建议更新
public static void Wait(这个IWebElement元素,IWebDriver驱动,浮点TimeOut) {
WebDriverWait Wait = new WebDriverWait(driver, TimeSpan.FromSeconds(TimeOut));
return Wait.Until(ExpectedConditions.ElementIsVisible(element));
此代码(元素)仍有一个错误 无法从OpenQa.Selenium.IWebElement转换为open.Qa.Selenium.By
真的觉得我处在过去几个月里所学到的一点点知识的边缘,所以谢谢你的帮助。
Page Class
namespace KukdFramework.PageObjects
{
public class Page
{
private static T GetPage<T>() where T : new()
public static HomePage HomePage
{
get { return GetPage<HomePage>(); }
}
浏览器工厂代码
private static readonly IDictionary<string, IWebDriver> Drivers = new Dictionary<string, IWebDriver>();
private static IWebDriver driver;
public static IWebDriver Driver
{
get
{
if (driver == null)
throw new NullReferenceException("The WebDriver browser instance was not initialized. You should first call the method InitBrowser.");
return driver;
}
private set
{
driver = value;
}
}
public static void InitBrowser(string browserName)
{
switch (browserName)
{
case "Firefox":
if (driver == null)
{
driver = new FirefoxDriver();
Drivers.Add("Firefox", Driver);
BrowserSettings();
}
break;
case "IE":
if (driver == null)
{
driver = new InternetExplorerDriver();
Drivers.Add("IE", Driver);
BrowserSettings();
}
break;
case "Chrome":
if (driver == null)
{
driver = new ChromeDriver();
Drivers.Add("Chrome", Driver);
BrowserSettings();
}
break;
}
}
答案 0 :(得分:0)
看起来你的WaitUntilVisible()
扩展方法在没有任何出路的情况下以递归方式调用自身。
这将导致堆栈溢出异常。
您可以将上述WebDriverWait
调用放在此方法中,并返回找到的IWebElement
,而不是递归调用此方法。
更新(来自评论):
您还需要传入WebDriver
实例。在上面的WebDriverWait
行中,您使用driver.Instance
。
另一种选择是修改扩展方法,以便在等待时间内要求WebDriverWait
的实例而不仅仅是float
。这样您就不需要单独传递驱动程序对象了。
答案 1 :(得分:0)
我不是C#程序员,但是JAVA和C#是相似的,因此您可以转换以下Java代码。
WaitUntilVisible 应该是这样的
public static void WaitUntilVisible(WebElement element, int timeOut){
WebDriverWait wait = new WebDriverWait(driver, timeOut);
wait.until(ExpectedConditions.visibilityOf(element));
}