Получение того же элемента, даже если элемент не существует в DOM с использованием Page Object Model

Конфигурация:

Селен: 2.53.1

Ява: 7

Eclipse IDE: Марс

Я использую POM Framework и шаблон проектирования PageFactory для этого. У меня есть ниже код домашней страницы:

public class RCONHomePage 
{
    @FindBy(css =".ng-scope>a span[translate='login.register']")
    public WebElement loginLink;

    @FindBy(xpath ="//a//span[text()='DASHBOARD']")
    public List<WebElement> dashboardLink;

    @FindBy(name = "number")
    public WebElement globalSearchMobileNumbertextBox;

    @FindBy(xpath = "//button[@class='btn rc-bg-border']")
    public WebElement globalSearchButton;

    @FindBy(css = "p.page-title.ng-scope >span")
    public WebElement globalSearchResult;


    WebDriver driver;

    public RCONHomePage(WebDriver driver)
    {

        PageFactory.initElements(new AjaxElementLocatorFactory(driver, 30), this);
        this.driver=driver;
    }

    public void clickOnLoginLink()
    {
        loginLink.click();
    }

    public void enterMobileNumberForGlobalSearch(String mobileNumber)   
    {
        globalSearchMobileNumbertextBox.clear();
        globalSearchMobileNumbertextBox.sendKeys(mobileNumber);
    }

    public void clickGlobalSearchButton()
    {
        globalSearchButton.click();
    }

    public String getGlobalSearchResult()
    {

        System.out.println(globalSearchResult.getText());
        return globalSearchResult.getText();

    }
}

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

Проблема в том, что мой тест показывает правильный результат, если номер мобильного телефона недействителен (показывает "запись не найдена"), но если я ввожу правильный номер мобильного телефона и проверим текст, он все еще показывает "запись не найдена". если я вручную найду этот текст для действительного числа. Элемент недоступен в DOM.

Это метод испытаний для сценариев:

@Test
public void searchForNonExistContact() throws InterruptedException, IOException
{
        homepage = new RCONHomePage(driver);

        homepage.enterMobileNumberForGlobalSearch("9422307800");
        homepage.clickGlobalSearchButton();
        System.out.println(homepage.globalSearchResult.getText());
    }

}

@Test
public void searchForExistContact() throws InterruptedException, IOException
{
        homepage = new RCONHomePage(driver);

        homepage.enterMobileNumberForGlobalSearch("9422307801");
        homepage.clickGlobalSearchButton();
        System.out.println(homepage.globalSearchResult.getText());
    }

}

Насколько я знаю, это должно произойти, если я использую @CacheLookup для этого элемента. Я не знаю, почему это происходит. Кто-нибудь может мне помочь?

1 ответ

Я думаю, что код выглядит хорошо, и проблема может выглядеть так: "тест не пройден во время выполнения, но не во время отладки". В моем случае я бы сделал еще несколько шагов, чтобы выяснить, что должно произойти:

  1. Правильный текст может отображаться "после задержки", или "запись не найдена" является сообщением по умолчанию, и для "записи найдена" требуется время. В этом случае я буду неявно ждать в течение некоторой секунды и снова запускать скрипт.
  2. Вместо распечатки текста я бы назвал findEment с ожидаемым текстом. Делая это, система будет ждать до истечения времени ожидания, чтобы получить элемент.

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

В моем случае я использовал следующую функцию для ожидания теста:

 /***
 * An expectation for checking WebElement with given locator has text with a value as a part of it
 * @param locator - used to find the element
 * @param pattern - used as expected text matcher pattern
 * @param timeout
 * @return Boolean true when element has text value containing @value
 */
public boolean textMatches(By locator, Pattern pattern, int timeout) {
    try {
        return getWebDriverFluentWait(timeout)
                .until(ExpectedConditions.textMatches(locator, pattern));
    } catch (Exception e) {
        return false;
    }
}

/***
 * An expectation for checking WebElement with given locator has specific text
 * @param locator - used to find the element
 * @param value - used as expected text
 * @param timeout
 * @return Boolean true when element has text value equal to @value
 */
public boolean textToBe(By locator, String value, int timeout) {
    try {
        return getWebDriverFluentWait(timeout)
                .until(ExpectedConditions.textToBe(locator, value));
    } catch (Exception e) {
        return false;
    }
}

/***
 * An expectation for checking if the given text is present in the specified element.
 * @param element - the WebElement
 * @param text - to be present in the element
 * @param timeout
 * @return true once the element contains the given text
 */
public boolean textToBePresentInElement(WebElement element, String text, int timeout) {
    try {
        return getWebDriverFluentWait(timeout)
                .until(ExpectedConditions.textToBePresentInElement(element, text));
    } catch (Exception e) {
        return false;
    }
}

/***
 * An expectation for checking if the given text is present in the element that matches the given locator.
 * @param locator - used to find the element
 * @param text - to be present in the element found by the locator
 * @param timeout
 * @return true once the first element located by locator contains the given text
 */
public boolean textToBePresentInElementLocated(By locator, String text, int timeout) {
    try {
        return getWebDriverFluentWait(timeout)
                .until(ExpectedConditions.textToBePresentInElementLocated(locator, text));
    } catch (Exception e) {
        return false;
    }
}

/***
 * An expectation for checking if the given text is present in the specified elements value attribute.
 * @param locator - used to find the element
 * @param text - to be present in the value attribute of the element found by the locator
 * @param timeout
 * @return true once the value attribute of the first element located by locator contains the given text
 */
public boolean textToBePresentInElementValue(By locator, String text, int timeout) {
    try {
        return getWebDriverFluentWait(timeout)
                .until(ExpectedConditions.textToBePresentInElementValue(locator, text));
    } catch (Exception e) {
        return false;
    }
}

/***
 * An expectation for checking if the given text is present in the specified elements value attribute.
 * @param element - the WebElement
 * @param text - to be present in the element's value attribute
 * @param timeout
 * @return true once the element's value attribute contains the given text
 */
public boolean textToBePresentInElementValue(WebElement element, String text, int timeout) {
    try {
        return getWebDriverFluentWait(timeout)
                .until(ExpectedConditions.textToBePresentInElementValue(element, text));
    } catch (Exception e) {
        return false;
    }
}

с

private Wait<WebDriver> getWebDriverFluentWait(int timeout) {
    return new FluentWait<WebDriver>(driver)
            .withTimeout(timeout, TimeUnit.SECONDS)
            .pollingEvery(1, TimeUnit.SECONDS)
            .ignoring(NoSuchElementException.class);
}
Другие вопросы по тегам