Selenium (Java) Правильное использование явного ожидания с PageFactory - PullRequest
0 голосов
/ 01 апреля 2020

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

В документах всегда отображается идентификация нового элемента, а затем назначение определенного ожидания указанному элементу

WebDriver driver = new ChromeDriver();
driver.get("https://google.com/ncr");
driver.findElement(By.name("q")).sendKeys("cheese" + Keys.ENTER);
// Initialize and wait till element(link) became clickable - timeout in 10 seconds
WebElement firstResult = new WebDriverWait(driver, Duration.ofSeconds(10))
        .until(ExpectedConditions.elementToBeClickable(By.xpath("//a/h3")));
// Print the first result
System.out.println(firstResult.getText());

В этом примере сначала создается новый элемент firstResult, затем ему назначается определенное ожидание.

Требуется ли это? Всегда следует делать таким образом?

Вот почему я спрашиваю.

Я использую модель PageFactory, и мои элементы определены с помощью аннотации FindBy, как показано здесь.

// Input field for slice ID
@FindBy(how = How.XPATH, using = "//input[@name='id']")
private WebElement inputSliceId;

Затем в том же классе я определил несколько удобных методов для их использования.

Так что теперь, в моих удобных методах, я должен делать такие вещи?

inputSliceId = new WebDriverWait(driver, Duration.ofSeconds(10))... 
inputSliceId.sendKeys(...

То, что я делал, и сейчас я спрашиваю, это помещает операторы ожидания, которые не присваиваются непосредственно рассматриваемому элементу.

Например, я делал что-то вот так.

buttonSubmit.click();
WebDriverWait wait = new WebDriverWait(driver, 5);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[@role='alertdialog']")));
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//div[@role='alertdialog']")));

Почему? (может быть совершенно не прав)

После нажатия кнопки мне нужно дождаться появления всплывающего окна. Как только это произойдет, я жду, пока оно исчезнет, ​​прежде чем продолжить

Вот главный вопрос Эти две строки ожидания ничего не делают, потому что я не назначаю их элементу? Или они все еще заставляют веб-драйвер удерживаться до тех пор, пока не возникнут условия, определенные ожиданием?

Ответы [ 3 ]

1 голос
/ 02 апреля 2020

Есть несколько вещей:

  • Если ваш вариант использования должен вызывать getText() для элемента, вместо elementToBeClickable(), использование visibilityOfElementLocated() будет просто идеально.
  • Чтобы извлечь текст, вам не нужно создавать новый элемент, вместо этого вы можете напрямую вызвать visibilityOfElementLocated(), как только элемент будет возвращен следующим образом:

    System.out.println(new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//a/h3"))).getText());
    
  • Если в вашем сценарии использования отсутствует проверка для всплывающего окна 1019 *, которое отображается и исчезает, вам не нужно вызывать официанта и безопасно игнорировать его. Поэтому, когда вы вызываете click() на buttonSubmit, вы можете перейти к следующей точке проверки, настроив временной интервал для всплывающего окна , которое будет отображаться и исчезать.

  • Итак, ваш оптимизированный блок кода будет:

    buttonSubmit.click();
    // consider the total timespan for the wait to be cumulative of: pop-up displayed + pop-up disappear + next interactable element to become clickable
    new WebDriverWait(driver, Duration.ofSeconds(20)).until(ExpectedConditions.elementToBeClickable(By.xpath("xpath_next_element_to_click")));
    

Соответствующее подробное обсуждение можно найти в Как добавить явное ожидание в PageFactory в PageObjectModel?

1 голос
/ 01 апреля 2020

Нет, вы не можете назначить оператор ожидания, как указано выше, вашему веб-элементу. Если вы хотите подождать, пока ваш элемент использует модель фабрики страниц для элемента ниже, вам нужно создать

publi c void isLoaded () throws Error {// Первоначальная загрузка, вызываемая при создании объекта страницы для убедитесь, что страница загружена в состояние, в котором она готова взаимодействовать с нами, в нашем случае это означает, что кнопка присутствует в DOM и видна.

public class BaseClass
{
     private void waitForVisibility(WebElement element) throws Error{
               new WebDriverWait(driver, 60)
                    .until(ExpectedConditions.visibilityOf(element));
        }
}

А затем в классе объектной модели вашей страницы Вы можете расширить этот BaseClass .

public class page extends BaseClass

{
    @FindBy(how = How.XPATH, using = "//input[@name='id']")
    private WebElement inputSliceId;

    waitForVisibility(inputSliceId);

}

Я определил ожидание в BaseClass для достижения повторного использования кода waitForVisibility для всех классов объектов страницы.

Также после нажатия кнопки, если вы хотите дождаться появления всплывающего окна, вы можете добавить код, подобный приведенному ниже:

    @FindBy(xpath = "//div[@role='alertdialog']")
    private WebElementFacade alertPopup;

    buttonSubmit.click();
    waitForVisibility(alertPopup);
0 голосов
/ 02 апреля 2020

Во-первых, вы можете объявить метод, в котором настраивается само ожидание, в отдельном классе, таком как base или parent, например:

protected void waitForElementToBeLoaded(WebElement element) {
 wait.until(ExpectedConditions.elementToBeClickable(element));
}

Затем вы можете объявить второй метод, в котором используется первый, в отдельном классе, который используется как вымышленная страница, например:

public void sendMessageForm( ){
    waitForElementToBeLoaded(sendBtn);
    sendBtn.click();
}

Наконец, каждый раз, когда вы используете предыдущий метод, будет запускаться ожидание, например:

contactUsPage.sendMessageForm();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...