A W3C-validated HTML 5 web page contains this working, simple button inside a login form.
<input data-disable-with="Signing in, please wait&hellip;"
name="commit" type="submit" value="Sign in" />
I'm writing a largely pointless test :-) in a Rails 3.2.17 application that's just to get the hang of Capybara and I've already got completely stuck Googling, reading documentation and reading source code to the test framework, with no joy - attempting to find this button by its name
(i.e. "commit"
) fails.
click_button("commit")
find_button("commit")
Both result in Capybara::ElementNotFound: Unable to find button "commit"
. If I use the visible button text of Sign in
then the element is found, i.e. these:
click_button("Sign in")
find_button("Sign in")
...both work fine, so it would appear that the XML parser isn't having any trouble finding the element.
Documentation for click_button
says that the locator works on "id, text or value", with "text" being meaningless for an input
element like this (the visible text is taken from the value
attribute), but relevant perhaps for button
elements. So, we might expect that to fail, though if we view the code via the documentation, find that it calls down to find
in the same way as find_button
. Yet find_button
is documented differently; it says it locates by "id, name or value". So sadly, we know from this that the documentation is broken because it says two different things for what turns out to be an identical call at the back end.
Either way, the element isn't found by name, and that means the lower level find
call isn't searching name
attributes as far as I can see. This means Capybara (2.2.1, on Nokogiri 1.6.1) is rather broken in that respect. How come nobody has noticed? I've Googled for ages and it doesn't seem to come up. I seem to be rather missing the point :-)
Why don't I just search for the English text in the button, you might ask? Because of internationalisation. This old, Rails 1 -> 2 -> 3 upgraded app has some I18n parts and other static text parts. I don't want to be forced to put I18n into any view that Capybara tests, just so I can have the test use I18n.t()
to ensure a match despite different languages or locale file updates. Likewise, it would clearly be very stupid in 2014 to write hard-coded English strings into my tests.
That's why we have names and IDs and such... The unique (in theory!) identifiers that are machine-read, not human-read.
I could hack up something that CSS-selected by "type=submit" but seriously, why isn't Capybara searching the name attribute when its documentation says it does, and why does the documentation disagree on what attributes are searched on two methods that call down to exactly the same back-end implementation with exactly the same parameters?
TIA :)
Capybara::ElementNotFound: Unable to find button "commit"
You don't have a button, you have an input. – sevenseacatfind
call takes various values in the first parameter with lots of different meanings. For example I can pass:xpath
or:fillable_field
. Seelib/capybara/selector.rb
for how these are added;:button
passes toXPath::HTML.button
and rdoc.info/github/jnicklas/xpath/XPath/HTML says that this matches "asubmit
,image
, orbutton
element". Given this, if you're responsible for the question downvote I'd appreciate it if you'd revoke that. – Andrew Hodgkinson