Есть отличная удаленная работа для php+codeception+jenkins+allure+docker спецов. 100% remote! Присоединиться к проекту

Остановить выполение тестов в maven до опрделенного времени

maven
Теги: #<Tag:0x00007f7b62461ab0>

#1

И так еще раз здравствуйте
так как меня посадили за чужой фреймворк и он раньше запускался только с тестнг а теперь переделан под мавен
суть
есть такая строчка кода в 1000 тестах
new Tool_Thread_Wait().Thread_Wait(1, 2000);
окей идем в реализацию

public class Tool_Thread_Wait {
    /*
    * if run = 0, class Tool_Thread_Wait switch off
   * if run = 1, class Tool_Thread_Wait switch on
   *
   * */

    private int run = 1;

    public void Thread_Wait(int number, long milsec) {
        if (run == number) {
            try {
                Thread.sleep(milsec);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

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

public class Test_001___CHART___Button_Alarm_Chart_ENG extends Initialize {
    @Test
    public void Tests() {
        PAGE.WEBSITE().LINK().Link_000_Language_ENG();

        PRESET.WAIT(1, 2000);

        PAGE.WEBSITE().ELEMENT().ALARM().CHART().Button_Alarm_Chart();

        PRESET.WAIT(1, 2000);

        String actual = PAGE.WEBSITE().ELEMENT().ALARM().CHART().Label_Alarm_Chart();
        String expected = "Live Chat";

        Assert.assertEquals(actual, expected);
    }
}

так вот в чем суть мавен такое я так понял не кушает , тесты он проганяет быстрее и на таких вейтах не останавливается
Вопрос - как поменять код что бы мавен все таки останавливался или все таки прийдется перепесать все тесты , на последний вариант у меня просто не так много времени , я стараюсь писать все таки с wait .


(Sergey Korol) #2

По рукам надо бить таким писакам. Если нужно чего-то ждать, explicit waits - ваше все. Если архитектурно там все построено более или менее, то изменять почти ничего не придется: добавить новую поисковую логику и поудалять все вхождения слип паттерна. Хотя, у меня почему-то очень большие сомнения касательно архитектурной валидности, исходя из увиденного. Да и вообще, судя по всему, начать придется не с рефакторинга, а с чтения code conventions. :wink:


#3

Не могу еще полностью оценить архитектуру , но вот добавить логику по типу

 WebElement myDynamicElement = (new WebDriverWait(driver, 10))
  .until(ExpectedConditions.presenceOfElementLocated(By.id("myDynamicElement")));

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


(Sergey Korol) #4

Это делается на уровне какой-нибудь BasePage / кастомных элементов. Т.е. всего 1 изменение в методе поиска для всех элементов. Но если у вас все навалено в кучу, и не реализовано переиспользование методов, то такой “фреймворк” можно смело выкидывать на помойку. Total time на изобретение костылей вам выльется в гораздо больше человеко-часов, чем эффорт на полноценный архитектурный дизайн. Естественно, если это есть кому делать на проекте. Без опыта вам конечно придется мириться с текущим беспределом. Но я бы вам порекомендовал создать отдельный бранч, в котором вы потихоньку будете готовить реализацию принципиально нового подхода. Опять-таки, предварительно нужно все же оценить целесообразность глобального рефакторинга. Если вы чувствуете, что проект “гиблый”, то наверное смысла нет в подобных активностях. Разве что для себя потренироваться.


#5

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

   public class Test_015___LABEL_LINK___007_Video_ENG extends Initialize {
        @Test
        public void Tests() {
            PAGE.WEBSITE().LINK().Link_000_Language_ENG();
    
            String actual = PAGE.WEBSITE().LABEL().Label_Link_007_Video();
            String expected = "Video instructions";
    
            Assert.assertEquals(actual, expected);
        }
    }

пускай дальше идем в метод лейбллинк 007 

public class Label_Link_007_Video extends Page_Any {
    @FindBy(xpath = "//div[@class='media_switcher_block']/ul/li[2]/a")
    @CacheLookup
    private WebElement el_Label_Link_007_Video;

    public Label_Link_007_Video(Page_Manager pages) {
        super(pages);
    }

    private WebElement el_Label_Link_007_Video() {
        return new Page_Manager(driver).initElements(new Label_Link_007_Video(pages)).el_Label_Link_007_Video;
    }

    public String Label_Link_007_Video() {
        new Tool_HighLights().HighLightElement(driver, el_Label_Link_007_Video());

        String res = el_Label_Link_007_Video().getText();

        return res;
    }
}

и тут я как понимаю по логике опираясь на эту статью введите описание ссылки

идем в педж менеджмент класс и в метод инит

public class Page_Manager {
    protected WebDriverWait wait;
    private WebDriver driver;

    public Page_Manager(WebDriver driver) {
        this.driver = driver;
    }

    public <T extends Page_Abstract> T initElements(T page) {
        PageFactory.initElements(new Util_Displayed_ElementLocatorFactory(driver, 100), page);

        return page;
    }

    public WebDriver getWebDriver() {
        return driver;
    }
}

ок тогда смотрм на утил

ublic class Util_Displayed_ElementLocatorFactory implements ElementLocatorFactory {
    private final WebDriver driver;
    private final int timeOutInSeconds;

    public Util_Displayed_ElementLocatorFactory(WebDriver driver, int timeOutInSeconds) {
        this.driver = driver;
        this.timeOutInSeconds = timeOutInSeconds;
    }

    public ElementLocator createLocator(Field field) {
        return new Util_Displayed_Element_Locator(driver, field, timeOutInSeconds);
    }
}

тогда в смотрим на метод дисплейелементлокатор

public class Util_Displayed_Element_Locator extends AjaxElementLocator {
    public Util_Displayed_Element_Locator(WebDriver driver, Field field, int timeOutInSeconds) {
        super(driver, field, timeOutInSeconds);
    }

    protected boolean isElementUsable(WebElement element) {
         
        return element.isDisplayed();
    }
}

и падают тесты как раз в элемент return element.isDisplayed() вопрос почему ?? ведь он сделал все согласно той статье ??? и что такое нужно сделать что бы не падали вставить вейт ???


(Sergey Korol) #6

Какой exception на isDisplayed вылетает?


#7

org.openqa.selenium.StaleElementReferenceException: stale element reference: element is not attached to the page document


(Sergey Korol) #8

Ну как бы элемент у вас закеширован -> @CacheLookup. Не удивительно, что стейлы летят.


#9

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


(Sergey Korol) #10

Ну судя по коду, стейлы там в принципе никак не хэндлятся. Лично я не являюсь сторонником стандартной связки FindBy + WebElement. Для меня всегда будет предпочтительней By + WebDriverWait + ExpectedConditions. При таком подходе стейлы для меня - это миф. :slight_smile:


#11

Но откуда они берутся ??? я не пойму


(Sergey Korol) #12

StaleElementReferenceException


#13

Я уже читал но все равно если написано все по статье которую я приводил и раньше тесты эти работали то почему сейчас я наблюдаю эту картину ??


(Sergey Korol) #14

Мы уже вроде выяснили, что статья вас никак не спасет от стейлов. Почему раньше работало? Наверное потому, что у вас 1ккк+ слипов понатыкано в каждом тесте. До определенного момента это работало, а теперь начало падать. Да и вообще, с той картиной, которую я увидел по приведенным кускам кода, я бы ничему больше не удивлялся. Ради собственного же интереса, возьмите 1 любой 100% падающий со стейлом тест, перепишите для него элементы под By + ExpectedConditions и узрите магию. :wink:


#15

Честно я не понимаю я уже день бьюсь над этой задачей и не понимаю летит експешн

org.openqa.selenium.StaleElementReferenceException: stale element reference: element is not attached to the page document
  (Session info: chrome=44.0.2403.107)
  (Driver info: chromedriver=2.12.301325 (962dea43ddd90e7e4224a03fa3c36a421281abb7),platform=Windows NT 6.1 SP1 x86_64) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 9 milliseconds

с разных тестов сюта , ели запустить тест 1 то вероятность что он пройдет где-то 80 процентов. например тест мы заходим на страницу и ищем раздел характеристики вот 2 теста 1 никогда не падает вот он

public class Test_008___LABEL_LINK___003_Features_RUS extends Initialize {
    @Test
    public void Tests() {

        String actual = PAGE.WEBSITE().LABEL().Label_Link_003_Features();
        String expected = "Характеристики";

        Assert.assertEquals(actual, expected);
    }
}

второй раз через раз

public class Test_009___LABEL_LINK___004_Pricing_ENG extends Initialize {
    @Test
    public void Tests() {
        PAGE.WEBSITE().LINK().Link_000_Language_ENG();

        String actual = PAGE.WEBSITE().LABEL().Label_Link_004_Pricing();
        String expected = "Pricing";

        Assert.assertEquals(actual, expected);
    }
}

отличие этих тестов лишь в смене языка как Вы можете видеть.  то есть я так понимаю  что 
Наиболее частой причиной этого является то, что страница с искомым элементом, была обновлена, или пользователь перешел на другую страницу. Реже, но все также достаточно распространен случай, когда библиотека JavaScript удалила элемент и заменила его элементом с таким же ID или атрибутами. В этом случае, несмотря на то, что замененные элементы могут выглядеть похожими на оригиналы, они отличаются. Selenium Driver не имеет возможности определить, что замененный элемент на самом деле тотже, что и ожидался. Если вы уверены, что элемент заменен идентичным и присутствует на странице, то нужно выполнить поиск элемента снова и получить актуальную ссылку на него.

хорошо как с этим бороться ?? давайте явно вызывать элемент ?? типа так

public class Label_Link_004_Pricing extends Page_Any {
    @FindBy(xpath = ".//*[@id='main_menu']/li[3]/a")

    private WebElement el_Label_Link_004_Pricing;

    public Label_Link_004_Pricing(Page_Manager pages) {
        super(pages);
    }

    //old code
   // private WebElement el_Link_004_Pricing() {
     //   return new Page_Manager(driver).initElements(new Label_Link_004_Pricing(pages)).el_Label_Link_004_Pricing;
   // }

    public String Label_Link_004_Pricing() {

        //new code
        WebElement element_testing= driver.findElement(By.xpath(".//*[@id='main_menu']/li[3]/a"));
        String res=element_testing.getText();
        //old code
        //String res = el_Link_004_Pricing().getText();

        return res;
    }
}

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


(Sergey Korol) #16

Да вы издеваетесь пожалуй…

Интереса ради, сколько еще раз нужно повторить ключевые слова ExpectedConditions / WebDriverWait, чтобы наступило наконец прозрение? Может хоть у официальной документации получится…


#17
  1. Спасибо что мне помогаете и проявляете терпение
  2. Сейчас объясню почему я был в заблуждении и я докопался до истины так сказать

как Вы помните летел експешн вида
org.openqa.selenium.StaleElementReferenceException: stale element reference: element is not attached to the page document

дебагером я прошелся и увидел что летит он отсюда

 protected boolean isElementUsable(WebElement element) {
         
        return element.isDisplayed();
    }

и я стал гуглить как это связано и наткнулся на это введите описание ссылки

думал ну ок буду обрабатывать ексепшн и стал крутить вертеть в голове мысли как грамотно обработать, но подлянка заключалась в другом а именно здесь

@FindBy(xpath = "//div[@class='media_switcher_block']/ul/li[2]/a")
    @CacheLookup
    private WebElement el_Label_Link_007_Video;

в суть ? например если возьмем такой код

WebElement element= driver.findElement(By.xpath(" "));
если у нас не будет найден элемент по заданному локатору вылетит ексепшн - носачелементексепшн
и я думал что этап файднбай тоже проходит то есть элемент находится оказывается нет, никакого ексепшена не летит , хотя причина именно в нем , в действительности не находился элемент по заданному локатору . Что я сделал временно ?? просто поставил вейт все-го лишь на 1 сек и уже пару сотню тестов прошло. Это не правильное решение и его нужно исправить я думаю создать метод в который мы передаем локатор и ждем появления элемента но мне нужно зайти в 1000 тестов и закинуть локатор в мой новый метод и удалить старый не нужный кусок , чем я и думаю заняться .


(Denis Repon) #18

привет. почитал комментарии. не выходит.
часть кода:

var elemDescr = driver.FindElements(By.XPath("//div[label[text()='xxx:']] //textarea"));
if(elemDescr.Count>0){
elemDescr[0].Click();
elemDescr[0].Clear();
elemDescr[0].SendKeys("123456789");
waitForOne.Until(ExpectedConditions.PresenceOfAllElementsLocatedBy( By.XPath("//div[label[text()='xxx:']] //textarea") ));
elemDescr[0].Click();
}

вывадиливается ошибка на последней строке elemDescr[0].Click(); > stale element reference: element is not attached to the page document


(Sergey Korol) #19

А вы почитайте внимательней javadocs - что возвращает метод until. :wink: А потом подумайте над тем, какую ссылку вы пытаетесь использовать в последней строке, и почему это не будет работать.


(Denis Repon) #20

true\false ?

тогда вопрос. если я удаляю строку с
“waitForOne.Until(ExpectedConditions.PresenceOfAllElementsLocatedBy(…”

то я не могу еще раз отправить elemDescr[0].SendKeys( или нажать elemDescr[0].Click();