golu
golu

Reputation: 839

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))

Upvotes: 1

Views: 2660

Answers (3)

MortenB
MortenB

Reputation: 3529

Newer versions of selenium have EC.visibility_of_all_elements_located()

Example html from getting userdata from a slow ldap, so it usually takes around 2-3sec to load:

<div class="user-details-info">
            <!-- Id-number --->
            <div class="user-details-line">
                <b id="label-username">Fødselsnummer</b>
                <span>15917499923</span>
            </div>
            <!-- Name --->
            <div class="user-details-line">
                <b>Navn</b>
                    <span>BEGEISTRET OMSETNING</span>
            </div>
            <!-- Birthdate --->
            <div class="user-details-line">
                <b>Fødselsdato</b>
                    <span>15.11.1974</span>
            </div>
            <!-- Phone number --->
            <div class="user-details-line collapsable">
                <b>Mobilnummer</b>
                    <span id="user-phone">+4799114758</span>
            </div>
            <!-- External UserID --->
            <div class="user-details-line collapsable">
                <b>Virksomhetens BrukerID</b>
                    <span>test13-user-admin-lookupuser</span>
            </div>

            <!-- Id-proofed time --->
            <div class="user-details-line collapsable">
                <b>Dato for ID-kontroll</b>
                    <span>21.02.2024</span>
            </div>

            <!-- Id-proof method --->
            <div class="user-details-line collapsable">
                <b>ID-kontroll metode</b>
                    <span>BankID</span>
            </div>

            <!-- Organisation --->
            <div class="user-details-line collapsable">
                <b>Organisasjon</b>
                    <span>test-ikomm-test12</span>
            </div>
            <!-- Address --->
            <div class="user-details-line">
                <b>Adresse</b>
                    <span>Austvika 2, 7746 HASVÅG</span>
            </div>
</div>
#!/usr/bin/env python3
from selenium import webdriver
from selenium.webdriver.firefox.service import Service as FirefoxService
import selenium.webdriver.firefox.options
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait

options = selenium.webdriver.FirefoxOptions()
options.log.level = "trace"
s = FirefoxService(log_path='./geckodriver.log')
wd = webdriver.Firefox(options=options)

# lots of stuff omitted

els = WebDriverWait(wd, 10).until(EC.visibility_of_all_elements_located((By.XPATH,"//div[starts-with(@class,'user-details-line')]")))
for el in els:
  print(f"user-details:{el.text}")
user-details:Fødselsnummer
15917499923
user-details:Navn
BEGEISTRET OMSETNING
user-details:Fødselsdato
15.11.1974
user-details:Mobilnummer
+4799114758
user-details:Virksomhetens BrukerID
test13-user-admin-lookupuser
user-details:Dato for ID-kontroll
21.02.2024
user-details:ID-kontroll metode
BankID
user-details:Organisasjon
test-ikomm-test12
user-details:Adresse
Austvika 2, 7746 HASVÅG

Upvotes: 0

alecxe
alecxe

Reputation: 473753

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)))

Upvotes: 4

unutbu
unutbu

Reputation: 879083

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.

Upvotes: 1

Related Questions