【问题标题】:RSpec + headless Chrome for front-end integration testRSpec + headless Chrome 用于前端集成测试
【发布时间】:2018-09-11 13:26:18
【问题描述】:

我正在尝试测试使用 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 代码,以便在前端填充便利设施吗?

提前致谢!!

【问题讨论】:

    标签: ruby-on-rails rspec capybara google-chrome-headless


    【解决方案1】:

    从包装 div 的类名custom-control custom-checkbox 来看,我很确定这里的问题不是没有正确填充字段(您可以使用save_and_open_screenshot 来验证这一点,或输出page.html) 而是实际的 html &lt;input type="checkbox" ...&gt; 元素实际上在页面上不可见(正如错误告诉你的那样)。这可能是为了通过显示选中/未选中状态的图像来为复选框提供精美的样式。在这种情况下,要选中复选框,您有几个选项。第一个选项是找出用户实际需要单击哪个元素来更改设置,并让 Capybara 执行此操作。比如

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

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

    check('Some amenity', allow_label_click: true)
    

    如果您希望 checkuncheckchoose 在隐藏复选框/单选按钮时始终被允许单击关联的标签,您可以通过设置将其设为默认值

    Capybara.automatic_label_click = true
    

    【讨论】:

    • 正确,我使用的是 Bootstrap 4 的 custom-checkbox,它确实似乎在创建一个输入复选框,而不是实际的 input[type="checkbox"]。一旦单击自定义复选框,后者可能会通过 Javascript 被选中。但是,我仍然无法使用您描述的方法使其工作。我会继续尝试看看是否需要选择其他内容。
    • @DaniG2k 为您的问题添加为该控件生成的实际 HTML,而不是 vue 模板,因为听起来您的 label 元素实际上可能与复选框没有正确关联
    • 好的,我已将实际生成的 HTML 添加到问题中以获取示例便利性
    • @DaniG2k 这就是你的问题——HTML id 不允许包含空格,这意味着 for 属性实际上并没有将标签链接到复选框——你想使用其他东西比输入的id 属性和标签的for 属性的文本
    • @DaniG2k 这解决了您的问题吗?如果是这样,请不要忘记接受答案,以便问题被标记为已回答。
    【解决方案2】:

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

    check('Some amenity', allow_label_click: true)
    

    你可以这样解决:

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

    【讨论】:

      猜你喜欢
      • 2014-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-09
      • 1970-01-01
      • 1970-01-01
      • 2013-01-03
      • 1970-01-01
      相关资源
      最近更新 更多