显式等待不适用于基于 Angular 的 PayPal 沙箱

Explicit waits doesn't work on PayPal sandbox which based on Angular

我对 Selenium Python 的 PayPal 沙箱自动化有疑问。 通常,我会在按钮中显式等待每个操作方法,如 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)

唯一有效的方法是静态 python 睡眠,这是完全不合适的!但是当我在页面上的每个第一个操作之间添加 2 秒的睡眠时,测试通过没有任何问题,而我试图用 WebDriverWait(self.context.browser, timeout=15).until(EC.visibility_of_all_elements_located) 替换 sleep ,当所有元素都可见时测试停止在页面上。 有人可以处理这个吗? 我的代码 在每个页面对象之间休眠:

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()

Selenium wait 有时不适用于基于 AngularJsreactJs 的应用程序,这就是为什么量角器是基于 AngularJsreactJs 的应用程序的最佳工具。虽然我希望如果您可以尝试以下解决方案,它可以像基于 Javascript.

一样工作

一个函数将检查页面是否已完全加载。

  def page_has_loaded():
    page_state = browser.execute_script(
      'return document.readyState;'
    ) 
    return page_state == 'complete'

然后结合使用等待和非常短的睡眠时间,页面加载后可以减少。

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)

visibility_of_all_elements_located() 将 return 一个 列表 ,相反你需要使用 visibility_of_element_located() 它将 return 一个 WebElement.

理想情况下,如果您的用例是调用 click(),那么您需要为 element_to_be_clickable() 引入 WebDriverWait,您可以使用以下任一方法 :

  • 使用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
    

参考

您可以在以下位置找到相关的详细讨论:

  • Do we have any generic function to check if page has completely loaded in Selenium