Error running ruby code containing a regular expression and index value - ruby

Getting the following error running a ruby script:
C:/Ruby/test3.rb:30: syntax error, unexpected tINTEGER, expecting ')'
...41afa164b242__Rate/ => :index 1).set "00.10"
...
#b.text_field(:id, /Contracts_[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}__ContractTranslationQualities_[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}__ContractPrices_[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}__ContractPriceWordRates_0ec7c68c-663a-40aa-9ab6-41afa164b242__Rate/ => :index 1).set "00.10"
BTW the regex is checked against the html code using Rubular.com and it checks out. I am successfully using this method in other pages that do not contain multiple elements with the same id. However on this page I am testing there are 4 text fields with this id so I need to index unless you have another suggestion. Thanks for the help.
<td>
<div class="symbol-left-inner-addon">
<span class="CurrencySymbol" title="USD">$</span>
<input id="Contracts_b05b4efc-fc08-427b-9319-6a25409eded1__ContractTranslationQualities_f056e412-af83-4965-8fbd-c516f17fb8cf__ContractPrices_9d79ae47-3295-4cbc-9ed5-5b96e53ed1c1__ContractPriceWordRates_b5356ba9-bdc8-49a8-855a-8c2271078f61__Rate" class="form-control numericInput text-right valid" type="text" value="0.00" name="Contracts[b05b4efc-fc08-427b-9319-6a25409eded1].ContractTranslationQualities[f056e412-af83-4965-8fbd-c516f17fb8cf].ContractPrices[9d79ae47-3295-4cbc-9ed5-5b96e53ed1c1].ContractPriceWordRates[b5356ba9-bdc8-49a8-855a-8c2271078f61].Rate" data-val-required="The Rate field is required." data-val-number="The field Rate must be a number." data-val="true">
</div>
</td>
^

When using multiple locators, it has to be passed as a Hash. It would look like (with the ID condensed for readability):
#b.text_field(:id => /Contracts/, :index => 1).set "00.10"
Or if you prefer the newer style:
#b.text_field(id: /Contracts/, index: 1).set "00.10"

Related

How to locate, using Xpath, an input field without using its id

I'm working with a web page with the following HTML where I want to identify the first <input> field inside the <span> using a text_field from within a page-object.
<div id="131:"> Please enter your name:
<span class="autocompspan " style="position:static;">
<input style="position: static;" class="autocompinput yui-ac-input" id="132:" name="132:"
onfocus="juic.fire("132:","_focus",event);"
onchange="juic.fire("132:","_despatchChange",event);"
onblur="juic.fire("132:","_blur",event);" size="60"
onkeydown="juic.fire("132:","_onkeydown",event);"
onkeyup="juic.fire("132:","_onkeyup",event);" aria-disabled="false" value=""
role="combobox" aria-autocomplete="list" aria-owns="132:_divList"
aria-activedescendant="132:_divAD" findtype="proxy" delimchar="" hideusername="false"
fetchusername="false" autocomplete="off" type="text">
<input value="" id="132:_hidden" name="132:_hidden" type="hidden">
</span>
</div>
If I use :id => '132:' to identify the field things work fine. I.e. text_field(:target_user_name, :id => '132:' ) works.
The issue is that this HTML is generated by the underlying app (SAP) which does not always generated the same value for the <input> field id so using the id cannot be relied upon to consistently identify the element.
So, given the above HTML what other ways might I go about reliably finding this <input> field.
I've tried the following, none of which work. Most of them time out waiting for the element to be located.
text_field(:target_user_name, :xpath => "//*[#class='autocompinput yui-ac-input' and #role = 'combobox']" )
text_field(:target_user_name, :xpath => "//*[#class='autocompinput' and #role = 'combobox']" )
text_field(:target_user_name, :xpath => "//span/input[#class='autocompinput yui-ac-input' and #role = 'combobox']" )
text_field(:target_user_name, :xpath => "//input[#class='autocompinput yui-ac-input' and #role = 'combobox']" )
text_field(:target_user_name, :class => 'autocompinput yui-ac-input')
Any thoughts?
When an element does not have unique identifiable attributes, you should look at the elements around it. In this case, there is user visible text that helps a user identify the purpose of the field. That same text can be used to identify the element in Watir.
As the surrounding div only contains the labelling text, you can search for that div by its text and get the only text field in it:
browser.div(text: 'Please enter your name:').text_field
As a page-object accessor:
text_field(:target_user_name) { div_element(text: 'Please enter your name:').text_field_element }
Firstly, Watir is designed to make it so that you shouldn't have to use XPATH.
It depends on how many different elements/ids are on the page, but I've found that using regular expressions often works well with dynamically generated ids. So either grab the id and use it elsewhere:
id = browser.text_field(id: /\d\d\d/).tr(':', '')
or just use it directly:
text_field(:target_user_name, id: /\d\d\d:/)
In this particular case you can check the first input field after 'Please enter your name:' text using below xpath:
//div[text()='Please enter your name:']//following::input[1]
In general if you encounter fields that does not have a unique identifier you can rely on static text or fields and then use xpath functions such as following, preceding etc.

accessing a <p> in Watir, which doesn't have attribute

I have this html code.
<div class="main" data-reactid=".0.2.1.1">
<div contenteditable="true" data-reactid=".0.2.1.1.0" autocomplete="off">
<p>
<br>
</p>
</div>
</div>
I have to write in tag. For this I wrote as:
paragraph(:article_title) {div_element(:class=>'main').div(:index=>1).paragraph(:index=>1)}
but it is giving an error. I don't understand what is wrong in this.
There are a couple of problems:
Watir uses a 0-based index. As a result, div(:index=>1) actually means to find the 2nd div tag. As this does not exist, you will get an unable to locate element error.
div and paragraph are not methods defined in the page-object gem. You will get deprecation errors when you try to use them. It should be div_element and paragraph_element respectively.
Try doing:
paragraph(:article_title) {div_element(:class=>'main').div_element(:index=>0).paragraph_element(:index=>0)}
More simply, since :index => 0 is implied:
paragraph(:article_title){div_element(:class=>'main').div_element.paragraph_element}
As there is only one paragraph element, you could further simplify it to:
paragraph(:article_title) {div_element(:class=>'main').paragraph_element}

How to find a field using placeholder text in Watir?

I have two search fields and I want to find the second one to set some text.
I have tried using div however it always finds the first search field.
Does anyone one have a suggestion on how to find the second object or use the unique placeholder text "Search..." ?
HTML:
input type="text" name="searchString" id="searchString" projects="" for="" placeholder="Search" class="form-control"
input type="text" name="searchString" id="searchString" placeholder="Search..." class="form-control"
Ruby - Watir:
#b.link(:text => "http://ml-test.mytest.com/Client/Profile/ab295b41-2c5e-4100-bdee-e757405238bb").click
#b.text_field{div(:class => "col-sm-4 col-md-3", :placeholder => "Search...")}.set "Automation (Test)"
It looks like the problem might simply be a typo in the code. Notice in the line:
#b.text_field{div(:class => "col-sm-4 col-md-3", :placeholder => "Search...")}.set "Automation (Test)"
That a block, seen by the {}, is being passed to the text_field method. The text_field method does not do anything with blocks, as a result the code is really just doing:
#b.text_field.set "Automation (Test)"
As there is no locator supplied to the text field, it will input the first text field on the page.
To locate the text field based on the placeholder attribute (or any other locator), it needs to be passed as an argument instead of a block:
#b.text_field(:placeholder => "Search...").set "Automation (Test)"
You had included a div as well. Assuming that it is an ancestor element need to find the text field, it should be:
#b.div(:class => "col-sm-4 col-md-3").text_field(:placeholder => "Search...").set "Automation (Test)"

XPATH required for an input text field?

i have a text box in my web application,Where i need to give input. I am trying to find the xpath of the text box. the following error is thrown.
Unable to locate element: {"method":"xpath","selector":"
HTML code:
<div class="input">
<input id="firstName" class="long" type="text" maxlength="50" value="" name="firstName
I want the xpath for firstName textbox.
//input[#type='text']
And this for generally targeting a text input (what I was after)
Try this one:
//input[#id='firstName']
Explanation:
// search on all levels
input for element nodes with the name of "input"
[#id='firstName'] having an attribute (#) with the name of "id" and a value of "firstName"
at least 3 simple ways to get this:
1)Driver.FindElement(By.XPath("//input[#id='firstName']"));
2)Driver.FindElement(By.Id("firstName"));
3)Driver.FindElement(By.CssSelector("#firstName"));
//*[text()[contains(.,'firstName')]]
finding by text would always work.

how to access this element

I am using Watir to write some tests for a web application. I need to get the text 'Bishop' from the HTML below but can't figure out how to do it.
<div id="dnn_ctr353_Main_ctl00_ctl00_ctl00_ctl07_Field_048b9dfa-bc64-42e4-8bd5-b45385e5f45b_view" style="display: block;">
<div class="workprolabel wpFieldLabel">
<span title="Please select a courtesy title from the list.">Title</span> <span class="validationIndicator wpValidationText"></span>
</div>
<span class="wpFieldViewContent" id="dnn_ctr353_Main_ctl00_ctl00_ctl00_ctl07_Field_048b9dfa-bc64-42e4-8bd5-b45385e5f45b_view_value"><p class="wpFieldValue ">Bishop</p></span>
</div>
Firebug tells me the xpath is:
html/body/form/div[5]/div[6]/div[2]/div[2]/div/div/span/span/div[2]/div[4]/div[1]/span[1]/div[2]/span/p/text()
but I cant format the element_by_xpath to pick it up.
You should be able to access the paragraph right away if it's unique:
my_p = browser.p(:class, "wpFieldValue ")
my_text = my_p.text
See HTML Elements Supported by Watir
Try
//span[#id='dnn_ctr353_Main_ctl00_ctl00_ctl00_ctl07_Field_048b9dfa-bc64-42e4-8bd5b45385e5f45b_view_value']//text()
EDIT:
Maybe this will work
path = "//span[#id='dnn_ctr353_Main_ctl00_ctl00_ctl00_ctl07_Field_048b9dfa-bc64-42e4-8bd5b45385e5f45b_view_value']/p";
ie.element_by_xpath(path).text
And check if the span's id is constant
Maybe you have an extra space in the end of the name?
<p class="wpFieldValue ">
Try one of these (worked for me, please notice trailing space after wpFieldValue in the first example):
browser.p(:class => "wpFieldValue ").text
#=> "Bishop"
browser.span(:id => "dnn_ctr353_Main_ctl00_ctl00_ctl00_ctl07_Field_048b9dfa-bc64-42e4-8bd5-b45385e5f45b_view_value").text
#=> "Bishop"
It seems in run time THE DIV style changing NONE to BLOCK.
So in this case we need to collect the text (Entire source or DIV Source) and will collect the value from the text
For Example :
text=ie.text
particular_div=text.scan(%r{div id="dnn_ctr353_Main_ctl00_ctl00_ctl00_ctl07_Field_048b9dfa-bc64-42e4-8bd5-b45385e5f45b_view" style="display: block;(.*)</span></div>}im).flatten.to_s
particular_div.scan(%r{ <p class="wpFieldValue ">(.*)</p> }im).flatten.to_s
The above code is the sample one will solve your problem.

Resources