Явное ожидание не работает в песочнице PayPal, которая основана на Angular - PullRequest
1 голос
/ 13 января 2020

У меня проблема с автоматизацией песочницы PayPal от Selenium Python. Обычно я записывал в кнопку явные ожидания для каждого метода действия, например send_keys() или click(), но они просто не работают. Я перепробовал почти все доступные явные ожидания.

Я пытался адаптировать метод, который будет ожидать, пока скрипт Angular не будет полностью загружен, но он полностью не работает из-за этого приложения, основанного на Angular v.1., выполнив javascript. Например:

while self.context.browser.execute_script(
"return angular.element(document).injector().get('$http').pendingRequests.length === 0"):
             sleep(0.5)

Единственный метод, который работает, это stati c python sleep, что совершенно неуместно! Но когда я добавляю 2 секунды сна между каждым первым действием на странице, тест проходит без проблем, в то время как я пытаюсь заменить sleep, например, WebDriverWait(self.context.browser, timeout=15).until(EC.visibility_of_all_elements_located), тест останавливается, когда все элементы видны на странице. Кто-то может справиться с этим? Мой код ведьма спит между объектами каждой страницы:

context.pages.base_page.asert_if_url_contain_text("sandbox.paypal.com")
context.pages.paypal_login_page.login_to_pp_as(**testPP)
sleep(2)
context.pages.choose_payment_page.pp_payment_method("paypal")
sleep(2)
context.pages.pay_now_page.click_pay_now()
sleep(2)
context.pages.finish_payment_page.click_return_to_seller()
sleep(5)
context.pages.base_page.open()

Пример метода с явным ожиданием:

def click_pay_now(self):
    WebDriverWait(self.context.browser, timeout=15).until(EC.visibility_of_all_elements_located)
    self.pay_now_button.is_element_visible()
    self.pay_now_button.click()

Ответы [ 2 ]

1 голос
/ 13 января 2020

visibility_of_all_elements_located() вернет список , вместо этого вам нужно использовать visibility_of_element_located(), который вернет WebElement .

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

  • Использование CSS_SELECTOR:

    WebDriverWait(self.context.browser, timeout=15).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "element_css"))).click()
    
  • Использование XPATH:

    WebDriverWait(self.context.browser, timeout=15).until(EC.element_to_be_clickable((By.XPATH, "element_xpath"))).click()
    
  • Примечание : у вас есть добавить следующие операции импорта:

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    

Ссылка

Соответствующее подробное обсуждение можно найти в:

1 голос
/ 13 января 2020

Selenium wait иногда плохо работает с приложениями на базе AngularJs или reactJs, поэтому транспортир - лучший инструмент для приложений на основе AngularJs или reactJs. Хотя я надеюсь, что если вы попробуете приведенное ниже решение, оно может работать так, как оно основано на Javascript.

Функция будет проверять, полностью ли загружена страница. комбинация очень маленького времени ожидания, которое может быть меньше, как только страница будет загружена.

def wait_for(condition_function):
  start_time = time.time() 
  while time.time() < start_time + 2: 
    if condition_function(): 
      return True 
    else: 
      time.sleep(0.1) 
  raise Exception(
   'Timeout waiting for {}'.format(condition_function.**name**) 
  )

И вы можете назвать это, как указано ниже:

wait_for(page_has_loaded)
...