Reputation: 45
Good day everyone!
I have an element
<tbody class="cp-ads-list__table-item _sas-offers-table__item cp-ads-list__table- item_state-deposit" data-card_id="16676514">
I'd like to access it by the data-card_id tag, but when I try the following
@browser.tbody(:data_card_id => "16676514").hover
I get an error
unable to locate element, using {:data_card_id=>"16676514", :tag_name=>"tbody"} (Watir::Exception::UnknownObjectException)
I guess my code would have worked if the tag were "data-card-id", but it's "data-card_id". How do I access my element by this attribute?
Upvotes: 3
Views: 560
Reputation: 46836
Problem
You are right that the problem is the underscore in the data attribute. As seen in the ElementLocator, when building the XPath expression, all underscores are converted to dashes (in the else part of the statement):
def lhs_for(key)
case key
when :text, 'text'
'normalize-space()'
when :href
# TODO: change this behaviour?
'normalize-space(@href)'
when :type
# type attributes can be upper case - downcase them
# https://github.com/watir/watir-webdriver/issues/72
XpathSupport.downcase('@type')
else
"@#{key.to_s.gsub("_", "-")}"
end
end
Solution - One-Off
If this is the only data attribute that is using underscores (rather than dashes), I would probably manually build the XPath or CSS expression.
@browser.tbody(:css => '[data-card_id="16676514"]').hover
Solution - Monkey Patch
If using underscores is a standard on the website, I would probably consider monkey patching the lhs_for method. You could monkey patch the method so that you only change the first underscore for data attributes:
module Watir
class ElementLocator
def lhs_for(key)
puts 'hi'
case key
when :text, 'text'
'normalize-space()'
when :href
# TODO: change this behaviour?
'normalize-space(@href)'
when :type
# type attributes can be upper case - downcase them
# https://github.com/watir/watir-webdriver/issues/72
XpathSupport.downcase('@type')
else
if key.to_s.start_with?('data')
"@#{key.to_s.sub("_", "-")}"
else
"@#{key.to_s.gsub("_", "-")}"
end
end
end
end
end
This would then allow your original code to work:
@browser.tbody(:data_card_id => "16676514").hover
Upvotes: 4