Самым большим препятствием при тестировании ExtJS с Selenium является то, что ExtJS не отображает стандартные элементы HTML, а Selenium IDE наивно (и справедливо) генерирует команды, нацеленные на элементы, которые просто действуют как декор - лишние элементы, которые помогают ExtJS со всем рабочим столом. Смотри и чувствуй. Вот несколько советов и приемов, которые я собрал при написании автоматического теста Selenium для приложения ExtJS.
Общие советы
Расположение элементов
При создании тестовых примеров Selenium путем записи действий пользователя с помощью Selenium IDE в Firefox, Selenium будет основывать записанные действия на идентификаторах элементов HTML. Однако для большинства интерактивных элементов ExtJS использует сгенерированные идентификаторы, такие как «ext-gen-345», которые могут измениться при последующем посещении той же страницы, даже если не было внесено никаких изменений в код. После записи действий пользователя для теста необходимо вручную выполнить все действия, которые зависят от сгенерированных идентификаторов, и заменить их. Возможны два типа замен:
Замена локатора идентификатора на локатор CSS или XPath
Локаторы CSS начинаются с «css =», а локаторы XPath начинаются с «//» (префикс «xpath =» необязателен). Локаторы CSS менее подробны, их легче читать, и им следует отдавать предпочтение перед локаторами XPath. Однако могут быть случаи, когда необходимо использовать локаторы XPath, потому что локатор CSS просто не может его вырезать.
Выполнение JavaScript
Некоторым элементам требуется больше, чем простое взаимодействие с мышью и клавиатурой из-за сложной визуализации, выполняемой ExtJS. Например, Ext.form.CombBox на самом деле не <select>
элемент, а текстовый ввод с отдельным раскрывающимся списком, который находится где-то в нижней части дерева документа. Чтобы правильно имитировать выбор ComboBox, можно сначала смоделировать щелчок по стрелке раскрывающегося списка, а затем щелкнуть по появившемуся списку. Однако поиск этих элементов с помощью локаторов CSS или XPath может быть обременительным. Альтернативный вариант - найти сам компонент ComoBox и вызвать на нем методы для имитации выбора:
var combo = Ext.getCmp('genderComboBox');
combo.setValue('female');
combo.fireEvent('select');
В Selenium runScript
команду можно использовать для выполнения вышеуказанной операции в более краткой форме:
with (Ext.getCmp('genderComboBox')) { setValue('female'); fireEvent('select'); }
Как справиться с AJAX и медленным рендерингом
Selenium имеет разновидности «* AndWait» для всех команд ожидания загрузки страницы, когда действие пользователя приводит к переходу или перезагрузке страницы. Однако, поскольку выборка AJAX не включает фактическую загрузку страницы, эти команды нельзя использовать для синхронизации. Решение состоит в том, чтобы использовать визуальные подсказки, такие как наличие / отсутствие индикатора прогресса AJAX или появление строк в сетке, дополнительных компонентов, ссылок и т. Д. Например:
Command: waitForElementNotPresent
Target: css=div:contains('Loading...')
Иногда элемент появляется только через определенное время, в зависимости от того, насколько быстро ExtJS отрисовывает компоненты после того, как действие пользователя приводит к изменению представления. Вместо использования произвольных задержек с pause
командой, идеальный метод - подождать, пока интересующий элемент не окажется в пределах нашей досягаемости. Например, чтобы щелкнуть элемент после того, как он появится:
Command: waitForElementPresent
Target: css=span:contains('Do the funky thing')
Command: click
Target: css=span:contains('Do the funky thing')
Использование произвольных пауз - не лучшая идея, поскольку различия во времени, возникающие в результате выполнения тестов в разных браузерах или на разных машинах, сделают тестовые примеры нестабильными.
Не кликабельные элементы
Некоторые элементы не могут быть активированы click
командой. Это потому, что прослушиватель событий фактически находится в контейнере, наблюдая за событиями мыши на его дочерних элементах, которые в конечном итоге всплывают до родительского. Вкладка - один из примеров. Чтобы щелкнуть вкладку a, вы должны смоделировать mouseDown
событие на метке вкладки:
Command: mouseDownAt
Target: css=.x-tab-strip-text:contains('Options')
Value: 0,0
Проверка поля
Поля формы (компоненты Ext.form. *), Которые имеют связанные регулярные выражения или vtypes для проверки, будут запускать проверку с определенной задержкой (см. validationDelay
Свойство, которое по умолчанию установлено на 250 мс), после того, как пользователь вводит текст или сразу после того, как поле теряет фокус - или размывает (см. validateOnDelay
свойство). Чтобы запустить проверку поля после выдачи команды типа Selenium для ввода текста внутри поля, вам необходимо выполнить одно из следующих действий:
Запуск отложенной проверки
ExtJS запускает таймер задержки проверки, когда поле получает события нажатия клавиш. Чтобы запустить этот таймер, просто вызовите фиктивное событие keyup (не имеет значения, какой ключ вы используете, поскольку ExtJS игнорирует его), за которым следует короткая пауза, которая длиннее, чем validationDelay:
Command: keyUp
Target: someTextArea
Value: x
Command: pause
Target: 500
Запуск немедленной проверки
Вы можете ввести в поле событие размытия, чтобы вызвать немедленную проверку:
Command: runScript
Target: someComponent.nameTextField.fireEvent("blur")
Проверка результатов проверки
После проверки вы можете проверить наличие или отсутствие поля ошибки:
Command: verifyElementNotPresent
Target: //*[@id="nameTextField"]/../*[@class="x-form-invalid-msg" and not(contains(@style, "display: none"))]
Command: verifyElementPresent
Target: //*[@id="nameTextField"]/../*[@class="x-form-invalid-msg" and not(contains(@style, "display: none"))]
Обратите внимание, что проверка «display: none» необходима, потому что после отображения поля ошибки, а затем его необходимо скрыть, ExtJS просто скроет поле ошибки, а не полностью удалит его из дерева DOM.
Советы по отдельным элементам
Щелчок по кнопке Ext.form.Button
Опция 1
Команда: нажмите Цель: css = button: contains ('Сохранить')
Выбирает кнопку по ее подписи
Вариант 2
Команда: нажмите кнопку Target: css = # save-options
Выбирает кнопку по ее id
Выбор значения из Ext.form.ComboBox
Command: runScript
Target: with (Ext.getCmp('genderComboBox')) { setValue('female'); fireEvent('select'); }
Сначала устанавливает значение, а затем явно запускает событие выбора, если есть наблюдатели.