Reputation: 12598
Using Python Selenium I am trying to check if an element is visible and then click it if it is...
# Check to see if element is visible
myelement = driver.find_element_by_xpath("//a[@id='form1']")
if myelement.is_displayed():
print (" ")
else:
driver.find_element_by_xpath("//a[@id='form1']").click
This isn't working, where am I going wrong?
Upvotes: 4
Views: 19158
Reputation: 343
The best way to do it is by creating a base class and redefining click and find method and use this instead:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support.select import Select
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from abc import abstractmethod
class LocatorMode:
XPATH = "xpath"
CSS_SELECTOR = "cssSelector"
NAME = "name"
ID = "id"
TAG_NAME = "tagName"
class BasePage(object):
def __init__(self, driver):
self.driver = driver
def wait_for_element_visibility(self, waitTime, locatorMode, Locator):
element = None
if locatorMode == LocatorMode.ID:
element = WebDriverWait(self.driver, waitTime).\
until(EC.visibility_of_element_located((By.ID, Locator)))
elif locatorMode == LocatorMode.NAME:
element = WebDriverWait(self.driver, waitTime).\
until(EC.visibility_of_element_located((By.NAME, Locator)))
elif locatorMode == LocatorMode.XPATH:
element = WebDriverWait(self.driver, waitTime).\
until(EC.visibility_of_element_located((By.XPATH, Locator)))
elif locatorMode == LocatorMode.CSS_SELECTOR:
element = WebDriverWait(self.driver, waitTime).\
until(EC.visibility_of_element_located((By.CSS_SELECTOR, Locator)))
else:
raise Exception("Unsupported locator strategy.")
return element
def wait_until_element_clickable(self, waitTime, locatorMode, Locator):
element = None
if locatorMode == LocatorMode.ID:
element = WebDriverWait(self.driver, waitTime).\
until(EC.element_to_be_clickable((By.ID, Locator)))
elif locatorMode == LocatorMode.NAME:
element = WebDriverWait(self.driver, waitTime).\
until(EC.element_to_be_clickable((By.NAME, Locator)))
elif locatorMode == LocatorMode.XPATH:
element = WebDriverWait(self.driver, waitTime).\
until(EC.element_to_be_clickable((By.XPATH, Locator)))
elif locatorMode == LocatorMode.CSS_SELECTOR:
element = WebDriverWait(self.driver, waitTime).\
until(EC.element_to_be_clickable((By.CSS_SELECTOR, Locator)))
else:
raise Exception("Unsupported locator strategy.")
return element
def find_element(self, locatorMode, Locator):
element = None
if locatorMode == LocatorMode.ID:
element = self.driver.find_element_by_id(Locator)
elif locatorMode == LocatorMode.NAME:
element = self.driver.find_element_by_name(Locator)
elif locatorMode == LocatorMode.XPATH:
element = self.driver.find_element_by_xpath(Locator)
elif locatorMode == LocatorMode.CSS_SELECTOR:
element = self.driver.find_element_by_css_selector(Locator)
else:
raise Exception("Unsupported locator strategy.")
return element
def fill_out_field(self, locatorMode, Locator, text):
self.find_element(locatorMode, Locator).clear()
self.find_element(locatorMode, Locator).send_keys(text)
def click(self, waitTime, locatorMode, Locator):
self.wait_until_element_clickable(waitTime, locatorMode, Locator).click()
Upvotes: 3
Reputation: 11
is_displayed() != is visible
So, .click() does not work if the element is out of the screen, but is still "displayed"
Correct step is you have to scroll the element into the screen and visible, and then click()
Upvotes: 0
Reputation: 50
You could also do a try/except:
try:
driver.find_element_by_xpath("//a[@id='form1']").click() # will click element if visible
except:
print "Element not visible."
Upvotes: 1
Reputation: 50819
You have two problems
click
is a method, it should be click()
Currently you are trying to click if the button is not displayed. It should be
if myelement.is_displayed():
driver.find_element_by_xpath("//a[@id='form1']").click()
else:
print (" ")
You also don't have to relocate the element to click on it
myelement = driver.find_element_by_xpath("//a[@id='form1']")
if myelement.is_displayed():
myelement.click()
else:
print (" ")
Upvotes: 4
Reputation: 11034
Assuming your xpath is correct, you should use click()
, instead of click
. It's a method, not an attribute.
Upvotes: 6