NoSuchElementException не отлавливается блоком try catch

Как отлавливать исключения Селениума? Таким способом не работает:

public void createSpace() {
    browseButton.click();
    createSpaceButton.click();
    try {
      selectTemplateButton.doubleClick();
      spaceName.setValue(SPACE_NAME);
    } catch (NoSuchElementException exception) {
      selectTemplateButton.doubleClick();
      spaceName.setValue(SPACE_NAME);
    }
    spaceKey.setValue(SPACE_KEY).pressEnter();
    try {
      $(byText("Welcome to your new space!")).waitUntil(exist, MEDIUM_WAIT);
    } catch (NoSuchElementException exception) {
      spaceKey.pressEnter();
      $(byText("Welcome to your new space!")).waitUntil(exist, MEDIUM_WAIT);
    }
  }

В логе Caused by: NoSuchElementException. И визуально видно, что код в блоке catch не работает.

Отлавливать исключения селениума в большинстве случаев плохая практика. В селениде есть методы для проверки элементов $().isDisplayed() и $().exists(). Используйте их.

Ну начнем с того, что если вы ловите NoSuchElementException в catch блоке - может быть, ваш catch блок и не должен работать. С чего бы ему делать нужное действие, если элемент так и не нашелся в первый раз?

Смотри:

  • в try ты ищешь что-то, оно не находится, выбрасывает исключение
  • в catch ты ловишь это исключение, повторяешь все в точности то же самое (и опять ловишь то же самое исключение) прям сразу же.

Почему так может случаться:

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

Как только элемент стал находиться - убираешь явную паузу и переписываешь на implicit или explicit ожидание этого элемента (чтобы тест отрабатывал быстрее).
Если элемент так и не стал находиться - опять проверяешь, правильный ли ты придумал локатор и пересматриваешь свое условие для взаимодействия: чаще всего, чтобы click() проходил, для explicit ожидания используется условие EC.element_to_be_clickable или EC.visibility_of_element_located (в Python).

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

P.S.:
название топика не корректно, NoSuchElementException прекрасно отлавливается блоком try\catch, просто в самом блоке catch у тебя повторно поднимается это исключение. И его обработать уже некому :slight_smile:

2 лайка

Ваше подробное объяснение ушло мимо ворот.

Selenide вызывает следующее исключение, внутри которого ваш NoSuchElement, так что отлавливаете parent exception и будет вам счастье -
http://selenide.org/javadoc/4.2/com/codeborne/selenide/ex/UIAssertionError.html

3 лайка

Если уж Вы используете Selenide, так и используйте его везде. Странно как-то, сначала у Вас чистый Selenium, ниже уже Selenide.

Вы ловите исключение, а потом в catch блоке делаете те же действия. Какой в этом смысл? Почитайте спеку WebDriver, поучите Java. Больше тут ничего не посоветуешь.

Спасибо! Оказалось я пытался отловить Селениум ошибку в Селениде и оно его не видело (вот и не исполняло код в catch), а надо отлавливать именно Селенид (просто не знал про отдельные exeptions Селенида)