【问题标题】:Capybara/Selenium/Chrome: test passes only when calling save_screenshotCapybara/Selenium/Chrome:仅在调用 save_screenshot 时测试通过
【发布时间】:2020-12-11 14:03:45
【问题描述】:

我正在从 Poltergeist 迁移到无头 Chrome。

宝石文件:

group :test do
  # Capybara - Headless, JavaScript-executing browser for Selenium
  gem 'selenium-webdriver'  # Selenium webdriver (needed to use Chrome driver)
  gem 'webdrivers', '~> 4.0', require: false # Run Selenium tests more easily with automatic installation and updates for all supported webdrivers.
  gem 'capybara-screenshot' # Automatically save screen shots when a scenario fails
  ...
end

spec/support/capybara.rb:

Capybara.javascript_driver = :selenium_chrome_headless

我有一个规范来测试聚焦一个元素是否将 CSS 类应用于一个元素。

it 'shows the fullscreen toggler on focus', js: true do
  visit new_user_path
  page.execute_script("$('#user_about').focus()")
  expect(page).to have_css '.textarea-fullscreenizer-toggler'
end

有了 Poltergeist,它就过去了。对于:selenium_chrome_headless,它不会:

expected to find visible css ".textarea-fullscreenizer-toggler" within #<Capybara::Node::Element tag="div" path="/HTML/BODY[1]/MAIN[1]/DIV[1]/DIV[1]/FORM[1]/FIELDSET[1]/DIV[1]/DIV[1]/DIV[5]"> but there were no matches. Also found "", which matched the selector but not all filters. 

不过,使用:selenium_chrome,它通过了!所以看起来headless和non-headless driver做不同的事情!这很不舒服。

有趣的是,在聚焦元素后放置 save_screenshot 时,规范也会通过 headless chrome!

我可以在这里做什么?我在正确的轨道上?我应该改用https://github.com/twalpole/apparition 驱动程序吗?

【问题讨论】:

    标签: ruby-on-rails selenium rspec capybara


    【解决方案1】:

    您也可以在帮助程序 capybara.rb 文件中为 headless chrome 尝试类似的操作。

    require "selenium/webdriver"
    
    Capybara.register_driver :chrome do |app|
      Capybara::Selenium::Driver.new(app, browser: :chrome)
    end
    
    Capybara.register_driver :headless_chrome do |app|
      capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
        chromeOptions: { args: %w(headless disable-gpu) }
      )
    
      Capybara::Selenium::Driver.new app,
        browser: :chrome,
        desired_capabilities: capabilities
    end
    
    Capybara.javascript_driver = :headless_chrome
    

    这对我有用。也可能对你有用。

    【讨论】:

    • 这对我来说不会headless 模式启动 Chrome。
    【解决方案2】:

    对我来说似乎是一个时间问题。我的猜测是,当匹配器已经执行时,用于触发焦点的 jQuery 调用需要一些时间。但是,由于它找到了一个尚不可见的元素,因此会引发错误。插入屏幕截图可能只需要足够的时间让 JavaScript 评估您的命令。

    您是否尝试过显式匹配expect(page).to have_selector('.textarea-fullscreenizer-toggler', visible: true) 之类的可见元素? 此外,焦点触发也可以这样完成:find('#user_about').trigger('focus')。这也可以解决问题,因为它在触发事件后返回。

    【讨论】:

      【解决方案3】:

      您提供的错误显然没有为所示代码返回,因为您提供的代码没有确定任何范围或检查文本。将来如果错误与代码匹配会更好。话虽如此,下面的答案是基于可用信息的猜测。

      问题很可能是您的 JS 执行在页面完全加载之前发生,因此页面正在重置焦点。发生这种情况是因为visit 不保证页面在返回时已完全加载/稳定。要同步,您需要在 execute_script 调用之前检查页面上的某些内容以指示页面已加载/稳定。

      访问 new_user_path expect(page).to have_css('input#first_input:focus') # 等到最初聚焦的元素被加载/显示/聚焦 page.execute_script("$('#user_about').focus()")

      请注意,尽管在测试中使用execute_script 通常是个坏主意,因为它并没有做用户会做的事情 - 你最好让 Capybara 做用户会执行的任何操作以使你关心的元素集中.

      【讨论】:

      • 你说得对,我从代码中删除了 text: ... 过滤器,因为它不相关,但忘记将其从错误消息中删除。我很快就会更深入地看看你在写什么。谢谢。
      猜你喜欢
      • 2018-10-24
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      • 2017-02-26
      • 1970-01-01
      • 1970-01-01
      • 2012-02-23
      • 1970-01-01
      相关资源
      最近更新 更多