Add an option for attach_file to allow modifying the elements style since they are so often hidden on the page

This commit is contained in:
Thomas Walpole 2016-12-30 12:33:57 -08:00
parent 007a095ee3
commit 4d6773811e
5 changed files with 39 additions and 4 deletions

View File

@ -230,6 +230,7 @@ module Capybara
# @option options [String] id Match fields that match the id attribute
# @option options [String] name Match fields that match the name attribute
# @option options [String, Array<String>] :class Match links that match the class(es) provided
# @option options [Hash] style A Hash of CSS styles to change before attempting to attach the file
#
# @return [Capybara::Node::Element] The file field element
def attach_file(locator, path, options={})
@ -237,10 +238,31 @@ module Capybara
Array(path).each do |p|
raise Capybara::FileNotFound, "cannot attach file, #{p} does not exist" unless File.exist?(p.to_s)
end
# Allow user to update the CSS style of the file input since they are so often hidden on a page
if style = options.delete(:style)
ff = find(:file_field, locator, options.merge({visible: :all}))
_update_style(ff, style)
end
find(:file_field, locator, options).set(path)
end
private
def _update_style(element, style)
script = <<-JS
var el = arguments[0];
var css = arguments[1];
for (var prop in css){
if (css.hasOwnProperty(prop)) {
el.style[prop] = css[prop]
}
}
JS
begin
session.execute_script(script, element, style)
rescue Capybara::NotSupportedByDriverError
warn "The :style option is not supported by the current driver - ignoring"
end
end
def _check_with_label(selector, checked, locator, options)
locator, options = nil, locator if locator.is_a? Hash

View File

@ -107,4 +107,12 @@ Capybara::SpecHelper.spec "#attach_file" do
end.to raise_error(Capybara::ElementNotFound)
end
end
context "with :style option", requires: [:js, :es_args] do
it "can change the CSS style of the file input field" do
@session.visit('/with_js')
expect { @session.attach_file("hidden_file", __FILE__) }.to raise_error Capybara::ElementNotFound
@session.attach_file("hidden_file", __FILE__, style: { opacity: 1, display: 'block' })
end
end
end

View File

@ -5,13 +5,13 @@ Capybara::SpecHelper.spec "#evaluate_script", requires: [:js] do
expect(@session.evaluate_script("1+3")).to eq(4)
end
it "should pass arguments to the script" do
it "should pass arguments to the script", requires: [:js, :es_args] do
@session.visit('/with_js')
@session.evaluate_script("document.getElementById('change').textContent = arguments[0]", "Doodle Funk")
expect(@session).to have_css('#change', text: 'Doodle Funk')
end
it "should support passing elements as arguments to the script" do
it "should support passing elements as arguments to the script", requires: [:js, :es_args] do
@session.visit('/with_js')
el = @session.find(:css, '#change')
@session.evaluate_script("arguments[0].textContent = arguments[1]", el, "Doodle Funk")

View File

@ -11,13 +11,13 @@ Capybara::SpecHelper.spec "#execute_script", requires: [:js] do
expect{ @session.execute_script("$('#change').text('Funky Doodle')") }.not_to raise_error
end
it "should pass arguments to the script" do
it "should pass arguments to the script", requires: [:js, :es_args] do
@session.visit('/with_js')
@session.execute_script("document.getElementById('change').textContent = arguments[0]", "Doodle Funk")
expect(@session).to have_css('#change', text: 'Doodle Funk')
end
it "should support passing elements as arguments to the script" do
it "should support passing elements as arguments to the script", requires: [:js, :es_args] do
@session.visit('/with_js')
el = @session.find(:css, '#change')
@session.execute_script("arguments[1].textContent = arguments[0]", "Doodle Funk", el)

View File

@ -110,6 +110,11 @@
<input type="test" name="with-key-events" id="with-key-events">
<p id="key-events-output"></p>
</p>
<p>
<input type="file" id="hidden_file" style="opacity:0; display: none;">
</p>
<script type="text/javascript">
// a javascript comment
var aVar = 123;