Finding Multiple Elements with PageObject modeling

Viewed 138

I have IWebElements defined like this:

[FindsBy(How = How.Id, Using = "actionHistoryBtn")]
private IWebElement actionHistoryButtons;

But the only way I have been able to find elements with the same Id is by doing this:

private ReadOnlyCollection<IWebElement> actionHistoryButtons => driver.FindElements(By.Id("actionHistoryBtn"));

Is there a way I can create a collection in the same format? Or how I can modify this to get all elements using "WhateverId" Or is the ReadOnlyCollection the only way to get all the elements?

1 Answers

To simply answer your question, ReadOnlyCollection<IWebElement>, a collection of elements, is what driver.FindElements() returns so that's the data type you need to use. You can't use IWebElement because that represents a single element, not a collection of elements like you are looking for.

Having said that... some advice.

Simon Stewart, the Selenium Project lead and creator of PageFactory, has said not to use PageFactory. Here's a keynote from a seleniumconf a few years ago where he states this.

Keynote - Selenium: State of the Union - Simon Stewart – Selenium Project & WebDriver
25:18 Don't use PageFactory

Besides the fact that Simon said not to use it, it's best not to have state in your page objects, e.g. don't grab elements and store them in properties. Instead grab them as you need them... that will reduce StaleElementExceptions and other issues.

Here's a real quick sample page object showing what I'm describing.

class SamplePage
{
    private readonly By _actionHistoryButtonsLocator = By.Id("actionHistoryBtn");

    public ReadOnlyCollection<IWebElement> GetActionHistoryButtons()
    {
        return Driver.FindElements(_actionHistoryButtonsLocator);
    }
}
Related