简体   繁体   English

Capybara attach_file不会触发Firefox中的React onChange处理程序

[英]Capybara attach_file not triggering React onChange handler in Firefox

I'm testing file upload functionality on a page built with React. 我正在使用React构建的页面上测试文件上载功能。 The React page has a hidden file input field with an onChange event listener wired up to it. React页面有一个隐藏文件输入字段,其中有一个onChange事件监听器。 When a file is selected it triggers the onChange and the file is processed. 选择文件后,它会触发onChange并处理文件。 I have a test that uses Capybara and javascript to expose the hidden input, use Capybara's attach_file method to attach the file to the input and check to make sure the file uploaded and appears in the user's file list. 我有一个使用Capybara和javascript来公开隐藏输入的测试,使用Capybara的attach_file方法将文件附加到输入并检查以确保文件已上载并显示在用户的文件列表中。 This test works in Chrome and the file is processed after using Capybara's attach_file method, but it does not work in Firefox - the file goes into the input, but it is never processed. 此测试在Chrome中运行,文件在使用Capybara的attach_file方法后处理,但在Firefox中不起作用 - 文件进入输入,但从未处理过。 I suspect that for some reason React isn't detecting the onChange in Firefox or it isn't getting fired. 我怀疑由于某些原因,React没有在Firefox中检测到onChange,或者它没有被解雇。 I need the test to work in both browsers. 我需要测试才能在两种浏览器中工作。

I've tried using execute_script with the appropriate vanilla javascript (no jquery) to create and dispatch both change and input events in firefox with no luck. 我已经尝试使用execute_script和相应的vanilla javascript(没有jquery)来创建和分发firefox中的更改和输入事件而没有运气。 After everything I try, I end up with nothing more than the exposed input field and the file name selected showing in it. 在我尝试的所有内容之后,我最终只得到暴露的输入字段和显示在其中的文件名。 As a SDET, I must work with the front-end code as-is. 作为SDET,我必须按原样使用前端代码。

React input for the file 对文件的反应输入

<input
          className={css.hiddenInput}
          onChange={event => {
            actions.uploadAttachment(event, personOneId, personTwoId);
          }}
          ref={file => (this.file = file)}
          type="file"
        />

Ruby/Capybara/javascript code exposing the input and attaching the 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

And a few examples of things I tried to trigger the event after the attach_file has been completed 以及我在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 })")

Per @Thomas Walpole's suggestions, I also tried the following things and received the following errors 根据@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

The fact that it works in Chrome but not in Firefox would tend to indicate a bug in either Capybara, geckodriver, or your app, so make sure you're running current versions of Capybara and geckodriver. 它在Chrome中运行但在Firefox中运行的事实往往表明Capybara,geckodriver或您的应用程序中存在错误,因此请确保您运行的是当前版本的Capybara和geckodriver。 If that doesn't fix things you can try clicking on another element after attaching the file to see if that triggers blur/change events (different browsers may generate the event at different times). 如果这不能解决问题,您可以在附加文件后尝试单击其他元素,以查看是否触发模糊/更改事件(不同的浏览器可能会在不同时间生成事件)。

Beyond that, current versions of Capybara provide support for making hidden file inputs visible without you having to resort to custom JS, which may be more reliable and have more consistent behavior. 除此之外,当前版本的Capybara提供了对隐藏文件输入可见的支持,而无需使用自定义JS,这可能更可靠并且具有更一致的行为。 In your case that would be something like (no locator necessary if only one file input on page) 在您的情况下将是这样的(如果页面上只有一个文件输入,则没有定位器)

attach_file(File.expand_path("./spec/files/#{attachment}"), make_visible: true)

If the default CSS applied doesn't make the file input visible you can specify custom CSS like 如果应用的默认CSS不使文件​​输入可见,则可以指定自定义CSS

attach_file(File.expand_path("./spec/files/#{attachment}"), 
            make_visible: {visibility: 'visible', width: 'auto', height: 'auto'})

A cleaner, and more user like, solution in very recent versions of Capybara would be to use attach_file in its block mode which requires you to perform the actions a user would use to trigger file selection and then attempts to determine which file input is being used without worrying about visibility. 在最新版本的attach_file中,更清洁,更像用户的解决方案是在其块模式下使用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

Note: using execute_script to manually generate and dispatch events is generally a bad idea when testing since it allows to do things a user never could and may hide real bugs in your app. 注意:在测试时使用execute_script手动生成和调度事件通常是一个坏主意,因为它允许用户做不到的事情并且可能隐藏应用程序中的真正错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM