1

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.

Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431
Amokrane Chentir
  • 29,907
  • 37
  • 114
  • 158

3 Answers3

4

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')
noli
  • 15,927
  • 8
  • 46
  • 62
  • Thanks. The thing is there are many buttons on the page but the first one is the one I want to be clicked on. Don't know what would be the behaviour in this case. I tried and I get a: stack level too deep (SystemStackError) error. By the way I checked with a well formed page (the one that you get when going to www.twitter.com/sessions/new). – Amokrane Chentir Apr 22 '11 at 10:27
  • last thing I can suggest is to give your button an id, and search by id :( – noli Apr 22 '11 at 10:32
  • I really wish I could :) But I would have to send a ticket to Twitter then :). – Amokrane Chentir Apr 22 '11 at 10:35
  • 1
    didn't get you were testing twitter directly.. see if this helps http://www.selectorgadget.com/ – noli Apr 22 '11 at 10:51
  • Nice tool. I got: //*[contains(concat( " ", @class, " " ), concat( " ", "button", " " ))] with it and tested it by doing: find(:xpath, "//*[contains(concat( \" \", @class, \" \" ), concat( \" \", \"button\", \" \" ))]"). It still doesn't find it :(. It's driving me crazy! Anyway, +1 for the help and don't hesitate to come back if you have other ideas about this :). – Amokrane Chentir Apr 22 '11 at 11:13
1

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.

Community
  • 1
  • 1
Иван Бишевац
  • 13,811
  • 21
  • 66
  • 93
0

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.

Малъ Скрылевъ
  • 16,187
  • 5
  • 56
  • 69