CSS selector path for text box that comes immediately after h3 with text "Company Name" - ruby

Below is my html
<div class="right" data-bindattr-13="13">
<h3>Company Name</h3>
<div class="input-row">
<input id="ember4258" class="ember-view ember-text-field" type="text"/>
</div>
<h3>Full Company Legal Name</h3>
<div class="input-row">
<input id="ember4259" class="ember-view ember-text-field" type="text"/>
</div>
<h3>Company Phone</h3>
<div class="input-row">
<input id="ember4260" class="ember-view ember-text-field" type="text"/>
</div>
<h3>Federal Tax / Employer ID (EIN)</h3>
<div class="input-row">
<input id="ember4261" class="ember-view ember-text-field" type="text"/>
</div>
</div>
Since class value off all the text fields and respective parent div class attributes are same I need to fill these text fields without using nth-of-type.
I have done work around to create a CSS selector that should point the text box that is immediately after <h3>Full Company Legal Name</h3> .
h3:contains(^Company Name$)+div>input
But my Capybara script is not recognizing the above way and throwing the below error.
annotateInvalidSelectorError_': The given selector h3:contains(^Company Name$)+div>input is either invalid or does not result in a WebElement. The following error occurred: (Selenium::WebDriver::Error::InvalidSelectorError)
InvalidSelectorError: An invalid or illegal selector was specified
Can any one provide a CSS that matches my requirement?
Regards,
Avinash Duggirala

The contains pseudo class was deprecated, which is why the InvalidSelectorError occurs. There is currently no way to check text nodes using CSS-selectors.
Instead, you can use XPath to traverse the DOM to sibling elements.
text_field = page.find(:xpath, '//h3[text() = "Company Name"]/following-sibling::div[1]/input')
text_field.set('some value')

Related

xPath how to access input text file with generic name

Is there any option to access input in code like this:
(...)
<div class="dialogProp">
<div class="gwt-Label">Name</div>
<div class="floatLeft">
<div>
<input type="text" class="textBox">
</div>
<div class="notVisible"></div>
</div>
<div class="dialogProp">
<div class="gwt-Label">Surname</div>
<div class="floatLeft">
<div>
<input type="text" class="textBox">
</div>
<div class="notVisible"></div>
</div>
(...)
As you can see I got two inputs and only difference between them is label inside of div with different text inside. This kind of pattern can be found all around of website and I cannot change this. I can not add id's as well.
Do you know if there is possibility to add to the xPath this different text inside of div's?
Let's say I would like to access first input.
Of course I could use some ass long xPath, but I would like to reuse this with text inside of gwt-Label as variable.
Use below to locate input by label text:
//div[#class="gwt-Label" and .="Name"]/following-sibling::div//input
In Python you can pass label from variable:
label = "Name"
xpath = '//div[#class="gwt-Label" and .="%s"]/following-sibling::div//input' % label
To access the input with respect to the label text you can use the following solution:
labelText = "Name"
#or labelText = "Surname"
xpath = "//div[#class='gwt-Label' and contains(.,'" +labelText+ "')]//following::div[1]//input"

Need to select a checkbox, based on text in another div

<div class="bli-category">
<div class="row ng-scope" ng-repeat="placementtrack by $index">
<div class="col-sm-12">
<div class="col-sm-1 bli-category-checkbox">
<input class="bli-check-box ng-valid" type="checkbox" ng-click="addPlacement" ng-checked="checkedPlacementIndex" ng-model="selectedPlacement">
</div>
<div class="col-sm-8 bli-category-content">
<div class="ng-binding" ng-bind="placement.placementName">page_details</div>
</div>
</div>
</div>
I need to select the checkbox in class='bli-check-box ng-valid' for the text in class='ng-binding'
When I try to get the xpath like
//input[#class='bli-check-box ng-valid']
it selects all the 4-5 checkboxes
To select the checkbox in class='bli-check-box ng-valid' with respect to the text in class='ng-binding' i.e. page_details you can use the following xpath :
//div[#class='bli-category']//div[#class='ng-binding' and contains(.,'page_details')]//preceding::input[#class='bli-check-box ng-valid']
Note : As the element is an Angular element you have to induce wait for the element to be clickable before attempting to click.
//div[text='page_detials' and class='ng-binding']/../preceding-sibling::div//input[class='bli-check-box ng-valid']
The above xpath starts with finding the node which has the custom text that you know. It then traverses to its parent and then its previous sibling which in your case houses your required input node. So after traversing to the div you select its child which is your required input node.

How do i match the value which has a radio button checked

I have a list of similar looking DIVs without any Div ID, except one has a check box checked and others doesn't. What i need is to find the value from a child tag only if a radio button is selected.
Below is a simpler version of my code.
<div class = "XYZ">
<input type="radio" checked>
<input type="hidden" value="This is a great thing 1">
</div>
<div class = "XYZ">
<input type="radio">
<input type="hidden" value="This is a great thing 2">
</div>
Result needed is
This is a great thing 1
Unfortunately the source code cannot be changed.
Your xpath should look for a div that contains the checked input and to get the value for the one that has value attribute.
First selector returns the input, the second returns the value.
//div[.//input[#checked]]/input[#value]
//div[.//input[#checked]]/input/#value
As an alternative you can use the following sibling:
//input[#checked]/following-sibling::input
If you want to also use the class of the parent div:
//div[#class='XYZ']/input[#checked]/following-sibling::input

Enter text in input in Watir with same class

I am trying to enter text into an input field and can not successfully get it working. I have two inputs that look like this:
<div class"outerParentClass">
<div class="classLabel">From</div>
<div class="classA classB classD">
<div class="classE">
<div class="classText"> TEXT HERE </div>
<input class="classInputA classInoutB" type="text">
</div>
</div>
</div>
<div class="classLabel">To</div>
<div class="classA classB classD">
<div class="classE">
<div class="classText"> DIFFERENT TEXT HERE </div>
<input class="classInputA classInoutB" type="text">
</div>
</div>
</div>
</div>
Both the inputs are the exact same format as above. There are no Id's and both have the same classes. I am struggling at entering the text into these or even finding them correctly.
When I do this:
browser.text_field(:class => "classInputA").size
It returns 20
When I do this:
browser.text_field(:class => "classInputA")
It returns:
#<Watir::TextField:0x..fbccafb7ed2e9b85e located=false selector={:class=>"classInputA", :tag_name=>"input"}>
Not sure how to locate either of these inputs. Any suggestions?
The text adjacent to the field provides a label and context for the field. As it is likely unique, you can use this to identify the element.
To do this, find the div containing the label text. Then navigate to the adjacent div that contains the text field.
browser.div(text: 'From', class: 'classLabel') # label of interest
.element(xpath: './following-sibling::div[1]') # adjacent div containing text field
.text_field # the text field
Note that in the next release of Watir, .element(xpath: './following-sibling::div[1]') will be replaceable by just .following-sibling.

Selenium script for dynamic ID textbox

I have to click on element whose Id is changeable,means dynamic value assign to text box everytime . I have to insert value in text box.
Following is the inspect element code of text box
<div class="invoicing-details">
<div>
<label for="PaidToName_b62b89226e5f4fcbb74d0d27a9db88ca"> To </label>
<input id="PaidToContactID" type="hidden" value="" name="PaidToContactID">
<div class="controls">
<input id="PaidToName_b62b89226e5f4fcbb74d0d27a9db88ca" type="hidden" style="display:none;" value="" name="PaidToName_b62b89226e5f4fcbb74d0d27a9db88ca">
<input id="PaidToName_b62b89226e5f4fcbb74d0d27a9db88ca_value" class=" autocompleter field " type="text" style="width:127px;" tabindex="10" value="" maxlength="255" name="PaidToName_b62b89226e5f4fcbb74d0d27a9db88ca_value" autocomplete="off">
<div id="PaidToName_b62b89226e5f4fcbb74d0d27a9db88ca_suggestions" class="autocomplete" style="display: none; height: 200px; width: 200px;"> </div>
<script type="text/javascript">
</div>
</div>
"PaidToName_b62b89226e5f4fcbb74d0d27a9db88ca_value" this is text box id.
I used following code
self.set_text_value('div.invoicing-details input' ,"my value",true)
but it does not work and getting syntax error.
Can anyone help me and provide syntax how to write ruby script for seleinum.
Dynamic ids very bad for automation. You can try to add other property to input element with stable name. As i clearly understood you need to click on element and then input text in it?! I'm not good at ruby, but i think this should look like:
element = driver.find_elements(:css,".invoicing-details .autocompleter")
element.click
element.send_keys "Some text"
You can try to find id of an element using next xpath: //input[#id=(//label[contains(text(),'To')]/#for)]. Here you find a label by its text and then get for attribute (it is needed id).
element = driver.find_elements(:xpath,"//input[#id=(//label[contains(text(),'To')]/#for)]")
element.click
element.send_keys "Some text"

Resources