I am using Python 3.7 and Selenium 3.141.0. On slow-loading pages, it often helps to use code like this to capture DOM objects:
myDiv = WebDriverWait(driver, 60).until(
expected_conditions.presence_of_element_located((By.CSS_SELECTOR, "div.myClass")))
That code searches an entire page for a <div>
element that has class myClass
. But I sometimes want to use presence_of_element_located()
to search only within a given WebElement object. For example, building on the code above, I want to run code like this:
myDiv2 = WebDriverWait(driver, 60).until(
myDiv.presence_of_element_located((By.CSS_SELECTOR, "div.myClass2")))
That second code block doesn't work; I get an error message telling me, understandably, that presence_of_element_located()
isn't a method of WebElement objects. The code also fails if I replace myDiv.presence_of_element_located()
with myDiv.find_element()
. In that case, I get an invalid-argument message:
selenium.common.exceptions.InvalidArgumentException: Message: invalid argument: 'using' must be a string
Is there a way to use waits and expected conditions to test the presence of elements, or otherwise search for elements, while restricting the search to a WebElement object like myDiv
? In a sense, this can be done by writing a complex CSS or Xpath selector—but I would like to avoid that.
I've checked SO posts and the Selenium documentation of expected conditions , but I haven't found anything that speaks to this question.
presence_of_element_located()
is an expectation for checking that an element is present on the DOM of a page. This does not necessarily mean that the element is visible and is used to find the element returns the WebElement once it is located.
Once the element myDiv
is returned through:
myDiv = WebDriverWait(driver, 60).until(expected_conditions.presence_of_element_located((By.CSS_SELECTOR, "div.myClass")))
To search another element with respect to the found WebElement you can use the following solution:
myDiv2 = WebDriverWait(myDiv, 60).until(expected_conditions.presence_of_element_located((By.CSS_SELECTOR, "div.myClass2")))
Under the hood , presence_of_element_located
only uses find_element
and returns the element found.
Having this in mind, you can create your own custom expected conditions method presence_of_element_located_inside_element
(for lack of a better name):
from selenium.common.exceptions import NoSuchElementException
class presence_of_element_located_inside_element(object):
def __init__(self, first_locator, second_locator):
self.first_locator = first_locator
self.second_locator = second_locator
def __call__(self, driver):
try:
first_elem = driver.find_element_by_css_selector(self.first_locator)
second_elem = first_elem.find_element_by_css_selector(self.second_locator)
return second_elem
except NoSuchElementException:
return False
And then you can use it inside your tests:
elem = WebDriverWait(driver, 20).until(presence_of_element_located_inside_element('div.myClass1', 'div.myClass2'))
This is just for illustrative purposes and only supports string CSS selectors.
It can, of course, be adjusted to take as parameters a By
type and then you can use different locator strategies for each element.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.