Получение того же элемента, даже если элемент не существует в 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 ответ
Я думаю, что код выглядит хорошо, и проблема может выглядеть так: "тест не пройден во время выполнения, но не во время отладки". В моем случае я бы сделал еще несколько шагов, чтобы выяснить, что должно произойти:
- Правильный текст может отображаться "после задержки", или "запись не найдена" является сообщением по умолчанию, и для "записи найдена" требуется время. В этом случае я буду неявно ждать в течение некоторой секунды и снова запускать скрипт.
- Вместо распечатки текста я бы назвал 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);
}