Marj Marj - 1 year ago 68
C# Question

How to initialize FindsBy in page factory when the Object IDs are dynamic

I have this code for my IDs:

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);

How do I declare this in my FindsBy? Apparently, this doesn't work:

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


Answer Source

You need to change the way you're identifying the elements from Id to Xpath.

[FindsBy(How = How.Xpath, Using = "your_xpath_here")] public IWebElement contactBox { get; set; }

And to give you a short explanation of why it's not working, it's because the Using="" is accepting a constant value and you have a variable inside.

In order to do it using a variable in your id, xpath or something else you could create a property method of type By or IWebElement depending on what you need to do afterwards (although a By is preferred because you can use it a parameter in your WebDriverWaits): For By;

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

For IWebElement:

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

This way you no longer need the [FindsBy] attribute.


If you want to enter text in your contact box you will do:

driver.FindElement(ContactBoxBy(counter)).SendKeys("text to be inserted");

or directly using the IWebElement:

ContactBox.SendKeys("text to be inserted");