0

I'm trying to write an if statement for a collection but I've encountered with a problem. Just for instance, the following element has li tag that indicates whether the element is active:

<dl class="p-property-item">
<dt class="p-item-title" data-spm-anchor-id="42e07cb3WzvrLA">Color:</dt>
    <dd class="p-item-main">
        <ul id="j-sku-list-3" class="sku-attr-list util-clearfix" data-sku-prop-id="14" data-sku-show-type="none" data-isselect="true" data-spm-anchor-id="2114.10010108.1000016/B.i3.42e07cb3WzvrLA">
               <li class="active">
                    <a data-role="sku" data-sku-id="29" id="sku-2-29" href="javascript:void(0)" data-spm-anchor-id="2114.10010108">
                        <span data-spm-anchor-id="42e07cb3WzvrLA">White</span>
                    </a>
               </li>
        </ul>
                    <div data-role="msg-error" class="msg-error sku-msg-error" style="display: none;">
                        Please select a Color
                    </div>
    </dd>

I get all elements from a page and put it into collection:

@FindBy(how = How.CSS, using = "#j-product-info-sku > dl:nth-child(2) > dd > ul > li > a > span")
private ElementsCollection colorList;

public ElementsCollection getColor() { return colorList; }

But I have no idea how to get elements from the collection which have "active" li. I mean, how to get all active elements, is there any option to recognise them?

Note: All elements are visible so it's not relevant to filter by visible option.

I also used the java method that is mentioned here: Filtering an ElementsCollection

    public static Condition hasChildWithCondition(final By locator, final Condition condition) {
    return new Condition("hasChildWithCondition") {
        public boolean apply(WebElement element) {
            return element.findElements(locator).stream().
                    filter(child -> condition.apply(child)).count() > 0;
        }

        public String toString() {
            return this.name;
        }
    };
}



Condition hasChild = hasChildWithCondition(By.cssSelector("li"), Condition.text("active"));

if ((page.getColor().size() != 0) && (page.getColor().filterBy(hasChild))){
            //to do
        }

but in my case I get an error: Operator && cannot be applied to 'boolean','com.codeborne.selenide.ElementsCollection'

hamvee
  • 141
  • 3
  • 13

3 Answers3

1

Locator you use below return collection of span elements and you can't filter it with parent li element:

@FindBy(how = How.CSS, using = "#j-product-info-sku > dl:nth-child(2) > dd > ul > li > a > span")

You can get directly all active elements with .p-property-item li.active span css selector.
Also you can get collection of li elements using .p-property-item li selector, then filter it by active class and get color.

In your method below you trying to filter by text instead of class, use Condition.cssClass("active"):

Condition hasChild = hasChildWithCondition(By.cssSelector("li"), Condition.text("active"));

Your code should look like:

ElementsCollection colorList = $$(".p-property-item li");
String activeColor = colorList.filterBy(Condition.cssClass("active")).shouldHaveSize(1).$("span").text();

//or

ElementsCollection colorList = $$("#j-product-info-sku > dl:nth-child(2) > dd > ul > li");
ElementsCollection activeList = colorList.filterBy(Condition.cssClass("active"));
ElementsCollection disabledList = colorList.filterBy(Condition.cssClass("disabled"));
Sers
  • 12,047
  • 2
  • 12
  • 31
  • Hi @Sers! Thank you for directing me to the right track. But it turns out that there are several `li` implementations: **1)** `
  • ` the css selector collects both disabled and active elements `#j-product-info-sku > dl:nth-child(2) > dd > ul > li > a > span` **2)** `
  • ` selector collects only active elements `#j-product-info-sku > dl:nth-child(2) > dd > ul > li.active a span` **3)** `
  • ` selector collects only disabled elements `#j-product-info-sku > dl:nth-child(2) > dd > ul > li.disabled a span` – hamvee Sep 16 '18 at 14:45
  • But now I'm again at a dead end: The method can get active elements by using the second option, the questions are a) how to sort out collection of the first option in order to get only active elements? b) how can I use the third option? – hamvee Sep 16 '18 at 14:45
  • @TimurAibulatov example I gave you with filter by cssClass should bring to you only li elements with class active. Change your selector, remove `> a > span`. To get disabled just replace `active` class to `disabled` – Sers Sep 16 '18 at 14:50
  • Why not use separate 2) and 3) option selectors and not filter? – Sers Sep 16 '18 at 14:56