使用 Selenium API 扩展添加命令 - '(Command) 是一个 'method' 但像 'type' 一样使用

Using Selenium API extension to add command - '(Command) is a 'method' but is used like a 'type'

我目前正在使用 Selenium WebDriver API 为 Web 应用程序开发 UI 测试。在我的工作中,我真的觉得缺少 "Assert Element Present" 类型的命令,在谷歌搜索后我发现有人写了一个扩展来添加一个。

我已经将它集成到我的一个测试中,但是当尝试 运行 测试时它抛出错误 '(Command) is a 'method' but is used like a 'type'.我知道这对于像我这样的新手 运行 来说是一个很常见的问题,但我已经阅读了很多关于这个问题的答案,但没有找到一个适用于我的答案 - 我真的看不出是什么这里错了。

这是我的分机:

namespace SeleniumTest
{
    public static class WebDriverExtensions 
    {
     public bool IsElementPresent(IWebDriver driver, By locator) //adds 'IsElementPresent' command which asserts presence of element
        {
            driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromMilliseconds(100));

            try
            {
                driver.FindElement(locator);
                driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromMilliseconds(100));
                return true;
            }
            catch (NoSuchElementException)
            {
                driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromMilliseconds(20000));
                return false;
            }
        }
    }

这是我在测试用例中尝试使用它的示例:

 [TestFixture]
   public class SeleniumTest
    {
        private IWebDriver driver;

        [SetUp]
        public void Setup()
        {
            driver=new FirefoxDriver();
            Console.WriteLine("Starting Login Test"); 
        }


        [TestCase]
        public void LoginTest()
        {
            var IsElementPresent = new WebDriverExtensions.IsElementPresent(By.Id("MainContent_MainContent_Panel_Grids"));
            driver.Navigate().GoToUrl("http://www.website.com/account/Login.aspx");
            driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));

            IWebElement query = driver.FindElement(By.Name("LoginForm$UserName"));
            query.SendKeys("username");
            driver.FindElement(By.Name("LoginForm$Password"));
            query.SendKeys("password");
            driver.FindElement(By.Id("LoginForm_Button1"));
            query.Click();

            driver.IsElementPresent(By.Id("MainContent_MainContent_Panel_Grids"));
        }

确切的错误是:

'SeleniumTest.WebDriverExtensions.IsElementPresent(OpenQA.Selenium.IWebDriver, OpenQA.Selenium.By)' is a 'method' but is used like a 'type' - Line 55, Column 60

感谢所有 advice/help,如果可能的话,请尽可能基本地解释我哪里出错了 - C# 对我来说是新手,我想从我的错误中吸取教训!

您在这段代码中有 3 个问题:

  1. classWebDriverExtensions是静态的,而它的方法IsElementPresent不是。静态 class 的所有成员也必须是静态的。

  2. 在出现错误的那一行(第 55 行): var IsElementPresent = new WebDriverExtensions.IsElementPresent(By.Id("MainContent_MainContent_Panel_Grids")); 您应该删除 new 关键字。

  3. 方法IsElementPresent有两个参数——驱动程序和定位器,但你只传递定位器。

修复它的最佳方法是 通过在 IWebDriver[=55 之前添加关键字 this 使方法 IsElementPresent 成为 extension method =] 如:

public bool IsElementPresent(this IWebDriver driver, By locator)

并将调用代码更改为: var IsElementPresent = new driver.IsElementPresent(By.Id("MainContent_MainContent_Panel_Grids"));

解释:

new关键字仅用于创建非静态class(静态classes的实例(对象)不能有实例)。此外,如果您必须创建一个实例,那么您应该在 class 名称(例如 var IsElementPresent = new WebDriverExtensions().IsElementPresent(...))之后加上括号,以便它调用构造函数。

使用扩展方法,您将第一个参数(标有 this 的参数)作为表达式传递到点左侧(在我们的例子中为 driver),而不是内部括号。这只是一个语法糖,但实际上它的行为与调用带有 2 个参数的方法完全一样。