Rails/Capybara测试中attach_file无法适配Active Storage直传如何解决?
使用Capybara测试Rails Active Storage直传功能时文件上传失败问题
使用Capybara开展系统测试时,无法向启用了direct upload功能的文件输入框上传文件。切换到直传模式前所有测试均可正常运行,手动通过浏览器提交对应表单也完全正常,但在Capybara环境下始终无法成功上传。
相关代码
视图层输入框代码
<%= f.input :desktop_files, as: :file, input_html: { direct_upload: true, multiple: true } %>
测试用例上传代码
attach_file 'uploads_create_assets_former[desktop_files][]', "#{fixture_path}/files/image.jpg"
报错信息
运行包含上述代码的测试时,会抛出如下异常:
Selenium::WebDriver::Error::UnexpectedAlertOpenError: unexpected alert open: {Alert text : Error reading image.jpg} (Session info: headless chrome=94.0.4606.81)
同时Capybara启动的浏览器控制台可见FileReader相关报错。
环境信息
依赖版本
- ruby (3.0.0)
- rails (6.1.4.1)
- selenium-webdriver (4.0.3)
- capybara (3.35.3)
- webdrivers (4.7.0)
Capybara驱动配置
Capybara.register_driver :headless_chrome do |app| options = Selenium::WebDriver::Chrome::Options.new( args: %w[headless disable-gpu no-sandbox window-size=1440x768] ) options.add_preference(:download, prompt_for_download: false, default_directory: Rails.root.join('tmp/downloads').to_s) options.add_preference(:browser, set_download_behavior: { behavior: 'allow' }) Capybara::Selenium::Driver.new(app, browser: :chrome, capabilities: options) end
补充说明
已完全按照Rails官方Active Storage直传文档实现功能,文件在表单提交时触发上传。
对应表单HTML代码如下:
<form class="formtastic uploads_create_assets_former" id="new_uploads_create_assets_former" enctype="multipart/form-data" action="/admin/upload/create" accept-charset="UTF-8" method="post"> <fieldset class="inputs"> <ol> <li class="file input optional" id="uploads_create_assets_former_desktop_files_input"><label for="uploads_create_assets_former_desktop_files" class="label">Dateien (Computer)</label> <input id="uploads_create_assets_former_desktop_files" multiple="multiple" data-direct-upload-url="http://127.0.0.1:49538/rails/active_storage/direct_uploads" type="file" name="uploads_create_assets_former[desktop_files][]" /> </li> </ol> </fieldset> <fieldset class="actions"> <ol> <li class="action input_action " id="uploads_create_assets_former_submit_action"> <input type="submit" name="commit" value="Nächster Schritt" data-disable-with="Nächster Schritt" /> </li> </ol> </fieldset> </form>
排查验证
已搭建最小可复现项目验证问题,确认以下信息:
- 文件路径正确,路径错误会直接抛出
Capybara::FileNotFound异常,测试中未出现该类异常 - 尝试过相对路径、绝对路径均无效
- 测试文件对所有用户开放读权限,权限信息如下:
-rw-r--r-- 1 martintomas staff 26436 Oct 22 12:51 image.jpg
- 本地环境和CI环境均可复现相同问题
临时解决方案
如果完全信任Active Storage直传的官方实现,且没有自定义直传相关JS代码,可以在系统测试中临时关闭直传功能绕过问题:
def attach_file(locator = nil, paths, make_visible: nil, **options) turn_off_direct_upload # Capybara does not work with direct upload super end def turn_off_direct_upload page.execute_script 'document.querySelectorAll("input[data-direct-upload-url]:not([data-direct-upload-url=\"\"])").forEach((input) => { delete input.dataset.directUploadUrl } )' end
内容的提问来源于stack exchange,提问作者martintomas
相关产品推荐
相关产品推荐

