t.me/atinfo_chat Telegram группа по автоматизации тестирования

selenoid cucumber selenide tests in parralel

Теги: #<Tag:0x00007fd76a5bcdd8> #<Tag:0x00007fd76a5bcd10> #<Tag:0x00007fd76a5bcc20> #<Tag:0x00007fd76a5bcb08> #<Tag:0x00007fd76a5bca18> #<Tag:0x00007fd76a5bc950>

Привет коллеги, проблема с запуском тестов в разных контейнерах на селеноид(при последовательном запуске все отрабатывает отлично)

фрагменты кода:
настройка параллельного запуска только в мавен:

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.2</version>
               <configuration>
                <parallel>methods</parallel>
                <useUnlimitedThreads>true</useUnlimitedThreads>
            </configuration>

Раннер клас - 1, там только настройка селеноида

//Configuration.timeout = 10000;
// Configuration.remote = “http://localhost:4444/wd/hub”;
//
// DesiredCapabilities capabilities = new DesiredCapabilities();
// capabilities.setBrowserName(“chrome”);
// capabilities.setVersion(“86.0”);
// capabilities.setCapability(“enableVNC”, true);
// capabilities.setCapability(“enableVideo”, true);
// capabilities.setCapability(“enableLog”, true);
// Configuration.browserCapabilities = capabilities;

открывается 3 контейнера при паралельном запуске(по 1 на фичу)
(1 тест всегда отрабатывают, остальные падают с ошибкой элемент нот фаунд)

так выглядит пейдж обжект:

@Getter
@Slf4j

public class MainPage extends AbstractPage {

@FindBy(xpath = "//span[text()='бла бла']")
private SelenideElement zadaniyaNaVidachu;

так выглядит абстракт пейдж:

public abstract class AbstractPage {
    public synchronized SelenideElement get(String nameOfElement) {
        Class<?> clazz = getClass();
        for (Field field : clazz.getDeclaredFields()) {
            if (field.getName().equals(nameOfElement)) {
                try {
                    field.setAccessible(true);
                    return (SelenideElement) field.get(this);
                } catch (IllegalAccessException e) {
                    log.error("no such element" + e);
                }
            }
        }
        throw new IllegalArgumentException();
    }

класс шагов:
public static Map<String, AbstractPage> pages = new HashMap<>();

@Пусть("^была открыта страница \"([^\"]*)\"$")
    public void openPage(String url) {
      open(url);
        getWebDriver().manage().window().maximize();
        //preload all pages
        pages.put("MainPage", page(MainPage.class));
      
    }

пример шага нажатия на кнопку

@И("пользователь сделал клик на {string} на странице {string}")
    public void пользовательСделалКликНаНаСтранице(String elementName, String page) {
        AbstractPage abstractPage = pages.get(page);
        if (abstractPage != null) {
            abstractPage.get(elementName).waitUntil(Condition.exist, 60000);
            abstractPage.get(elementName).waitUntil(Condition.visible, 60000);
            abstractPage.get(elementName).click();
        } else {
            log.error("no such page " + page);
        }
    }

вывод при паралельном запуске:
[INFO]
[INFO] Results:
[INFO]
[ERROR] Failures:
[ERROR] Element not found {By.xpath: //label[contains(@data-testid, ‘Label’)][text() = ‘Статус обработки’]/…/following-sibling::div}
Expected: exist
Timeout: 60 s.
Caused by: NoSuchElementException: no such element: Unable to locate element: {“method”:“xpath”,“selector”:"//label[contains(@data-testid, ‘Label’)][text() = ‘Статус обработки’]/…/following-sibling::div"}
[ERROR] Errors:
[ERROR] null
[INFO]
[ERROR] Tests run: 3, Failures: 1, Errors: 1, Skipped: 0

я подозреваю что либо как-то не так работает веб драйвер, может не натравлен куда надо, или создался не так(хотя это же селениде там все само создается нет?)
либо какой-то кусок кода в многопоточности этой не работает

Покажите реализацию pages.put
И пока не поздно, избавьтесь от этого не нужного кода вообще. Вот как реализовать страницы: https://ru.selenide.org/documentation/page-objects.html

это хэш мапа обычная

public static Map<String, AbstractPage> pages = new HashMap<>();

Ну тогда в ней надо ещё и драйвер хранить. Для каждой пейджи.
Не городите огород. Селенид хранит драйвер. А вы его функционал хотите перебороть.
Я привёл пример реализации пейджобжекта.

Я вижу такую проблему - как человек не участвующий в разработке вашего фреймворка узнает весь список доступных страниц? Тогда надо где-то хранить список “page”, актуализировать его всегда.
А если у него будет сразу список страниц под рукой - он сразу сможет вызывать методы из них. И у вас получается, страницы могут хранить только элементы, это не очень удобно.

ну вопрос же не об удобстве, а именно о запуске в паралели,
по ссылке упоминается что вариант с @findby тоже уместен, согласен не лучшая реализация,
но разве именно она влияет на то что элементы не находятся?
получается из-за нее как-то драйвер не так создается?
я вот в этом моменте не оч понял

p.s. вроде он даже тред локал драйвер
private static final SelenideDriver staticSelenideDriver = new ThreadLocalSelenideDriver();

может в моем случае мапа с пейджами тоже должна быть тред локал?

А, так она у вас статик же, конечно.
Опять же это ещё раз показывает что вы городите огород, который не нужен.