How to test client code in a Github Actions workflow

What I’m trying to do:

I’m trying to run client code tests as part of our test suite in Github Actions.

As part of our CI process, we have a test suite that runs automatically when Pull Requests (PR) are opened on Github, where we host our Anvil app code, to prevent erroneous code being pushed to our main branch.

This works for about 95% of our server code, which we can treat more or less like a regular Python package. With the help of Anvil uplink and some hacks to mock Anvil features like portable classes, we can just run the tests through pytest on the Github-hosted runner VM. This works well enough.

However, we have so far not come up with a satisfying solution for the client code. We don’t necessarily need full-on mocking of user interface interactions for now, but being able to run unit test for functions and methods that run as Skulpt-generated JavaScript in the browser would already be better than nothing.

What I’ve tried and what’s not working:

We have considered and/or tried the following:

  • Use a similar approach as with the server code: run a test suite on the Github-hosted runner, with Python unittest and skulpt (npm start py3 ../client_code/tests/ This does not work because there is no ._anvil_designer module in this context, as also discussed by @a.dalessandro (see Running unit tests locally with Pytest)
  • Use anvil-test, as presented by @owen.campbell here: Library to assist automated testing. This looks like it’s close to what we want. However, it requires you to test against a specific app environment/URL with an Anvil-hosted branch behind it. This does not seem to fit into our desired workflow, in which the code that gets tested is that on the source feature branch of the PR hosted on Github. So the app behind the URL would need to correspond to that feature branch.

Possible reason/solution:

If there was a way to dynamically set up an Anvil app environment corresponding to the origin branch of the PR, and then capture and propagate the URL of that temporary environment into the test runner, an approach like anvil-test would probably be something we’d explore further. We might be able to set up a clone of the app on the Github-hosted runner (using something like Anvil Docs | Host apps on your own server) and run the tests against that clone?

Has anyone solved this problem or got further than we have so far?

One option is to make the client side form code as thin as possible and use modules (with no anvil imports) for all of the logic. Those can then be imported and tested in much the same way as your server code leaving only the UI elements untested.