Cypress test approach for testing with Metamask

Viewed 2973

I want to test how my application interacts with Metamask (e.g. is the wallet open?) and create a flexible test configuration that enables me to access the application by 'mounting' the Metamask interface in a similar way to how ordinary 'login' is done (I use MM for login effectively) in the Assert JS (2018) lecture videos like: https://www.youtube.com/watch?v=5XQOK0v_YRE Is there any reference material or advice for testing Metamask with Cypress? Cypress has the following documentation for loading a Chrome extension plugin:

    module.exports = (on, config) => {
      on('before:browser:launch', (browser, launchOptions) => {
        // supply the path to an unpacked WebExtension
        // NOTE: extensions cannot be loaded in headless Chrome
        launchOptions.extensions.push('/path/to/webextension')

        return launchOptions
      })
    }

but there's no other assistance beyond this. Once it's loaded, how would I interact with it to produce meaningful tests? I expect that this should be possible. I see that other's have considered the issues and I have posted this question in the MM github: https://github.com/MetaMask/metamask-extension/issues/8605 thx ...

1 Answers

As per: https://github.com/cypress-io/cypress/issues/1965

You can't test or interact with extensions using Cypress with ease.

As a workaround, I've used puppeteer in conjunction with Cypress to be able to achieve this.

Your example for loading extensions is correct. You can see my approach here, which downloads latest metamask version before loading it in browser: https://github.com/Synthetixio/synpress/blob/16095f8eb9ad6d92e95719c903878c32991a8ab2/plugins/index.js#L56-L58

However, remember about these things before going this way:

  1. Because metamask is opened as a new tab on initial install after you run a browser, Cypress tests won't start with default setup because Cypress background tab will be "inactive". To fix this, you need to use these:
module.exports = (on, config) => {
  on('before:browser:launch', async (browser = {}, arguments_) => {
    if (browser.name === 'chrome') {
      arguments_.args.push('--disable-background-timer-throttling');
      arguments_.args.push('--disable-backgrounding-occluded-windows');
      arguments_.args.push('--disable-renderer-backgrounding');
    }
}

https://github.com/Synthetixio/synpress/blob/16095f8eb9ad6d92e95719c903878c32991a8ab2/plugins/index.js#L48-L53

  1. Always use "chromeWebSecurity": true in cypress.json config, otherwise metamask will won't work properly with dapps and have issues with connection. https://github.com/Synthetixio/synpress/issues/17

Consider if you won't need to turn them off in long term: https://docs.cypress.io/guides/guides/web-security.html#Limitations

  1. Always run Cypress inside headed mode (cypress run --headed). Headless won't work with extensions.

Feel free to checkout Synpress which is an integration of metamask with Cypress: https://github.com/Synthetixio/synpress

I think you can find a lot of details here which will suit your needs.

Cheers, Jakub.

Related