Can't locate element - Selenium - python

I'm trying to find a textarea in my facebook group. The login is ok, driver.get(group) is ok too but then, when I try to locate the textarea, it returns that it can't locate it. The weird thing is that I can clearly see it there.
def send_post(self,text,group):
assert self.logged == True
self.driver.get(group)
text_field = self.driver.find_element_by_css_selector('div.innerWrap').find_element_by_tag_name('xhpc_message_text')
text_field.send_keys(text)
self.driver.find_element_by_xpath("//button[#value='1']").click()
Do you know what am I doing wrong? Do you have a better way to post to fb group?

xhpc_message_text isn't a tag name; textarea is.
If you're talking about the post-writing <textarea>, then it has a name attribute (different!) of xhpc_message_text. You can combine your find_element_by_* calls into one:
text_field = self.driver.find_element_by_css_selector('div.innerWrap [name="xhpc_message_text"]')

Related

Send text and click ENTER on expath

I clicked the text box but I am unable to send a text.
divselected = driver.find_elements_by_xpath("//*[contains(text(), 'Add a public comment...')]")[0].click()
divselected.send_keys("Talk-Talk")
Unable to add comments and press enter.
I did some search and I think this should work, just clear and send return key.
divselected = driver.find_elements_by_xpath("//*[contains(text(), 'Add a public comment...')]")[0].click()
divselected.clear()
divselected.send_keys("Talk-Talk")
divselected.send_keys("Keys.RETURN")
You wrong variable initialize for divselected, remove .click().
So, it's should like this:
divselected = driver.find_elements_by_xpath("//*[contains(text(), 'Add a public comment...')]")[0]
divselected.click()
divselected.send_keys('Talk-Talk')
divselected.submit()
Or if .submit() doesn't work, use .send_keys(Keys.ENTER):
#following import
from selenium.webdriver.common.keys import Keys
divselected.send_keys(Keys.ENTER)
But in this case if you want get the first element (refers to your index [0]), actually you don't need .find_elements_*. You can use .find_element_(without s):
divselected = driver.find_element_by_xpath("//*[contains(text(), 'Add a public comment...')]")

selenium driver: get the tagname of a element

I would like to get the name of the element data-test-carrier-name with python, more specific i want to get as a result "trenitalia".
The HTML part looks like this:
div class="_1moixrt _dtnn7w" tabindex="0"span data-test-carrier-name="trenitalia"
I tried it as followed but without any luck:
company = driver.find_element_by_xpath('//div[#class="_1moixrt _dtnn7w"]')
company.get_attribute("data-test-carrier-name")
Please check element is visible before you start fetching its attribute.
org = driver.find_element_by_xpath('(//div[#class="_1moixrt _dtnn7w"])[1]/span[1]')
# Find the value of _1moixrt _dtnn7w?
val = org.get_attribute("data-test-carrier-name")

Selenium webdriver isn't able to clear a field, but is able to send_keys to it

I'm trying to create a program that signs up for instagram with a new account, I've got the emails and the rest generated, when I go ahead and send_keys to the appropriate fields, it does it just fine. I wanted to implement a retry function, which would clear the email field and try with a different mail. However this does not work, even though send_keys to it worked previously? Snippet of my code below.
driver.get('https://www.instagram.com')
driver.find_element_by_xpath("//*[contains(#aria-label,'Email')]").send_keys(mail)
driver.find_element_by_xpath("//*[contains(#aria-label,'Full')]").send_keys(name + lastname)
driver.find_element_by_xpath("//*[contains(#aria-label,'User')]").send_keys(namae+lastonamae+pamae2)
driver.find_element_by_xpath("//*[contains(#aria-label,'Password')]").send_keys(password)
driver.find_element_by_xpath("//*[contains(#type,'submit')]").click()
This attempts to create a new account with the appropriate credentials, however when it fails, I want it to try to look for an element that is only present when it fails, and if it finds that, it should clear the email field and retry with a different one. Code below.
driver.find_element_by_xpath('//*[#id="react-root"]/section/main/article/div[2]/div[1]/div/form/div[3]/div/div[2]/span') #this looks for the element only present on the fail page
driver.find_element_by_xpath("//*[contains(#aria-label,'Email')]").clear()
driver.find_element_by_xpath("//*[contains(#aria-label,'Email')]").send_keys(mail2)
It doesn't clear the field, but doesn't raise an error either. It then proceeds to type the 2nd email with no problems. I appreciate any help on the matter.
EDIT: Posting a bigger chunk of the code.
def signup():
driver.get('https://www.instagram.com')
time.sleep(7)
if trycounter < 3: #this is almost always true, just a failsafe
driver.find_element_by_xpath("//*[contains(#aria-label,'Email')]").send_keys(mail1)
driver.find_element_by_xpath("//*[contains(#aria-label,'Full')]").send_keys(name + ' ' + lastname)
driver.find_element_by_xpath("//*[contains(#aria-label,'User')]").send_keys(name+lastname+extension)
driver.find_element_by_xpath("//*[contains(#aria-label,'Password')]").send_keys(password)
driver.find_element_by_xpath("//*[contains(#type,'submit')]").click()
time.sleep(7)
try: #this only executes if a popup that wants you to confirm your age pops up
driver.find_element_by_xpath('//*[#id="igCoreRadioButtonageRadioabove_18"]').click()
driver.find_element_by_xpath('/html/body/div[3]/div/div[3]/div/button').click()
time.sleep(5)
except:
pass
try:
randomgen() #generates the mail,password and name
driver.find_element_by_xpath('//*[#id="react-root"]/section/main/article/div[2]/div[1]/div/form/div[3]/div/div[2]/span')
time.sleep(1)
driver.find_element_by_xpath("//*[contains(#aria-label,'Email')]").clear()
time.sleep(1)
driver.find_element_by_xpath("//*[contains(#aria-label,'Email')]").send_keys(mail2)
driver.find_element_by_xpath("//*[contains(#aria-label,'User')]").send_keys(username)
driver.find_element_by_xpath("//*[contains(#type,'submit')]").click()
time.sleep(7)
You can use following code as alternative for clear method:
from selenium.webdriver.common.keys import Keys
email_element = driver.find_element_by_xpath("//*[contains(#aria-label,'Email')]")
email_element.send_keys(Keys.CONTROL, 'a')
email_element.send_keys(mail1)
fullname_element = driver.find_element_by_xpath("//*[contains(#aria-label,'Full')]")
fullname_element.send_keys(Keys.CONTROL, 'a')
fullname_element.send_keys(name + ' ' + lastname)
# do it for other field as well
So this will definitely work as a workaround. I just tried it on instagram. Although there was no field with an aria label called Email for me. It was aria-label "Mobile Number or Email" for me.
driver.execute_script("$(\"input[aria-label='Email']"\").value = '';");
I will keep looking at it to see why the clear command didn't work though.
You can try something like this to delete mail1.
driver.find_element_by_xpath("//*[contains(#aria-label,'Email')]").send_keys(Keys.chord(Keys.CONTROL,"a"))
driver.find_element_by_xpath("//*[contains(#aria-label,'Email')]").send_keys(Keys.DELETE)
driver.find_element_by_xpath("//*[contains(#aria-label,'Email')]").send_keys(mail2)

How can I click in link but without "a href" [Selenium + Python]

I don't know how can I click on "Utwórz konto" on https://www.morele.net/login.
I tried:
link_registration = driver.find_element_by_class_name("//li[#class = 'el-login-nav register']")
link_registration.click()
but I get error:
selenium.common.exceptions.InvalidSelectorException: Message: Given
css selector expression ".//li[#class = 'el-login-nav register']" is
invalid: InvalidSelectorError: './/li[#class = 'el-login-nav
register']' is not a valid selector: ".//li[#class = 'el-login-nav
register']"
You are trying to pass an XPath expression to the "by class name" locator - no wonder it fails.
I would use a CSS selector instead:
register = driver.find_element_by_css_selector(".autorization-form .register")
register.click()
.autorization-form .register would match an element having a register class somewhere (at any depth level) inside an element having an autorization-form class. Space here means parent-child relationship - but the child can be at any level inside the parent.
You are getting that error because you used the find_element_by_class_name() command but passed in an xpath. You need to either use find_elements_by_xpath() or a different locator function. Either of these should work:
driver.find_element_by_xpath("//li[#class = 'el-login-nav register']");
driver.find_element_by_css_selector("li.register")

How to get rid of Cannot focus element exception

I faced with following issue with chromedriver: I have a text input field and a texarea. I can successfully send text to both elements with follow code
input = driver.find_element_by_xpath('//input[#type="text"]')
input.send_keys('test')
textarea = driver.find_element_by_xpath('//textarea[not(#readonly)]')
textarea.send_keys('test')
But if to try this code
text_fields = driver.find_elements_by_xpath('//*[input[#type="text"] or textarea[not(#readonly)]]')
for field in text_fields:
field.send_keys('test')
I get selenium.common.exceptions.WebDriverException: Message: unknown error: cannot focus element
P.S. Adding field.click() before sending text or using ActionChains failed to solve issue. Also len(text_fields) return 2, so both elements correctly matched with XPath
The second expression will return the parent element of the input or textarea. If you wish to get both in a single XPath then:
text_fields = driver.find_elements_by_xpath("//input[#type='text'] | //textarea[not(#readonly)]")
for field in text_fields:
field.send_keys('test')
Or with a CSS selector :
text_fields = driver.find_elements_by_css_selector("input[type='text'] , textarea:not([readonly])")
for field in text_fields:
field.send_keys('test')

Categories

Resources