Reputation: 839
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
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
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
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