ruby-on-rails - tests - rspec rails 5
¿Cómo seleccionar la fecha de un cuadro de selección usando Capybara en Rails 3? (11)
Dado el siguiente código Formtastic representa el selector de fecha predeterminado de Rails:
= f.input :born_on, end_year: Time.now.year, start_year: 60.years.ago.year
En su especificación, divida la fecha en llamadas separadas a cada etiqueta de selección individual:
select ''1956'', from: ''person_born_on_1i''
select ''July'', from: ''person_born_on_2i''
select ''9'', from: ''person_born_on_3i''
No me gusta que este código sea tan consciente del HTML, pero sí funciona con las versiones de gemas en este momento.
Gemas:
- Capibara 2.1.0
- Formtastic 2.2.1
- Rieles 3.2.13
- RSpec 2.13.0
Estoy escribiendo una especificación para un controlador en el proyecto de Rails 3 usando RSpec y Capybara, y quiero seleccionar la fecha actual de un cuadro de selección. Lo intenté:
select Date.today, :from => ''Date of birth''
pero la especificación falla y obtengo un error:
Fallo / Error: seleccione Fecha.al día,: desde => ''Fecha de nacimiento'' NoMethodError: método indefinido `to_xpath ''para Lun, 18 Jul 2011: Fecha
¿Como arreglarlo?
PD En el archivo de vista utilizo la etiqueta simple_form_for y el cuadro de selección se genera por código:
f.input :date_of_birth
Debe especificar el valor exacto tal como está en el menú de selección en html. Entonces, si su selección tiene valores como "2011/01/01", entonces necesita escribir:
select ''2011/01/01'', :from => ''Date of birth''
Tu código falla porque pasas un objeto de fecha.
En mi situación particular, estoy agregando potencialmente múltiples campos de selección de fecha a la página con la función accepts_nested_attributes_for
. Esto significa que no estoy seguro de cuál será la id
completa o el name
de los campos.
Aquí está la solución que surgió en caso de que ayude a alguien más en Google:
Estoy envolviendo el campo de selección de fecha en un contenedor div con una clase:
<div class=''date-of-birth-container''>
<%= f.date_select :date_of_birth %>
</div>
Luego, en mi especificación de funciones:
within ''.date-of-birth-container'' do
find("option[value=''1'']", text: ''January'').select_option
find("option[value=''1'']", text: ''1'').select_option
find("option[value=''1955'']").select_option
end
Aquí hay un método de ayuda que escribí para él:
def select_date_within_css_selector(date, css_selector)
month_name = Date::MONTHNAMES.fetch(date.month)
within css_selector do
find("option[value=''#{date.month}'']", text: month_name).select_option
find("option[value=''#{date.day}'']", text: date.day.to_s).select_option
find("option[value=''#{date.year}'']").select_option
end
end
Luego usando el ayudante:
select_date_within_css_selector(Date.new(1955, 1, 1), ''.date-of-birth-container'')
Encontré una solución limpia para rspec y capybara para probar usando métodos de selección de fecha y hora, donde en tu HTML utilizas una selección de fecha y hora o selección de fecha. Esto funciona con Rails 4, RSpec 3.1 y Capybara 2.4.4.
Diga en su formulario HTML que tiene lo siguiente:
<%= f.datetime_select(:start_date, {default: DateTime.now, prompt: {day: ''Choose day'', month: "Choose month", year: "Choose year"}}, {class: "date-select"}) %>
el asistente de DateTime Select View creará 5 campos de selección con ids como id="modelname_start_date_1i"
, donde el ID the se adjunta con 1i, 2i, 3i, 4i, 5i. Por defecto Año, Mes, Día, Hora, Minuto. Si cambia el orden de los campos, asegúrese de cambiar la función de ayuda a continuación.
1) Crear un Ayudante de funciones para las fechas y horas de ayuda
spec / support / helpers / date_time_select_helpers.rb
module Features
module DateTimeSelectHelpers
def select_date_and_time(date, options = {})
field = options[:from]
select date.strftime(''%Y''), :from => "#{field}_1i" #year
select date.strftime(''%B''), :from => "#{field}_2i" #month
select date.strftime(''%-d''), :from => "#{field}_3i" #day
select date.strftime(''%H''), :from => "#{field}_4i" #hour
select date.strftime(''%M''), :from => "#{field}_5i" #minute
end
def select_date(date, options = {})
field = options[:from]
select date.strftime(''%Y''), :from => "#{field}_1i" #year
select date.strftime(''%B''), :from => "#{field}_2i" #month
select date.strftime(''%-d''), :from => "#{field}_3i" #day
end
end
end
Tenga en cuenta que para el día que uso %-d
que le da un valor numérico no acolchado (es decir, 4) en lugar de %d
que tiene un valor numérico sin acolchado (es decir, 04). Compruebe los formatos de fecha con strftime
2) Luego debe incluir sus métodos de ayuda de fecha y hora en spec / support / helpers.rb para que pueda usarlos en cualquier archivo de especificación.
require ''support/helpers/date_time_select_helpers''
RSpec.configure do |config|
config.include Features::DateTimeSelectHelpers, type: :feature
end
3) En su archivo de especificaciones puede llamar a su ayudante. Por ejemplo:
feature ''New Post'' do
scenario ''Add a post'' do
visit new_post_path
fill_in "post[name]", with: "My post"
select_date_and_time(2.days.from_now, from:"post_start_date")
click_button "Submit"
expect(page).to have_content "Your post was successfully saved"
end
end
Gracias a Dylan por señalarlo, pero en caso de que alguien esté buscando la versión de pepino, puede usar esto:
select_date("Date of birth", :with => "1/1/2011")
Para obtener más información, vea select_date .
Lo siguiente funcionó para mí, usando un date_field:
fill_in "Date", with: DateTime.now.strftime(''%m/%d/%Y'')
Para Rails 4 , en caso de que alguien llegue a esta pregunta sin estar limitado a Rails 3.
select ''2020'', from: ''field_name_{}_1i''
select ''January'', from: ''field_name_{}_2i''
select ''1'', from: ''field_name_{}_3i''
Por supuesto, puede extraer esto a un ayudante y hacerlo dinámico.
Parece que este ha sido suficientemente cubierto, pero vea los documentos de Capybara para obtener una respuesta oficial. Puede seleccionar por nombre, id o texto de etiqueta.
Tenía el mismo problema. Busqué en Google mucho y lo resolvió de esta manera:
Escribió macros de selección de fecha en /spec/request_macros.rb El método select_by_id es necesario para mí, porque el mes depende de la traducción
module RequestMacros def select_by_id(id, options = {}) field = options[:from] option_xpath = "//*[@id=''#{field}'']/option[#{id}]" option_text = find(:xpath, option_xpath).text select option_text, :from => field end def select_date(date, options = {}) field = options[:from] select date.year.to_s, :from => "#{field}_1i" select_by_id date.month, :from => "#{field}_2i" select date.day.to_s, :from => "#{field}_3i" end end
Los agregué a mi /spec/spec_helper.rb
config.include RequestMacros, :type => :request
Ahora en mis pruebas de integración en especificaciones / solicitudes puedo usar
select_date attr[:birthday], :from => "user_birthday"
Gracias a http://jasonneylon.wordpress.com/2011/02/16/selecting-from-a-dropdown-generically-with-capybara/ y https://gist.github.com/558786 :)
Una ligera adaptación de la respuesta de Markus:
def select_date(date, options = {})
raise ArgumentError, ''from is a required option'' if options[:from].blank?
field = options[:from].to_s
select date.year.to_s, :from => "#{field}_1i"
select Date::MONTHNAMES[date.month], :from => "#{field}_2i"
select date.day.to_s, :from => "#{field}_3i"
end
con crédito para Markus Hartmair por una excelente solución, prefiero usar etiquetas como selectores debido a una mejor legibilidad. Entonces mi versión de su módulo de ayuda es:
module SelectDateHelper
def select_date(date, options = {})
field = options[:from]
base_id = find(:xpath, ".//label[contains(.,''#{field}'')]")[:for]
year, month, day = date.split('','')
select year, :from => "#{base_id}_1i"
select month, :from => "#{base_id}_2i"
select day, :from => "#{base_id}_3i"
end
end
llámalo así:
select_date "2012,Jan,1", :from => "From date"