Cucumber/Capybara - How to search for a specific button using XPath?
I am trying to figure out how to write an oAuth/Twitter signin feature with Cucumber/Capybara. Part of it, consists in visiting the page: http://www.twitter.com/sessions/new and filling in the username, the password and then clicking on the 'Sign in' button. That last step is not working as expected, the html code for that page looks like this (located in french):
<fieldset class=开发者_运维知识库"textbox">
<label class="username">
<span>Nom d'utilisateur ou e-mail</span>
<input type="text" value="" name="session[username_or_email]" autocomplete="on" />
</label>
<label class="password">
<span>Mot de passe</span>
<input type="password" value="" name="session[password]" />
</label>
</fieldset>
<fieldset class="subchck">
<button type="submit" class="submit button">Se connecter</button>
I have a defined the step like this in web.steps (note that I am not using the default capybara driver but capybara-mechanize):
Given /^I sign in$/ do
visit 'http://twitter.com/sessions/new'
fill_in "Username or email", :with => 'xxx'
fill_in "Password", :with => 'xxx'
find(:xpath, 'button[@class="submit button"]')
....
end
The find(:xpath,..) line is not working properly. I tried to put a '/s' (regex for space character) but I still get this error message:
Unable to find '//button[@class="submit\sbutton"]' (Capybara::ElementNotFound)
I also tried:
xpath_for("submit button")
But I get a stack level too deep error!
I am not really confident with my regex/xpath element finding skills so please tell me what is wrong with my code and how I could find that button?
Thanks so much for helping me!
[EDIT]
Turns out the default selector is :css. I changed it to :xpath:
Capybara.default_selector = :xpath
But it still doesn't solve my problem.
What if you try
click_on "Se connecter"
EDIT: Trying in nokogiri (cause capybara uses nokogiri) it doesn't work for me when I use your HTML as is (meaning it doesn't even see the element in the document). But when I enclose everything in a single root node, it works.. don't know if there's an issue with your page HTML or something.. with a well formed page, it "should" work. not sure how much this helps
<html>
<fieldset class="textbox">
<label class="username">
<span>Nom d'utilisateur ou e-mail</span>
<input type="text" value="" name="session[username_or_email]" autocomplete="on" />
</label>
<label class="password">
<span>Mot de passe</span>
<input type="password" value="" name="session[password]" />
</label>
</fieldset>
<fieldset class="subchck">
<button type="submit" class="submit button">Se connecter</button>
</html>
with this HTML, I can just use the xpath
xpath('//button')
Instead:
find(:xpath, 'button[@class="submit button"]')
you should have:
find('button.submit.button')
Above is css, since it's default selector.
If you want solution with XPath look at https://stackoverflow.com/a/11752824/507018, but it's uglier.
If you have the exact match to class of button <button class="submit button">
, you can try just the following:
find(:xpath, '//button[@class="submit button"]')
Make sure that you didn't forget the double slash in the beginning of the search string.
精彩评论