From d6f20e3fb8a2ca53cba3d0fd90fbf8d9a9e364ae Mon Sep 17 00:00:00 2001 From: Antony Date: Tue, 26 Sep 2023 17:27:41 +1000 Subject: [PATCH 1/2] Support time inputs Do not modify time input value in JS Extract time inputs to seperate test file The test inputs load a data attribute for an SVG icon. This is changing the count of network requests in unrelated tests. Add support for week and month inputs --- lib/capybara/cuprite/javascripts/index.js | 5 +- lib/capybara/cuprite/node.rb | 12 ++ spec/features/session_spec.rb | 234 ++++++++++++++++------ spec/support/views/time_inputs.erb | 15 ++ 4 files changed, 199 insertions(+), 67 deletions(-) create mode 100644 spec/support/views/time_inputs.erb diff --git a/lib/capybara/cuprite/javascripts/index.js b/lib/capybara/cuprite/javascripts/index.js index 81bc8db8..5793a5d2 100644 --- a/lib/capybara/cuprite/javascripts/index.js +++ b/lib/capybara/cuprite/javascripts/index.js @@ -127,12 +127,9 @@ class Cuprite { this.trigger(node, "focus"); this.setValue(node, ""); - if (node.type == "number" || node.type == "date" || node.type == "range") { + if (node.type == "number" || node.type == "date" || node.type == "range" || node.type == "time" || node.type == "month" || node.type == "week") { this.setValue(node, value); this.input(node); - } else if (node.type == "time") { - this.setValue(node, new Date(value).toTimeString().split(" ")[0]); - this.input(node); } else if (node.type == "datetime-local") { value = new Date(value); let year = value.getFullYear(); diff --git a/lib/capybara/cuprite/node.rb b/lib/capybara/cuprite/node.rb index f7e68f44..5928503d 100644 --- a/lib/capybara/cuprite/node.rb +++ b/lib/capybara/cuprite/node.rb @@ -103,6 +103,18 @@ def set(value, options = {}) command(:select_file, files) when "color" node.evaluate("this.setAttribute('value', '#{value}')") + when 'date' + value = value.to_date.iso8601 if !value.is_a?(String) && value.respond_to?(:to_date) + command(:set, value.to_s) + when "time" + value = value.to_time.strftime("%H:%M") if !value.is_a?(String) && value.respond_to?(:to_time) + command(:set, value.to_s) + when "month" + value = value.to_date.strftime("%Y-%m") if !value.is_a?(String) && value.respond_to?(:to_date) + command(:set, value.to_s) + when "week" + value = value.to_date.strftime("%G-W%V") if !value.is_a?(String) && value.respond_to?(:to_date) + command(:set, value.to_s) else command(:set, value.to_s) end diff --git a/spec/features/session_spec.rb b/spec/features/session_spec.rb index 277d5384..b40ef3b9 100644 --- a/spec/features/session_spec.rb +++ b/spec/features/session_spec.rb @@ -162,86 +162,194 @@ end describe "Node#set" do - before do - @session.visit("/cuprite/with_js") - @session.find(:css, "#change_me").set("Hello!") - end + context "with_js" do + before do + @session.visit("/cuprite/with_js") + @session.find(:css, "#change_me").set("Hello!") + end - it "fires the change event" do - expect(@session.find(:css, "#changes").text).to eq("Hello!") - end + it "fires the change event" do + expect(@session.find(:css, "#changes").text).to eq("Hello!") + end - it "fires the input event" do - expect(@session.find(:css, "#changes_on_input").text).to eq("Hello!") - end + it "fires the input event" do + expect(@session.find(:css, "#changes_on_input").text).to eq("Hello!") + end - it "accepts numbers in a maxlength field" do - element = @session.find(:css, "#change_me_maxlength") - element.set 100 - expect(element.value).to eq("100") - end + it "accepts numbers in a maxlength field" do + element = @session.find(:css, "#change_me_maxlength") + element.set 100 + expect(element.value).to eq("100") + end - it "accepts negatives in a number field" do - element = @session.find(:css, "#change_me_number") - element.set(-100) - expect(element.value).to eq("-100") - end + it "accepts negatives in a number field" do + element = @session.find(:css, "#change_me_number") + element.set(-100) + expect(element.value).to eq("-100") + end - it "fires the keydown event" do - expect(@session.find(:css, "#changes_on_keydown").text).to eq("6") - end + it "fires the keydown event" do + expect(@session.find(:css, "#changes_on_keydown").text).to eq("6") + end - it "fires the keyup event" do - expect(@session.find(:css, "#changes_on_keyup").text).to eq("6") - end + it "fires the keyup event" do + expect(@session.find(:css, "#changes_on_keyup").text).to eq("6") + end - it "fires the keypress event" do - expect(@session.find(:css, "#changes_on_keypress").text).to eq("6") - end + it "fires the keypress event" do + expect(@session.find(:css, "#changes_on_keypress").text).to eq("6") + end - it "fires the focus event" do - expect(@session.find(:css, "#changes_on_focus").text).to eq("Focus") - end + it "fires the focus event" do + expect(@session.find(:css, "#changes_on_focus").text).to eq("Focus") + end - it "fires the blur event" do - expect(@session.find(:css, "#changes_on_blur").text).to eq("Blur") - end + it "fires the blur event" do + expect(@session.find(:css, "#changes_on_blur").text).to eq("Blur") + end - it "fires the keydown event before the value is updated" do - expect(@session.find(:css, "#value_on_keydown").text).to eq("Hello") - end + it "fires the keydown event before the value is updated" do + expect(@session.find(:css, "#value_on_keydown").text).to eq("Hello") + end - it "fires the keyup event after the value is updated" do - expect(@session.find(:css, "#value_on_keyup").text).to eq("Hello!") - end + it "fires the keyup event after the value is updated" do + expect(@session.find(:css, "#value_on_keyup").text).to eq("Hello!") + end - it "clears the input before setting the new value" do - element = @session.find(:css, "#change_me") - element.set "" - expect(element.value).to eq("") - end + it "clears the input before setting the new value" do + element = @session.find(:css, "#change_me") + element.set "" + expect(element.value).to eq("") + end - it "supports special characters" do - element = @session.find(:css, "#change_me") - element.set "$52.00" - expect(element.value).to eq("$52.00") - end + it "supports special characters" do + element = @session.find(:css, "#change_me") + element.set "$52.00" + expect(element.value).to eq("$52.00") + end - it "attaches a file when passed a Pathname" do - filename = Pathname.new("spec/tmp/a_test_pathname").expand_path - File.write(filename, "text") + it "attaches a file when passed a Pathname" do + filename = Pathname.new("spec/tmp/a_test_pathname").expand_path + File.write(filename, "text") + + element = @session.find(:css, "#change_me_file") + element.set(filename) + expect(element.value).to eq("C:\\fakepath\\a_test_pathname") + ensure + FileUtils.rm_f(filename) + end - element = @session.find(:css, "#change_me_file") - element.set(filename) - expect(element.value).to eq("C:\\fakepath\\a_test_pathname") - ensure - FileUtils.rm_f(filename) + it "sets a value for a color input" do + element = @session.find(:css, "#change_me_color") + element.set("#ddeeff") + expect(element.value).to eq("#ddeeff") + end end - it "sets a value for a color input" do - element = @session.find(:css, "#change_me_color") - element.set("#ddeeff") - expect(element.value).to eq("#ddeeff") + # The time inputs are loading SVG icons as data: urls. + # This is causing other unrelated tests to break. + # Keep the time inputs (And others with SVG icons) in their own file + context "time_inputs" do + before(:each) do + @session.visit("/cuprite/time_inputs") + end + + it "sets a value for a time input" do + element = @session.find(:css, "#change_me_time") + element.set("17:21") + expect(element.value).to eq("17:21") + end + + it "sets a value for a time input with a time object" do + element = @session.find(:css, "#change_me_time") + element.set(Time.new(2023, 9, 26, 17, 21)) + expect(element.value).to eq("17:21") + end + + it "sets a value for a time input with a date object" do + element = @session.find(:css, "#change_me_time") + element.set(Date.new(2023, 9, 26)) + expect(element.value).to eq("00:00") + end + + it "sets a value for a time input with a datetime object" do + element = @session.find(:css, "#change_me_time") + element.set(DateTime.new(2023, 9, 26, 17, 21)) + expect(element.value).to eq("17:21") + end + + it "sets a value for a date input" do + element = @session.find(:css, "#change_me_date") + element.set("2023-09-26") + expect(element.value).to eq("2023-09-26") + end + + it "sets a value for a date input with a date object" do + element = @session.find(:css, "#change_me_date") + element.set(Date.new(2023, 9, 26)) + expect(element.value).to eq("2023-09-26") + end + + it "sets a value for a date input with a time object" do + element = @session.find(:css, "#change_me_date") + element.set(Time.new(2023, 9, 26, 17, 21)) + expect(element.value).to eq("2023-09-26") + end + + it "sets a value for a date input with a datetime object" do + element = @session.find(:css, "#change_me_date") + element.set(DateTime.new(2023, 9, 26, 17, 21)) + expect(element.value).to eq("2023-09-26") + end + + it "sets a value for a month input" do + element = @session.find(:css, "#change_me_month") + element.set("2023-09") + expect(element.value).to eq("2023-09") + end + + it "sets a value for a month input with a date object" do + element = @session.find(:css, "#change_me_month") + element.set(Date.new(2023, 9, 26)) + expect(element.value).to eq("2023-09") + end + + it "sets a value for a month input with a time object" do + element = @session.find(:css, "#change_me_month") + element.set(Time.new(2023, 9, 26, 17, 21)) + expect(element.value).to eq("2023-09") + end + + it "sets a value for a month input with a datetime object" do + element = @session.find(:css, "#change_me_month") + element.set(DateTime.new(2023, 9, 26, 17, 21)) + expect(element.value).to eq("2023-09") + end + + + it "sets a value for a week input" do + element = @session.find(:css, "#change_me_week") + element.set("2023-W39") + expect(element.value).to eq("2023-W39") + end + + it "sets a value for a week input with a date object" do + element = @session.find(:css, "#change_me_week") + element.set(Date.new(2023, 9, 26)) + expect(element.value).to eq("2023-W39") + end + + it "sets a value for a week input with a time object" do + element = @session.find(:css, "#change_me_week") + element.set(Time.new(2023, 9, 26, 17, 21)) + expect(element.value).to eq("2023-W39") + end + + it "sets a value for a week input with a datetime object" do + element = @session.find(:css, "#change_me_week") + element.set(DateTime.new(2023, 9, 26, 17, 21)) + expect(element.value).to eq("2023-W39") + end end end diff --git a/spec/support/views/time_inputs.erb b/spec/support/views/time_inputs.erb new file mode 100644 index 00000000..46d7d971 --- /dev/null +++ b/spec/support/views/time_inputs.erb @@ -0,0 +1,15 @@ + + + + cuprite with_js + + + + + +

+

+

+

+ + From 8a17f9224c81dcfb99b5369de7da510a169c83df Mon Sep 17 00:00:00 2001 From: Antony Date: Wed, 26 Feb 2025 21:19:14 +1100 Subject: [PATCH 2/2] Use double quoted string --- lib/capybara/cuprite/node.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/capybara/cuprite/node.rb b/lib/capybara/cuprite/node.rb index 5928503d..eb5f89e3 100644 --- a/lib/capybara/cuprite/node.rb +++ b/lib/capybara/cuprite/node.rb @@ -103,7 +103,7 @@ def set(value, options = {}) command(:select_file, files) when "color" node.evaluate("this.setAttribute('value', '#{value}')") - when 'date' + when "date" value = value.to_date.iso8601 if !value.is_a?(String) && value.respond_to?(:to_date) command(:set, value.to_s) when "time"