0

I'm try to write process on UI with selenium and python3.x. In some case, I would like to wait particular query finish before go to next step. since during the query finish, there is no element I can pick up to use and return document.readyState as complete does not work for me. Is it possible to use selenium wait.until to do it? like

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
WebDriverWait(driver, 120).until(lambda x: "query return 0")
WebDriverWait(driver, 120).until(EC."something to wait for")
jacobcan118
  • 7,797
  • 12
  • 50
  • 95
  • How would a user know that the query is completed? What changes in the UI, etc. Wait on that. – JeffC Aug 21 '18 at 18:12
  • the problem is no ui changed...the test application just wait over there, if I keep perform more ui operation. page turn into blank page – jacobcan118 Aug 21 '18 at 20:56
  • That's not the best user experience... no indication in the UI that something is going on in the background and if I try to do something else, the page goes blank. If this is your site, I would talk to dev about some UI elements that indicate that something is going on in the background that you can wait for with your script. – JeffC Aug 21 '18 at 21:52
  • to be honest, i did and some dev just do not care. – jacobcan118 Aug 22 '18 at 13:26
  • there is merit in the idea that not all apps are adequately testable. If the app isn't easily testable, then that becomes the dev's problems as preventable bugs aren't being caught. If the devs don't care, then it may be necessary to go over their head to the lead of the project. Frame the problem as not just a QA or automation problem, but as something that affects the ability to identify and mitigate risk over long periods of time which hurts everyone – Julian Aug 22 '18 at 18:50

2 Answers2

5

Shorter solution:

WebDriverWait(driver, 10).until(lambda d: d.execute_script("return jQuery.active == 0"))
Sers
  • 12,047
  • 2
  • 12
  • 31
1

If the query is being run with Ajax and you are using JQuery, you could try using the javascript executor in order to wait for all ajax requests in flight to finish after intitiating the request:

driver.execute_script("return jQuery.active == 0")

You could wrap this into a custom ExpectedCondition for re-use with code like this:

class ajax_requests_to_finish(object):
    def __call__(self, driver):
        return driver.execute_script("return jQuery.active == 0")

This can be used like this:

# First perform an action that fires an ajax request
wait = WebDriverWait(driver, 10)
wait.until(ajax_requests_to_finish())

Disclaimer: I'm a java programmer, I don't really know any python. I drew upon this page as an example for how to create custom wait conditions in Python, since I only know how to do this in Java. Sorry if my code is incorrect, this sourced page describes a more generic working example. https://selenium-python.readthedocs.io/waits.html

Edit: As sers pointed out in another answer, this potential solution is possible as a one-liner

Julian
  • 1,665
  • 2
  • 15
  • 33
  • thank you. but my query is not jquery, always jump to timeout exception for waiting `jQuery.active == 0` – jacobcan118 Aug 21 '18 at 19:27
  • That's too bad. Can you share any details about what technology the site under test is using? Both for frond end technology and the back end technology serving content? – Julian Aug 21 '18 at 19:34
  • frontend is react back end is nodejs. query is send out for login/logout to get okta sign-in_widget https://developer.okta.com/code/javascript/okta_sign-in_widget – jacobcan118 Aug 21 '18 at 20:17
  • Third party integrations can be difficult, because sometimes there really just isn't any available hook to use, which might be the case here. One thing to look at is what ajax library your project is using. You're likely using a specific one, and it will likely have a small javascript api available for inspecting it's state. The solution to your problem if you go this route would be completely unique and dependent on that library – Julian Aug 22 '18 at 18:52