3

I am trying to implement a Ruby script that will take in a username and password, then proceed to fill in the account details on a login form on another website and return the then follow a link and retrieve the account history. To do this I am using the Mechanize gem.

I have been following the examples here but still I cant seem to get it to work. I have simplified this down greatly to try get it to work in parts but a supposedly simple filling in a form is holding me up.

Here is my code:

# script gets called with a username and password for the site
require 'mechanize'


#create a mechanize instant
agent = Mechanize.new 

agent.get('https://mysite/Login.aspx') do |login_page|

    #fill in the login form on the login page
    loggedin_page = login_page.form_with(:id => 'form1') do |form|
        username_field = form.field_with(:id => 'ContentPlaceHolder1_UserName')
        username_field.value = ARGV[0]
        password_field = form.field_with(:id => 'ContentPlaceHolder1_Password')
        password_field.value = ARGV[1]


        button = form.button_with(:id => 'ContentPlaceHolder1_btnlogin')
    end.submit(form , button)

    #click the View my history link
    #account_history_page = loggedin_page.click(home_page.link_with(:text => "View My History"))

    ####TEST to see if i am actually making it past the login page
    #### and that the View My History link is now visible amongst the other links on the page
    loggedin_page.links.each do |link|
        text = link.text.strip
        next unless text.length > 0
        puts text if text == "View My History"
    end
    ##TEST 

end

Terminal error message:

stackqv2.rb:19:in `block in <main>': undefined local variable or method `form' for main:Object (NameError)
from /usr/local/lib/ruby/gems/1.9.1/gems/mechanize-2.5.1/lib/mechanize.rb:409:in `get'
from stackqv2.rb:8:in `<main>'
alroc
  • 27,574
  • 6
  • 51
  • 97
John
  • 1,823
  • 2
  • 13
  • 14
  • 1
    Are you sure you get that error with the code you posted? There is no `form_with` on line 14. It looks like you'd get that error if you'd called `agent.form_with` – ramblex Dec 19 '12 at 15:19
  • I corrected the error message I am getting. – John Dec 19 '12 at 15:42

2 Answers2

9

You don't need to pass form as an argument to submit. The button is also optional. Try using the following:

loggedin_page = login_page.form_with(:id => 'form1') do |form|
    username_field = form.field_with(:id => 'ContentPlaceHolder1_UserName')
    username_field.value = ARGV[0]
    password_field = form.field_with(:id => 'ContentPlaceHolder1_Password')
    password_field.value = ARGV[1]
end.submit

If you really do need to specify which button is used to submit the form, try this:

form = login_page.form_with(:id => 'form1')
username_field = form.field_with(:id => 'ContentPlaceHolder1_UserName')
username_field.value = ARGV[0]
password_field = form.field_with(:id => 'ContentPlaceHolder1_Password')
password_field.value = ARGV[1]

button = form.button_with(:id => 'ContentPlaceHolder1_btnlogin')
loggedin_page = form.submit(button)
ramblex
  • 3,042
  • 21
  • 20
2

It's a matter of scope:

page.form do |form|
  # this block has its own scope
  form['foo'] = 'bar' # <- ok, form is defined inside this block
end

puts form # <- error, form is not defined here

ramblex's suggestion is to not use a block with your form and I agree, it's less confusing that way.

pguardiario
  • 53,827
  • 19
  • 119
  • 159