views:

37

answers:

1

the code that didn't work:

login_form = page.form_with(:method => 'post')

and code that works

login_form = page.form_with(:method => 'POST')

I inspected the form object via puts page.forms.inspect and got

[#<WWW::Mechanize::Form
 {name nil}
{method "POST"}
....]

html source:

<form class="login" method="post"> <fieldset>
<legend>Members Login</legend> 

<div>
<label for="auth_username">Username</label> <input id="auth_username" name="auth_username">
</div>

<div>
<label for="auth_password">Password</label> <input id="auth_password" name="auth_password" type="password">
</div>

</fieldset>
<div class="buttons">
<input name="auth_login" type="submit" value="Login"><p class="note"><a href="/forgotpassword">Forgot your password?</a></p>

</div>

</form>
+1  A: 

Looking at the source, it could be that Mechanize is supposed to work like that. It forces the form method to uppercase when it fetches the form; you are expected to supply the method in uppercase when you want to match it. You might ping the mechanize person(s) and ask them if it's supposed to work like that.

Here in Mechanize.submit, it forces the form method to uppercase before comparing it:

def submit(form, button=nil, headers={})
  ...
  case form.method.upcase  
  when 'POST'
    ...
  when 'GET'
    ...
  end
  ...
end

and here again in Form.initialize, the method is forced to uppercase:

  def initialize(node, mech=nil, page=nil)
    ...
    @method           = (node['method'] || 'GET').upcase

But in page.rb is the code where mechanize is matching a form (or link, base, frame or iframe) against the parameters you gave, the parameter you passed in is not forced to uppercase, so it's a case sensitive match:

      def #{type}s_with(criteria)
        criteria = {:name => criteria} if String === criteria
        f = #{type}s.find_all do |thing|
          criteria.all? { |k,v| v === thing.send(k) }
        end
        yield f if block_given?
        f
      end

Well, it's a case sensitive match if you pass in a string. But if you pass in a regex, it's a regex match. So you ought to be able to do this:

login_form = page.form_with(:method => /post/i)

and have it work fine. But I would probably just pass in an uppercase String, send the Mechanize person(s) an email, and move on.

Wayne Conrad
@Wayne Conrad: thank you Wayne. Very nice explanation, even myself understood :-)
Radek
@Radek, My pleasure.
Wayne Conrad