1

我正在使用 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); 
    }
}

但是,employerSelect 是由 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; 

我可以扩展什么来做这样的事情?

4

1 回答 1

0

不幸的是,FindsByAttributesealedSelenium 中。因此,您不能覆盖它来添加新的行为。并且How是一个Enum所以没有办法在不覆盖整个属性类的情况下添加新值。

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

但是,我不认为密封 FindsBy 是一个深思熟虑的设计决定,而是 .NET Selenium 是 Java Selenium 的直接端口这一事实的结果。在 Java 中,默认情况下所有类都是“密封的”,并且必须明确标记为虚拟以允许覆盖。C# 正好相反,我认为大多数类在 Java-C# 移植期间都被标记为密封,因此没有考虑是否应该允许它。

在 Selenium 的最新版本之前,By该类也是密封的,而这只是固定的,我正在利用它来创建我自己的 By 查找。(使用 jQuery 选择器)。我敢肯定有人可以提交一个拉取请求来做同样的事情FindsBy

于 2012-12-06T00:49:26.557 回答