I'm using Selenium Webdriver for testing a Django/Python based web application. I use both, the phantomjs and firefox drivers. We use django's LiveServerTest test case, which basically starts up a test webserver for the app.
Now, on our CI environment (wercker), I sometimes - but not always - get a TimeoutException from my webdriver.get(url) calls. The thing is, though, that when I look at the screenshots (which I collect on exceptions) the actual page seems to be rendered just fine.
I'm already using a technique to wait for a page reload that is described here: http://www.obeythetestinggoat.com/how-to-get-selenium-to-wait-for-page-load-after-a-click.html. This wrapper basically waits until the old page's HTML element is replaced with the new one. It seemed to resolve similar problems for when I run my tests locally.
So, what am I experiencing here? How can I proceed? Any hints greatly apreciated.
Edit: I followed Artem's advice and remove all external resources (fonts and google maps calls). I initially thought that helped but then got other errors instead. I now get TimeoutExceptions in a click() call... Here's the log:
Traceback (most recent call last):
File "/pipeline/build/flatfox/tests/ui/utils.py", line 57, in wrapper
func(self, *args, **kwargs)
File "/pipeline/build/flatfox/tests/ui/test_auction_cycle.py", line 157, in test_manage_applications
self.driver.find_element_by_css_selector('.modal-dialog .btn[name=reject]').click()
File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webelement.py", line 65, in click
self._execute(Command.CLICK_ELEMENT)
File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webelement.py", line 385, in _execute
return self._parent.execute(command, params)
File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 173, in execute
self.error_handler.check_response(response)
File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/errorhandler.py", line 166, in check_response
raise exception_class(message, screen, stacktrace)
TimeoutException: Message: u'{"errorMessage":"Click failed: timeout","request":{"headers":{"Accept":"application/json","Accept-Encoding":"identity","Connection":"close","Content-Length":"81","Content-Type":"application/json;charset=UTF-8","Host":"127.0.0.1:55196","User-Agent":"Python-urllib/2.7"},"httpVersion":"1.1","method":"POST","post":"{\\"sessionId\\": \\"d67c58a0-610d-11e4-a75e-eb735e81fd4c\\", \\"id\\": \\":wdc:1414767284194\\"}","url":"/click","urlParsed":{"anchor":"","query":"","file":"click","directory":"/","path":"/click","relative":"/click","port":"","host":"","password":"","user":"","userInfo":"","authority":"","protocol":"","source":"/click","queryKey":{},"chunks":["click"]},"urlOriginal":"/session/d67c58a0-610d-11e4-a75e-eb735e81fd4c/element/%3Awdc%3A1414767284194/click"}}' ; Screenshot: available via screen
Edit: Here's the code making the click():
with wait_for_page_load(self.driver):
self.driver.find_element_by_css_selector('.modal-dialog .btn[name=reject]').click()
with
def wait_for(condition_function):
start_time = time.time()
while time.time() < start_time + 10:
time.sleep(0.2)
if condition_function():
return True
raise Exception('Timeout waiting for {0}'.format(condition_function.__name__))
class wait_for_page_load(object):
def __init__(self, browser):
self.browser = browser
def __enter__(self):
self.old_page = self.browser.find_element_by_tag_name('html')
def page_has_loaded(self):
new_page = self.browser.find_element_by_tag_name('html')
return new_page.id != self.old_page.id
def __exit__(self, *_):
try:
wait_for(self.page_has_loaded)
except Exception, e:
logging.getLogger("test.ui").error("wait_for_page_load(): failed with %s", e)
I'm a bit lost now and wonder whether it has something to do with the CI environment...
Thanks, Bernhard