© 2018 WebHive

Заполняем поля даты с capybara

В процессе написания теста формы для cucumber столкнулся с проблемой заполнения поля типа дата. Как известно стандартный рельсовый вариант состоит из трёх select-ов где выбираются соответственно год, месяц и день. Какого-то встроенного решения для заполнения такого вида полей я к своему удивлению не нашёл. Ниже напишу как проблема была разрешена.

Собственно решение задачи описано вот тут [https://gist.github.com/szimek/558786], но распишу подробнее да и опишу возникшие грабли.

Создаём модуль lib\cucumber\rails\capybara_select_dates_and_times.rb следующего содержимого

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
require "xpath" # XPath is a separate gem now

module Cucumber
module Rails
module CapybaraSelectDatesAndTimes
def select_date(field, options = {})
date = Date.parse(options[:with])
selector = %Q{.//fieldset[contains(./legend, "#{field}")]}
within(:xpath, selector) do
find(:xpath, '//select[contains(@id, "_1i")]').find(:xpath, ::XPath::HTML.option(date.year.to_s)).select_option
find(:xpath, '//select[contains(@id, "_2i")]').find(:xpath, ::XPath::HTML.option(date.strftime('%B').to_s)).select_option
find(:xpath, '//select[contains(@id, "_3i")]').find(:xpath, ::XPath::HTML.option(date.day.to_s)).select_option
end
end

def select_time(field, options = {})
time = Time.parse(options[:with])
selector = %Q{.//fieldset[contains(./legend, "#{field}")]}
within(:xpath, selector) do
find(:xpath, '//select[contains(@id, "_4i")]').find(:xpath, ::XPath::HTML.option(time.hour.to_s.rjust(2,'0'))).select_option
find(:xpath, '//select[contains(@id, "_5i")]').find(:xpath, ::XPath::HTML.option(time.min.to_s.rjust(2,'0'))).select_option
end
end

def select_datetime(field, options = {})
select_date(field, options)
select_time(field, options)
end
end
end
end

Собственно проблемой тут стали селекторы для группы полей — в данном случае это fieldset с label-ом внутри, что само по себе и правильно, но в моём случае использовался twitter bootstrap и селекторы пришлось «доработать напильником».

Подключаем его в features\support\env.rb

1
2
3
4
5
6
7
...

require 'cucumber/rails/capybara_select_dates_and_times'

...

World(Cucumber::Rails::CapybaraSelectDatesAndTimes)

Ну и добавляем в features\step_definitions\web_steps.rb

1
2
3
4
5
6
7
8
9
10
11
When /^(?:|I )select "([^\"]*)" as the "([^\"]*)" time$/ do |time, selector|
select_time(selector, :with => time)
end

When /^(?:|I )select "([^\"]*)" as the "([^\"]*)" date$/ do |date, selector|
select_date(selector, :with => date)
end

When /^(?:|I )select "([^\"]*)" as the "([^\"]*)" date and time$/ do |datetime, selector|
select_datetime(selector, :with => datetime)
end

Теперь в сценариях можно заполнять поля следующим образом

1
2
3
....
And select "1/1/1980" as the "Date of birth" date
...

Здесь 1/1/1980 это требуемая дата в произвольной форме. Оно внутре парсится через Date.parse(...), а Date of birth это label поля.

Комментарии