Marj Marj - 3 months ago 9
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; }

Thanks!

Answer

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.

Usage:

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