1

I'm trying to select an element in Selenium using Python which looks like this:

<div class="class1 class2" an-attribute="attribute-value"></div>

and use it inside a wait on an expected condition like this:

WebDriverWait(self.driver, timeout).until(
 expected_conditions.presence_of_element_located(
  (By.XPATH, '//div[@an-attribute="attribute-value"][@class="class1 class2"]')))

This wait always results in a TimeoutException.

I've also tried the alternative XPath syntax:

'//div[@an-attribute="attribute-value" and @class="class1 class2"]'

I am able to get this element using the same XPath value in find_element_by_xpath(). If I pause the test and inspect the browser web console, I can see that the div indeed has this attribute and classes. This is true for both Firefox and Chromium.

Is this a bug in Selenium or am I using it incorrectly?

mijiturka
  • 161
  • 3
  • 14

1 Answers1

1

You need to take care of a couple of facts as follows :

  • As per the HTML you have shared the webelement doesn't looks to be selectable so you can't select perhaps you can invoke click() which would have been much more clear with the revealing of the exact an-attribute attribute.

  • The WebDriverWait which you have defined looks perfect but if moving forward if you are trying to invoke click() method then instead of expected_conditions clause presence_of_element_located you should have used element_to_be_clickable as follows :

    WebDriverWait(driver, 20).until(expected_conditions.element_to_be_clickable((By.XPATH, "//div[@class='class1 class2' and @an-attribute='attribute-value']"))).click()
    
  • Still as presence_of_element_located is returning TimeoutException but in console you are able to locate it implies that the element is not within the Viewport. So you need to bring the webelement within the Viewport first as follows :

    my_element = self.driver.find_element_by_xpath("//div[@class='class1 class2' and @an-attribute='attribute-value']")
    self.driver.execute_script("return arguments[0].scrollIntoView(true);", my_element)
    
DebanjanB
  • 118,661
  • 30
  • 168
  • 217
  • Interesting! Maybe I used the wrong terminology with "select" - I meant "locate"; I don't want to click the element, just ensure that it's there. I did manage to get the wait condition to return without exception by scrolling to the element first - but this defeats the purpose of the wait condition! I want to ensure that the element is present before I continue; if I first scroll into view, then I get a transient error. I guess it was incorrect to say that I can reliably get the element with find_element_by_xpath(). Is there a way to wait until an element is present at all on the page? – mijiturka Feb 23 '18 at 05:11
  • Of-coarse each and every element are different and distinct on each webpage. Hence there can't be **any single element** present on all on the pages. On each and every page you have to find/locate the intended elements with different [_Locator Strategy_](https://stackoverflow.com/questions/48369043/official-locator-strategies-for-the-webdriver/48376890#48376890) – DebanjanB Feb 23 '18 at 05:15
  • I wasn't talking about multiple pages; I just don't understand how to wait until a particular element is on a particular page. What is the point of presence_of_element_located if it does not wait until an element is *present* - and if it did, then why would I have to scroll to it before the wait? A scroll will fail if the element is still not present. – mijiturka Feb 23 '18 at 05:29