Есть ли способ объединить гем объекта страницы и вызовы javascript

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

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

это, по-видимому, вызвано тем, что метод объекта/селена страницы не запускает метод изменения javascript, который необходим для того, чтобы приложение знало, что поле было заполнено.

это можно исправить с помощью кода, такого как

on(SettingsPage).payment_method_account_number = number
@browser.execute_script("$('input[name=account_number]').change()")

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

есть ли лучший способ решить эту проблему, чем то, что я показал?


person charlietaylor    schedule 14.10.2014    source источник
comment
Можете ли вы опубликовать свое определение payment_method_account_number? Кажется странным, что метод объекта страницы не запускает метод изменения.   -  person Johnson    schedule 14.10.2014


Ответы (2)


Чтобы избежать дублирования определения элемента в объекте страницы, а также в скрипте execute_script, вы можете передать элемент объекта страницы в скрипт.

Базовый Selenium-WebDriver (и, следовательно, гем Page-Object) поддерживает массив arguments в выполняемом скрипте. Этот массив аргументов в основном берет элементы Selenium-WebDriver и преобразует их во что-то, что можно использовать в сценарии. Метод Page-Object execute_script обрабатывает преобразование элементов в нужный тип, поэтому вам просто нужно:

  1. Объявить скрипт, который использует массив аргументов
  2. Передать в PageObject::Element

Например, предположим, что ваш объект страницы использовал метод доступа:

text_field(:payment_method_account_number, :name => 'account_number')

Следовательно, объект страницы будет иметь метод payment_method_account_number_element, возвращающий PageObject::Element для этого текстового поля.

В сценарии, который вы хотите выполнить, вы можете заменить способ поиска элемента массивом аргументов и передать PageObject::Element методу execute_script:

execute_script("$(arguments[0]).change();", payment_method_account_number_element)

Затем вы можете переписать вызов on как:

on(SettingsPage) do |page|
  page.payment_method_account_number = number
  page.execute_script("$(arguments[0]).change();", page.payment_method_account_number_element)
end

(Или, как указал Дейн, поместите это в метод объекта страницы.)

person Justin Ko    schedule 14.10.2014

У меня была похожая проблема, но событие было «onblur» вместо «onchange». Я бы предположил, что при изменении сработает, но если это не так, вы можете использовать подход, аналогичный моему. В итоге я создал виджет который переопределил метод "#{name}=", чтобы он также вызывал событие на месте. Это немного сложнее, но при этом вся магия сосредоточена в одном классе, а код остается кратким.

person Alexis Andersen    schedule 14.10.2014