How to access multiple text boxes in selenium - python

i am trying fill the text boxes. Each time you get into the page the the number of text boxes will be different and the name of them will be different.
<div class="fb-single-line-text">
<div class="display-flex" data-test-single-line-text-input-wrap="true">
<!---->
<input name="urn:li:fs_easyApplyFormElement:(urn:li:fs_normalized_jobPosting:2620509178,30257397,numeric)" id="urn:li:fs_easyApplyFormElement:(urn:li:fs_normalized_jobPosting:2620509178,30257397,numeric)" class="ember-text-field ember-view fb-single-line-text__input" aria-required="true" aria-describedby="urn:li:fs_easyApplyFormElement:(urn:li:fs_normalized_jobPosting:2620509178,30257397,numeric)-error-message" data-test-single-line-text-input="" type="text">
</div>
</div>
the above lines are the html code of first text box
<div class="fb-single-line-text">
<div class="display-flex" data-test-single-line-text-input-wrap="true">
<!---->
<input name="urn:li:fs_easyApplyFormElement:(urn:li:fs_normalized_jobPosting:2620509178,30257389,numeric)" id="urn:li:fs_easyApplyFormElement:(urn:li:fs_normalized_jobPosting:2620509178,30257389,numeric)" class="ember-text-field ember-view fb-single-line-text__input" aria-required="true" aria-describedby="urn:li:fs_easyApplyFormElement:(urn:li:fs_norm
alized_jobPosting:2620509178,30257389,numeric)-error-message" data-test-single-line-text-input="" type="text">
</div>
</div>
So i see all of them class name in comman so i tried to get all the eemphasized textlemnts inside the class . but i could not find a possible way for it. can someone help me with that

There are multiple ways to deal with this situation.
use find_elements to find out how many input boxes are present in UI, also you could send different message to those input box.
total_no_of_input_with_div_single_line_text = len(driver.find_elements(By.CSS_SELECTOR, "div.fb-single-line-text input"))
print(total_no_of_input_with_div_single_line_text)
Now you can send_keys to individual elements like this :-
total_no_of_input_with_div_single_line_text[0].send_keys('some string')
you can always change the index above from 0 to 1, 2 etc.
second in a loop like this :
for ele in driver.find_elements(By.CSS_SELECTOR, "div.fb-single-line-text input"):
ele.send_keys('some value here')
other way would be to use xpath indexing to locate the element.
(//div[#class='fb-single-line-text']/descendant::input)[1]
should locate the first web element input in the page, also you have the access to change that to [2], [3] and so on..

Related

How to locate a nested element by using Selenium webdriver?

I have the following html:
<label class="control-label col-sm-4" for="bla-bla">
"Value date"
::after
</label>
<div class="col-sm-8">
<div class="row">
::before
<div class="col-sm-2>
<label class="control-label" for="bla-bla">
"Priority"
::after
</label>
</div>
::after
</div>
::after
</div>
I need to extract both the elements like "Value date" and the "Priority" element.
Here is my current solution:
elements = [f for f in driver.find_elements(By.XPATH, "//*[contains(#class, 'control-label')]")]
It works perfectly with the elements like "Value date", but it doesn't see the "Priority" element. I see that "Priority" is nested in the "Value date" element here. Maybe, it somehow affects the way XPATH works.
I tried adding the exact class match, but without any result:
elements = [f for f in driver.find_elements(By.XPATH, "//*[contains(#class, 'control-label') or #class = 'control-label']")]
Actually the XPATH was working OK. The problem was in what I was doing with the found elements next. I was extracting text by using the .text() method which doesn't always work as expected. If you experience similar problems, try using .get_attribute('innerText') and .get_attribute('textContent').

Robot Framework, Python, Selenium "Page Should Contain" do not work

Here is my code :
${verifications} Create List
Set Test Variable ${verifications}
Input text ${societes_input_nom} ${nom_etablissement} ${TEST_NAME}
Append To List ${verifications} ${nom_etablissement} ${TEST_NAME}
Input text ${societes_input_contact_email_casino} ${email}
Append To List ${verifications} ${email}
Input text ${societes_input_contact_adresse} ${adresse}
Append To List ${verifications} ${adresse}
Input text ${societes_input_site_web} ${url_siteweb}
Append To List ${verifications} ${url_siteweb}
FOR ${item} IN #{verifications}
Page Should Contain ${item}
END
Here the HTML for the input :
<div class="form-group">
<label for="title"><h4>Nom de l'établissement
</h4></label>
<br>
<div class="input-group">
<div class="input-group-addon" >
<i class="fa fa-building">
</i>
</div>
<input type="text" style="display: none;" id="initialvalue_prop_1" name="initialvalue_prop_1" maxlength="1000" value="TNR Activite Casino"
/>
<input type="text" id="prop_1" name="prop_1" maxlength="1000" value="TNR Activite Casino"
/>
But, the "page should Contain" do not find my ${nom_etablissement} ${TEST_NAME}
But when i'm looking the page, thoses words are in the page (and the DOM)
The error :
Page should have contained text 'TNR Activite Casino' but did not.
I don't know how to fix that, I tried many thing but nothing work...
Can you help me pls ?
Page Should Contain check for actual text and not the values of the attribute. To get value of attribute you should use -
${Value}= Get Element Attribute xpath://input[#id='initialvalue_prop_1'] value
If you want to assert value inside the textfield then use the keyword -
Textfield Value Should Be ${textfield_locator} ${value_to_be_asserted}
For more details Get Element Attribute

How to click the 2nd text box with smae class name in selenium using python

I have recently started using selenium with python and stuck with the below problem. It may be simple but I have tried a lot while searching through different answers but could not solve it.
I want to click the 2nd text box with class name 'param-text-input text-input numeric-value'
<div class="bet-widget-main-row-right">
<div class="bet-widget-main-content">
<div class="bet-params">
<div class="param-wrapper">
<span class="param-label">Label1</span>
<div class="param-input -desktop">
<div class="param with-error">
<span class="param-input-wrapper">
<span class="param-currency numeric-value">£</span>
<input type="text" class="param-text-input text-input numeric-value" value=".04" tabindex="0" size="3" maxlength="11">
</span>
</div>
<div class="param-input_ticks"></div>
</div>
</div>
<div class="param-wrapper">
<span class="param-label">Label2</span>
<div class="param-input -desktop">
<div class="param">
<span class="param-input-wrapper">
<input type="text" class="param-text-input text-input numeric-value" value="2.18" tabindex="0" size="4" maxlength="8">
</span>
</div>
<div class="param-input_ticks"></div>
</div>
</div>
</div>
</div>
<div class="bet-submit"><button class="confirm-bet-button -accented micro-button" type="submit" disabled="" tabindex="0"><span>Button1</span></button></div></div>
I have tried multiple solutions but none work:
self.driver.find_element_by_xpath("//[#class='param-text-inp‌​ut.text-input.numeri‌​c-value'][2]").clear‌​()
self.driver.find_element_by_css_selector("[input.param-text-‌​input.text-input.num‌​eric-value][2]").cle‌​ar()
self.driver.find_element_by_xpath("//input[#class='param-tex‌​t-input'][2]").clear‌​()
Any pointers/help is appreciated.
In the case that you would prefer to use a CSS selector, the following will choose that second input:
div.param-wrapper:nth-of-type(2) input.param-text-input.text-input.numeric-value
we're looking for the second "param-wrapper" because that is the thing which will correctly count the parameters.
It's pretty easy:
self.driver.find_elements_by_xpath('//input[#Class="param-text-‌​input.text-input.num‌​eric-value"]')[1].clear()
or
from selenium.webdriver.common.keys import Keys
self.driver.find_elements_by_xpath('//input[#Class="param-text-‌​input.text-input.num‌​eric-value"]')[1].send_keys(Keys.BACKSPACE)
You need to make an object list in the first place. So you should find all the placeholders with the same name. Then get said item, which is the second element(list are zero based, so 1 is second)
Cheers
It is possible in XPath to select the n-th object that corresponds to your XPath expression.
To achieve this you use the [n] at the end of of your expression.
What you forgot is to put () around your expression before adding the [n].
So your XPath should be (//input[#class='param-tex‌​t-input'])[2].
To click the 2nd text box with class name 'param-text-input text-input numeric-value' you can use the following code block :
self.driver.find_element_by_xpath("//div[#class='bet-params']//following-sibling::input[2]").clear()

using nth-type or nth-child to select n element

Q: What XPath or CSS selector I can use to select 2nd <div class="checkbox">?
I have tried to use:
XPath - //div[#class="checkbox"][2]
CSS - div.checkbox:nth-child(2)
However none of them worked on chrome developer tool.
I can use $x('//div[#class="checkbox"]') to see all three checkboxes
I can use $x('//div[#class="checkbox"]')[0] to specify the 1st div.checkbox
I can use $x('//div[#class="checkbox"]')[1] to specify the 2nd div.checkbox
Here's an example of my HTML Structure
<div class="fs">
<div class="f">
<div class="checkbox">
<input type="radio" value="A">
<label for="A">A</label>
</div>
</div>
<div class="f">
<div class="checkbox">
<input type="radio" value="B">
<label for="B">B</label>
</div>
</div>
<div class="f">
<div class="checkbox">
<input type="radio" value="C">
<label for="C">C</label>
</div>
</div>
</div>
Rather than trying to find the second element by index, another possibility would be to get it by the value on the INPUT or the text in the LABEL that is contained in that DIV. A couple XPaths would be
//div[#class='checkbox'][./input[#value='B']]
//div[#class='checkbox'][./label[.='B']]
You need 2nd element from the results. Which can be done by using below
(//div[#class="checkbox"])[2]
I think CSS doesn't allow such a thing to select from a result
Since JeffC and Tarun Lalwani already suggested XPath way of doing it, I'd like to suggest a different approach.
In CSS, one can use :nth-child selector to choose 2nd <div class="f"> and grab the nested div from there. (> can be omitted)
div.f:nth-child(2) > div.checkbox
Similarly, the following works in XPath:
//div[#class='f'][2]/div[#class='checkbox']
One can choose an element based on the attribute value with CSS selector using Attribute selectors, but one cannot select the parent, unfortunately.

Selenium (python) text deletes on its own

Selenium is able to find these elements and send_text to them, but right after the text is written it is automatically deleted. Am I calling .send_text() wrong, or am I finding the wrong element to interact with?
This is a popup frame dialog, but I can't seem to focus on the frame. I'm not even sure I need to as selenium still interacts with the text fields.
Here is the javascript:
<div class="control-group">
<label class="control-label">Patient ID</label>
<div class="controls">
<input data-ng-model="subject.Code" data-custom-error="Patient ID already exists in this center" class="ng-valid ng-dirty" data-original-title="" type="text">
<i class="required-field" style="top:inherit">*</i>
</div>
</div>
Here is one method I have been using:
patientID = 'testID'
driver.find_element_by_xpath("//input[#data-ng-model='subject.Code']").send_keys(patientID)
also,
driver.find_element_by_css_selector(".controls > input[data-ng-model='subject.Code']").send_keys(patientID)
As I said, both find the correct element and send text but the text is immediately deleted. Any ideas, I'm stuck.
I'm using firefox, but the same happens in chrome.
Have you checked if there is any javascript code in the page listening to changes to the input field and deleting its contents?

Categories