Не могу получить текст любого веб элемента с сайта http://booking.uz.gov.ua (JAVA)

@vtimchenko87, сперва, проверьте какая версия WebDriver, которую вы используете. Всегда используйте последнюю, ну или, хотя-бы чтобы она была > 2.30

:warning: только в диагностических целях, перед сбором информации с таблицы, поставьте
Thread.sleep(4000);
Если тест отработает правильно, замените Thread.sleep(4000); на метод класса WebDriverWait

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

1 лайк

Да , получил текст с этого xpath '//*[@id="langs"]/li[1]/a/b' , но почему не могу получить текст с этого элемента "//*[@id='ts_res_tbl']//tr[1]/td[1]/a" ?

Спасибо , но WebDriver 2.35.0

Дмитрий спасибо Вам огромное тест отработал когда дописал Thread.sleep(4000);

На этот метод заменить нужно driver.manage().timeouts().implicitlyWait(4, TimeUnit.SECONDS); ?

Есть разные подходы, implicit wait будет действовать глообально на все элементы.
WebDriverWait действует локально и ожидает выполнения некоторого условия, вот есть такая тема

Есть еще такая статья про варианты ожиданий:

1 лайк

Попробуй также AjaxElementLocatorFactory, возможно этот механизм лучше подойдет

Спасибо Вам Александр

заинтересовала данная тематика!
Так как часто ежу домой и в Киев решил тоже написать свой фреймворк для booking.uz.gov.ua!
драйвер проходиться по кнопкам “Выбрать” и оставляет заказы в корзину, потом делает скриншот и через каждые 30 мин этот скрин приходит на почту! Таким образом мы можем видеть все поезда и их стоимость по данному направлению и в выбранное время, просто зайдя в свой почтовый ящик!

Ссылка на гитхаб
https://github.com/mamax/bookingTrains

Критиковать и ругать можно? :slight_smile:

А есть чем? :smiley:

Как по мне, то достаточно чистый код:

  • Четко выделенные методы действия в PageObject’ ах, например в OrderPage.java
  • В OrderTest.java достаточно четко выраженный код сценария.

В SendMail, конечно, накручено с кучей параметров. Я бы вынес эти 16 параметров лучше в отдельный класс, и принимал бы его как единственный параметр в SendMail.sendMail

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

2 лайка

критика приветствуется

Ну если бегло:

  1. Зачем так сложно?
orderPage = PageFactory.initElements(getWebdriver(), OrderPage.class);
return PageFactory.initElements(driver, ResultPage.class);
  1. Зачем использовать ExpectedConditions.visibilityOfElementLocated(), если можно задекларить элементы и использовать visibilityOf(WebElement element)?

  2. Локаторы в тестах - это не тру, хардкод - тоже.

                resultPage = orderPage.getBilet("Êèåâ", "Âèííèöà", "19.12.2013", "18:00");
                resultPage.WaitForPageToLoadByCss(".num");
  1. Слипы тоже
Thread.sleep(4000L);
  1. Трай-кэтч, за редким исключением, тоже. Особенно с кэтченьем всего-и-вся: catch(Exception e).
    Здесь, если бельё в поезде отсутствует, скрипт будет честно ждать 8 секунд имплисит вейта, которые абсолютно не нужны. Куда более гармонично будет выглядеть что-нибудь isExist(WebElement el), который будет сетать имплисит вейт в ноль, а потом восстанавливать. Что-то вроде WebElement.isDisplayed() throws NoSuchElementException when element is not found · Issue #1880 · SeleniumHQ/selenium-google-code-issue-archive · GitHub.
                        try{                                
                                if (Postel.isSelected()){
                                        Postel.click();
                                }                                
                        }catch(Exception e){ 
                                System.out.println("error - there is no Postel in this train "+ e.getMessage());
                                e.printStackTrace();                                
                        }
  1. Зачем такие извращения с public static void main(String[] args) и мавеном, когда у листенера testng есть onFinish(ITestContext testContext)?
  2. Ну и не удержусь - там же вполне вменяемый локатор рисуется?
 @FindBy (xpath="//tbody/tr/td[4]/div[1]/label/input")
1 лайк

привет!
спасибо! дельные комментарии! я согласен! перезалил!
по пункту 3 там по другому было непросто выкрутиться,чтобы дождаться блочка(он яваскриптом подтягивается) но я вспомнил про Xpath)
4. - если использовать конструкцию

public static boolean isPresentAndDisplayed(final WebElement element) {
  try {
    return element.isDisplayed();
  } catch (NoSuchElementException e) {
    return false;
  }
}

то тут тоже по имплиситу нужно ждать!
5. Знаю лутше тянуть джарники мейвеном, но пока руки не дошли нормально разобраться, с антом как-то проще
6. исправил

Я для себя выбрал такой путь, что имплисит вейт у меня по дефолту – ноль.
Для проверки, использую код, похожий на тот, что приведенный по ссылке, но усложненный обстоятельствами:

  1. Отлавливаю не все Exceptions, а только от вебдрайвера, и сохраняю ошибки в переменную. Это необходимо для того, чтобы в случае таймаута вывести предыдущию ошибку в лог
  2. Поддерживается таймаут в ожидании. Да… было один раз, что скрипт хотел ожидать элемента вечсность. Пришлось убить и таймаут добавить.
  3. Есть метод с одним параметром и таймаутом по умолчанию.

На C# есть очень удобная конструкция методов-расширений, и в реальном коде, это выглядет так:

// внутри пейджобжекта
this.txtLoginField.Wait().SendKeys(“hello”)

Т.е. Wait-у неявно прийдет параметр txtLoginField, которого он и будет ждать.

А в Java-подобном варианте, это бы вглядело так:

UntilVisible(this.txtLoginField).SendKeys(“hello”);
       public static IWebElement UntilVisible(IWebElement element, TimeSpan timeOut)
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();

            while (true)
            {
                WebDriverException lastException = null;
                try
                {
                    if (element.Displayed)
                    {
                        return element;
                    }
                    System.Threading.Thread.Sleep(100);
                }
                catch (ElementNotVisibleException e)     { lastException = e; }
                catch (NoSuchElementException e)         { lastException = e; }
                catch (StaleElementReferenceException e) { lastException = e; }

                if (sw.Elapsed > timeOut)
                {
                    string exceptionMessage = lastException == null ? "" : lastException.Message;
                    string errorMessage = string.Format("Wait.UntilVisible: Element was not displayed after {0} Milliseconds" +
                                                        "\r\n Error Message:\r\n{1}", timeOut.TotalMilliseconds, exceptionMessage);
                    throw new TimeoutException(errorMessage);
                }
            }
        }

Мелочи поправили, а основное либо не поняли, либо не исправили.
Попробую на пальцах:
A. Почему не сделать так, и навсегда забыть о PageFactory и getWebDriver()?

        public Page() {
                this.driver = getWebDriver();
                PageFactory.initElements(driver, this);
        }

B. То, что вы объявили переменные “String fromCity” и т.д. ничего не меняет - это все равно хардкод, ровно как и magic numbers, а-ля “new WebDriverWait(driver, 10)” и прочее. Входные данные на то и “входные” - они должны быть отдельно, особенно в данном случае. Вот например скачал я с гит хаба и хочу использовать, вот только незадача - мне надо направление Киев-Минск в 11-00, в Киев 11.01.2014, а обратно 14-го, да и email надо бы изменить. И да - джаву я не знаю. Вы представляете сколько мне времени придется потратить, изучая сорсы, что бы найти где-что поменять? В одном только SendEmail адрес нужно поменять в 4-х местах.

С. У вас люто-бешено закручена отправка emails. Я, признаться, впал в пятиминутный ступор, когда пытался в этом разобраться. К чему эта гора таргетов в build.xml и void main(String[] args), когда более логично это бы смотрелось в листенере по onFinish()?

*:rage2: @vmaximv is on killing spree *

Уполномоченный званием модератора, данным мне великим основателем этого форума,

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

присуждаю @vmaximv вот это: :poop:

Не совсем понятно что конкретно присужено @vmaximv, но судя по формулировке что-то не очень приятное :slight_smile:
Только вот не совсем понятно за что - особо злобных формулировок вроде нет, все замечания по делу (предварительно получено согласие автора на критику).

Особо злобных формулировок действительно не было, и это – хорошо. Но, на мой взгляд, градус критики возрос. Хотелось бы, снизить его, и вернуть стиль общения в более конструктивное русло.

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

И я не спорю, замечания @vmaximv, действительно по делу. И я понимаю, что @vmaximv писал их из лучших побуждений. Но, на мой взгляд, сделаны они в слишком резкой форме.

1 лайк