简体   繁体   中英

Knockout computed data-binding with Capybara not working

I have a knockout view-model with a computed field, and when I fill out the form manually it works fine, but in my Capybara test using fill_in, it seems like knockout doesn't recognize that the input field changed, and so it doesn't update the select options for the computed field. Is there a way to get knockout computed working with capybara? Here's my spec:

it "saves a new appointment for driver", :js => true do
  date = 1.day.from_now.saturday? ? 2.days.from_now : 1.day.from_now

  driver = FactoryGirl.create(:driver, field_worker_name: Driver::DEFAULT_FIELD_WORKER_NAME)
  visit "/drivers/#{driver.id}"
  click_button 'Schedule An Appointment'
  fill_in("case_details_appointment_date", :with => date.strftime("%Y/%m/%d"))
  select("12 pm - 2 pm", :from => "case_details_appointment_time")
  select("Fund Enrollment", :from => "case_details_appointment_reason")
  fill_in("case-notes", :with => "Some Appointment Notes")
  click_button "Add Appointment"

  expect(page).to have_content 'Case was successfully created'
  expect(page).to have_selector("#schedule-appointment")

  driver_case = driver.reload.cases.last
  driver_case.type.should == 'schedule_appointment'

  expect(page).to have_content 'Case History'
  expect(page).to have_content driver_case.updated_at.strftime("%Y/%m/%d")
end

And the relevant view

<div class="inline col-sm-6">
  <%= detail_fields.label :appointment_date, "What is the date for the appointment?", class: 'required' %>
  <div class="input-group">
    <span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span></span>
    <%= detail_fields.text_field :appointment_date,
    placeholder: "yyyy/mm/dd",
    class: 'form-control date-input',
      type: 'tel',
      'data-bind' => "value: date, optionsCaption: 'yyyy/mm/dd'" %>
    </div>
  </div>
  <div class="inline col-sm-6">
    <%= detail_fields.label :appointment_time, 'What time is the appointment?', class: 'required' %>
    <%= detail_fields.select :appointment_time, Case::APPOINTMENT_WEEKDAYS,
    { prompt: "Select an Appointment Time" },
    {class: 'form-control', required: 'required', 'data-bind' => 'options: available_timeslots'} %>
  </div>
  <div class="inline col-sm-6">
    <%= detail_fields.label :appointment_reason, 'What is the reason for the appointment?', class: 'required' %>
    <%= detail_fields.select :appointment_reason,
    ['Fund Enrollment', 'General Information', 'ACA Navigation', 'Claims Assistance'],
    { prompt: "Select an Appointment Reason" },
    {class: 'form-control', required: 'required'} %>
  </div>
</div>

And the knockout view-model

ready = ->
  HEALTHFUND.AppointmentViewModel = {}
  HEALTHFUND.AppointmentViewModel = (->

    @date = ko.observable()

    @weekday_timeslots = ['10 am - 12 pm', '12 pm - 2 pm', '2 pm - 4 pm', '4 pm - 6 pm', '6 pm - 9 pm', '9 pm - 12 am']
    @sunday_timeslots = ['12 pm - 2 pm', '2 pm - 4 pm', '4 pm - 6 pm', '6 pm - 8 pm']
    @available_timeslots = ko.computed =>
      input_date = new Date(@date()).getDay()

      if input_date == 0
        return @sunday_timeslots
      else if input_date < 6
        return @weekday_timeslots
      else
        return []

  )()

$(document).ready ready
$(document).on "page:load", ready

I ended up using phantomjs/poltergeist and had to use the element.native.send_key method to get knockout to recognize that the input value changed. Hope this helps someone!

it "saves a new appointment for driver", js: true, driver: :poltergeist do
  date = 1.day.from_now.saturday? ? 2.days.from_now : 1.day.from_now

  driver = FactoryGirl.create(:driver, field_worker_name: Driver::DEFAULT_FIELD_WORKER_NAME)
  visit "/drivers/#{driver.id}"
  click_button 'Schedule An Appointment'
  find('input#case_details_appointment_date').native.send_key(date.strftime("%Y/%m/%d"))
  find('#case_details_appointment_time').click
  select("12 pm - 2 pm", :from => "case_details_appointment_time")
  select("Fund Enrollment", :from => "case_details_appointment_reason")
  fill_in("case-notes", :with => "Some Appointment Notes")
  click_button "Schedule Appointment"

  expect(page).to have_content 'Case was successfully created'
  expect(page).to have_selector("#schedule-appointment")

  driver_case = driver.reload.cases.last
  driver_case.type.should == 'schedule_appointment'

  expect(page).to have_content 'Case History'
  expect(page).to have_content driver_case.updated_at.strftime("%Y/%m/%d")
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM