Introducing Cypress-polkadot-wallet: End-to-End Testing for Your Dapp

Introducing Cypress-polkadot-wallet: End-to-End Testing for Your Dapp

As part of our last treasury proposal, the Multix team has committed to building a tool to help developers test their Dapps with automated end-to-end testing. We’re happy to announce the tool is ready for use! It’s called  Cypress-polkadot-wallet, and here’s a quick guide on what it does and how to use it.

Test your Dapp, yes, but how?

In our view, if there should be one type of test for a Dapp, it should be end-to-end. While unit tests or component tests are useful, there is no better way to catch regressions and bugs than to automate and perform the whole flow of actions that a real user would do when using the Dapp. Since only a few platforms are available to achieve what we want, we chose the Cypress framework to write our tests due to its unmatched developer experience.

To test a Dapp, you must test the user interface that interacts with a blockchain. This process can be done by connecting your Dapp to a test network like Rococo to perform transactions using test tokens. However, for better performance and flexibility, you can use the Chopsticks tool to create a parallel reality of any substrate chain—more on this below. 

Now, there’s still a missing piece. While the Dapp needs to fetch data from the blockchain and allows users to submit transactions to the network, these transactions must be signed to be accepted. Also, the Dapp needs to interact with a wallet, and depending on the users’ actions on this wallet, the Dapp should react accordingly.

For example, say a user lands on your application for the first time and has yet to connect their wallet to share their account. Or they may have refused to authorize the wallet connection. Those edge cases, away from the happy path, must also be tested.

Until now, in Dapp development, we've had to simulate user interactions with a wallet. This hurdle is what we chose to address with Cypress-polkadot-wallet. With this tool, developers can now initiate a wallet that will get injected into the browser. They can select the accounts it contains, inspect authentication and transaction requests, and approve, reject, or sign them at will with simple functions.

Tests running from the Example Dapp in Cypress.

How to setup the testing strategy

In the cypress-polkadot-wallet repository, you will find two sections. The source code of the Cypress plugin can be found in `/packages/plugin`, but probably more interesting is an example Dapp in `packages/example`. It is written in vanilla JS, along with a whole suite of tests showing you how to use the cypress-polkadot-wallet plugin. 

In the repo, you will also find documentation of the accessible functions in the main readme. Finally, you can use the CI scripts to help run those tests for every commit in your CI with GitHub actions. We recommend reading the Cypress doc if you have never used Cypress before, but it should not affect your understanding of this article.

Let’s dive in.

Cypress is agnostic to any front-end framework. Whether you build your Dapp using React, Vue, or any other framework, it doesn’t matter, as it will simply automate the clicking of buttons and filling inputs.

To keep it simple, we wrote a minimal Dapp in vanilla JS with basic functions. If you look at index.html, it has a “Connect” button to allow users to connect with their wallet. It has a send function with an input field to specify the token amount and a “Send Tx” button to perform a token transfer. Below is the main part of the index.html:

The main.ts file describes actions linked to the buttons and input. Below is the code used when users click on “Connect.” This example is a typical flow in Polkadot Dapps, where `web3Enable` is called to see what wallets are available. If a wallet gets installed, then call `web3Accounts` to get access to its accounts.

Some other logic, not displayed here, makes it possible to connect to a Rococo node to send a number of tokens specified in the input and print the events sent by the nodes. While this setup is very simple, it allows for a variety of tests, including interactions where the user would submit transactions that get rejected. While this is common logic to most Dapps in the Polkadot ecosystem, there hasn’t been an easy way to test user interactions with a wallet.

The testing part

With Cypress installed in the example package, the test files live in packages/example/cypress. To be able to use the cypress-polkadot-wallet plugin, all we need to do is install it with a packet manager and then import it. (See the readme for more information). You can then use the new dedicated functions directly in your tests!

Below is an example of one of the first relevant tests:

The above example is the happy path of a user, Alice, connecting their wallet to the Dapp. The wallet gets an authentication request, and Alice approves it. The functions cy.initWallet, cy.getAuthRequests, and cy.approveAuth are all part of the Cypress plugin. 

You can look at the other tests in this example to verify that we get an error when Alice rejects the authentication request. We also test the function when a transaction is submitted to the chain successfully and when a transaction gets submitted to the chain with an error (e.g., insufficient funds). Find all the functions provided by the plugin in the repo’s readme.

Going further

Look at our CI scripts, running the tests in a headless browser every time there’s a new commit. This script builds the Dapp, launches it, and launches the tests against it.

As the intro mentions, you can get even further by connecting your Dapp to a Chopsticks node. This way, you can fund accounts and run your tests on a fork of Kusama, allowing them to perform better than running them on a test network.

You only need to launch Chopsticks before your tests and connect your Dapp to it. Check out the CI workflow in Multix, where we use it.

Since we built this tool to support the development of Multix, it has been battle-tested for several months. In the Multix CI, we set up and ran Chopsticks and a Susquid indexer with the Multix UI interfacing with them. By utilizing Cypress and this plugin, we verified that all the significant user interactions are behaving as expected. This rigorous testing process bolstered our confidence in the development and release of Multix, and we recommend others to experience its benefits as well.

Test it out for yourself!

👉 cypress-polkadot-wallet

Have questions or feedback? 

Get in touch 👉@Tbaut

About ChainSafe

ChainSafe is a leading blockchain research and development firm specializing in protocol engineering, cross-chain interoperability, and web3 gaming. Alongside its contributions to major ecosystems such as Ethereum, Polkadot, and Filecoin, ChainSafe creates solutions for developers across the web3 space utilizing expertise in gaming, interoperability, and decentralized storage. As part of its mission to build innovative products for users and improved tooling for developers, ChainSafe embodies an open-source and community-oriented ethos to advance the future of the internet.

Website | Twitter | Linkedin | GitHub | Discord | YouTube | Newsletter