Can't acess dynamic element on webpage - python-3.x

I can't acess a textbox on a webpage box , it's a dynamic element. I've tried to filter it by many attributes on the xpath but it seems that the number that changes on the id and name is the only unique part of the element's xpath. All the filters I try show at least 3 element. I've been trying for 2 days, really need some help here.
from selenium import webdriver
def click_btn(submit_xpath): #clicks on button
submit_box = driver.find_element_by_xpath(submit_xpath)
submit_box.click()
driver.implicitly_wait(7)
return
#sends text to text box
def send_text_to_box(box_xpath, text):
box = driver.find_element_by_xpath(box_xpath)
box.send_keys(text)
driver.implicitly_wait(3)
return
descr = 'Can't send this text'
send_text_to_box('//*[#id="textfield-1285-inputEl"]', descr)' #the number
#here is the changeable part on the xpath
:
edit: it worked now with the following xpath //input[contains(#id, 'textfield') and contains(#aria-readonly, 'false') and contains (#class, 'x-form-invalid-field-default')] . Hopefully I found something specific on this element:

You can use partial string to find the element instead of an exact match. That is, in place of
send_text_to_box('//*[#id="textfield-1285-inputEl"]', descr)' please try send_text_to_box('//*[contains(#id,"inputEl")]', descr)'
In case if there are multiple elements that have string 'inputE1' in id, you should look for something else that remains constant(some other property may be). Else, try finding some other element and then traverse to the required input.

Related

XPATH: Inputting value for an unknown number of xpaths using .find_elements_by_xpath

I've done a lot of searching around for this, but it seems like I can only find the answers in .js . What I would like to do is through python use .find_elements_by_xpath , and having selected an unknown number of elements, input a value by iterating from top to bottom of relevant elements. It is important to know that there may be anywhere from 1+ number of elements that need to be filled.
Some have suggested this method in .js :
driver.findElements(By.xpath("<xpath>")).then(function(elem) {
for(var i=0; i<elem.length; i++){
driver.findElements(By.xpath("<xpath>")).get(i).sendKeys('some Text');
}
});
I'm not skilled enough to translate that properly, but maybe it'll give someone an idea for the solution.
Hopefully my intention is clear enough! Thanks everyone so much for your help.
This is how it will look like on Python. Code with comments:
from selenium.webdriver.common.by import By
from selenium import webdriver
website = "https://YOURWEBSITE.com"
driver = webdriver.Chrome(executable_path='YOUR/PATH/TO/chromedriver.exe')
driver.get(website)
# if you want to find all inputs on the page using XPATH and send there some value use:
all_inputs_on_the_page = driver.find_elements(By.XPATH, "//div//input")
for input in all_inputs_on_the_page:
input.send_keys("TEXT_TO_INSERT")
# if you want to find some elements and after that - find some elements inside these elements then use:
divs_on_the_page = driver.find_elements(By.XPATH, "//div")
for div in divs_on_the_page:
inputs_inside_a_div = div.find_elements(By.XPATH, ".//input")
for input in inputs_inside_a_div:
input.send_keys("TEXT_TO_INSERT")

What is the difference between 'page_source' and 'find_element_by_tag_name("body").text'?

Trying to find whether a text is present on UI login page (web-page).
I could verify it by 'driver.page_source()' and driver.find_element_by_tag_name("body").text
driver.page_source()
text = "abcd"
page_source = driver.execute_script("return document.body.innerHTML;")
if text in page_source:
return True
else:
return False
driver.find_element_by_tag_name("body").text
text = "abcd"
value = text in self.browser.find_element_by_tag_name("body").text
if value:
return True
else:
return False
What's the difference between method1 and method2 ?
Which one is preferred to do the required task ?
Which is faster ?
Or anySelenium-UI methods to be used ?
Any help would be appreciated. Looking for valuable inputs.
Any idea on this ? Any help here ?
Page source will give all the text including HTML tags, styles etc. as you have written yourself in execute script to return the innerHTML. So, all HTML code will be returned which obviously will contain the text too. You can also get the whole html with selenium too instead of using JavaScript executor by browser.page_source.
On the other hand, browser.find_element_by_tag_name("body").text will return all the text you see on the page without html tags.
To me, the 2nd method should be preferred and faster because you will have string of smaller length(without un-necessary html tags) and the actual text you are interested in.

How to get text which is inside the span tag using selenium webdriver?

I want to get the text which is inside the span. However, I am not able to achieve it. The text is inside ul<li<span<a<span. I am using selenium with python.
Below is the code which I tried:
departmentCategoryContent = driver.find_elements_by_class_name('a-list-item')
departmentCategory = departmentCategoryContent.find_elements_by_tag_name('span')
after this, I am just iterating departmentCategory and printing the text using .text i.e
[ print(x.text) for x in departmentCategory ]
However, this is generating an error: AttributeError: 'list' object has no attribute 'find_elements_by_tag_name'.
Can anyone tell me what I am doing wrong and how I can get the text?
Problem:
As far as I understand, departmentCategoryContent is a list, not a single WebElement, then it doesn't have the find_elements_by_tag_name() method.
Solution:
you can choose 1 of 2 ways below:
You need for-each of list departmentCategoryContent first, then find_elements_by_tag_name().
Save time with one single statement, using find_elements_by_css_selector():
departmentCategory = driver.find_elements_by_css_selector('.a-spacing-micro.apb-browse-refinements-indent-2 .a-list-item span')
[ print(x.text) for x in departmentCategory ]
Test on devtool:
Explanation:
Your locator .a-list-item span will return all the span tag belong to the div that has class .a-list-time. There are 88 items containing the unwanted tags.
So, you need to add more specific locator to separate the other div. In this case, I use some more classes. .a-spacing-micro.apb-browse-refinements-indent-2
You're looping over the wrong thing. You want to loop through the 'a-list-item' list and find a single span element that is a child of that webElement. Try this:
departmentCategoryContent = driver.find_elements_by_class_name('a-list-item')
print(x.find_element_by_tag_name('span').text) for x in departmentCategoryContent
note that the second dom search is a find_element (not find_elements) which will return a single webElement, not a list.

How to convert selenium webelelements to list of strings in python

I have gathered obligatory data from the scopus website. my outputs have been saved in a list named "document". when I use type method for each element of this list, the python returns me this class:
"<class'selenium.webdriver.firefox.webelement.FirefoxWebElement'>"
In continius in order to solve this issue, I have used text method such this:
document=driver.find_elements_by_tag_name('td')
for i in document:
print i.text
So, I could see the result in text format. But, when I call each element of the list independently, white space is printed in this code:
x=[]
for i in document:
x.append(i.text)
print (x[2]) will return white space.
What should I do?
As you have used the following line of code :
document=driver.find_elements_by_tag_name('td')
and see the output on Console as :
"<class'selenium.webdriver.firefox.webelement.FirefoxWebElement'>"
This is the expected behavior as Selenium prints the reference of the Nodes matching your search criteria.
As per your Code Attempt to print the text leaving out the white spaces you can use the following code block :
x=[]
document = driver.find_elements_by_tag_name('td')
for i in document :
if (i.get_attribute("innerHTML") != "null") :
x.append(i.get_attribute("innerHTML"))
print(x[2])
My code was correct. But, the selected elements for displaying were space. By select another element, the result was shown.

In Watir, how to get the full text, from a portion of text?

I have a portion of HTML that looks similar to:
<table><tbody><tr>
<td><div> Text Goes Here </div></td>
<td> ... rest of table
There are no IDs, no Titles, no descriptors of any kind to easily identify the div that contains the text.
When an error occurs on the page, the error is inserted into the location where "Text Goes Here" is at (no text is present unless an error occurs). Each error contains the word "valid".
Examples: "The form must contain a valid name" or "Invalid date range selected"
I currently have the Watir code looking like this:
if browser.frame(:index => 0).text.includes? "valid"
msg = # need to get full text of message
return msg
else
return true
end
Is there any way to get the full text in a situation like this?
Basically: return the full text of the element that contains the text "valid" ?
Using: Watir 2.0.4 , Webdriver 0.4.1
Given the structure you provided, since divs are so often used I would be inclined to look for the table cell using a regular expression as Dave shows in his answer. Unless you have a lot of nested tables, it is more likely to return just the text you want.
Also if 'valid' may appear elsewhere then you might want to provide a slightly larger sample of the text to look for
. browser(:cell => /valid/).text
Try this
return browser.div(:text => /valid/).text
or
return browser.table.div(:text => /valid/).text
if the valid is not found, it should return nil.

Resources