Взять из коллекции элемент отфильтровав по вложенному элементу, и многократно использовать не фильтруя заново а беря тот же элемент.

Нужно взять из колекции элемент пропущенный через фильтр и выбранный рандомно.

Фильтр это кастомное условие Condition из примеров селенида child("xpath", Condition.attributeMatching("attr", "regex"))

Далее через этот элемент ищутся и выполняются разные действия, в том числе происходит изменение вложенного элемента по которому был отфильтрован нужный верхний элемент, и получается так что при каждом обращении к элементу он каждый раз применяет фильтр, и берет следующий элемент от текущего отфильтрованного если иконка Red сменилась на Blue.

<div>
    <a iconRed><\a>
</div>
<div>
    <a iconRed><\a>
</div>
<div>
    <a iconBlue><\a>
</div>
<div>
    <a iconRed><\a>
</div>

Например нашли все div с иконкой Red рандомно выбрали div 2 иконка Red, сделали клик, иконка стала Blue, при следующем обращении к переменной которой был присвоен элемент div 2 выбирается следующий div 4 с иконкой Red Если элемент div был последний то out of bound exception.

В моем представлении если я присваиваю переменной конкретный div из коллекции то он так и должен остаться ссылкой на этот div без применения фильтра. Фильтр это только условие по которому я его выбрал.

ElementCollection ec = $$x(".//div")
    .filter(child("./a", attributeMatching("attr", "Red$")));
SelenideElement se = ec.get(random());

Как понять что происходит и как исправить?

Единственное на данный момент решение прогнать коллекцию элементов или через стрим(старый) с стрим фильтром или прогнать отфитрованную коллекцию через стрим asFixedIterable собрать их в лист и рандомно выбрать.

Не так. В селениде все элементы каждый раз перезапрашивают элемент из браузера (на тот случай, если что-то изменилось, элементы перерисовались, DOM обновился и т.д.).

Зафиксировать элемент можно с помощью метода toWebElement().

WebElement fixedWebElement = $.toWebElement();

Если очень захочется использовать у него селенидовские методы, можно завернуть его в доллар:
SelenideElement fixedSelenideElement = $(fixedWebElement);

1 лайк

Да про это читал, знаю, но ведь я беру элемент выше, пускай он и перезапрашивается, как то слегка не ожидано что взяв элемент выше пускай и отфильтровав его, его фильтр сохраняется, ладно бы мой локатор указывал прямо на конечную точку или от нее отталкивался.

Про то как зафиксировать элемент с возвратом обратно в качестве SelenideElement не знал, спасибо!

Наверное на этом вопрос исчерпан, но почему так? Разве моё представление не логичное?

Каждый вариант по-своему логичный. В определённом контексте твой логичный. В другом контексте другой подход кажется логичным.
А вообще изначально это получилось случайно. Перепоиск сделали, чтобы бороться с флейки тестами, а потом оказалось, что люди заюзали эту возможность в хвост и в гриву. Например, люди любят объявлять SelenideElement как статическое поле в классе, и они рассчитывают, что он будет каждый раз искаться заново. Теперь это поведение уже фиг поменяешь. :slight_smile:

1 лайк