Short story: I am writing a feature test for a django app using lettuce and splinter. The scenario fails due to some lack of sync at the step calls.
The question: Is there a way to prevent this error from happening wihtout adding an artificial waiting time to my step?
Longer story: The scenario checks if an existing user is able to log in.
Scenario: User exists as admin
Given I access the url "/login/"
And The user "someuser" with password "something" exists as admin
When I fill username with "someuser" and password with "exists"
And I submit the form
Then I see the paragraph "You're successfully logged in!"
the critical step here is:
@step(r'I see the paragraph "(.*)"')
def see_paragraph(step, text):
assert text in world.browser.html
When I harvest the lettuce feature, it randomly fails.
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/lettuce/core.py", line 143, in __call__
ret = self.function(self.step, *args, **kw)
File "/vagrant/src/enext/apps/auth/features/authentication-steps.py", line 21, in see_paragraph
assert text in world.browser.html
AssertionError
When I tried to debug it, I found that printing the response would make it work every time, so I could not reproduce the error. Adding a pause also seems to do the trick.
@step(r'I see the paragraph "(.*)"')
def see_paragraph(step, text):
# print world.browser.html.encode('utf-8')
# either the next or the previous line fixes it
time.sleep(0.3)
assert text in world.browser.html
At first it looked like it was related to the test database flush, but I removed the other scenarios, and the flush as well, and it kept happening.
It might depend on what your And I submit the form
makes. If this step clicks on "submit" button or something like that then it's the place where the problem starts.
Webdriver waits for page to load almost after all actions except clicking and other "onpage" interactions. So after click it immediately looks for presence of element without waiting for response.
As a solution I would recommend you to use wait_time
argument as described at splinter docs or write your own function that goes in a loop of checking statement until specified timeout.
P.S.: I also recommend you to look at python selenium and it's wait(browser, timeout).until(some_statement)