← Back Published on

Metamask Integration with Cypress

I wanted to test if a decentralised application is connected to the Metamask Wallet to perform certain scenarios that require a wallet connection. I am currently using Cypress Test Framework which is amazing but.. unfortunately Metamask is a browser extension that is not supported by Cypress tests. So how can we give Cypress the power to test Metamask integration ? 

Here comes @synthetixio/synpress plugin for the rescue !! Synpress can be added as a plugin to the existing cypress framework without disturbing the cypress tests that have already been added for other scenarios. Let's see below the steps involved in adding this plugin.

Step 1:

To add the synpress plugin, the first step is to obviously install it. Use the below command in the terminal and check if package.json has been updated with the plugin under Dev Dependencies. This command will create a node_modules folder for synpress.

npm i @synthetixio/synpress

package.json will have below but not limited to

"devDependencies": { "@synthetixio/synpress": "^3.0.0", "cypress": "^10.0.3"}

Note:Please keep in mind, versions will be based on what is latest at the moment of your installation

Step 2:

Import the synpress plugin in the cypress/support/e2e.js file. The key supportFile will have the value as this file path in the cypress.config.js later. The synpress support files will be processed and loaded before the test commences.

import "@synthetixio/synpress/support";

Step 3:

Load the plugin into cypress configuration by adding the below lines to cypress.config.js

What exactly happens here?

Practically, We fetch the synpress plugins from node_modules and feed this into Cypress plugin handler which is setupNodeEvents. 

Your cypress.config.js will include but not limited to below:

const { defineConfig } = require("cypress");

const { synpressPlugins } = require("@synthetixio/synpress/plugins");

module.exports = defineConfig({ 

userAgent: "synpress",

chromeWebSecurity: true, 

e2e: {  

setupNodeEvents(on, config) { 

synpressPlugins(on, config); 

return require("./cypress/plugins/index.js")(on, config); }, 

baseUrl: " ", 

specPattern: "cypress/e2e/**/*.{js,jsx,ts,tsx}", 

experimentalSessionAndOrigin: true, 

supportFile: "cypress/support/e2e.js", },});

Important Note:

1. Set the base url as per your application

2. experimentalSessionAndOrigin: true is recommended for synpress to work correctly

3. Tests have to be run in headless mode unless you use Docker

4. supportFile Value to be according to where the support file of your project is. Here, in my cypress framework it's e2e.js

5. userAgent: "synpress"

Step 4:

Add a new .env file with Metamask credentials

NETWORK=
PRIVATE_KEY=
PASSWORD= 

Network name can be mainnet, goerli, sepolia and localhost

Private Key can be exported from your metamask account

Password is your metamask sign-in password

Step 5:

Now, let us write a simple test walletConnect

when we run the script, synpress will do a global before function using task, setupMetamask() which loads and adds Metamask extension to browser before the test starts.

Below script does the following

1. login to application

2. click on wallet icon

3. click connect wallet button

4. sign in to metamask wallet through synpress command

5. assert successfull wallet connection in application

6. assert wallet account number is as expected

Let's see the code.

before(function () { 

//Cypress custom command : Check cypress/support/commands.js

cy.login().

then(function () { 

cy.visit("/"); 

//Click Wallet Icon and assert endpoint 

pageLocator.getWalletIcon().click();

//click on connect wallet

cy.get('buttonLocatorhere').click(); 

//synpress command : automatically signs in to wallet with metamask password cy.acceptMetamaskAccess(); 

//assert wallet connected display 

 wallet.getWalletConnectedMessage().should("exist"); 

//assert Correct Metamask Wallet Address is displayed in Account cy.contains(Cypress.env("wallet_address")).should("exist");});


after
(function () { 

//synpress command

cy.disconnectMetamaskWalletFromAllDapps();});


describe("metamask integration with Cypress", function () 

{ it("should successfully pass the test, function () { 

cy.visit("/"); 

Write normal tests here

})

})

Step 6:

Add script for synpress in package.json

"scripts": {

"synpress:run:test": "STABLE-MODE=TRUE synpress run --configFile cypress.config.js --spec ./cypress/e2e/2-advanced-examples/metaEthList.js"

}

Synpress is super cool because it will run a global beforeAll where it will automatically

1. Load the Metamask browser extension and enter credentials to sign in to the wallet account.

2. Go back to the application's connect wallet (Cypress window)

Remember to pass the PRIVATE_KEY as environmental variable.

Articles that strongly influenced my learning are

1. github repo by one of my linkedIn friends who did an excellent contribution to community by making an example architecture

https://github.com/DavitMkhita...

2. https://www.npmjs.com/package/...

3.  https://medium.com/coinmonks/t...

4. https://github.com/synthetixio...

5. https://medium.com/andamp/how-...

Voila....Now we are ready to run the test.