#30973: Selenium wait_page_loaded waits for wrong page (race condition)
---------------------------------------------+--------------------------
               Reporter:  Johannes Hoppe     |          Owner:  nobody
                   Type:  Bug                |         Status:  new
              Component:  Testing framework  |        Version:  master
               Severity:  Normal             |       Keywords:  selenium
           Triage Stage:  Unreviewed         |      Has patch:  0
    Needs documentation:  0                  |    Needs tests:  0
Patch needs improvement:  0                  |  Easy pickings:  0
                  UI/UX:  0                  |
---------------------------------------------+--------------------------
 Right now
 `django.contrib.admin.tests.AdminSeleniumTestCase.wait_page_loaded` waits
 for the `body` HTML-tag to be present. It is meant to be executed after a
 page reload is triggered, like a form submit.

 However, if the test suite is a little faster than our browser (race
 condition), we are looking get confirmation for the body tag of the old
 page, not the new one.

 The safe (and correct) way to wait in selenium for a page to re reloaded
 is to wait until the old one is gone and the new one is ready. Preferably
 with a context manager like so:

 {{{
 @contextmanager
 def wait_page_loaded(self, timeout=10):
     """
     Block until page has started to load.
     """
     from selenium.common.exceptions import TimeoutException
     from selenium.webdriver.support import expected_conditions as ec

     try:
         old_page = self.selenium.find_element_by_tag_name('html')
         yield
         # Wait for the next page to be loaded
         self.wait_until(ec.staleness_of(old_page), timeout=timeout)
         self.wait_until(
             lambda driver:
                 driver.execute_script('return document.readyState;') ==
 'complete',
             timeout=timeout

         )
     except TimeoutException:
         # IE7 occasionally returns an error "Internet Explorer cannot
         # display the webpage" and doesn't load the next page. We just
         # ignore it.
         pass
 }}}

 In some cases we might also want to wait for a site to be ready after a
 regular `selenium.get`.
 In that case with should have a separate method, like so:

 {{{
     def wait_page_ready(self, timeout=10):
         """
         Block until page has started to load.
         """
         self.wait_until(
             lambda driver: driver.execute_script('return
 document.readyState;') == 'complete',
             timeout
         )
 }}}

 This bug currently affects a lot of tests and fails preferably when you
 run FireFox but I've seen it on Chrome too.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/30973>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/052.a26ce546c35bb809b9db25e077fcf6f5%40djangoproject.com.

Reply via email to