Элемент заполняется пока еще не загрузился

Добрый день. Есть такая проблема. Перехожу по ссылке, открывается страница с одним инпутом… И мне нужно его заполнить. По факту происходит так

homePage.header.rightNavBar.loginAsActivityDropdownLink.click();
loginAsPage.emailInput.shouldBe(Condition.Visible);
loginAsPage.emailInput.setValue(VALID_LOGIN);
loginAsPage.signInBtn.click();
loginAsPage.emailErrorMessage.shouldBe(Condition.visible);

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

Как это обойти?

Никакие задержку, вейты не помогают. Кроме ужасного Threed.sleep(3000). Посоветуйте что делать? Как правильно ждать?

Элементы такие. Простые и обычные

@FindBy(id = "Email")
    public SelenideElement emailInput;

@FindBy(id = "signInLoginAsFormButton")
    public SelenideElement signInBtn;

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

Нет конечно. Если в дебаге все работает, и с задержкой в пару секунд тоже(((

Страница не загрузилась или скрыта спиннером?
При 2-м варианте я видел имплементацию спиннера, который типа on top по z-index, но при этом элементы считываются как visible, поскольку z-index никак не влияет на visibility.
В этом случае могу порекомендовать сделать так:

  1. Ждём появления спиннера (до 0.5…1с, для стабильности на случай, если он появляется с задержкой).
  2. Если нашли - ждём исчезновения спиннера. Сильно зависит от имплементации, может быть как stale, так и not visible или какая ещё экзотика, надо смотреть на реальную имплементацию.
  3. Продолжаем тест.

Может, поможет поменять emailInput.shouldBe(visible) на emailInput.shouldBe(enabled)?

2 лайка

к сожалению это пробовала и не помогает.

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

Хм… Такого не бывает. Бывает так, что страница после загрузки выполняет ajax queries и не показывает инпуты до завершения выполнения запросов. Обычно грамотная имплементация предусматривает вышеуказанные спиннеры - это самый простой способ сделать контролы non-interactible, пока не выполнятся все запросы. Если их нет - может использоваться любой другой splash screen. Я бы рекомендовал 2 вещи:

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

Я, если честно, тоже такое впервые вижу.
Руками вроде все как обычно.
А скриншот при падении не даст результатов, потому что он тут не падает и заполняет поле, а на самом деле поле оказывается пустым((

Я советую обратить внимание на эти 3 секунды.
Сколько-то из них загружается и рендерится страничка, сколько-то явно идёт ожидание какого-то события (завершение ajax, …).
Очевидно, раз тест не падает с ошибкой “element not found” - значит, элемент есть.
Если текст не заполняется - значит, элемент non-interactible и надо понять причину.
Если Вы уверены, что нет никакого сплеш скрина, перекрывающего данный контрол - возможно, сам контрол не разрешает ввод в течение этих 3-х секунд. Проверьте стили и попытайтесь понять, чего именно ждать.
Могу предложить ещё 1 вариант, если лень искать, но это очень ugly :slight_smile:
Селениум разрешает custom waits.
Сделайте wait, который вводит значение в инпут, затем считывает значение из инпута и сравнивает с введенным. Если значения не совпадают - retry.