Nokogiri Error: undefined method `radiobutton_with

2019-05-10 00:46发布

问题:

I try to access a form using mechanize (Ruby). On my form I have a gorup of Radiobuttons. So I want to check one of them.

I wrote:

target_form = (page/:form).find{ |elem| elem['id'] == 'formid'}
target_form.radiobutton_with(:name => "radiobuttonname")[2].check

In this line I want to check the radiobutton with the value of 2. But in this line, I get an error:

: undefined method `radiobutton_with' for #<Nokogiri::XML::Element:0x9b86ea> (NoMethodError)

回答1:

The problem occured because using a Mechanize page as a Nokogiri document (by calling the / method, or search, or xpath, etc.) returns Nokogiri elements, not Mechanize elements with their special methods.

As noted in the comments, you can be sure to get a Mechanize::Form by using the form_with method to find your form instead.

Sometimes, however, you can find the element you want with Nokogiri but not with Mechanize. For example, consider a page with a <select> element that is not inside a <form>. Since there is no form, you can't use the Mechanize field_with method to find the select and get a Mechanize::Form::SelectList instance.

If you have a Nokogiri element and you want the Mechanize equivalent, you can create it by passing the Nokogiri element to the constructor. For example:

sel = Mechanize::Form::SelectList.new( page.at_xpath('//select[@name="city"]') )

In your case where you had a Nokogiri::XML::Element and wanted a Mechanize::Form:

# Find the xml element
target_form = (page/:form).find{ |elem| elem['id'] == 'formid'}
target_form = Mechanize::Form.new( target_form )

P.S. The first line above is more simply achieved by target_form = page.at_css('#formid').