The following is Slim.
.checkboxes__item
= f.check_box :insert_thumbnail, { checked: @article.new_record? || @article.insert_thumbnail, class: 'a-toggle-checkbox' }
= f.label :insert_thumbnail, 'insert thumbnail?'
HTML
<input name="article[insert_thumbnail]" type="hidden" value="0">
<input class="a-toggle-checkbox"
type="checkbox"
value="1"
checked="checked"
name="article[insert_thumbnail]"
id="article_insert_thumbnail">
<label for="article_insert_thumbnail">insert thumbnail?</label>
</div>
I would like to check this checkbox in the E2E test, but it does not work.
check 'insert thumbnail?', visible: false
Error:
ArticlesTest#test_uncheck_checkbox_whether_to_display_thumbnail_in_body:
Selenium::WebDriver::Error::ElementNotInteractableError: element not interactable
(Session info: headless chrome=117.0.5938.62)
test/system/articles_test.rb:292:in `block in <class:ArticlesTest>'
I understand this error to mean that the element exists but cannot be manipulated.
Is this due to CSS? Or should I just pass an option other than visible to the check method?
.a-toggle-checkbox
+size(0)
display: block
+position(fixed, left 0)
opacity: 0
overflow: hidden
visibility: hidden
uncheck 'insert thumbnail?', visible: true
Error:
ArticlesTest#test_uncheck_checkbox_whether_to_display_thumbnail_in_body:
Capybara::ElementNotFound: Unable to find visible checkbox "insert thumbnail?" that is not disabled
test/system/articles_test.rb:292:in `block in <class:ArticlesTest>'
scroll_to 'insert thumbnail?'
uncheck 'insert thumbnail?', visible: false
find('label[for=article_insert_thumbnail]').click
=> I can click.But I want to use check/uncheck
method.
Due to the fact that your check boxes are not visible and you are are targeting the label element with your selector, I believe you just need to enable the automatic_label_click
option.
Whether
Element#choose
,Element#check
,Element#uncheck
will attempt to click the associated <label> element if the checkbox/radio button are non-visible.
Capybara.configure do |config|
config.automatic_label_click = true
end
Or pass that option explicitly to the check
method e.g.
check 'insert thumbnail?', allow_label_click: true
Here is the actual method, which has a secondary attempt if this option is true, and the error is "catchable" which it is in your case (See below).
This will then look for the label and call click (which seems to work for you now)
def _check_with_label(selector, checked, locator,
allow_label_click: session_options.automatic_label_click, **options)
options[:allow_self] = true if locator.nil?
synchronize(Capybara::Queries::BaseQuery.wait(options, session_options.default_max_wait_time)) do
el = find(selector, locator, **options)
el.set(checked)
rescue StandardError => e
raise unless allow_label_click && catch_error?(e)
begin
el ||= find(selector, locator, **options.merge(visible: :all))
unless el.checked? == checked
el.session
.find(:label, for: el, visible: true, match: :first)
.click(**(Hash.try_convert(allow_label_click) || {}))
end
rescue StandardError # swallow extra errors - raise original
raise e
end
end
end
For Reference the "Catchable Errors" (catch_error?(e) #=> true
) in this case would be:
Selenium::WebDriver::Error::StaleElementReferenceError
Selenium::WebDriver::Error::ElementNotInteractableError
Selenium::WebDriver::Error::InvalidSelectorError
Selenium::WebDriver::Error::ElementClickInterceptedError
Selenium::WebDriver::Error::NoSuchElementError
Selenium::WebDriver::Error::InvalidArgumentError
Capybara::ElementNotFound