Library to assist automated testing

I’ve started a small library to assist with automated testing of my anvil apps, so I thought I’d publish it to github and pypi:

It currently has general helper functions to click an element, send keystrokes to an element and to read the text value of an element plus login and signup functions for the normal forms from the anvil user service.

It’s also changing fast…


I’ve created a trivial app to demonstrate the use of the testing libary at

The app presents a login form. If you click ‘cancel’, you should see a ‘Hello World’ message and if you login with the credentials ‘’ and ‘AnvilWorks’, you should instead see the message ‘Hello Owen’

Here is the code to test that the app is working properly:

import pytest

from anvil_test import session

browser = 'firefox'
url = ''
email = ''
password = 'AnvilWorks'

xpaths = {
    'cancel_button': '/html/body/div[4]/div/div/div[3]/button[2]',
    'label': '/html/body/div[2]/div/div/div[1]/div[3]/div[1]/div/div/div/div/div/div/div/div/div/div/span'

def test_session():
    session.init(browser, url)

def logged_in_session(test_session):
    session.login(email, password)

def anonymous_session(test_session):['cancel_button'])

def test_anonymous_session(anonymous_session):
    label_text = session.get_text(xpaths['label'])
    assert label_text == 'Hello World'

def test_logged_in_session(logged_in_session):
    label_text = session.get_text(xpaths['label'])
    assert label_text == 'Hello Owen'

To run it, you will need to pip install selenium, pytest and anvil_test.

You will also need to have firefox available on your machine and to install geckodriver and ensure it is available on your path.

(If you prefer to use Chrome, install chromedriver, ensure it is on your path and replace “browser = ‘firefox’” in the demo code with “browser=‘chrome’”

If you save the code as ‘’, you can then run it using:


and you should see it automatically start a browser session, navigate to the app, click the cancel button, close that session, start a new session, login and close down. For both sessions, it will have extracted the message text, compared it with the expected result and will report whether the test passed or failed.


Have you tested it with chrome at all? I am attempting to use it and get a timeout exception when trying to log in.

selenium.common.exceptions.TimeoutException: Message:

On some light googling, this generally occurs when the targeted element can’t be found.


This also is occuring with firefox, so maybe it has more to do with my application…I’ll keep digging.


specifically here: site-packages\selenium\webdriver\support\

when looking for the email_xpath /html/body/div[4]/div/div/div[2]/div/ul/li[2]/input

def until(self, method, message=''):

        """Calls the method provided with the driver as an argument until the \

        return value does not evaluate to ``False``.

        :param method: callable(WebDriver)

        :param message: optional message for :exc:`TimeoutException`

        :returns: the result of the last call to `method`

        :raises: :exc:`selenium.common.exceptions.TimeoutException` if timeout occurs

   screen = None
        stacktrace = None

        end_time = time.monotonic() + self._timeout
        while True:
                value = method(self._driver)
                if value:
                    return value
            except self._ignored_exceptions as exc:
                screen = getattr(exc, 'screen', None)
                stacktrace = getattr(exc, 'stacktrace', None)
            if time.monotonic() > end_time:
        raise TimeoutException(message, screen, stacktrace)


I am hoping this makes sense :crossed_fingers: as I am a novice web dev.

It looks like my login HTML is a bit different and the email_xpath needs to be updated. I’m currently shooting from the hip, hoping to hit.


I am now realizing I should’ve maybe made a different post.

EDIT 3 was the issue, a many more

tags changed the indexing in /html/body/div[XXX], not sure if this is application-specific or because the anvil source, itself, has changed.

I haven’t looked at this in years. The chances of it working now are very small.

1 Like

If you time update your github repo (it isn’t the same version that is part of the PyPI repository), I’d love to fork the library to work with current anvil.

If not, no worries. I’ll just make my own and credit you if I have your permission :slight_smile:

1 Like

It’s open source. Go for it!