mirror of
https://github.com/teamcapybara/capybara.git
synced 2022-11-09 12:08:07 -05:00
Set time and datetime-local fields via JS to support other locales
This commit is contained in:
parent
56458cb93d
commit
e8874a1cbc
4 changed files with 52 additions and 77 deletions
|
@ -6,6 +6,7 @@ Release date: unreleased
|
|||
* Support for using `select` with text inputs associated with a datalist element
|
||||
* `type` filter on `:button` selector
|
||||
* Support for server operating in https mode
|
||||
* Selenium driver now uses JS to fill_in date and time fields when passed date or time objects [Aleksei Gusev, Thomas Walpole]
|
||||
|
||||
# Version 3.0.3
|
||||
Release date: 2018-04-30
|
||||
|
@ -21,7 +22,7 @@ Release date: 2018-04-13
|
|||
|
||||
### Fixes
|
||||
|
||||
* Fixexpression filter descriptions in some selector failure messages
|
||||
* Fix expression filter descriptions in some selector failure messages
|
||||
* Fix compounding of negated matechers - Issue #2010
|
||||
|
||||
# Version 3.0.1
|
||||
|
|
|
@ -1,19 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Capybara::Selenium::Node < Capybara::Driver::Node
|
||||
SET_FORMATS = Hash.new(date: '%Y-%m-%d', time: '%H:%M', datetime: "%m%d%Y\t%I%M%P").merge(
|
||||
firefox: {
|
||||
date: '%Y-%m-%d',
|
||||
time: '%H:%M',
|
||||
datetime: "%m%d%Y\t%I%M%P"
|
||||
},
|
||||
chrome: {
|
||||
date: '%m%d%Y',
|
||||
time: '%I%M%P',
|
||||
datetime: "%m%d%Y\t%I%M%P"
|
||||
}
|
||||
)
|
||||
|
||||
def visible_text
|
||||
native.text
|
||||
end
|
||||
|
@ -253,39 +240,35 @@ private
|
|||
yield
|
||||
end
|
||||
|
||||
def set_date(new_value) # rubocop:disable Naming/AccessorMethodName
|
||||
new_value = new_value.to_date.strftime('%Y-%m-%d') if new_value.respond_to?(:to_date)
|
||||
begin
|
||||
is_value_changing = new_value != value
|
||||
driver.execute_script(<<-JS, self)
|
||||
arguments[0].dispatchEvent(new Event('focus'));
|
||||
arguments[0].value = '#{new_value}';
|
||||
JS
|
||||
if is_value_changing
|
||||
driver.execute_script(<<-JS, self)
|
||||
arguments[0].dispatchEvent(new Event('input'));
|
||||
arguments[0].dispatchEvent(new Event('change'));
|
||||
JS
|
||||
end
|
||||
rescue Capybara::NotSupportedByDriverError
|
||||
set_text(new_value)
|
||||
end
|
||||
def set_date(value) # rubocop:disable Naming/AccessorMethodName
|
||||
return set_text(value) unless value.respond_to?(:to_date)
|
||||
# TODO: this would be better if locale can be detected and correct keystrokes sent
|
||||
update_value_js(value.to_date.strftime('%Y-%m-%d'))
|
||||
end
|
||||
|
||||
def set_time(value) # rubocop:disable Naming/AccessorMethodName
|
||||
if value.respond_to?(:to_time)
|
||||
set_text(value.to_time.strftime(SET_FORMATS[driver.browser_name][:time]))
|
||||
else
|
||||
set_text(value)
|
||||
end
|
||||
return set_text(value) unless value.respond_to?(:to_time)
|
||||
# TODO: this would be better if locale can be detected and correct keystrokes sent
|
||||
update_value_js(value.to_time.strftime('%H:%M'))
|
||||
end
|
||||
|
||||
def set_datetime_local(value) # rubocop:disable Naming/AccessorMethodName
|
||||
if value.respond_to?(:to_time)
|
||||
set_text(value.to_time.strftime(SET_FORMATS[driver.browser_name][:datetime]))
|
||||
else
|
||||
set_text(value)
|
||||
end
|
||||
return set_text(value) unless value.respond_to?(:to_time)
|
||||
# TODO: this would be better if locale can be detected and correct keystrokes sent
|
||||
update_value_js(value.to_time.strftime('%Y-%m-%dT%H:%M'))
|
||||
end
|
||||
|
||||
def update_value_js(value)
|
||||
driver.execute_script(<<-JS, self, value)
|
||||
if (document.activeElement !== arguments[0]){
|
||||
arguments[0].focus();
|
||||
}
|
||||
if (arguments[0].value != arguments[1]) {
|
||||
arguments[0].value = arguments[1]
|
||||
arguments[0].dispatchEvent(new InputEvent('input'));
|
||||
arguments[0].dispatchEvent(new Event('change', { bubbles: true }));
|
||||
}
|
||||
JS
|
||||
end
|
||||
|
||||
def set_file(value) # rubocop:disable Naming/AccessorMethodName
|
||||
|
|
|
@ -64,40 +64,4 @@ RSpec.describe "Capybara::Session with chrome" do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#fill_in' do
|
||||
before do
|
||||
@session = TestSessions::Chrome
|
||||
@session.visit('/form')
|
||||
end
|
||||
|
||||
context "Date/Time" do
|
||||
before do
|
||||
@session.execute_script <<-JS
|
||||
window.capybara = {formDateFiredEvents: []};
|
||||
['focus', 'input', 'change'].forEach(function(eventType) {
|
||||
document.getElementById('form_date')
|
||||
.addEventListener(eventType, function() { window.capybara.formDateFiredEvents.push(eventType) });
|
||||
});
|
||||
JS
|
||||
end
|
||||
|
||||
it "should generate standard events on changing value" do
|
||||
expect {
|
||||
@session.fill_in('form_date', with: Date.today)
|
||||
}.to change {
|
||||
@session.evaluate_script('window.capybara.formDateFiredEvents')
|
||||
}.to %w[focus input change]
|
||||
end
|
||||
|
||||
it "should not generate input and change events if the value is not changed" do
|
||||
expect {
|
||||
@session.fill_in('form_date', with: Date.today)
|
||||
@session.fill_in('form_date', with: Date.today)
|
||||
}.to change {
|
||||
@session.evaluate_script('window.capybara.formDateFiredEvents')
|
||||
}.to %w[focus input change focus]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -129,6 +129,33 @@ RSpec.shared_examples "Capybara::Session" do |session, mode|
|
|||
end
|
||||
end
|
||||
|
||||
context '#fill_in with Date' do
|
||||
before do
|
||||
session.visit('/form')
|
||||
session.execute_script <<-JS
|
||||
window.capybara_formDateFiredEvents = [];
|
||||
['focus', 'input', 'change'].forEach(function(eventType) {
|
||||
document.getElementById('form_date')
|
||||
.addEventListener(eventType, function() { window.capybara_formDateFiredEvents.push(eventType); });
|
||||
});
|
||||
JS
|
||||
# work around weird FF issue where it would create an extra focus issue in some cases
|
||||
session.find(:css, 'body').click
|
||||
end
|
||||
|
||||
it "should generate standard events on changing value" do
|
||||
session.fill_in('form_date', with: Date.today)
|
||||
expect(session.evaluate_script('window.capybara_formDateFiredEvents')).to eq %w[focus input change]
|
||||
end
|
||||
|
||||
it "should not generate input and change events if the value is not changed" do
|
||||
session.fill_in('form_date', with: Date.today)
|
||||
session.fill_in('form_date', with: Date.today)
|
||||
# Chrome adds an extra focus for some reason - ok for now
|
||||
expect(session.evaluate_script('window.capybara_formDateFiredEvents')).to eq(%w[focus input change])
|
||||
end
|
||||
end
|
||||
|
||||
context "#fill_in with { clear: Array } fill_options" do
|
||||
it 'should pass the array through to the element' do
|
||||
pending "selenium-webdriver/geckodriver doesn't support complex sets of characters" if marionette?(session)
|
||||
|
|
Loading…
Reference in a new issue