Не могу нажать веб-кнопку с помощью webdriverio

Я пытаюсь изучить автоматизацию с помощью webdriverio в nodejs прямо сейчас, по общему признанию, не очень хорошо разбираясь в jquery в HTML. вот где я:

Я написал скрипт, который до сих пор успешно регистрирует меня в учетной записи и переходит на нужную страницу. Моя цель - сделать бронирование, но когда я нажимаю на элемент бронирования, появляется всплывающее окно с некоторыми предварительно загруженными данными и кнопкой «Сделать бронирование», которая при нажатии запускает функцию javascript. Однако мне не удалось успешно воссоздать фактический щелчок.

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

<div class="inside">
            <ul class="toolBtns">

                <li id="ctl00_ctrl_MakeBookingTime_liCancelChanges" class="cancelChanges">
                    <a id="ctl00_ctrl_MakeBookingTime_lbCancelChanges" href="javascript:__doPostBack('ctl00$ctrl_MakeBookingTime$lbCancelChanges','')">Discard Changes</a></li>
                <li id="ctl00_ctrl_MakeBookingTime_liBook" class="bookRes">
                    <a id="ctl00_ctrl_MakeBookingTime_lbBook" href="javascript:__doPostBack('ctl00$ctrl_MakeBookingTime$lbBook','')">Make Reservation</a></li>
            </ul>               
        </div>

До сих пор я пытался щелкнуть по нему, используя это (это код после моего «клиентского» объявления)

  .execute(executeFunction).then(function(resp){
  console.log('execute function status:',resp.state) // should log true if element is there
})
.waitForExist('#ctl00_ctrl_MakeBookingTime_lbBook').then(function(exists){
  console.log('button exists status:',exists.state) // should log true if element is there
})
.elements('#ctl00_ctrl_MakeBookingTime_lbBook').then(function(resp){
    console.log('element found status: ',resp);
  return; //wait for the popup to load before executing the click
}).click('=Make Reservation') //this is the line that doesn't seem to work

эта последняя строка не работает. Как вы видите, я использую регулярное выражение в качестве элемента запроса, но я также попробовал только идентификатор элемента напрямую, как было предложено здесь. Я также пытался вручную выполнить функцию javascript в ссылке HREF, но это просто закрывает окно, фактически не делая резервирования:

.execute("javascript:__doPostBack('ctl00$ctrl_MakeBookingTime$lbBook")

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

Любые предложения или ссылки на другие статьи были бы очень полезны. Я часами копаюсь и не могу понять. Спасибо!

Обновлять

:ChristianB запросил логи, вот они:

2:32:16.747 INFO - Done: [execute script: javascript:LaunchLockedReserver(this,event,'54','200','12/19/2015','9:15 AM','2');, []]
12:32:16.752 INFO - Executing: [find elements: By.xpath: //*[contains(@id, "ctl00_ctrl_MakeBookingTime_lbBook") and contains(., "Make Reservation")]])
12:32:16.766 INFO - Done: [find elements: By.xpath: //*[contains(@id, "ctl00_ctrl_MakeBookingTime_lbBook") and contains(., "Make Reservation")]]
12:32:17.023 INFO - Executing: [find elements: By.xpath: //*[contains(@id, "ctl00_ctrl_MakeBookingTime_lbBook") and contains(., "Make Reservation")]])
12:32:17.038 INFO - Done: [find elements: By.xpath: //*[contains(@id, "ctl00_ctrl_MakeBookingTime_lbBook") and contains(., "Make Reservation")]]
12:32:17.303 INFO - Executing: [find elements: By.xpath: //*[contains(@id, "ctl00_ctrl_MakeBookingTime_lbBook") and contains(., "Make Reservation")]])
12:32:17.303 INFO - Executing: [find element: By.xpath: //*[contains(@id, "ctl00_ctrl_MakeBookingTime_lbBook") and contains(., "Make Reservation")]])
12:32:17.311 INFO - Done: [find elements: By.xpath: //*[contains(@id, "ctl00_ctrl_MakeBookingTime_lbBook") and contains(., "Make Reservation")]]
12:32:17.568 WARN - Exception thrown
org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"xpath","selector":"//*[contains(@id, "ctl00_ctrl_MakeBookingTime_lbBook") and contains(., "Make Reservation")]"}

Кажется, последняя часть не работает. Спасибо, что указали мне на журналы. Странно то, что когда я напрямую меняю регулярное выражение только на идентификатор, оно все равно выдает эту ошибку:

12:38:33.483 WARN - Exception thrown
org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"id","selector":"ctl00_ctrl_MakeBookingTime_lbBook"}

Я буду продолжать пытаться и проверять журналы

Обновление №2

Я ввел журнал в функции .then для каждой из функций, которые я запускаю (см. обновленный код выше), и функция .waitForExists, похоже, даже не запускается. Мой вывод консоли после запуска функции выглядит так:

execute function status: success
Error: element (#ctl00_ctrl_MakeBookingTime_lbBook) still not existing after 500ms
at elements("#ctl00_ctrl_MakeBookingTime_lbBook") - isExisting.js:43:17
at isExisting("#ctl00_ctrl_MakeBookingTime_lbBook") - waitForExist.js:31:21

В основном кажется, что он переходит от .execute прямо к функции .elements...


person RodneyStanger    schedule 12.12.2015    source источник
comment
Можете ли вы предоставить какие-либо журналы Selenium? Хотелось бы увидеть, был ли щелчок успешным и существует ли элемент   -  person ChristianB    schedule 12.12.2015
comment
@ChristianB только что добавил их в исходный пост. Спасибо, что указали мне на журналы. Кажется, он не находит элемент. Я посмотрю, смогу ли я исправить селектор элементов.   -  person RodneyStanger    schedule 12.12.2015
comment
Чего я не понимаю, так это того, что функции .waitForExist и функции .click используют один и тот же параметр селектора, но функция .click не находит элемент.   -  person RodneyStanger    schedule 12.12.2015
comment
Попробуйте просто сделать это: .click('#ctl00_ctrl_MakeBookingTime_lbBook') должен быть только один элемент с этим идентификатором.   -  person ChristianB    schedule 12.12.2015
comment
Да, я пробовал это, все еще не найдя элемент. См. последний журнал в моем исходном сообщении для журнала селена для этой попытки. Возможно ли, что моя функция waitForExist работает недостаточно долго, чтобы всплывающее окно загружалось?   -  person RodneyStanger    schedule 12.12.2015
comment
нет, он останавливается чуть больше, чем через полсекунды. Не могли бы вы выполнить команду elements после waitForExists, чтобы проверить, действительно ли такой элемент существует?   -  person ChristianB    schedule 12.12.2015
comment
кажется, нашел -- 13:21:46.320 INFO - Выполнение: [найти элементы: By.id: ctl00_ctrl_MakeBookingTime_lbBook]) 13:21:46.327 INFO - Готово: [найти элементы: By.id: ctl00_ctrl_MakeBookingTime_lbBook] 13:21: 46.362 INFO - Готово: [найти элементы: By.id: ctl00_ctrl_MakeBookingTime_lbBook]   -  person RodneyStanger    schedule 12.12.2015
comment
Это неправильно! Все эти команды являются асинхронными, поэтому вам нужно запускать их в очереди, например client.waitForExist(...).click(...)   -  person ChristianB    schedule 12.12.2015
comment
ах ладно чертов асинхронный. Я попробую это. спасибо   -  person RodneyStanger    schedule 12.12.2015
comment
так что это должно исключить асинхронную ошибку, верно? Элемент по-прежнему не найден :( .waitForExist('#ctl00_ctrl_MakeBookingTime_lbBook',true,8000,function(err){ return; //дождитесь загрузки всплывающего окна перед выполнением клика }).click('#ctl00_ctrl_MakeBookingTime_lbBook')   -  person RodneyStanger    schedule 12.12.2015
comment
можете ли вы попробовать это, чтобы проверить вывод: client.waitForExist(...).elements(...).then(console.log).click(...)   -  person ChristianB    schedule 12.12.2015
comment
вывод console.log: { состояние: «успех», sessionId: «6b173cd5-067d-4124-8ff4-c498f4001343», hCode: 402151617, значение: [], класс: «org.openqa.selenium.remote.Response» , статус: 0 }   -  person RodneyStanger    schedule 12.12.2015
comment
ok кажется, что нет доступного элемента. Пожалуйста, попробуйте разные селекторы, такие как =Make Reservation или .bookRes a. Если это не сработает, попробуйте использовать xpath.   -  person ChristianB    schedule 12.12.2015


Ответы (1)


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

Из http://webdriver.io/api/utility/waitForExist.html . Его Future возвращает логическое значение в зависимости от того, найдет ли он селектор или нет, как только ms закончится.

.waitForExist(selector[,ms][,reverse]).then(callback);

ms и reverse не являются обязательными. Вам нужно значение по умолчанию, которое для ms установлено в вашем конфигурационном файле wdio.

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

waitForExist('#ctl00_ctrl_MakeBookingTime_lbBook').then(function(exists){ console.log(exists) // should log true if element is there })

Вам не нужно пытаться частично соответствовать «Сделать резервацию», поскольку селектор идентификатора должен быть уникальным.

Обновление:

Фьючерсы связаны цепочкой, и может быть трудно сказать, где фьючерс разорвал цепочку. Иногда, когда я не могу понять, где что-то ломается, я вставляю вызовы между каждым членом цепочки с чем-то, что, как я знаю, что-то вернет, например

.getTitle().then(function(title){
    console.log(title);
});

Свойство exists.state недоступно. Хотя этого нет в документации, я проверил, что waitForExists принимает значение true или false. Если вы не уверены в передаваемом параметре, вы можете использовать console.log(arguments) для получения аргументов в виде массива. НЕ ИСПОЛЬЗУЙТЕ ЭТО ДЛЯ ПРОИЗВОДСТВА. Попробуйте сделать это в обратном вызове waitForExist.then(), чтобы увидеть, что у вас есть.

Вам не нужно elements (даже если это не является корнем проблемы). Если вы хотите нажать только одну кнопку, .click(#ctl00_ctrl_MakeBookingTime_lbBook) это то, что должно быть сделано.

Можете ли вы подробнее описать следующий код? Это может повлиять и на остальную часть цепочки Future. Можешь вывести console.log(arguments) и опубликовать?

.execute(executeFunction).then(function(resp){
  console.log('execute function status:',resp.state) // should log true if element is there
  console.log(arguments);
})
person garajo    schedule 15.12.2015
comment
Спасибо за предложение garrickajo. Я обновил исходный пост, чтобы показать код, который я использую сейчас. Странно то, что функция .waitForExist вообще не выводит никакого текста. Я понятия не имею, почему, но кажется, что эта функция полностью пропущена (я поместил вывод консоли в исходный пост). Я изменил свой файл wdio.config.js и сделал тайм-аут равным 10 с, но даже функция .elements, похоже, дает сбой. Не совсем уверен, почему. - person RodneyStanger; 17.12.2015