Continuing script in selenium when element is not present on a page - python

I am trying to get selenium set up to send out messages automatically and have not yet got around to check if the specific listing has already been sent a message. This causes selenium to give a NoSuchElementException because its looking for (By.XPATH, ('//span[contains(text(),"Message")]'))
How can I have it skip these pages where the element doesn't exist?
message = driver.find_element(By.XPATH, ('//span[contains(text(),"Message")]'))
message.click()
Very small snippet that shows the code where the issue is.

Instead of find_element you should use find_elements here.
find_elements returns a list of found matches. So, in case of match (such element exists) it will return non-empty list. It will be interpreted by Python as Boolean True. Otherwise, in case of no matches found the returned list is empty, it is interpreted by Python as Boolean False.
To perform click you can get the first element in the returned list, as following:
message = driver.find_elements(By.XPATH, ('//span[contains(text(),"Message")]'))
if message:
message[0].click()

Related

Is there a way to structure an if statement so that it can identify if an XPATH exists in python selenium?

I am currently playing around with Selenium trying to learn it by doing and have encountered this issue; occasionally a button on the website appears with a different XPATH, so I wanted to try and create a workaround. This is what I am trying to use:
if bool(wd.find_element_by_xpath('//*[#id="basketPageApp"]/div/div[2]/div/div/div[1]/div/div[2]/a')) == TRUE:
button = wd.find_element_by_xpath('//*[#id="basketPageApp"]/div/div[2]/div/div/div[1]/div/div[2]/a')
else:
button = wd.find_element_by_xpath('//*[#id="guestCheckout"]/div/div/div[2]/section/div[2]/div[1]/div')
I'm sure I can't use an if statement in this manner but I hope this gets the idea of what I am trying to achieve across.
Selenium will throw an exception in case find_element method could not find element matching the passed locator.
It will not return you a Boolean True or False.
What can you do here is to use find_elements_by_xpath instead of find_element_by_xpath since find_elements_by_xpath will return you a list of found matches. So, in case there was a match you will get a non-empty list interpreted by Python as a Boolean True while in case of no match found it will return an empty list interpreted by Python as a Boolean False. Also, this will never throw exception.
So your code could be something like:
if wd.find_elements_by_xpath('//*[#id="basketPageApp"]/div/div[2]/div/div/div[1]/div/div[2]/a'):
button = wd.find_element_by_xpath('//*[#id="basketPageApp"]/div/div[2]/div/div/div[1]/div/div[2]/a')
else:
button = wd.find_element_by_xpath('//*[#id="guestCheckout"]/div/div/div[2]/section/div[2]/div[1]/div')
You can use try and except
try:
button = wd.find_element_by_xpath('//*[#id="basketPageApp"]/div/div[2]/div/div/div[1]/div/div[2]/a')
except:
button = wd.find_element_by_xpath('//*[#id="guestCheckout"]/div/div/div[2]/section/div[2]/div[1]/div')

Search for a specific element in multiple pages and click using Python Selenium

Hi im trying to navigate from page 1 to page 5 (the element can be in any of the pages)and find and click on a specific element using python selenium.
The following is the element from the page:
<span _ngcontent-mtx-c123"" class"ng-star-inserted">ABC Company</span>
i tried by using : driver.find_element_by_name("ABC Company").click() but this doesnt work.
Another Way i tried:
1. element_path="//span[contains(text(),'ABC Company')]"
2. while True:
3. if(driver.find_elements_by_xpath(element_xpath)): driver.find_element_by_xpath(element_xpath).click()
4. else: driver.find_element_by_xpath("xpath to goto next page").click()
I need the code to find element from the next pages until its found and then click it.
is there any other way to do this???
Thanks in Advance
First, you need to check if the element is present and only if it does - click it. Otherwise you will get exception while trying clicking non-existing element.
driver.find_elements returns a list of web elements matching the passed locator. So if there are such elements it will return non-empty list interpreted as True by Python. Otherwise empty list is returned interpreted as False.
As about the locator for the element you are looking for: you can locate the element according to the text it contains. It can be done with XPath.
As following:
element_xpath = "//span[contains(text(),'ABC Company')]"
if(driver.find_elements_by_xpath(element_xpath)):
driver.find_element_by_xpath(element_xpath).click()
If you need to update the XPath locator dynamically you can pass the text as parameter. Let's say you have a list of texts, you can iterate on them as following:
for txt in texts:
element_xpath = "//span[contains(text(),'{}')]".format(txt)
if(driver.find_elements_by_xpath(element_xpath)):
driver.find_element_by_xpath(element_xpath).click()

Python-Selenium - if else statement to check element visibility and clicking if available

I am using below code to check element visibility and click if available.
if element is available it is clicking quickly and moving to next code.
Problem:
if element is not visible/available it is taking more to time to skip and move to next code.
i understand it may take some time.
Question is:
is there any way to perform quickly if element not visible or if any other code to perform my test case quickly.
elements = self.driver.find_elements_by_partial_link_text("<element>")
if not elements:
print("Element Not Found")
else:
element = elements[0]
element.click()
based on your code, you are interested only on the first link (elements[0]), you can restrict the driver to find the first link only using below method
find_element_by_partial_link_text

return Find_element_by_name as a string In Python

I need some help form all of you, so I have something like this:
element = driver.find_element_by_name("SiteMinderVarForm")
print (element)
When I execute the program I receive:
selenium.webdriver.remote.webelement.WebElement (session="d49d6df9305f2e92eb81aed5c0ed848b", element="0.6436298007036831-4")
And I need a string as result.
I'm trying to automatically login into a web site. If the process of login fails because of an incorrect password or username I need to show a pop up with an error message. So I'm trying to get the name of the form and check if is equal to the actual name. In case it is equal that means the process is successful, and if not the process fails.
If you have any better ideas to do that please let me know.
From your question, it seems like you want the text value contained in the webelement. You can use the webelement.getAttribute("value") method. If you want to get the name attribute of the webelement with name SiteMinderVarForm:
element = driver.find_element_by_name("SiteMinderVarForm")
value = element.getAttribute("name")
print(value)
Similar to Using Selenium Web Driver to retrieve value of a HTML input
More examples at: Get Attribute values using Webdriver
You may also be able to use the webelement.getText() method.
element = driver.find_element_by_name("SiteMinderVarForm")
value = element.getText()
print(value)
Difference between getText() and getAttribute()

WebDriverWait on find_elements_by_xpath

I am trying to figure out how WebDriverWait works with find_elements_by_xpath. How does it know that all related elements have loaded or does it just wait until page is loaded.
I can understand if we have a specific element using find_element_by_xpath, but not sure with find_elements_by_xpath.
For example:
elements = WebDriverWait(driver, 5).until(lambda driver: driver.find_elements_by_xpath("//table[#id='%s']/tbody/tr" % myid))
The expected condition you've presented would actually evaluate to True once there is at least one element matching the XPath expression. In other words, it is equivalent to:
expression = "//table[#id='%s']/tbody/tr" % myid
wait.until(EC.presence_of_element_located((By.XPATH, expression)))
webdriver isn't waiting for the page to be loaded -- it can't since the page's contents could be continually changing. Instead it simply executes the find_elements_* command and if successful, the WebDriverWait(...).until call returns the elements found. It is no different than find_element_by_xpath, except that more than one element may be returned.

Categories

Resources