Использование @contextmanager и yield для ожидания загрузки страницы - PullRequest
0 голосов
/ 25 января 2019

Я использую следующий код, основанный на этом blogpost (последний раздел):

from selenium.webdriver.support.expected_conditions import staleness_of
from selenium.webdriver.support.ui import WebDriverWait

@contextmanager
def wait_for_page_load(self, timeout=15):
    old_page = self.driver.find_element_by_tag_name('html')
    yield
    WebDriverWait(self.driver, timeout).until(staleness_of(old_page))

, где self.driver - объект селенового веб-драйвера.
Этот диспетчер контекста может затем использоваться в блоке with:

def click_on_the_link():
    with self.wait_for_page_load():
        self.driver.find_element_by_link_text('a link')

Насколько я понял, старая страница сохраняется, и, если новая страница еще не загружена, создается объект WebDriverWait, который ждет загрузки сайта, прежде чем продолжить. Затем выполняются действия на новой странице, например, нажав на ссылку.

Однако код не имеет смысла для меня. Согласно документации :

В тот момент, когда генератор дает результат, выполняется блок, вложенный в оператор with. Затем генератор возобновляется после выхода из блока.

Если код в блоге верен, как метод может ожидать загрузки сайта, если код внутри оператора with выполняется первым?

1 Ответ

0 голосов
/ 25 января 2019

Поскольку он использует явное ожидание .

WebDriverWait(self.driver, timeout).until(staleness_of(old_page))

Это будет ждать, пока раздел staleness_of завершится успешно или выдаст исключение, если истекло время ожидания. Поскольку этот код выполняется после yield, любая операция с драйвером будет перехвачена этим.

UPDATE

Если вы просто хотите, чтобы ваш драйвер ждал элемента a link, вы можете использовать WebDriverWait напрямую

def click_on_the_link(self):
    wait = WebDriverWait(self.driver, 10)
    wait.until(element_to_be_clickable('a link'))
    self.driver.find_element_by_link_text('a link')
...