«Элементарный» Вор или плата за использование Selenide

Однажды, в одном из супермаркетов, при оплате пластиковой картой, у меня произошло двойное списание, и, позвонив в один, всем известный банк, я узнал, что у них произошел какой-то сбой, и проблема массовая, но на вопрос когда же все-таки мне вернут мои деньги, я услышал:
Деньги вы держите в нашем банке, так? - Так. А значит они не ваши, а наши. Вот когда захотим, тогда и вернем! *короткие гудки*
Не сказать, что я был удивлен подобным ответом, да и деньги конечно по итогу вернули, но случай был необычный.
Так вот в данной мини-статье я, ничего не подозревая, как и в случае двойного списания средств, описанного абзацем выше, сидел себе писал код тестов на Java, используя Selenide, и вдруг, заметил самую настоящую «магию»!
Немного мнения о Selenid'е
Многие знают, что это широко известный в узких (QA) кругах, базирующийся на более известном, в более широких кругах, инструмент для автоматизации тестирования UI, в частности, WEB-тестирования. Не буду углубляться в холиварное «Selenium vs Selenide», но стоит отметить, что Selenide сделан на базе Selenium, так же в его библиотеках доступны «селенеумовские» методы и классы. Но любовь пользователей он имхо заслужил за более краткий синтаксис а-ля: $$(elementsXPath),
$$(elementsSelector)
и т п; за отсутствие необходимости настройки и конфигурирования (в частности указания пути к исполняемому файлу WebDriver.exe) - хотя кое-какое конфигурирование все равно присутствует в селениде; возможность обходиться безsleeps
и waits
на каждом углу; удобная работа с приложениями с Ajax-вызовами; и наверное есть еще какая-то вкусовщина в пользу селенида, но думаю, она незначительна. Мне на самом деле не принципиален выбор между двумя этими инструментами, но вот «магия» описанная ниже, немного пошатнула мое доверие к селениду...
Итак, от слов к делу. Нам понадобится:
IDE (например Intelij Idea, версия думаю не принципиальна уж сами понимаете)
Gradle (или любой другой сборщик для Java)
Selenide (
'com.codeborne:selenide:6.12.3' //последняя на момент написания статьи
)Java 8 (думаю тоже не принципиально, но тестировал на восьмой)
Ниже приведен самый банальный код:
public class Main {
public static void main(String[] args) {
//создаем список элементов «сграбленных» с таблицы сайта:
List<SelenideElement> items = $$x(tableItemsPath);//допустим их там 50 шт.
//создаем лист ал-ля взять первые, пусть например 3, элемента:
List<SelenideElement> actualList = items.subList(0, 3);
//создаем «буферный» лист для эксперимета:
List<SelenideElement> expectedList = new ArrayList<>();
/*циклом итерируемся по actualList, добавляя в наш буфер actualList
элемент на каждой итерации: */
for (SelenideElement elem : actualList) {
expectedList.add(elem);
}
//и тут, казалось бы проитерировались...
//записали все элементы в новый список...
//и оба списка должны содержать одинаковое кол-во элементов...
//Но! Как бы ни так!
System.out.println("expected list size: " + expectedList.size());
System.out.println("actual list size: " + actualList.size());
System.out.println("expected list: " + expectedList);
System.out.println("actual list: " + actualList);
}
}
Ну и собственно вывод консоли:
Можем проверить на наличие null
в списке:
//так:
items.subList(0, 3).forEach(e -> {
assert e != null;
});
//или так:
assert !items.subList(0, 3).contains(null);
А вот и разгадка:
AtomicInteger x = new AtomicInteger();
items.subList(0, 3).forEach(e -> {
x.addAndGet(1);
});
System.out.println("it's about magic: " + x); //it's about magic: 2
Виновник этого «волшебства» кроется в методе .subList();
поскольку «селенидовский» лист, возвращаемый функцией $$x
, хоть и имплементирует java.util.List
, видимо имеет кривые методы под капотом, благодаря которым, при итерировании по коллекции совершаем на 1 итерацию меньше.
Вообще говоря это мой первый опыт с Selenide, до этого я пользовался Selenium. Код выше, естественно для примера. И с описанной проблемой, я столкнулся, написав уже не один с десяток файлов кода в проекте. А сами знаете кто, сами знаете в чём кроется. Но вот, что бы этого кого-то найти, пришлось постараться. Признаюсь честно. Горело пока искал.
P.S. За сим прощаюсь, до скорого!