我正在使用React构建的页面上测试文件上传功能。 React页面有一个隐藏的文件输入字段,并带有一个onChange事件监听器。选择文件后,它将触发onChange并处理文件。我有一个使用Capybara和javascript公开隐藏输入的测试,使用Capybara的attach_file方法将文件附加到输入中,并检查以确保该文件已上传并出现在用户的文件列表中。此测试在Chrome中有效,并且使用Capybara的attach_file方法处理文件后,但在Firefox中不起作用-文件进入输入,但从未处理过。我怀疑由于某种原因,React无法在Firefox中检测到onChange或没有被触发。我需要测试才能在两种浏览器中使用。
我尝试将execute_script与适当的普通javascript(无jquery)结合使用,以在Firefox中创建和分发change和input事件,但没有运气。经过一切尝试,最终我得到的只是暴露的输入字段和其中显示的所选文件名。作为SDET,我必须按原样使用前端代码。
文件的反应输入
<input
className={css.hiddenInput}
onChange={event => {
actions.uploadAttachment(event, personOneId, personTwoId);
}}
ref={file => (this.file = file)}
type="file"
/>
Ruby / Capybara / javascript代码公开输入并附加文件
def expose_attachment_input
page.execute_script(
'document.querySelector(`input[class^=attachments__hidden-input]`)
.setAttribute(`style`, `visibility: visible; width: auto; height: auto;`);'
)
page.execute_script(
'document.querySelector(`input[class^=attachments__hidden-input]`)
.setAttribute(`name`, `attachments`);'
)
end
def add_new_attachment(attachment = 'some.gif')
expose_attachment_input
attach_file(
'attachments',
File.expand_path("./spec/files/#{attachment}")
)
end
在attach_file完成后,我尝试触发事件的一些示例
page.execute_script("document.getElementsByName('attachments')[0].dispatchEvent(new Event('change'))")
page.execute_script("document.getElementsByName('attachments')[0].dispatchEvent(new Event('input'))")
page.execute_script("document.getElementsByName('attachments')[0].dispatchEvent(new Event('change'), { bubbles: true })")
根据@Thomas Walpole的建议,我还尝试了以下操作并收到以下错误
page.attach_file(File.expand_path("./spec/files/some.gif"), make_visible: true)
Capybara::ExpectationNotMet: The style changes in :make_visible did not make the file input visible
attach_file(File.expand_path("./spec/files/some.gif”), make_visible: {visibility: 'visible', width: 'auto', height: 'auto'})
The hidden input temporarily flashes visible, then disappears and no file attachment is processed.
attach_file(File.expand_path("./spec/files/some.gif")) do
page.find('span', text: ‘Add Attachments’).click
end
Capybara::ElementNotFound: Unable to find visible file field nil with allow_self true
attach_file(File.expand_path("./spec/files/some.gif”), make_visible: true) do
page.find('span', text: ‘Add Attachments’).click
end
Capybara::ExpectationNotMet: The style changes in :make_visible did not make the file input visible
答案 0 :(得分:0)
它可以在Chrome中运行但不能在Firefox中运行的事实往往表明Capybara,geckodriver或您的应用程序存在错误,因此请确保您正在运行最新版本的Capybara和geckodriver。如果仍不能解决问题,您可以在附加文件后尝试单击另一个元素,以查看是否触发了模糊/更改事件(不同的浏览器可能会在不同时间生成该事件)。
除此之外,当前版本的Capybara还提供了使隐藏文件输入可见的支持,而无需诉诸自定义JS,这可能更可靠并且行为更一致。在您的情况下,可能会是这样(如果在页面上仅输入一个文件,则无需定位器)
attach_file(File.expand_path("./spec/files/#{attachment}"), make_visible: true)
如果应用的默认CSS无法使文件输入可见,则可以指定自定义CSS,例如
attach_file(File.expand_path("./spec/files/#{attachment}"),
make_visible: {visibility: 'visible', width: 'auto', height: 'auto'})
在最近的Capybara版本中,更清洁,更受用户喜欢的解决方案是在其阻止模式下使用attach_file
,这要求您执行用户将用来触发文件选择的操作,然后尝试执行确定正在使用哪个文件输入而不必担心可见性。
attach_file(File.expand_path("./spec/files/#{attachment}")) do
click_button('Choose files') # whatever action a user does to trigger file selection
end
注意:在测试时,使用execute_script
手动生成和调度事件通常不是一个好主意,因为它可以执行用户永远无法做的事情,并且可能会在您的应用中隐藏真正的错误。