Wait for the element to be selected in Selenium - python

There is a text field which gets automatically populated after a certain time by the website and the the text cursor moves to the same text field
<html>
<div>
<input type=text id=name>Enter here</div>
<html>
the input field gets selected and filled automatically by the website after a few seconds. I want selenium to wait till it gets selected and then carry on with the further code.
I've done:
wait=WebDriverWait(driver,10)
element=driver.find_element_by_id("name")
wait.until(expected_conditions.element_to_be_selected(element))
It throws error even though the text field is filled by the website.

The expected_conditions.element_to_be_selected() follows this spec. Specifically:
This operation only makes sense on input elements of the Checkbox- and Radio Button states (emphasis mine)
Your input is of type text, so it will not work.
You will have to use a different approach. Perhaps something like:
Read the text (the #value attribute).
Wait until it changes to anything else.

There were a few answers on other similiar questions which seem to work for respective questions. I did not find anything for python though.
What i did is run an infinite loop until the text present in the element had length not equal to zero.
while 1 is not 5:
if len(element.get_attribute("value")) is not 0:
break
else:
continue
value attribute of element has the value of whatever string is present in the textfield.

Related

Python Selenium lists only one li repeatedly

I'm trying to make an attendance app, using Selenium; the script should read the names and click on a designated checkbox when a name is matched. What happens is that it keeps clicking on the first checkbox repeatedly. When I looked into it turns out that it only reads the first li only.
here's the HTML code
<div class="members">
<ul class="memberlist"></ul>
</div>
the li are generated via fetch API from the database
when I try these in python, it only reads the first li element over and over
for i in range(len(df)):
print(driver.find_element(By.XPATH,".//ul[#class='memberlist']/li/p").text)
for i in range(len(df)):
print(driver.find_element(By.CLASS_NAME,"name").text)
also, I tried the solution from this and I don't think this is the correct syntax
selenium python for loop printing only first element repeatedly
Update: as per dosas comment, this did list all the names instead of just one, then I wrote this to click on the checkboxes of the attendees.
for i in range(len(df)):
# match names of the sheet with the 'name' class in the webpage
if df['name'][i]==driver.find_elements(By.CLASS_NAME,"name")[i].text:
driver.find_elements(By.CLASS_NAME, week)[i].click()
print(driver.find_elements(By.CLASS_NAME,"name")[i].text)
else:
print('No match')
Now I have a different problem, the attendance excel sheet has to be in the same order as the list on the web page, otherwise, it'll show 'No match'. So how do I make it search the whole page for each particular name?

With Selenium/Python how do I get the page viewable text of a checked radio button (or checkbox)?

I have a form that I am processing where I need to get the text values of all checked radio buttons (one radio button checked per line item of course).
The HTML is like so (for a radio button that is checked):
<div style="white-space:nowrap;margin-right:15px;display:inline-block;">
<input
type="radio"
name="question_id[927]"
id="question_id[927]"
value="276"
class="noborder"
checked="">Blue
</div>
Even though the checked="" attribute value is empty, selenium/python will return correctly that it is checked by calling: is_checked = element.get_attribute('checked'), so that works.
The other radio buttons in the line item, that are not checked, simply leave out the checked="" attribute.
I need to get the word Blue into a variable.
After experimenting with many things, I cannot seem to extract the text beside the radio button.
I am successfully finding the list of radio button 'Element's', iterating through those and successfully finding which one is checked, and now only need to get the text value of the radio button that is checked to store that value in a database.
webdriver.get_attribute() only works with items inside the <input..> tag.
The text I need to get is enclosed by a <div>, and all radio buttons in the list are enclosed by the same <div> text.
I need to do the same with a list of checkbox values, getting the text from each one that is checked, and the construction is the same, with the text just after the <input...> tag and just before the closing </div>
I have searched every selenium / python article I could find, and am given no clue as to how to get this text.
It would be greatly appreciated if anyone anywhere has a working code line/snippet that would work to get this.
thank you,
It seem like you want to get the div tag text from the parent of the current input tag, so try using the parent approach like the following:
elems = driver.find_elements_by_xpath('//input[#checked]//parent::div')
print(len(elems))
for elem in elems:
print(elem.text)
Reference: XPath Axes

Unable to get all children (dynamic loading) selenium python

This question has already been answered and one of the easiest ways is to get the tag name, if already known, within the element
child_elements = element.find_elements_by_tag_name("<tag name>")
However, for the following element pasted, only 9 out of 25 instances of the tag name is returned. I am novice in JavaScript and thus, I am not able to zero down on the reason. In this example, I am trying to get the dt tag within the ol element. The code snippet I am using for that is,
par_element = browser.find_element_by_class_name('search-results__result-list')
child_elements = par_element.find_elements_by_tag_name("dt")
The element skeleton/structure from the page source is shown in the image below:
(the structure is the same for all the div tags, as one is expanded to show for example.
I have also tried getting the class name result-lockup__name directly, and it still returns only 9 out of the 25 instances. What could be the reason?
EDIT
Initially,all the elements were not loaded, and thus I had to scroll through the page by
browser.execute_script('window.scrollTo(0,document.body.scrollHeight)')
When the problem occurred once again, and I was not able to figure out, I raised this question. Apparently, it looks like even the scroll is not helping, as certain elements look hidden
After manually scrolling through them again, keeping the code in pause, I was able to "enable" them.
Is this a type of mask to save sites from being scraped? I feel now that I would probably have to scroll up in increments to reveal them all, but is there a smarter way?
The elements are loading dynamically and you need to scroll the page slowly to get all the child elements.Try the below code hopefully it will work.This is just an workaround.
element_list=[]
while True:
browser.find_element_by_tag_name("body").send_keys(Keys.DOWN)
time.sleep(2)
listlen_before=len(element_list)
par_element = browser.find_element_by_class_name('search-results__result-list')
child_elements = par_element.find_elements_by_tag_name("dt")
for ele in child_elements:
if ele.text in element_list:
continue
else:
element_list.append(ele.text)
listlen_after = len(element_list)
if listlen_before==listlen_after:
break

Robot Framework finds text that does not exist

I am validating some texts on a webpage . There are two piece of text that should be mutually exclusive i,e only one of the texts should be visible at any time.
The element xpath=//*[#id="study_info"] actually retrieves the texts "No records available" or "Showing page x of x" based on the records and only one of this texts shows on the page. if there is no record, It shows "No record Available" otherwise it shows "showing Page x of x"
When I am trying to validate these in Robot Framework, It actually finds both text at a time, although I can see only one text. I do not know what is happening here.. The below code should fail as the texts are mutually exclusive and only one of the texts are visible. But it passes without any problem.
Page Should Contain No records available
Page Should Contain Showing page
Page Should Contain Element xpath=//*[#id="study_info"]
The full code for the element is
"<div class="dataTables_info" id="study_info" role="status" aria-live="polite">No records available</div>
I need to understand what is happening and how to fix it.
Depending on the visualization (js) framework used, the text that is currently NOT visible may very well be in the HTML - the div having it to be hidden, put in a stack of possible values, etc., and to replace the visible element as needed.
The keyword Page Should Contain goes through the whole current html - it actually uses a locator xpath=//*[contains(., %s)], where %s is the string you're after, and if any (hidden/overlaid/js source) element has the text, will return true.
To solve your particular case, I'd suggest a little bit different approach - get the text value of that element, and assert it's the expected one:
${locator}= Set Variable xpath=//*[#id="study_info"]
${current text}= Get Text ${locator}
Should Contain ${current text} Showing page
Should Not Contain ${current text} No records available # and vice-versa

Selenium, CSS, and Python: not being able to view default text in a textbox

I have a text field, which contains the default text 'abc'. When I write something inside this field or the cursor is inside this field then the default text disappears. The underlying HTML tag for this field is:
<div id="InputDefault" class="defaultText" style="visibility: visible;">abc</div>
Now, manually everything works fine. I am writing a test-case in Selenium to check if the default text appears once the field is empty. But in the test-case, it somtimes works and more often it fails. I have written the following function:
#I first delete the text in the field (I have used a text element)/
self.se.type(#I first delete the text in the field (I have used a text element).
self.se.type(locators["search_field_header"], "")
#Then I focus on the field.
self.se.set_cursor_position("headerParam", "")
#Then I focus on the field
self.se.set_cursor_position("headerParam",0)
#Press the TAB key to move focus away from the search field to get default text.
self.se.key_press_native("9")
self.se.set_speed(1000)
is_footer_default_text_present = self.is_element_available("InputDefault")
But this is somehow not working. What is the problem and is there a better/robust solution?
Use selenium.is_visible(locator). If it doesn't work then use selenium.is_text_present(value) or if (Expectedvalue == selobj.get_value(parameter)).
If it still doesn't work, refresh the page and try the above.

Categories

Resources