使用 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 个问题:
classWebDriverExtensions
是静态的,而它的方法IsElementPresent
不是。静态 class 的所有成员也必须是静态的。
在出现错误的那一行(第 55 行):
var IsElementPresent = new WebDriverExtensions.IsElementPresent(By.Id("MainContent_MainContent_Panel_Grids"));
您应该删除 new
关键字。
方法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 个参数的方法完全一样。
我目前正在使用 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 个问题:
class
WebDriverExtensions
是静态的,而它的方法IsElementPresent
不是。静态 class 的所有成员也必须是静态的。在出现错误的那一行(第 55 行):
var IsElementPresent = new WebDriverExtensions.IsElementPresent(By.Id("MainContent_MainContent_Panel_Grids"));
您应该删除new
关键字。方法
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 个参数的方法完全一样。