问题
I'm trying to test a part of my Rails 5.1 app that makes use of Vue.js. The issue I'm encountering is that, for example when generating a list, the Vue code looks like:
<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>
and the actual HTML that this produces once evaluated looks like this:
<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>
I end up getting this error in my specs:
Capybara::ElementNotFound:
Unable to find visible checkbox "Some amenity" that is not disabled
This is because the amenities are defined in the Vue component but are not output in the HTML until they are parsed by the JS interpreter I believe.
I am trying to test with Chrome Headless. I've created the following chrome_driver.rb file:
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
and in my rails_helper.rb:
require 'selenium/webdriver'
RSpec.configure do |config|
# ...
Capybara.javascript_driver = :headless_chrome
end
my RSpec test looks something like this:
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
but as mentioned, the error I get is:
Capybara::ElementNotFound:
Unable to find visible checkbox "Some amenity" that is not disabled
Any idea how I can get Chrome headless to parse the Vue.js code so that the amenities get populated on the frontend?
Thanks in advance!!
回答1:
Judging by the class names of the wrapping div, custom-control custom-checkbox
, I'm pretty certain the issue here isn't that the fields aren't being populated correctly (you can use save_and_open_screenshot
to verify that, or output page.html
) but rather the actual html <input type="checkbox" ...>
element is not actually visible on the page (as the error tells you). This was probably done in order to provide a fancy styling to the checkbox by showing images for the checked/unchecked states. To check the checkbox in that case you have a couple of options. The first option is to figure out what element the user actually needs to click to change the setting, and have Capybara do that. For instance
find(:label, 'Some amenity').click
The cleaner solution, when there is a correctly associated label element, is to tell the check
method it's allowed to click the label if it needs to
check('Some amenity', allow_label_click: true)
If you want check
, uncheck
, and choose
to always be allowed to click the associated label when a checkbox/radio button is hidden you can make that the default by setting
Capybara.automatic_label_click = true
回答2:
If your label contains a link it will be clicked and not the check box itself:
check('Some amenity', allow_label_click: true)
You can solve it this way:
check('Some amenity', visible: :hidden)
来源:https://stackoverflow.com/questions/49609406/rspec-headless-chrome-for-front-end-integration-test