Как проверить правильность всех элементов PageObject (Java, Serenity, Cucumber)

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

Веб-сайт, над которым я работаю, не имеет согласованных тегов id, и использование @FindBy() иногда требует некоторой игры. Я пытаюсь сделать простой процесс:

  1. Перейдите к URL-адресу PageObject
  2. проверьте, доступны ли все элементы в PageObject с помощью селена

Знаете ли вы способ получить доступ ко всем элементам PageObjects, не создавая метод для каждого из них? Метод, который инициализирует все элементы?


person Alex    schedule 24.04.2019    source источник
comment
Объект страницы, использующий фабрику страниц, не проверяет существование элемента, пока вы не попытаетесь получить к нему доступ. Это по дизайну. Метод initElements инициализирует все определенные элементы в классе значением null. Если вместо этого он попытается получить доступ ко всем определенным элементам, многие классы потерпят неудачу, поскольку обычно определяют все потенциальные элементы, даже если они еще не находятся в DOM, но будут позже. Здесь нет ярлыка, кроме написания методов обработчика-оболочки для выполнения явных ожиданий и обработки исключений.   -  person Bill Hileman    schedule 24.04.2019
comment
Я не знаю, легче ли это, чем просто метод, который их инициализирует, но вы можете внедрить концепцию самотестирования в свой объект базовой страницы, что позволит вам регистрировать элементы по мере их создания, возможно, с типом элемента (например, ссылка, раскрывающийся список, ввод). Когда вы вызываете myPage.selfTest(), он перебирает все зарегистрированные элементы и проверяет их в соответствии с их типом (или просто проверяет, отображаются ли они).   -  person Nathaniel C    schedule 24.04.2019
comment
После нескольких попыток я могу использовать отражение, чтобы получить все поля класса, а затем проверить, является ли каждое из них присутствующим(). Поскольку переменные WebElementFacade являются закрытыми, я должен поместить этот метод внутри класса, а это значит, что мне нужно поместить этот метод в каждый класс, и есть предложения по обходу этого?   -  person Alex    schedule 24.04.2019
comment
Как побочный момент, вы можете рассмотреть возможность использования isDisplayed(), поскольку isPresent() только проверяет, находится ли элемент в DOM (видимый или нет), и не гарантирует, что с элементом можно взаимодействовать.   -  person Nathaniel C    schedule 24.04.2019
comment
@NathanielC, я согласен, в моем конкретном случае есть элементы, которые скрыты в модальном окне или отображаются только после события на странице, и в этом случае метод .isDisplayed() для этих случаев не сработает.   -  person Alex    schedule 26.04.2019


Ответы (1)


Попробовав несколько разных способов, я использовал отражение внутри класса, чтобы получить все поля, а затем использовал .isPresent();, чтобы проверить, находится ли элемент на странице. Это решение требует, чтобы этот метод был помещен в каждый класс, который вы хотите протестировать, чего я пытался избежать.

Решение:

SuiteRunner

@RunWith(CucumberWithSerenity.class)
@CucumberOptions(features = "src/test/resources/features/checkElems")
public class RegressionTestSuite {}

Файл функций: CanFindElems.feature

Feature: Check if WebPage Object elements can be found

  Scenario: Check if the page's elements are reachable
    Given navigate to webpage
    Then check page elements

Тестовый класс

public class CanFindElemsTest {

  // Change the class
  ClassYouAreTesting page;

  @Given("^navigate to webpage$")
  public void navigate_to_webpage() throws Exception {

    page.open();
  }


  @Then("^check page elements$")
  public void check_page_elements() throws Exception {

    page.checkPageElementsExist();
  }
}

Класс страницы

public class SomeWebPage extends PageObject {

  @FindBy(id = "someID")
  private WebElementFacade someElement;

  @FindBy(linkText = "some text")
  private WebElementFacade someLink;

  @FindBy(className = "some-class")
  private WebElementFacade anotherElement;


  public void checkPageElementsExist() throws Exception {

    Field[] allFields = getClass().getDeclaredFields();
    for (Field field : allFields) {

      if (field.get(this) instanceof WebElementFacade) {

        WebElementFacade f = (WebElementFacade) field.get(this);

        if (!f.isPresent()) {

          System.out.println("ElementNotFound: " + field.getName());
        } else {

          System.out.println("Found: " + field.getName());
        }
      }
    }
  }

}
person Alex    schedule 24.04.2019
comment
По крайней мере, вы можете переместить checkPageElementsExist в базовый класс и заставить его принимать массив элементов в качестве аргумента. Вам все равно придется обернуть его в дочерние объекты страницы, но это будет однострочный вызов, который вызывает родительский метод и передает элементы, вместо того, чтобы дублировать весь метод для каждого объекта страницы. Это похоже на проблему, которая имеет еще более умное решение... - person Nathaniel C; 24.04.2019
comment
Когда я попробовал это. Я не мог получить доступ к переменным, потому что они закрыты. - person Alex; 10.05.2019