Hristo.L
Hristo.L

Reputation: 75

WebDriver: FindsBy random select

I read some posts about random select in WebDriver, but was unable to make it work for me. I need to select random option from drop down menu. The html code of the menu (the one that I posted) is visible in the console only when the drop down is clicked and the options are visible in the page. I'm giving you the code that I use in C# also. If you need any additional information feеl free to ask.

This is the html

<input class="form-control ui-select-search ng-pristine ng-valid ng-touched" autocomplete="off" tabindex="-1" aria-expanded="true" aria-label="Select box" aria-owns="ui-select-choices-9" aria-activedescendant="ui-select-choices-row-9-2" placeholder="Select material" ng-model="$select.search" ng-show="$select.searchEnabled && $select.open" type="text">
<ul class="ui-select-choices ui-select-choices-content dropdown-menu" role="listbox" ng-show="$select.items.length > 0" repeat="material in materialsForTransfer | array | propsFilter: {material_name: $select.search}">
    <li id="ui-select-choices-9" class="ui-select-choices-group">
        <div class="divider ng-hide" ng-show="$select.isGrouped && $index > 0"></div>
        <div class="ui-select-choices-group-label dropdown-header ng-hide" ng-show="$select.isGrouped" ng-bind="$group.name"></div>
        <div id="ui-select-choices-row-9-0" class="ui-select-choices-row" ng-class="{active: $select.isActive(this), disabled: $select.isDisabled(this)}" role="option" ng-repeat="material in $select.items" ng-if="$select.open" ng-mouseenter="$select.setActiveItem(material)" ng-click="$select.select(material,false,$event)">
            <a class="ui-select-choices-row-inner" href="javascript:void(0)" uis-transclude-append="">
                <div ng-bind-html="material.material_name | highlight: $select.search">LG Monitor</div>
            </a>
        </div>
        <div id="ui-select-choices-row-9-1" class="ui-select-choices-row active" ng-class="{active: $select.isActive(this), disabled: $select.isDisabled(this)}" role="option" ng-repeat="material in $select.items" ng-if="$select.open" ng-mouseenter="$select.setActiveItem(material)" ng-click="$select.select(material,false,$event)">
            <a class="ui-select-choices-row-inner" href="javascript:void(0)" uis-transclude-append="">
                <div ng-bind-html="material.material_name | highlight: $select.search">DELL Monitor</div>
            </a>
        </div>
        <div id="ui-select-choices-row-9-2" class="ui-select-choices-row" ng-class="{active: $select.isActive(this), disabled: $select.isDisabled(this)}" role="option" ng-repeat="material in $select.items" ng-if="$select.open" ng-mouseenter="$select.setActiveItem(material)" ng-click="$select.select(material,false,$event)">
            <a class="ui-select-choices-row-inner" href="javascript:void(0)" uis-transclude-append="">
                <div ng-bind-html="material.material_name | highlight: $select.search">CPU i5</div>
            </a>
        </div>
        <div id="ui-select-choices-row-9-3" class="ui-select-choices-row" ng-class="{active: $select.isActive(this), disabled: $select.isDisabled(this)}" role="option" ng-repeat="material in $select.items" ng-if="$select.open" ng-mouseenter="$select.setActiveItem(material)" ng-click="$select.select(material,false,$event)">
            <a class="ui-select-choices-row-inner" href="javascript:void(0)" uis-transclude-append="">
                <div ng-bind-html="material.material_name | highlight: $select.search">HDD 1TB</div>
            </a>
        </div>
    </li>
</ul>

And my code in C#

public class OrderTransferPage
{
    [FindsBy(How = How.CssSelector, Using = "span[ng-    click='$select.activate()']")][CacheLookup]
    private IWebElement ClickOnNameOfProductMaterial { get; set; }
    [FindsBy(How = How.CssSelector, Using = "div[ng-bind-html='material.material_name']")][CacheLookup]
    private IList<IWebElement> NameOfProductMaterial { get; set; }
}
public void OpenOT()
{
     ClickOnNameOfProductMaterial.ClickOnIt("Select Material", 15); //When I click on this element the drop down is generated.
     Data.RandomElement(NameOfProductMaterial).ClickOnIt("Selecting random element");
}

public static IWebElement RandomElement (this IList<IWebElement> element)
{
    Random rnd = new Random(); 
    int randomValue = rnd.Next(element.Count);
    IWebElement OurElement = element[randomValue];
    return OurElement;
}

Upvotes: 0

Views: 1060

Answers (2)

Hristo.L
Hristo.L

Reputation: 75

I managed to make it work and I'm posting the solution so anyone can use it if needed. All elements from the drop down had with same "ng-bind-html" and only different link text. So with the down code I made a list of all the elements in the drop down.

`[FindsBy(How = How.CssSelector, Using = "div[ng-bind-html='material.material_number | highlight: $select.search']")][CacheLookup]
 private IList<IWebElement> NameOfProductMaterial { get; set; }`

As you can see from the HTML at the begging I'm selecting the most nested element.

`Element_Extensions.RandomElement(NameOfProductMaterial).ClickOnIt("Select Material");`

Accessing the method that is making the random select.

`public static IWebElement RandomElement(this IList<IWebElement> element)
    {
        Random rnd = new Random();
        int randomValue = rnd.Next(1, (element.Count)-1);
        IWebElement OurElement = element[randomValue];
        Console.WriteLine(OurElement.Text + " is selected material");
        return OurElement;
    }`

The problem from the begging was the wrong element selection in the FindsBy row.

P.S. I hope that this information will be helpful to anyone. And JeffC thank you for your time and help. You made me think and discover the mistake.

Upvotes: 0

JeffC
JeffC

Reputation: 25611

You stated you are working with a dropdown. I'm making the assumption that the dropdown is an actual HTML SELECT element. If that's not true, then this code will not work. Let me know and I can adapt it.

I would take advantage of the SelectElement class. It makes working with SELECTs a LOT easier. I would do something like the below.

NOTE: I made a few changes to your function. This function doesn't return anything, it takes in a SelectElement, generates a random number (as yours does), and then selects the OPTION that corresponds to that random index.

static void SelectRandomElement(SelectElement select)
{
    Random rnd = new Random();
    int index = rnd.Next(select.Options.Count);
    select.SelectByIndex(index);
}

To use this, you would do something like

RandomElement(new SelectElement(selectElement));

Upvotes: 3

Related Questions