watir webdriver using a variable - ruby

I am having trouble using a variable in browser reference. I am trying to pass the field type such as ul, ol etc. The code works if I type ol, but I would like to use the pass variable labeled 'field'. I recieve an "undefined method for field" error.
I have tried also using #{field}, but that does not work either. The error is that field is not defined.
def CheckNewPageNoUl(browser, field, text1, output)
browser.a(:id => 'submitbtn').hover
browser.a(:id => 'submitbtn').click
output.puts("text1 #{text1}")
browser.body(:id => 'page').wait_until_present
if browser.table.field.exists?
output.puts(" #{text1} was found in CheckNewPageNoUl")
end
end
field = "ol"
text1 = "<ol>"
CheckText.CheckNewPageNoUl(b, field, text1, outputt)

To translate a string into a method call, use Object#send, which can take two parameters:
The method name (as string or symbol)
Arguments for the method (optional)
Some examples:
field = 'ol'
browser.send(field).exists?
#=> Translates to browser.ol.exists?
specifiers = {:text => 'text', :class => 'class'}
browser.send(field, specifiers).exists?
#=> Translates to browser.ol(:text => 'text', :class => 'class').exists?
For your code, you would want to have:
if browser.table.send(field).exists?
output.puts(" #{text1} was found in CheckNewPageNoUl")
end

Related

Cannot add new value to MongoDB's BSON field using Ruby

I have a document with the field admins and am looking to add new users into this field. The value for these new users is a simple number string.
def modify_admin(identity, doc)
ip_addr = "127.0.0.1:27017"
client = Mongo::Client.new([ip_addr], :database => "camp")
if doc[0] == 'r'
doc = doc[2..-1]
client[:inventory].update_one({"name": doc}, {$push => {"admins" => identity}})
client.close
end
The collection I'm trying to add is in this line: client[:inventory].update_one({"name": doc}, {$push => {"admins" => identity}}),
However I am running into the error NilClass instances are not allowed as keys in a BSON document. (BSON::InvalidKey).
I have tried different syntax for the $push method but nothing seems to work.
My document structure is as follows, I'm using symbols as the field value.
document = {:name => build_array[1], :owner => identity, :admins => identity}
How can I add new values to the :owner field using Ruby?
$push in ruby usually means global variable. So, all you need is to wrap $push operation into parentheses:
- client[:inventory].update_one({"name": doc}, {$push => {"admins" => identity}})
+ client[:inventory].update_one({"name": doc}, {"$push" => {"admins" => identity}})
And you should be fine

Ruby's Mechanize balks when selecting a radio button (maybe because its name is capitalized) but Perl's WWW::Mechanize works fine

I'm trying to submit a form with Ruby's Mechanize gem. This form has a set of radio buttons named "KeywordType". The individual buttons are named something like rdoAny, rdoAll and rdoPhrase. With Perl's WWW:Mechanize it works just fine:
my $result = $agent->submit_form(
form_number => 1,
fields => {
txtKeywords => 'foo bar baz',
lstLocationCode => '2100',
lstONETMajorGroup => '0',
KeywordType => 'rdoAny'
},
button => 'btnSearch'
);
but Ruby balks when I do this:
result = page.form_with(:id => 'frmSearch') do |field|
field.txtKeywords = 'foo bar baz'
field.lstLocationCode = '2100'
field.lstONETMajorGroup = '0'
field.KeywordType = 'rdoAny'
end.submit
This throws the error
"undefined method `KeywordType=' for #<Mechanize::Form:0x00000001c896e0> (NoMethodError)".
I've tried leaving out the KeywordType field, but then I just get sent back to the same page with no obvious error message. I've also tried doing things like field.radiobuttons.second.check and field.radiobuttons_with(:name => "KeywordType") to no avail.
And on a side note, is whatever's going on because Ruby sees a capitalized radiobutton name and thinks it's a constant?
Thanks.
Does this work?
field['KeywordType'] = 'rdoAny'
Edit: Oh, and I think you missed a part here:
result = page.form_with(:id => 'frmSearch') do |field|
should be (I think):
result = page.form_with(:id => 'frmSearch').fields.each do |field|
Gaah. The outdated version gremlin strikes again. "gem update mechanize" is now at least showing me the values for the two dropdowns.

How can I do a full text search with a phrase of more than one word, using Sequel full_text_search?

I am using ruby, Sequel and postgres. I have implemented full text search as follows:
get '/full_text_search' do
search_term = params[:search_term]
result = DB[:candidates].full_text_search(:experience, search_term).map do |row|
{ :id => row[:id], :first => row[:first], :last => row[:last], :designation => row[:designation], :company => row[:company], :email => row[:email], :phone => row[:phone], :city => row[:city], :country => row[:country], :industry => row[:industry], :status => row[:status], :remarks => row[:remarks], :experience => row[:experience] }
end
halt 200, result.to_json
end
This is executed by passing a search term from a text box, via an ajax call, so:
$(document).ready(function(){
$("#full_text_search").click(function(){
var search_term = $("#search_box").val();
$.getJSON("/full_text_search?search_term="+search_term, function(data) {
$.each( data, function( key, value ) {
//do something with returned data here
});//end each
});//end getJSON
});//end click
});//end doc
If my search term is just one word, "private" for example, I get the results back no problem but if I try a search term of 2 words (or more) "private equity", for example, I get an error and no data is returned.
So my question is how can I execute full text search (as above) with a phrase of 2 or more words?
I have already tried encapsulating the passed parameter with '' and "" unsuccessfully.
All help gratefully received. Thank you.
PostgreSQL's full text searching does not handle phrase searching natively. The best you can do is look for entries containing both words, using &: full_text_search(:experience, 'term1 & term2'), followed by using LIKE '%term1 term2%' if you want to do actual phrase searching.
I'll look into adding an :phrase=>true option to full_text_search that will make it operate as a phrase search.

Using multiple data sets in populate_page_with in page-object gem

I have a form that I populate with populate_page_with data_for using the page-object gem. It is defined this way:
def add_fruit(data = {})
populate_page_with data_for(:new_fruit, data)
add_fruit_submit
end
Then I call the method in my step this way:
on(AddFruitPage).add_fruit
My yml file looks like this:
new_fruit:
color: red
size: large
type: apple
price: 0.75
...
another_fruit
color: orange
size: medium
type: orange
price: 0.99
...
I know that I can overwrite each of these fields by doing something like this in my step:
When(^/I add a banana$/) do
on(AddFruitPage).add_fruit('color' => 'yellow', 'size' => 'small', 'type' => 'banana')
end
Since the data for another fruit is already in the yml file, can I use a parameter to tell the method which data to load rather than having to specify each value when I use the method? Something like:
def add_fruit(data = {})
if(data['type'] == 'another')
populate_page_with data_for(:new_fruit, data)
else
populate_page_with data_for(:another_fruit, data)
end
end
And call it this way?
on(AddFruitPage).add_fruit('type' => 'another')
Type is an optional parameter that would only be used to load another set of data. Color, size, type, and price all map to text fields on the page that are defined in the class. Is it possible to do something like this?
If you are using Ruby 2, you could used named parameters - creating a named parameter for the fruit type and the rest as being part of the data array.
Instead of using a 'type', which already exists in the data, I would probably use a parameter that specifies the first parameter of the data_for. The method definition would simply be:
def add_fruit(fruit_type: :new_fruit, **data)
populate_page_with data_for(fruit_type, data)
add_fruit_submit
end
Which could be called in variety of ways:
add_fruit() # Specify nothing
add_fruit(:color => 'red') # Just specify the data
add_fruit(:fruit_type => :another_fruit) # Just specify the fruit type
add_fruit(:fruit_type => :another_fruit, :color => 'red') # Specify fruit type and data
If you are using a version prior to Ruby 2, you can do the same with:
def add_fruit(data = {})
fruit_type = data.delete(:fruit_type) || :new_fruit
populate_page_with data_for(fruit_type, data)
add_fruit_submit
end

Skip HTML escape in custom label_tag helper in Rail 3

I have this nice class ErrorFormBuilder that allows me to add the error description near the corresponding field in the form view :
class ErrorFormBuilder < ActionView::Helpers::FormBuilder
#Adds error message directly inline to a form label
#Accepts all the options normall passed to form.label as well as:
# :hide_errors - true if you don't want errors displayed on this label
# :additional_text - Will add additional text after the error message or after the label if no errors
def label(method, text = nil, options = {})
#Check to see if text for this label has been supplied and humanize the field name if not.
text = text || method.to_s.humanize
#Get a reference to the model object
object = #template.instance_variable_get("##{#object_name}")
#Make sure we have an object and we're not told to hide errors for this label
unless object.nil? || options[:hide_errors]
#Check if there are any errors for this field in the model
errors = object.errors.on(method.to_sym)
if errors
#Generate the label using the text as well as the error message wrapped in a span with error class
text += " <br/><span class=\"error\">#{errors.is_a?(Array) ? errors.first : errors}</span>"
end
end
#Add any additional text that might be needed on the label
text += " #{options[:additional_text]}" if options[:additional_text]
#Finally hand off to super to deal with the display of the label
super(method, text, options)
end
end
But the HTML :
text += " <br/><span class=\"error\">#{errors.is_a?(Array) ? errors.first : errors}</span>"
is escaped by default in the view...
I tried to add the {:escape => false} option :
super(method, text, options.merge({:escape => false}))
without success
Is there any way to bypass this behavior ?
Thanks
Have you tried making your string html_safe?
irb(main):010:0> a = "A string"
=> "A string"
irb(main):011:0> a.html_safe?
=> false
irb(main):012:0> b = a.html_safe
=> "A string"
irb(main):013:0> b.html_safe?
=> true
See http://www.railsdispatch.com/posts/security and scroll down to "What you need to know" near the bottom:
In general, you can build your Rails app exactly as before. Rails will automatically escape any Strings that it doesn’t create. In almost all cases, this is the right behavior, with no further modifications required.
If Rails is escaping a String that you want to pass through without escaping, simply mark it safe. If you create a String in a helper, you may want to mark parts of it as safe.
I can't test whether this will work in your sub-classed helper, but I'd think so.
Just use <%= raw your_variable_here %>

Resources