C# 当对象ID是动态的时,如何在页面工厂中初始化FindsBy

C# 当对象ID是动态的时,如何在页面工厂中初始化FindsBy,c#,selenium-webdriver,pageobjects,C#,Selenium Webdriver,Pageobjects,我的ID有以下代码: public int counter = 0; public void AddClick(){ counter = counter + 1; driver.FindElement(By.Id(String.Format("btnAdd{0}_btnAddExpense", counter))).Click(); Console.WriteLine("I am clicked {0} times!", counter); } 我如何在FindsBy中声明这一点?显然,这

我的ID有以下代码:

public int counter = 0;
public void AddClick(){
counter = counter + 1;
 driver.FindElement(By.Id(String.Format("btnAdd{0}_btnAddExpense", counter))).Click();
 Console.WriteLine("I am clicked {0} times!", counter);
}
我如何在FindsBy中声明这一点?显然,这不起作用:

 [FindsBy(How = How.Id, Using = "(String.Format("btnAdd{0}_btnAddExpense", counter")]
 public IWebElement contactBox { get; set; }

您需要将标识元素的方式从
Id
更改为
Xpath

[FindsBy(How = How.Xpath, Using = "your_xpath_here")] public IWebElement contactBox { get; set; }
为了给你一个简短的解释为什么它不起作用,这是因为
Using=“
接受一个常量值,而你有一个变量在里面

为了使用
id
xpath
或其他内容中的变量执行此操作,您可以创建
By
IWebElement
类型的属性方法,具体取决于您以后需要执行的操作(尽管首选
By
,因为您可以在
WebDriverWait
中使用它作为参数): 对于由提供的

public By ContactBoxBy(string counter)
{
    get {return By.Id("btnAdd{0}_btnAddExpense" + counter);}
}
对于
IWebElement

public IWebElement ContactBox
{
    get {return driver.FindElement(By.Id("btnAdd{0}_btnAddExpense" + counter));}
}
ContactBox.SendKeys("text to be inserted");
这样,您就不再需要
[FindsBy]
属性

用法:

如果要在联系人框中输入文本,请执行以下操作:

driver.FindElement(ContactBoxBy(counter)).SendKeys("text to be inserted");
或者直接使用
IWebElement

public IWebElement ContactBox
{
    get {return driver.FindElement(By.Id("btnAdd{0}_btnAddExpense" + counter));}
}
ContactBox.SendKeys("text to be inserted");

我对页面对象模型和自动化脚本本身的概念非常陌生,因此对于这个基本问题我深表歉意。如何初始化FindsBy部分中的By ContactBoxBy?通过使用属性方法,您不再需要具有
[FindsBy]
属性。因此,当我使用属性方法时,为了使计数器递增,应该是这样的:public By ContactBoxBy(字符串计数器){counter=counter+1;get{return By.Id(“btnAdd{0}{btnAddExpense”+counter);}}对动态id使用计数器是一个非常糟糕的主意。如果您想使用
[FindsBy]
属性,那么可以更改为使用xpath来标识您的元素。对,尽管我想不出其他方法来处理我们正在使用的动态id。btnAdd{0}有btnAdd1、btdnAdd2等等,这就是我使用计数器的原因。