Selenium FindBy属性使用Javascript并在C#中等待

时间:2012-07-03 23:28:57

标签: c# c#-4.0 selenium pageobjects

我正在使用Selenium,我有以下扩展方法来执行javascript。

    private const int s_PageWaitSeconds = 30;

    public static IWebElement FindElementByJs(this IWebDriver driver, string jsCommand)
    {
        return (IWebElement)((IJavaScriptExecutor)driver).ExecuteScript(jsCommand);
    }

    public static IWebElement FindElementByJsWithWait(this IWebDriver driver, string jsCommand, int timeoutInSeconds)
    {
        if (timeoutInSeconds > 0)
        {
            var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
            wait.Until(d => d.FindElementByJs(jsCommand));
        }
        return driver.FindElementByJs(jsCommand);
    }

    public static IWebElement FindElementByJsWithWait(this IWebDriver driver, string jsCommand)
    {
        return FindElementByJsWithWait(driver, jsCommand, s_PageWaitSeconds);
    } 

在我的HomePage类中,我有以下属性。

public class HomePage : SurveyPage
{
    [FindsBy(How = How.Id, Using = "radio2")]
    private IWebElement employerSelect; 

    public HomePage(IWebDriver driver) : base(driver)
    {
    }

    public override SurveyPage FillOutThisPage()
    {
        employerSelect.Click();
        employerSelect.Submit();
        m_driver.FindElement(By.)
        return new Level10Page(m_driver); 
    }
}

但是,employeeSelect是由Javascript生成的,所以有办法做这样的事情:

public class HomePage : SurveyPage
{
    const string getEmployerJsCommand= "return $(\"li:contains('Employer')\")[0];";

    [FindsBy(How = How.FindElementByJsWithWait, Using = "getEmployerJsCommand")]
    private IWebElement employerSelect; 

    public HomePage(IWebDriver driver) : base(driver)
    {
    }

    public override SurveyPage FillOutThisPage()
    {
        employerSelect.Click();
        employerSelect.Submit();
        m_driver.FindElement(By.)
        return new Level10Page(m_driver); 
    }
}

本质上,我想将原始的ExecuteJs调用替换为FindsBy属性的一部分,例如:

    const string getEmployerJsCommand = "return $(\"li:contains('Employer')\")[0];";
    IWebElement employerSelect = driver.FindElementByJsWithWait(getEmployerJsCommand);

成为FindsBy属性的一部分,如下所示:

    const string getEmployerJsCommand= "return $(\"li:contains('Employer')\")[0];";

    [FindsBy(How = How.FindElementByJsWithWait, Using = "getEmployerJsCommand")]
    private IWebElement employerSelect; 

我可以延伸做些什么?

1 个答案:

答案 0 :(得分:0)

不幸的是,FindsByAttribute在Selenium中是sealed。因此,您无法覆盖它以添加新的行为。 HowEnum,因此无法覆盖整个属性类,无法添加新值。

所以目前没有办法做你想做的事。

但是,我不认为将FindsBy密封是一个刻意的设计决定,而是因为.NET Selenium是Java Selenium的直接端口。在Java中,默认情况下所有类都是“密封的”,并且必须明确标记为虚拟以允许覆盖。 C#是相反的,我认为大多数类在Java-C#端口被标记为密封,因此不考虑它是否应该被允许。

直到最新版本的Selenium,By类也被密封了,这只是修复了,我正在利用它来创建我自己的By查找。 (使用jQuery选择器)。我确定可以提交拉取请求以对FindsBy

执行相同操作