Voici ma tentative d'une solution complètement générique, en Python:
Tout d'abord, une fonction générique "wait" (utilisez un WebDriverWait si vous le souhaitez, je les trouve moche):
def wait_for(condition_function):
start_time = time.time()
while time.time() < start_time + 3:
if condition_function():
return True
else:
time.sleep(0.1)
raise Exception('Timeout waiting for {}'.format(condition_function.__name__))
Ensuite, la solution repose sur le fait que le sélénium enregistre un numéro d'identification (interne) pour tous les éléments d'une page, y compris l' <html>
élément de niveau supérieur . Lorsqu'une page s'actualise ou se charge, elle obtient un nouvel élément html avec un nouvel ID.
Donc, en supposant que vous vouliez cliquer sur un lien avec le texte "mon lien" par exemple:
old_page = browser.find_element_by_tag_name('html')
browser.find_element_by_link_text('my link').click()
def page_has_loaded():
new_page = browser.find_element_by_tag_name('html')
return new_page.id != old_page.id
wait_for(page_has_loaded)
Pour plus d'aide pythonique, réutilisable et générique, vous pouvez créer un gestionnaire de contexte:
from contextlib import contextmanager
@contextmanager
def wait_for_page_load(browser):
old_page = browser.find_element_by_tag_name('html')
yield
def page_has_loaded():
new_page = browser.find_element_by_tag_name('html')
return new_page.id != old_page.id
wait_for(page_has_loaded)
Et puis vous pouvez l'utiliser sur à peu près n'importe quelle interaction de sélénium:
with wait_for_page_load(browser):
browser.find_element_by_link_text('my link').click()
Je pense que c'est à l'épreuve des balles! Qu'est-ce que tu penses?
Plus d'informations dans un article de blog à ce sujet ici