How do you change element attributes using Python? - 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)

Related

How to find an element with respect to another element through selenium and python

<div class="block-inner">
<div class="form-group">
<label>Username</label>
<input type="text" name="username" class="required form-control" value="" placeholder="Enter your username...">
</div>
<div class="form-group w_margin">
<label>Password</label>
<input name="password" type="password" class="required form-control" style="" placeholder="Enter your password...">
</div>
</div>
Context
My need is to find Username in Web page and automatically has to move to the next element to fill value, and once it finds Password text and has to move to next element to fill password from dictionary. Please help me on this.
driver = webdriver.Chrome()
driver.get("https://account.genndi.com/login")
element = "//label[contains(text(),'')]" #xpath
dictCredentials = {'Username':'abcdef', 'Password':'123'}
for clas in driver.find_elements_by_xpath(element):
text = clas.text
if text in dictCredentials.keys():
inputbox = #please help here get corresponding input element
inputbox.send_keys(dictCredentials[text])
I know how to send keys directly into text box and it is easy too. But I wish to understand how to do the same operation indirectly with another class element.
To achieve this let me explain how you are going to do this.
So first you need to get the element of Username.
You have already done this with:
element = driver.findElement(by.xpath("//label[contains(text(),'')]"));
What you can also do is, get the parent element directly by saying:
element = driver.findElement(by.xpath("//label[contains(text(),'Username')]/.."));
With the /.. you are getting the ancestor of the element label with text Username
Now that you have found the element within which your input is located you can say:
inputElement = element.findElement(by.xpath("./input"));
This way, within the parent element you found, you are going to look for an input field.
As per the HTML you have shared to find the <label> tags with text as Username and Password and move to the next element to fill value you can create a function which will accept the <label> tag text and the text-to-send as two arguments and fill up the next <input> as follows :
def fillUp(labelText, inputValue):
driver.find_element_by_xpath("//label[.='" + labelText + "']//following::input[1]").send_keys(inputValue)
Now, you can call this function from anywhere within your script as follows :
fillUp("Username", "Chandrasekar ")
fillUp("Password", "Subramanian")
Just use "by_name" locator =)
user = {"name": "Alex", "password": 'pass'}
driver.find_element_by_name("username").send_keys(user.name)
driver.find_element_by_name("password").send_keys(user.password)
If you really want to find "Username" text in parent element - you have few other options:
First is to find wrapper element, that contains specific text, and search for input in it:
self.driver.find_element_by_xpath("//*[label[text()='Username']]/input").send_keys("name")
self.driver.find_element_by_xpath("//*[label[text()='Password']]/input").send_keys("pass")
Or search for element's sibling input:
self.driver.find_element_by_xpath("//label[text()='Username']/following-sibling::input[1]").send_keys("pass")
self.driver.find_element_by_xpath("//label[text()='Password']/following-sibling::input[1]").send_keys("pass")
You can get it with this pseudo xpath:
//*[#name='username']
Then:
//*[#name='password']
The "move", you can achieve with your code following this pattern:
click on the input field
clear filed
enter text
move to the next element
clear filed
enter text

InvalidElementStateException: Message: invalid element state: Element is not currently interactable and may not be manipulated

I'm using SeleniumLibrary for Robot Framework and i do have an issue regarding of Input Text function:
HTML:
<div class="form-group">
<label class="col-sm-6 control-label" for="gngFeeValue" >What is the expected Fee Value?</label>
<div class="col-sm-4">
<input id="gngFeeValue" data-role="numerictextbox"
data-format="###,###,###,###,###,##0"
data-decimals="0"
data-spinners="false"
data-bind="value: gng.feeValue, disabled: isInputDisabled" placeholder="Enter fee value" />
</div>
</div>
TEST.robot:
Expected Fee Value - Value
[Arguments] ${expectedFeeValue}
Input Text //*[#id="gngFeeValue"] ${expectedFeeValue}
I do get an error:
InvalidElementStateException: Message: invalid element state: Element is not currently interactable and may not be manipulated
Anyone who could help me regarding this? Thanks!
I had the same problem. I couldn't find any elements on a specific form.
I realized that I could use the elements outside the form normally. So I started investigating html and found that it was inside an iframe.
To solve this, I only needed the SeleniumLibrary Select Frame:
Select Frame xpath=//*[#id="iframe"]
The webElement your are trying to interact with is either not clickable or it is disabled or may be it is out of browser's viewport. Selenium API is successful only on active interact-able webelements. Use Javascript, as a last mile solution.

Python Selenium can't locate element

I have some troubles locating a username field on a webpage.
Using find_element_by_name/class prompts me with a 'no such element' error.
After a lot of fiddling, I still can not get this to work. Have not had this problem on any other webpages where I used the same method. Hope anyone can help me out!
<input type="text" class="_ph6vk _o716c" aria-describedby="" aria-label="Telefoonnummer, gebruikersnaam of e-mailadres" aria-required="true" autocapitalize="off" autocorrect="off" autocomplete="username" maxlength="30" name="username" placeholder="Telefoonnummer, gebruikersnaam of e-mailadres" value="">
The HTML above represents the element which I want to locate.
In case of slow page load/render, instruct the driver to wait for 5 seconds (for the element to load):
driver.implicitly_wait(5).
Explicitly getting the input:
driver.find_element_by_xpath("//input[contains(#class, '_ph6vk')]")
Though the class name looks to be dynamically generated on each particular page load, in that case, you will have to count inputs on the page before wanted one:
driver.find_element_by_xpath("//input[1]")
or write there a full absolute XPath.
Try the following:
driver.find_element_by_css_selector("input._ph6vk._o716c")
this won't work:
find_element_by_class("_ph6vk _o716c")
as they are two different classes.

Getting text from angular element with no text value

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.

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()

Categories

Resources