You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RSpec+Capybara测试带Turbo确认的取消按钮时触发Selenium UnexpectedAlertOpenError错误

RSpec+Capybara测试带Turbo确认的取消按钮时触发Selenium UnexpectedAlertOpenError错误

看起来你遇到的是Turbo原生确认框和Capybara的accept_confirm配合时的时序问题,或是隐藏的弹窗干扰,我来给你几个排查和解决的方向:

1. 先确认Turbo的confirm是否用了原生alert

Turbo的turbo_confirm默认会调用浏览器原生的confirm(),但如果你的应用自定义了Turbo confirm适配器(比如用Bootstrap模态框替代原生弹窗),那accept_confirm就会失效——它只能处理原生弹窗。你可以手动在浏览器里测试下,点击Cancel按钮是不是弹出原生确认框,而非自定义模态框。

2. 调整accept_confirm的使用姿势

有时候Capybara的accept_confirm需要更明确的匹配和等待逻辑,你可以指定确认框的文本,并且确保按钮完全加载后再点击:

accept_confirm('Are you sure you want to cancel?') do
  find('button.button--danger', text: 'Cancel', wait: 5).click
end

这样能精准捕获目标弹窗,避免误抓其他意外弹出的窗口。

3. 排查是否有隐藏的空alert触发

你提到注释掉turbo_confirm和accept_confirm后报错依旧,这说明页面可能有其他地方触发了空文本的alert(错误提示里Alert text : 是空的)。你可以排查这些方向:

  • Stripe JS SDK是否有报错弹出alert?
  • Turbo请求失败时的错误处理是否弹出了alert?
  • 页面其他JS代码的异常是否触发了alert?

你可以临时关闭Chrome的headless模式,手动跑测试看浏览器里的实际情况:

# 修改rails_helper.rb的Chrome驱动配置
Capybara.register_driver :chrome do |app|
  Capybara::Selenium::Driver.new app, browser: :chrome,
                                      options: Selenium::WebDriver::Chrome::Options.new(args: %w[disable-gpu])
end

这样能直观看到页面加载或操作时有没有意外弹窗。

4. 手动重置Capybara会话

虽然Capybara默认每次测试都会重置会话,但Turbo的页面缓存偶尔会有影响,你可以在测试开头手动重置:

it 'cancels an active subscription' do
  Capybara.reset_sessions!
  email = sign_up_and_subscribe

  visit subscription_path

  accept_confirm('Are you sure you want to cancel?') do
    click_button 'Cancel'
  end

  # ... 断言代码
end

5. 检查Chrome与ChromeDriver版本匹配

错误显示你的Chrome版本是123.0.6312.87,务必确保ChromeDriver版本和Chrome完全一致——版本不兼容会导致弹窗处理异常。你可以用webdrivers gem自动管理版本:

# 在Gemfile的test组添加
gem 'webdrivers', group: :test

执行bundle install后,它会自动下载匹配当前Chrome版本的ChromeDriver。

6. 换一种测试思路绕开原生弹窗

如果原生弹窗的测试实在卡壳,你可以跳过确认框的测试(毕竟这是浏览器/Turbo的原生功能),直接验证业务逻辑:

it 'cancels an active subscription' do
  email = sign_up_and_subscribe
  visit subscription_path

  # 用JS直接触发按钮点击,跳过确认框
  page.execute_script("$('button[data-turbo-confirm]').trigger('click')")

  # 等待Turbo Stream更新完成
  expect(page).to have_content('We are cancelling your subscription.', wait: 5)

  subscription = User.find_by(email:).current_subscription
  expect(subscription.cancelled?).to be(true)
end

这种方式直接验证用户最终看到的结果和业务状态,同样能保证测试的有效性。

备注:内容来源于stack exchange,提问作者Michael Evans

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.17 12:43:10