Getting text from angular element with no text value - python

I've bumped into a text field in a simple table where the text I want to check/extract is not part of any value in the element.
Using Python and Selenium I was trying to get the value by using get_value, get_text or get_attribute but with no success. Everything returns
AttributeError: 'WebElement' object has no attribute 'get_text'
which is not surprising as there is no real value in the element. It's an AngularJS based website.
The element looks like this and the text inside is "France":
<span class="keyword-autocomplete-container" model="flavor.subregion" keyword-autocomplete="subregion" filter="{ancestorId: flavor.regionId || flavor.countryId}" with-aliases="true" replace-alias="true"> <input ng-model="localModel" ng-disabled="ngDisabled" mass-autocomplete-item="createOptions()" ng-keypress="onKeyPressed($event)" class="ng-pristine ng-valid ng-touched" autocomplete="off"></span>
with this children:
<input ng-model="localModel" ng-disabled="ngDisabled" mass- autocomplete-item="createOptions()" ng-keypress="onKeyPressed($event)" class="ng-pristine ng-valid ng-touched" autocomplete="off">
The selector I have pointed to that element works fine. I can type some text or click it with no issues. Anyone can help how to read a text from such element? Thank you.

Related

How do you change element attributes using Python?

I was wondering how to use python to change an element in a page's HTML code:
Specifically, from:
<input _ngcontent-mcp-c552="" type="number" name="bpm" placeholder="0" min="0" max="999" step="0.01" class="ng-valid ng-dirty ng-touched">
to
<input _ngcontent-mcp-c552="" type="number" name="bpm" placeholder="0" min="0" max="999" step="1" class="ng-valid ng-dirty ng-touched">
(Changing the step-size value)
The HTML I'm attempting to edit would not be of my own HTML file, but a public website. As such, the change would only be temporary; but I'm okay with that. Any help would be greatly appreciated. Thank you.
CONTEXT: Using automation, I'm trying to input a value (a number) into a textbox; but for some reason the send_keys function from selenium isn't sending any keys. So, I found that I could just select the element and hold the up arrow key until I attain the value I'd like. Problem is, the element's current step-size of 0.01 makes attaining the values I want (varying between 60-180) take very long. And now that's the problem I'm trying to sort out now.
To change the attribute from:
step="0.01"
to:
step="1"
you need to use setAttribute() as follows:
my_element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[#class='ng-valid ng-dirty ng-touched' and #name='bpm'][#type='number']")))
driver.execute_script("arguments[0].setAttribute('step','1')", my_element)

Find element using parent/sibling in python selenium

I am using selenium in python to scrape a web page designed with angular js and hence has no robust identifiers for elements such as id etc. I am completely reliant on CSS selectors (which are dynamic) and xpaths.
I have the following code -
<div class="dpm-form-row ng-star-inserted">
<dpm-input-number class="flex-6">
<dpm-input-label>
<label>Fixed Rate</label>
</dpm-input-label>
<dpm-input-number-bare>
<input size="1" type="text" placeholder="" class="ng-pristine ng-valid ng-touched">
</dpm-input-number-bare>
</dpm-input-number>
<div class="flex-6">
</div>
</div>
It's basically a label called "Fixed Rate" followed by an input text box. Its that box I am trying to grab.
I have managed to get the label using the following code, I am having trouble using the parent/sibling logic to get the box -
element = driver.find_element_by_xpath('//*[contains(text(),"Fixed Rate")]')
Repost from your preceding question. Original solution :
//input[#class="ng-pristine ng-valid ng-touched"][../preceding-sibling::dpm-input-label[1]/label[.="Fixed Rate"]]
3 XPath using following-sibling axis :
//dpm-input-label[label[.="Fixed Rate"]]/following-sibling::dpm-input-number-bare[1]/input
//dpm-input-label[label[contains(.,"Fixed Rate")]]/following-sibling::dpm-input-number-bare[1]/input
//dpm-input-label[contains(.,"Fixed Rate")]/following-sibling::dpm-input-number-bare[1]/input
3 XPath using preceding-sibling axis and multiple contains for the input element :
//input[contains(#class,"ng-pristine") and contains(#class,"ng-valid") and contains(#class,"ng-touched")][../preceding-sibling::dpm-input-label[1]/label[.="Fixed Rate"]]
//input[contains(#class,"ng-pristine") and contains(#class,"ng-valid") and contains(#class,"ng-touched")][../preceding-sibling::dpm-input-label[1]/label[contains(.,"Fixed Rate")]]
//input[contains(#class,"ng-pristine") and contains(#class,"ng-valid") and contains(#class,"ng-touched")][../preceding-sibling::dpm-input-label[1][contains(.,"Fixed Rate")]]
4 XPath using preceding axis :
//input[#class="ng-pristine ng-valid ng-touched"][preceding::label[1][.="Fixed Rate"]]
//input[#class="ng-pristine ng-valid ng-touched"][preceding::label[1][contains(.,"Fixed Rate")]]
//input[contains(#class,"ng-pristine") and contains(#class,"ng-valid") and contains(#class,"ng-touched")][preceding::label[1][.="Fixed Rate"]]
//input[contains(#class,"ng-pristine") and contains(#class,"ng-valid") and contains(#class,"ng-touched")][preceding::label[1][contains(.,"Fixed Rate")]]

Message - "unknown error: cannot focus element" - in python selenium driver

<div id="ccodeinput">
<input class="dropdownheader2" type="TEXT" name="CCODE" value="435435" size="14" maxlength="22">
</div>
This is the code for the Search field(see screenshot - upper right side). I am unable to pass values from a list to this search bar. But I am able to press the search button beside it.
How can I enter values in the search field?
This is what I have tried:
inputElement = chrome_driver.find_element_by_id('ccodeinput')
inputElement.send_keys(435435)
As per the HTML you have shared the <input> tag is a child of <div> tag, so to put text within the intended element you can use :
chrome_driver.find_element_by_xpath("//input[#class='dropdownheader2' and #name='CCODE']").send_keys("435435")

Setting the value of an <input> dropdown in Selenium with Python

I have a HTML page containing a form with an tag. I want to set the value of the drop down in this tag using Selenium.
This is how I retrieve the input element:
driver.find_element_by_xpath("/html/body/div[2]/div/div/form/div/div[1]/div[3]/div[1]/div/div[1]/input")
I tried to set the value using select_month.send_keys("09") but this is not accepted by the web page when I try to submit the form so I need to find another method.
EDIT: Here is the HTML of the form, I have ensured that it is the right element in my x-path:
<input autocomplete="off" tabindex="-1" class="ui-select-search ui-select-toggle ng-pristine ng-valid ng-touched" ng-click="$select.toggle($event)" placeholder="Select month" ng-model="$select.search" ng-hide="!$select.searchEnabled || ($select.selected && !$select.open)" ng-disabled="$select.disabled" type="text">
After messing around a bit and incorporating the better practice presented by alecxe, this solution worked...
driver.find_element_by_xpath("//input[#placeholder='Select month']").click()
driver.find_element_by_xpath("//*[contains(text(), '09')]").click()

get_text() or text property is not working for labels

I want to access the text of labels, but neither get_text() nor text property is working for the following HTML:
<label class="checkbox">
<input type="checkbox" value="BATSMC">
BATS Multicast PITCH
</label>
For example, here I want to get the value: BATS Multicast PITCH.
In Selenium-Python code:
print e.text
is giving blank spaces and get_text() is giving the following error:
AttributeError: 'WebElement' object has no attribute 'get_text'
I am getting the correct web element and am able to access other properties like size, location, parent etc. I expected "text" to work. Can anyone help?
The <label> tag in the above HTML does not have a text attribute.
If you want to retrieve the BATS Multicast PITCH string, then you need to get it from the <input> tag instead. For example, the following code will print this string:
e = driver.find_element_by_tag_name('input')
print e.text
If you want to retrieve the entire inner HTML of the <label> tag, then you can use:
e = driver.find_element_by_tag_name('label')
print e.get_attribute('innerHTML')
This will print "<input type="checkbox" value="BATSMC">BATS Multicast PITCH.
Of course, you probably have other <label> and <input> tags in your HTML, so you'll need to use a different method (other than find_element_by_tag_name) in order to find these specific elements.
BTW, I just noticed that the <input> tag in the HTML above is not properly closed...
Try use the innerText attribute to get only the text within the label tag.
e = driver.find_element_by_tag_name('label')
print e.get_attribute('innerText')

Categories

Resources