1

I have a problem with the automation of PayPal sandbox by Selenium Python. Generally, I wrote explicit waits for each action method like send_keys(), or click() into the button, but they just don't work. I tried almost all explicit waits that are available.

I tried to adapt method which will be waiting until Angular script will be fully loaded, but it totally doesn't work because of this app based on Angular v.1., by executing javascript. For example:

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

The only method which works are static python sleep, which is totally inappropriate! But when I add 2 seconds of sleep between every first action on the page, the test passing without any problems, while I trying to replace sleep by for example WebDriverWait(self.context.browser, timeout=15).until(EC.visibility_of_all_elements_located) , the test stop when all elements are visible on the page. Can someone handle this? My code witch sleeps between each page objects:

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

Example method witch explicit wait:

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()
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
wrozda
  • 179
  • 2
  • 7

2 Answers2

1

Selenium wait sometime not works well with AngularJs or reactJs based app that's why protractor is best tools for AngularJs or reactJs based app. Although I hope If you can try below solution it can work as it based on Javascript.

A function will check page is fully loaded or not.

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

Then use wait with combination of very small sleeping time that can be less as soon as page will be loaded.

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

And you can call it as mentioned below:

wait_for(page_has_loaded)
Muzzamil
  • 2,823
  • 2
  • 11
  • 23
  • Your solution works! Thank you a lot!:) I'm using Python because of most of my tested apps bases on `php code` . I didn't know that `AngularJs` or `ReactJs` are sometimes problematic. Thanks for your help! – wrozda Jan 13 '20 at 20:13
1

visibility_of_all_elements_located() will return a list, instead you need to use visibility_of_element_located() which will return a WebElement.

Ideally, if your usecase is to invoke click() then you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:

  • Using CSS_SELECTOR:

    WebDriverWait(self.context.browser, timeout=15).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "element_css"))).click()
    
  • Using XPATH:

    WebDriverWait(self.context.browser, timeout=15).until(EC.element_to_be_clickable((By.XPATH, "element_xpath"))).click()
    
  • Note : You have to add the following imports :

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

Reference

You can find a relevant detailed discussion in:

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • 1
    First what I did was I trying to use wait on a single element, with exactly the same way as on your tips, but Selenium didn't react for this. When I didn't have any ideas about what I can to do, I was trying to use any wait like`visibility_of_all_elements_located () ` but it didn't works too, now I know why. Thanks for your help !;) – wrozda Jan 13 '20 at 20:07