почему я получаю ссылку на устаревший элемент в тестовом методе? - PullRequest
0 голосов
/ 05 сентября 2018

В настоящее время я работаю над фреймворком автоматизации с использованием java, selenium, selenium-grid, pageObject with pageFactory.

Я пытаюсь создать метод для тестирования следующего HTML-кода:

<section class="footer-links">
<div class="footer-layout">
    <ul>
        <li class="title">Header</li>
        <li><a href="/home/">text</a></li>
        <li><a href="/about/">text</a></li>
        <li><a href="/games/">text</a></li>
        <li><a href="/games/download/" >text</a></li>
        <li><a href="/games/mobile/" >text</a></li>
        <li><a href="/events/" >text</a></li>
    </ul>
    <ul>
        <li class="title">Header</li>
        <li><a href="/publishers/" >text</a></li>
        <li><a href="/smth/" target="_blank" >text</a></li>
        <li><a href="/promo/press/" >text</a></li>
    </ul>
    <ul>
        <li class="title">Header</li>
        <li><a href="/support/" >text</a></li>
        <li><a href="/support/payment-inquiries/"  class="loginModalShow" rel="nofollow" >text</a></li>
        <li><a href="/support/general-inquiries/" >text</a></li>
        <li><a href="/support/game-inquiries/"  class="loginModalShow" rel="nofollow" >text</a></li>
    </ul>
    <ul>
        <li class="title">Header</li>
        <li><a href="/blog/" >text</a></li>
        <li><a href="/search/" rel="nofollow" >text</a></li>
        <li><a href="/directory/pc-games/" >text</a></li>
    </ul>
</div>

Код выше представляет нижний колонтитул, содержащий 4 списка с некоторыми ссылками.

То, что я пытаюсь сделать с помощью следующего метода, - это перебирать один раз по 4 спискам и снова внутри каждого списка, щелкая ссылки и проверяя URL-адрес, на который они перенаправляются, со своим значением атрибута href.

@FindBy(css = ".footer-links .footer-layout ul")
public List<WebElement> footerLinksLists;

public void checkFooterLinks(){
    if (footerLinksLists.size()==4){
        for(int i=0; i<footerLinksLists.size(); i++){
            List<WebElement> links =  wait.until(ExpectedConditions.visibilityOfAllElements(footerLinksLists.get(i).findElements(By.cssSelector("li:not(:first-child)")))); // footerLinksLists.get(i).findElements(By.cssSelector("li:not(:first-child)"));
            for (int j=0; j<links.size(); j++) {
                WebElement link = wait.until(ExpectedConditions.elementToBeClickable(links.get(j).findElement(By.cssSelector("a"))));
                String href = link.getAttribute("href");
                link.click();
                if(driver.getCurrentUrl().contains(href)){
                    log.info("Link " + href +" is ok");
                }
                driver.navigate().back();
            }
        }
    }else{
        log.info("the footer does not contain 4 link lists");
    }
}

После запуска моего теста он прерывается после входа в цикл for со следующей ошибкой

org.openqa.selenium.StaleElementReferenceException: The element reference of <li> is stale; either the element is no longer attached to the DOM, it is not in the current frame context, or the document has been refreshed

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

WebDriver driver = driverFactory.getDriver();
    WebDriverWait wait = driverFactory.getWait(driver);

homepagePageObject homePage = new homepagePageObject(driver, wait);
    PageFactory.initElements(driver,homePage);
    homePage.createAccount();
    homePage.checkVerifyAccountRibbon();
    homePage.signOut();
    homePage.Login();
    homePage.checkFooterLinks();

Первоначально я думал, что это как-то связано с ожиданием каждого элемента, но я получаю ту же ошибку после добавления условий ожидания / ожидаемого.

Может кто-нибудь объяснить, что я делаю не так и каково было бы лучшее решение в этом случае?

Ответы [ 2 ]

0 голосов
/ 07 сентября 2018

Этот метод не делает то, что вы хотите.

Во-первых, этот цикл проходит только в том случае, если количество нижних ссылок равно 4. Если количество ссылок изменилось или имеется ошибка, из-за которой оно равно 3, весь метод пропускается, и вы просто получаете запись в журнал факта. Поскольку нет никаких утверждений и метод ничего не возвращает, этот метод будет проходить каждый раз при запуске.

Во-вторых, если ссылка не содержит ожидаемого href, оператор if не будет выполнен. Все это означает, что в журналах не будет оператора OK. Метод будет по-прежнему выполняться и успешно.

Я бы предложил включить некоторые утверждения в этот тест. Либо как часть каждой итерации. Так что-то вроде этого:

List<WebElement> links =  wait.until(ExpectedConditions.visibilityOfAllElements(footerLinksLists.get(i).findElements(By.cssSelector("li:not(:first-child)")))); // footerLinksLists.get(i).findElements(By.cssSelector("li:not(:first-child)"));
        for (int j=0; j<links.size(); j++) {
            WebElement link = wait.until(ExpectedConditions.elementToBeClickable(links.get(j).findElement(By.cssSelector("a"))));
            String href = link.getAttribute("href");
            link.click();
            **assertTrue("The expected URL did not match",driver.getCurrentUrl().contains(href));**
            driver.navigate().back();
        }

или как возврат из самого метода

public boolean checkFooterLinks(){
  if (!footerLinksLists.size()==4){
     return false;
   }

    for(int i=0; i<footerLinksLists.size(); i++){
        List<WebElement> links =  wait.until(ExpectedConditions.visibilityOfAllElements(footerLinksLists.get(i).findElements(By.cssSelector("li:not(:first-child)")))); // footerLinksLists.get(i).findElements(By.cssSelector("li:not(:first-child)"));
        for (int j=0; j<links.size(); j++) {
            WebElement link = wait.until(ExpectedConditions.elementToBeClickable(links.get(j).findElement(By.cssSelector("a"))));
            String href = link.getAttribute("href");
            link.click();
            if(!driver.getCurrentUrl().contains(href)){
                return false;
            }
            driver.navigate().back();
        }
    }
   return true;

}

и затем дайте тесту проверить, что ссылки в порядке с

assertTrue("something is not right with the footer links",checkFooterLinks())

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

Тем не менее, я вижу значение проверки ссылок и того, что они содержат ожидаемое значение href, но я не уверен, какое значение даст проверка фактического URL.

Если href поврежден и указывает на www.google.com, тест будет пройден при совпадении двух значений. Просто пища для размышлений.

0 голосов
/ 05 сентября 2018

Поскольку страница обновляется, а элемент списка теряет свое значение.

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

public void checkFooterLinks(){
    if (footerLinksLists.size()==4){
        for(int i=0; i<footerLinksLists.size(); i++){
            List<WebElement> links =  wait.until(ExpectedConditions.visibilityOfAllElements(footerLinksLists.get(i).findElements(By.cssSelector("li:not(:first-child)")))); // footerLinksLists.get(i).findElements(By.cssSelector("li:not(:first-child)"));
            for (int j=0; j<links.size(); j++) {
                WebElement link = wait.until(ExpectedConditions.elementToBeClickable(links.get(j).findElement(By.cssSelector("a"))));
                String href = link.getAttribute("href");
                link.click();
                if(driver.getCurrentUrl().contains(href)){
                    log.info("Link " + href +" is ok");
                }
                driver.navigate().back();
            }
        links = wait.until(ExpectedConditions.visibilityOfAllElements(footerLinksLists.get(i).findElements(By.cssSelector("li:not(:first-child)"))));
        }
    }else{
        log.info("the footer does not contain 4 link lists");
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...