Selecting which div class ruby should select? (using watir) - ruby

I'm having an issue of selecting the content I want to store as a string, as the data has the same div class name and there is no set ID to use instead.
I'm aware of the first and last operator in ruby, but is there anyway to select the options in between?
So for example
<html>
<body>
<div class="example">1111</div>
<div class="example">2222</div>
<div class="example">3333</div>
<div class="example">4444</div>
<div class="example">5555</div>
</body>
</html>
How can I get ruby to select the 4th class of the same class name, so I can store 4444 as my string?

Another way (using Watir API):
browser.div(:class => "example", :index => 3)

browser.divs(:class => "example")[3]

Related

How to access the table,tr,td which has no attributes using Watir

I am trying to access the table as well it rows and table data(td),generally the table,tr and td has no attributes to use I tried with index but still no use,even I tried with the parent element of table still I was unable to access it.
<div class = "Links"></div>
<div class = "board">
<table>
<tbody>
<tr><td>Name</td><td>Value</td></tr>
<tr><td>shaik</td><td>500</td></tr>
<tr><td>shahrukh</td>900<td><span style="" has css properties ></span></td></tr>
</tbody>
</table>
</div>
I tried in the following way
#ie.table(index,0) and
#ie.div(:class,'Links').table(:index,0)
returned an error as unable to locate the element
#ie.table by itself should work.
#ie.div(:class, 'Links') is not a parent of the table element since the </div> comes before the <table> in the dom.
Try this,
myelem = browser.tr(:text, /Name/).td(:index => 2).text
#or you can use the more user-friendly aliases for those tags
myelem = browser.row(:text, /Name/).cell(:index => 2).text

Accessing a nested element 3 levels deep using page objects

Using the Page Object model and gem I want to access an element that is nested 3 layers deep. I've successfully accessed nested elements that are 2 elements deep but for 3 the same method isn't working.
3 elements defined in my Page Object:
div(:serv_info, :class => "service-info")
div(:validate_method, :class => "validate-method")
div(:scar_input_group, :class => "input-group")
So I tried to chain those 3 elements to access the div class input-container input-left-half round like this:
div(:scar_first_name_error){validate_method_element.serv_info_element.scar_input_group_element.div_element(:class => "input-container input-left-half round")}
But I got the error that serv_info_element is an undefined method, which makes sense, but is it possible to chain the 3 predefined elements I stated above to access the input-container input-left-half round?
I read this: https://github.com/cheezy/page-object/wiki/Nested-Elements but didn't want to have to repeat any code if I can help it.
Assuming that the nesting is always the same, rather than having the :scar_first_name_error map through each ancestor, you could define each element with respect to its parent (or ancestor).
Let us assume the HTML is:
<html>
<body>
<div class="validate-method">
<div class="service-info">
<div class="input-group">
<div class="input-container input-left-half round">
text
</div>
</div>
</div>
</div>
</body>
</html>
You could define the page as:
class MyPage
include PageObject
div(:serv_info) { validate_method_element.div_element(:class => "service-info") }
div(:validate_method, :class => "validate-method")
div(:scar_input_group) { serv_info_element.div_element(:class => "input-group") }
div(:scar_first_name_error) { scar_input_group_element.div_element(:class => "input-container input-left-half round") }
end
Notice that the :serv_info is defined with respect to its parent :validate_method, :scar_input_group is defined with respect ot its parent :serv_info, etc.
With this page object, we can see we can get the lower element's text:
page = MyPage.new(browser)
p page.scar_first_name_error
#=> "text"

Grails: how to pass a array (and not a string!) using remoteFunction (ajax) from controller to view?

I need to load different data in a div when I change a Select option, not only a simple string but I list/array/map of strings. My code:
View:
<div id="contextMenu">
<div id="testeDiv">${result}</div>
<form class="selecionarConta" name="formulario">
<g:select id="selecionaConta"
name="selecionarConta"
class="selectConta"
from="${menuDropDown}"
optionValue="string"
optionKey="value"
onchange="${remoteFunction(controller:'dashboard',action:'teste', update:'testeDiv', params:'\'varteste=\'+this.value')}"/>
</form>
</div>
Controller:
def teste() {
def result = [["Lemon":"${params.varteste}"],["Orange":"5"],["Grapefruit":"10"]]
[result:result]
}
Let's suppose I want to load an array or even an object in this div "testeDiv" and then any content I want, e.g. a list, or even a single element from this list e.g. <div id=testeDiv>${result[1]}</div>

Unable to click on checkbox. Using page-object-gem

I am having trouble clicking on a checkbox using the page-object-gem. The html code looks like this:
<label class='cc pointer value-apple'>
<input class='hidden' type='checkbox' value='apple'></input>
<div style="background-image:url(/images/fruit-apple-3453452346.jpg)"><div>
</label>
<label class='cc pointer value-banana'>
<input class='hidden' type='checkbox' value='banana'></input>
<div style="background-image:url(/images/fruit-banana-2359235674.jpg)"><div>
</label>
Using watir-webdriver I have no issues clicking on the label or div since the checkbox is hidden. Those work fine. However this does not seem to work using the page-object-gem. I have tried the following:
label(:select_fruit_apple, :class => /apple/)
on(FruitsPage).select_fruit_apple
div(:select_fruit_apple, :style => /apple/)
on(FruitsPage).select_fruit_apple
Any suggestions on how to do this is much appreciated.
Since Watir-Webdriver requires you to click the label or div, you will have to do the same with the page object.
The label and div accessor methods do not create methods to click the element. For the code you tried, when you call select_fruit_apple, it is just returning the text of the label or div element.
To click the label (or div), you will need to:
Get the label/div element. This can be done by either defining a method that uses a NestedElement or creating the label/div accessor and using the _element method.
Call the click method for the element. This will call Watir-Webdriver's click method.
Here is what the class would look like if you were using NestedElement directly:
class MyPage
include PageObject
def select_fruit_apple()
label_element(:class => 'value-apple').click
end
end
Alternatively, if you need the label/div element for multiple things, you might want to create an accessor for them:
class MyPage
include PageObject
label(:apple, :class => 'value-apple')
def select_fruit_apple()
apple_element.click
end
end
You can then call this method to set the checkbox:
on(FruitsPage).select_fruit_apple
Of course, if you want to save having to define a method for each fruit, you could use a method that takes a parameter:
class MyPage
include PageObject
def select_fruit(fruit)
label_element(:class => 'value-' + fruit).click
end
end
Then the method call would be:
on(FruitsPage).select_fruit('apple')

Unit testing with rspec2 and Nokogiri

I have a requirement to read a third-party public website. Currently I am able to do this via Nokogiri, but I'm having trouble writing some unit tests using rspec.
I have this HTML <div>:
<div class="user">
<div class="name">User Name</div>
</div>
In my Reader model I have the method name, which reads the name from the HTML:
class SampleReader
def name(html_div)
html_div.css('name')
end
end
In my RSpec test case I pass the above HTML <div> as a string to the name method and I get the following error:
undefined method `css' for #<String:0x007fd8a0b39c98>
I believe it's because Nokogiri cannot identified the string as HTML, so I would appreciate if someone can help me write the test case. And, if possible, my preferred option is to pass only the <div> string, not the entire HTML page source, to the method.
I'm using Rails 3.2.9
Rspec2
Nokogiri
You'll need to wrap the HTML string as a Nokogiri document:
require 'nokogiri'
str = <<-HTML
<div class="user">
<div class="name">User Name</div>
</div>
HTML
class SampleReader
def name(html_div)
doc = Nokogiri::HTML(html_div)
doc.css('.name').text
end
end
reader = SampleReader.new
puts reader.name(str) #=> "User Name"
Also, don't forget to upgrade your application to rails 3.2.11.

Resources