RSpec + headless Chrome 用于前端集成测试

RSpec + headless Chrome for front-end integration test

我正在尝试测试使用 Vue.js 的 Rails 5.1 应用程序的一部分。 我遇到的问题是,例如在生成列表时,Vue 代码如下所示:

<div v-for="(amenity, idx) in amenities">
  <div class="custom-control custom-checkbox">
    <input type="checkbox" class="custom-control-input" v-bind:id="amenity.text" v-model="checkedAmenities[idx]" :value="amenity.id">
    <label class="custom-control-label" v-bind="{ 'for': amenity.text }" >{{ amenity.text }}</label>
  </div>
</div>

并且它在评估后产生的实际 HTML 如下所示:

<div>
  <div class="custom-control custom-checkbox">
    <input id="Air conditioning" class="custom-control-input" value="0" type="checkbox"> <label for="Air conditioning" class="custom-control-label">Air conditioning</label>
  </div>
</div>

我最终在我的规格中遇到了这个错误:

Capybara::ElementNotFound:
  Unable to find visible checkbox "Some amenity" that is not disabled

这是因为便利设施是在 Vue 组件中定义的,但我相信它们在被 JS 解释器解析之前不会在 HTML 中输出。

我正在尝试使用 Chrome Headless 进行测试。我创建了以下 chrome_driver.rb 文件:

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

在我的 rails_helper.rb:

require 'selenium/webdriver'

RSpec.configure do |config|
  # ...
  Capybara.javascript_driver = :headless_chrome
end

我的 RSpec 测试看起来像这样:

scenario 'successfully', js: true do
  # do some things here..

  check('Some amenity')
  click_button 'Next'
  click_link 'Create Listing'

  expect(page).to have_content 'Listing was created successfully!'
end

但如前所述,我得到的错误是:

Capybara::ElementNotFound:
  Unable to find visible checkbox "Some amenity" that is not disabled

知道如何让 Chrome 无头地解析 Vue.js 代码,以便在前端填充便利设施吗?

提前致谢!!

根据包装 div、custom-control custom-checkbox 的 class 名称判断,我很确定这里的问题不是没有正确填充字段(您可以使用 save_and_open_screenshot 来验证,或输出 page.html) 但实际的 html <input type="checkbox" ...> 元素实际上在页面上不可见(正如错误告诉您的那样)。这样做可能是为了通过显示 checked/unchecked 状态的图像来为复选框提供精美的样式。在这种情况下要选中复选框,您有几个选项。第一个选项是弄清楚用户实际需要单击什么元素来更改设置,然后让 Capybara 执行此操作。例如

find(:label, 'Some amenity').click

当有正确关联的标签元素时,更清晰的解决方案是告诉 check 方法如果需要,允许点击标签

check('Some amenity', allow_label_click: true)

如果您希望在隐藏 checkbox/radio 按钮时始终允许 checkuncheckchoose 单击关联的标签,您可以将默认设置

Capybara.automatic_label_click = true

如果您的标签包含 link,它将被点击而不是复选框本身:

check('Some amenity', allow_label_click: true)

你可以这样解决:

check('Some amenity', visible: :hidden)