如何在RSpec中运行StimulusJS并测试TurboStream加载的模态框
解决RSpec系统测试中Stimulus控制器未运行导致模态框不可见的问题
核心问题定位
你遇到的问题本质是:Turbo Stream加载模态组件后,Stimulus控制器未在测试环境中执行显示逻辑,导致元素虽存在于DOM中但处于隐藏状态,Capybara无法定位到可见的表单字段。
关键配置与修复步骤
1. 启用支持JavaScript的Capybara驱动
系统测试必须使用能运行JS的驱动(如Cuprite、Selenium Chrome Headless),否则Stimulus和Turbo无法正常工作。
在spec/rails_helper.rb或spec/support/system_testing.rb中配置驱动:
RSpec.configure do |config| config.before(:each, type: :system) do # 推荐使用轻量无头浏览器Cuprite driven_by :cuprite, using: :chrome, screen_size: [1400, 1400] # 也可选择Selenium # driven_by :selenium_chrome_headless end end
2. 等待Stimulus完成DOM渲染与显示逻辑
不要仅检查模态框元素是否存在,要等待它可见——这能确保Stimulus已经执行了显示模态框的逻辑。
修改测试中的断言:
# 替换原来的存在检查,改为验证可见性 expect(page).to have_css("[data-controller='modal']", visible: true) # 或者直接等待目标表单字段可见,更直接 expect(page).to have_field("Username", visible: true)
3. 验证Stimulus控制器是否注册
可以在测试中加入调试逻辑,确认模态控制器已被Stimulus加载:
# 点击按钮后执行,检查控制器状态 modal_controller_loaded = page.execute_script("return !!Stimulus.controllers.find(c => c.identifier === 'modal')") expect(modal_controller_loaded).to be true
4. 确保测试环境资产编译正确
如果使用JS Bundling工具(如esbuild),需确保测试环境预编译了资产:
- 在
config/environments/test.rb中添加配置:config.assets.compile = true config.public_file_server.enabled = true - 运行命令预编译测试环境资产:
rails assets:precompile RAILS_ENV=test
修正后的测试代码示例
describe "Username modal", type: :system do it "should change the username" do visit profile_path expect(page).to_not have_css("[data-controller='modal']") page.find("#change-username").click # 等待模态框可见,确保Stimulus执行完成 expect(page).to have_css("[data-controller='modal']", visible: true) # 填写字段,显式指定超时时间避免等待不足 fill_in("Username", with: "testing01", wait: 5) page.find("#submit-change-username").click expect(page).to have_text("Username changed!") end end
内容的提问来源于stack exchange,提问作者Victor Luna
相关产品推荐
相关产品推荐

