我如何 select datepicker 使用 page-object-gem 和 jqueryui_widgets

how do i select datepicker using page-object-gem and jqueryui_widgets

我正在尝试结合使用 jqueryui_widgets 和 page-object-gem 来测试日期选择器,但第一步失败了。

  on(HasADatepickerPage).the_datepicker = date

我收到这个错误:

Watir::Exception::ObjectReadOnlyException: object is read only {:id=>"datepicker", :tag_name=>"input or textarea", :type=>"(any text type)"}
./features/step_definitions/datepicker_steps.rb:8:in `/^I enter the date "([^\"]*)"$/'
./features/has_a_datepicker.feature:8:in `When I enter the date "10/05/2015"'

has_a_date_picker_page.rb(jqueryui_widgets 示例 datepicker_page.rb

class HasADatepickerPage
  include PageObject

  jqueryui_datepicker(:the_datepicker, :id => 'datepicker')

end

问题:

  1. 在 on(HasADatepickerPage).the_datepicker = date 之前我需要做什么?
  2. 在 (HasADatepickerPage) 之前我需要做什么。the_datepicker_select_day 天?

我克隆了 jqueryui_widgets 项目,运行 日期选择器功能测试,工作正常。我尽可能地模拟了我的解决方案。

我在下面收录了我的 html 页面中的片段以及我能想到的其他荣耀细节。

谢谢, 蒂姆

血淋淋的细节

我的网站 html 对比(jqueryui_widgets 示例 datepicker.html

<div class="forms">
<div class="ajaxformitem" rel="Please select the number of passengers traveling">
<div class="ajaxformitem" rel="Please Enter the Date of Travel" style="background: transparent none repeat scroll 0% 0%;">
<div class="ajaxformitemleft">
<div class="ajaxformitemright">
<input id="datepicker" class="corner required hasDatepicker" type="text" placeholder="Pick Up Date" value="" readonly="true" name="PickUpTime[Date]"/>
<select id="hour" class="corner required" name="PickUpTime_Hour">
<select id="minute" class="corner required" name="PickUpTime[Mnute]">
</div>
</div>

ui-日期选择器-div:

<div id="ui-datepicker-div" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all" style="position: absolute; top: 199px; left: 635.5px; z-index: 12; display: block;">
<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix ui-corner-all">
<a class="ui-datepicker-prev ui-corner-all" title="Prev" onclick="DP_jQuery_1440799766008.datepicker._adjustDate('#datepicker', -1, 'M');">
<a class="ui-datepicker-next ui-corner-all" title="Next" onclick="DP_jQuery_1440799766008.datepicker._adjustDate('#datepicker', +1, 'M');">
<div class="ui-datepicker-title">
</div>
<table class="ui-datepicker-calendar">
<thead>
<tbody>
</table>
</div>

has_a_datepicker.feature - 与示例相同

Feature: Using the JQueryUI Datepicker widget

  Background:
    Given I am on the has datepicker page


  Scenario: Testing datepicker jqueryui_widgets
    When I enter the date "10/05/2015"
    And I select day "25"
    Then the date should be "10/25/2015"

datepicker_steps.rb - the_datepicker 对比(datepicker_one 和 datepicker_two)

Given(/^I am on the has datepicker page$/) do
  visit(HomePage)
  on(HomePage).select_radio_for 'From'
  on(HomePage).select_service 'Airport'
end

When(/^I enter the date "([^\"]*)"$/) do |date|
  on(HasADatepickerPage).the_datepicker = date
end

And(/^I select day "(\d+)"$/) do |day|
  on(HasADatepickerPage).the_datepicker_select_day day
end

Then(/^the date should be "([^\"]*)"$/) do |day|
  #on(DatepickerPage).datepicker_one.should == day
  expect(on(HasADatepickerPage).the_datepicker).to eql day
end

您的 ui-datepicker-div 有:<input id="datepicker" readonly="true"> Watir 不允许您将文本发送到设置为只读的元素。删除该属性,这应该可以工作。

选择日期

如果您查看 datepicker methods,所有与日历的交互都假定日历已经显示。如果您查看 gem 的测试(功能),您会发现他们总是先输入文本字段,这会打开日历。只有在那之后,测试才会尝试与日历交互。

但是,由于您的文本字段是只读的,您无法输入文本字段来触发弹出窗口。因此,您需要单击文本字段。日期选择器访问器创建一个 {name}_element 方法来访问文本字段。因此,你可以这样做:

page.the_datepicker_element.click
page.the_datepicker_select_day('15')

设置日期

直接设置日期的{name}=方法对你的控件不起作用。该方法只是在文本字段中键入内容,只读是无效的。

您似乎有 2 个选择:

  1. 单击 Next/Previous 月份控件,直到获得正确的月份,然后单击 select 日期。
  2. 使用JavaScript直接输入文本字段。

除非在输入日期时应用程序例外引发事件,否则我建议使用选项 2。它更快且更不容易出错。虽然它不模仿用户,但测试 jQuery 小部件中的交互不应该是您的责任。

date = '08/13/2015'
page.execute_script("arguments[0].value='#{date}';", page.the_datepicker_element)

如果你真的想像用户一样输入值:

# These libraries are added to help with doing date comparisons
require 'date'
require 'active_support/time'

# The date you want to set
date = '12/13/2015'

# Open the calender
page.the_datepicker_element.click

# Determine if we need to navigate to a prior or future month
final_date = Date.strptime(date, '%m/%d/%Y')
current_date = Date.strptime(
    "#{page.the_datepicker_month} #{page.the_datepicker_year}",
    '%B %Y'
)
difference = (final_date.year * 12 + final_date.month) - (current_date.year * 12 + current_date.month)

# Navigate to the required month/year
if difference < 0
    difference.abs.times { page.the_datepicker_previous_month }
else
    difference.abs.times { page.the_datepicker_next_month }
end

# Select the day
page.the_datepicker_select_day(final_date.day.to_s)

如您所见,必须单击 next/previous 控件会增加很多复杂性。