Blink Blink - 4 days ago 5
C# Question

Is there a way to limit the size of an element list in a Page Object?

I am working on an automated test and I am able to get a list of elements that I need on a page using the following:

using System.Collections.Generic;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.PageObjects;

namespace iOSAutomation.PageObjects
{
public class CCLMenu
{
private IWebDriver driver;

// Menu element buttons
[FindsBy(How = How.Id, Using = "btn_MenuElement")]
public IList<IWebElement> menuElement_buttons;


// Constructor
public CCLMenu(IWebDriver driver)
{
this.driver = driver;
PageFactory.InitElements(driver, this);
}
}
}


This gets a list of 166 elements though and takes a while to find them all and select one from the list to click. Here is a sample of the test:

[TestMethod]
public void SelectCCLOptions()
{
//...

// THIS CURRENTLY GETS A LIST OF 166 ELEMENTS; TODO - Find a way to limit list size
Debug.WriteLine("Array count: " + cclMenu.menuElement_buttons.Count);
Assert.IsTrue(isElementPresent(driver, cclMenu.menuElement_buttons.ElementAt(1), 60), "Unable to find country menu element button on " + cclMenu.ToString());
cclMenu.menuElement_buttons.ElementAt(1).Click();

//...
}


I am wondering if there is a way to limit the size of the list initialized in the Page Object because I only need about 30 of those elements and it would significantly speed up the test. I have tried initializing the list with the
new
keyword directly in the Page Object constructor with a specific capacity before calling
PageFactory.InitElements(...)
but it seems that a new list is instantiated each time the driver looks for the elements so this has no affect.

Any suggestions or is this even possible?

Edit: This is for an iOS phone application and we eventually want to be able to select a language at random at the beginning of our test run.

Answer

It seems like you're only interested in the second element. I suggest creating the following property:

public IWebElement CountryMenu {
    get {
        return driver.FindElement(By.CssSelector(".btn_MenuElement:nth-of-type(1)"));
    }
}

":nth-of-type" is a css selector to get an element in a collection by its index.

Alternatively, you could create a method to retrieve an item by its index:

public IWebElement GetMenu(int index) {
    return driver.FindElement(By.CssSelector(
        string.Format(".btn_MenuElement:nth-of-type({0})", index)
    ));
}

*note: I used class instead of id because it doesn't make sense to have multiple elements with the same id.

Comments