Подождите, пока элемент будет кликабельным, используя python и Selenium - PullRequest
0 голосов
/ 30 мая 2019

Есть способы ожидания объекта, например, кнопки, которую можно нажимать в селеновом питоне.Я использую time.sleep() и / или WebDriverWait...until, он отлично работает.

Однако, когда есть сотни объектов, есть ли способ установить задержку по умолчанию в глобальном масштабе, вместо того, чтобы реализовывать его на каждом объекте?

Действие click() должно иметь условное время ожидания?

Ответы [ 4 ]

1 голос
/ 30 мая 2019

Вы можете сделать несколько вещей ...

  1. Определите глобальное время ожидания по умолчанию, а затем используйте его при каждом создаваемом вами ожидании.

    default_wait_time = 10 # seconds
    ...
    wait = WebDriverWait(driver, default_wait_time)
    
  2. Внутри метода, в котором вы будете использовать ожидание несколько раз, вы можете создать экземпляр ожидания, сохранить его в переменной и затем повторно использовать.

    def my_method(self):
        wait = WebDriverWait(driver, 10)
        wait.until(EC.visibility_of_element_located((By.ID, "username")).send_keys("username")
        wait.until(EC.visibility_of_element_located((By.ID, "password")).send_keys("password")
        wait.until(EC.element_to_be_clickable((By.ID, "login")).click()
    
  3. Определите экземпляр WebDriverWait по умолчанию, а затем просто несколько раз используйте его.

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

    # some global location
    wait = WebDriverWait(driver, 10)
    ...
    # in your script, page object, helper method, etc.
    wait.until(EC.element_to_be_clickable((By.ID, "login")).click()
    
0 голосов
/ 14 июня 2019

Я придумаю это:

def myClick(by, desc):
    wait = WebDriverWait(dr, 10)
    by = by.upper()
    if by == 'XPATH':
        wait.until(EC.element_to_be_clickable((By.XPATH, desc))).click()
    if by == 'ID':
        wait.until(EC.element_to_be_clickable((By.ID, desc))).click()
    if by == 'LINK_TEXT':
        wait.until(EC.element_to_be_clickable((By.LINK_TEXT, desc))).click()

с этой функцией, код:

driver.find_element_by_link_text('Show Latest Permit').click()

будет

myClick('link_text', 'Show Latest Permit')

вместо.

Я провел пару недель с сотнями элементов, чтобы щелкнуть, я больше не видел ошибок.

0 голосов
/ 31 мая 2019

есть ли способ установить задержку по умолчанию во всем мире, вместо того, чтобы реализовать его на каждом объекте?

Да, это именно то, что делает установка неявного ожидания. Неявное ожидание используется для жизни WebDriver.

пример:

driver.implicitly_wait(10)

Информация:

0 голосов
/ 30 мая 2019

Прежде всего, time.sleep() не является элегантным решением для ожидания объекта, например. кнопка, которую можно нажимать , поскольку она ухудшает общую производительность выполнения теста . Вы можете найти пару подробных обсуждений в:


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

Причины

Любым возможным способом действие click() будет вызываться для различных типов элементов, таких как:

Несмотря на то, что все эти типы элементов динамически генерируются с помощью JavaScript и, по-видимому, выглядят одинаково, в основном между ними есть небольшая разница в отношении их функциональности и реализации. Например,

  • executeScript () : выполняет JavaScript в контексте текущего выбранного фрейма или окна. Предоставленный фрагмент скрипта будет выполнен как тело анонимной функции.
  • executeAsyncScript () : выполнение асинхронного фрагмента JavaScript в контексте текущего выбранного фрейма или окна. В отличие от выполнения синхронного JavaScript, сценарии, выполняемые с помощью этого метода, должны явно сигнализировать о завершении, вызывая предоставленный обратный вызов. Этот обратный вызов всегда вводится в выполняемую функцию как последний аргумент.

Итак, лучшим подходом было бы побудить WebDriverWait согласно вашей спецификации теста . Элемент, который должен стать интерактивным в течение 5 секунд , не должен (в идеале) иметь право на глобальное WebDriverWait 10 секунд . Это может скрыть серьезную ошибку JavaScript или AJAX , которая занимает больше времени для рендеринга DOM Tree . Точно так же элемент, который должен быть повернут на clickable в течение 10 секунд , не должен иметь права на глобальный WebDriverWait из 5 секунд . В этом случае ваш тест не будет выполнен по нежелательной причине.

В заключение, побудите WebDriverWait согласно вашей спецификации испытаний .

  • Образец A:

    WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input#btn_download"))).click()
    
  • Образец B:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[@class='standard']"))).click()
    

Обновление

В соответствии с обновлением вашего комментария, если какой-либо из ваших тестов основан на предварительном условии, что требуемый элемент должен (легко) взаимодействовать в HTML DOM , грубо говоря, вы можете избежать WebDriverWait и сразу же найдите и вызовите click() следующим образом:

  • Образец A:

    driver.find_element_by_css_selector("input.string.required#order_billing_name").click()
    
  • Образец B:

    driver.find_element_by_xpath("//div[@class='inner-article']/a//div[@class='sold_out_tag']").click()
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...