Coder Social home page Coder Social logo

metamask / test-dapp Goto Github PK

View Code? Open in Web Editor NEW
567.0 567.0 339.0 21.42 MB

The sample dapp used for e2e testing and metamask-extension QA

Home Page: https://metamask.github.io/test-dapp/

License: MIT License

HTML 28.47% JavaScript 64.50% Shell 1.43% CSS 0.79% Solidity 4.82%

test-dapp's Introduction

MetaMask Test Dapp

This is a simple test dapp for use in MetaMask e2e tests and manual QA.

Currently hosted here.

Usage

If you wish to use this dapp in your e2e tests, install this package and set up a script of e.g. the following form:

static-server node_modules/@metamask/test-dapp/dist --port 9011

The main page of the test dapp includes a simple UI featuring buttons for common dapp interactions.

There is a second page (request.html) that allows making requests directly to the provider using query parameters. This provides a simple way of testing RPC methods using an in-page provider.

It can be used by navigating to /request.html?method=${METHOD}&params=${PARAMS} (e.g. /request.html?method=eth_getLogs&params=[{ "address": "0x0000000000000000000000000000000000000000" }]). The page will make a request with the given RPC method and parameters using ethereum.request, and report the result as plain text.

Contributing

Setup

  • Install Node.js version 16
    • If you are using nvm (recommended) running nvm use will automatically choose the right node version for you.
  • Install Yarn v1
  • Run yarn setup to install dependencies and run any required post-install scripts
    • Warning: Do not use the yarn / yarn install command directly. Use yarn setup instead. The normal install command will skip required post-install scripts, leaving your development environment in an invalid state.

Testing and Linting

Run yarn lint to run the linter, or run yarn lint:fix to run the linter and fix any automatically fixable issues.

This package has no tests.

Deploying

After merging or pushing to main, please run yarn deploy in the package root directory if the contents of the dist/ directory have changed.

Development

Elements Must Be Selectable by XPath

All HTML elements should be easily selectable by XPath. This means that appearances can be misleading. For example, consider this old bug:

<button
  class="btn btn-primary btn-lg btn-block mb-3"
  id="approveTokensWithoutGas"
  disabled
>
  Approve Tokens Without Gas
</button>

This appears on the page as Approve Tokens Without Gas. In reality, the value included the whitespace on the second line, and caused XPath queries for the intended value to fail.

test-dapp's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

test-dapp's Issues

Rewrite using TypeScript/React?

The JavaScript is getting quite unwieldy (it's already at 1200+ lines). It would be nice to rewrite this project in a way that would be more representative of a real-world project. We use React in the extension already, so that seems like a natural progression. We might also consider using Redux (but that is optional). Also, we want to transition to TypeScript and we might as well switch this project to that.

connection isn't working properly

connect,
metamask.github.io gets added to list of connected sites
close test dapp
open to test dapp, connect and accounts buttons should be available, they appear to be, but are unresponsive
i think because the MetaMask onboarding obj is undefined

MetaMaskOnboarding

At line 184 isMetamaskInstalled() will return undefined so turning it into a false positive will go for Onboarding

  const updateButtons = () => {
    const accountButtonsDisabled = !isMetaMaskInstalled() || !isMetaMaskConnected()
    if (accountButtonsDisabled) {
      for (const button of accountButtons) {
        button.disabled = true
      }
      clearTextDisplays()
    } else {
      deployButton.disabled = false
      sendButton.disabled = false
      createToken.disabled = false
      personalSign.disabled = false
      signTypedData.disabled = false
      getEncryptionKeyButton.disabled = false
      ethSign.disabled = false
      personalSign.disabled = false
      signTypedData.disabled = false
      signTypedDataV3.disabled = false
      signTypedDataV4.disabled = false
    }

    if (!isMetaMaskInstalled()) {
      addEthereumChain.disabled = true
      onboardButton.innerText = 'Click here to install MetaMask!'
      onboardButton.onclick = onClickInstall
      onboardButton.disabled = false
    } else if (isMetaMaskConnected()) {
      addEthereumChain.disabled = false
      onboardButton.innerText = 'Connected'
      onboardButton.disabled = true
      if (onboarding) {
        onboarding.stopOnboarding()
      }
    } else {
      addEthereumChain.disabled = true
      onboardButton.innerText = 'Connect'
      onboardButton.onclick = onClickConnect
      onboardButton.disabled = false
    }
  }

[Bug]: Deploying a failing contract turns into a success Contract Deployment event

Problem: when I click on Deploy a failing contract, I'm expecting to see an error on the transaction log, but I see that Contract is deployed successfully (apparently).

deploy-failing-contract.mp4

Expectation: we should see an error saying "Failed" on the contract log transaction, like in the case below

deploy-failing-contract-expected.mp4

Steps:

  1. Go to Test Dapp
  2. Connect Metamask
  3. Click Deploy Failing contract
  4. Check Transaction activity tab

Bring back auto-deploy

It would be great if we didn't have to deploy the test dapp manually — if, instead, every time we pushed to main, it deployed itself. It seems like an attempt was made to add this using peaceiris/actions-gh-pages, but perhaps permissions aren't set up correctly on this repo. We'd have to get an admin to investigate this.

[Bug]: Sign-in With Ethereum (SIWE) buttons are not using EIP-55 compliant from addresses

Per EIP-4361 (SIWE) spec, the provided address must be EIP-55 compliant. If we update to the latest spruceid/siwe-parser package ^v2.1.0, the current test-dapp buttons will no longer parse as SIWE messages. This is because our RPC method, eth_accounts, returns all-lowercase, non-complaint EIP-55 addresses. Because of this, we've patched our version of the @spruceid/siwe-parser to exclude the EIP-55 check (PR).

Spec:
We need to enforce EIP-55 addresses for SIWE transactions

Links:
Related internal thread
Related eth_accountsPR comment

Add button that uses Web3 provider to send transaction

Currently, the test dapp only uses ethers.js for instantiating a provider. We need to also use web3.js, because many dapps use that exclusively. For us to properly test and QA MetaMask, we should test against the same tools that dapps use. Also, some functionality (e.g. batch transactions) are better supported by web3.js than ethers.

To start, let's just allow the test dapp to use web3 in place of ethers wherever it is currently used

  • add a radio button toggle somewhere on the top of the page. The options in the toggle should be "web3" and "ethers"
  • the toggle should default to ethers
  • if ethers is selected, the create token and deploy contract buttons should behave as they do today
  • if web3 is selected, create token and deploy contract should use web3 instead of the current "factories" created by the ethers provider, however the transactions created by the buttons should be the same

Make the "encrypt/decrypt" section usable as a minimal messenger

Current decryption demo only allows decrypting the message you encrypted to yourself. This doesn't really show off the feature.

The sections should be like this:

[get encryption key]
encryption key output
-------
type message
recipient encryption key
[encrypt message]
encrypted output (full, copyable)
--------
type encrypted input
[decrypt message]
decrypted output

Idea: Replace Bootstrap?

Bootstrap is a fine project if you always want to use the default UI elements and never want to have your own CSS or customize the UI in any way. Once you reach even a short point after starting to use Bootstrap, though, it gets progressively more and more difficult to customize. (This is the problem with UI frameworks in general, by the way.) It would be better and easier in the long run if we used our own CSS. There are a couple of routes we could take:

  • Use our own design system borrowed from the extension
    • This might be difficult considering we've never tried to extract this (to my knowledge)
  • Use something like Tailwind to build our own UI
    • This would be best combined with the switch to React
    • This is not as hard as it sounds — we may have to spend time up front to add styles for buttons, text inputs, etc. but in my experience Tailwind is incredibly easy to get started with, and you don't really have to think about best practices or file organization

Starting Dapp on a locale node

hey,
i could not start the dapp in my local evironment with http-server - also i did everything in your read.me.

Questions:

  1. static-server node_modules/@metamask/test-dapp/dist --port 9011: Is this right because i could not find the "dist" directory.
  2. Could you please send show - the step-by-step - what i have to do when i changed something in the sources
  3. When i open the browser - what shell i paste in the URL (i tried it with localhost:9011/test-dapp - but this doesn't work. thanks for helping me.

Add buttons to deploy a contract that will always fail when sending a transaction to it

We need our test dapp to be able to test error cases. A basic error case that we need to add is a transaction with a smart contract, which will always fail because of a condition internal to the smart contract code.

Here is the code for a smart contract. Transactions sent to this contract will always fail if the value of the transaction is less than 0xfff

pragma solidity 0.5.12;

contract MMCheck {

    function() external payable {
        assert(msg.value > 0xfff);
        msg.sender.transfer(msg.value);
    }
}

The following code would create a transaction to deploy this contract:

var mmcheckContract = new web3.eth.Contract([{"payable":true,"stateMutability":"payable","type":"fallback"}]);
var mmcheck = mmcheckContract.deploy({
     data: '0x6080604052348015600f57600080fd5b50608b8061001e6000396000f3fe6080604052610fff3411600e57fe5b3373ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f193505050501580156053573d6000803e3d6000fd5b5000fea265627a7a72315820631b0dbb6b871cdbfdec2773af15ebfb8e52c794cf836fe27ec21f1aed17180f64736f6c634300050c0032', 
     arguments: [
     ]
}).send({
     from: web3.eth.accounts[0], 
     gas: '4700000'
   }, function (e, contract){
    console.log(e, contract);
    if (typeof contract.address !== 'undefined') {
         console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
    }
 })

We need to add a section to the test dapp that has two buttons, one to deploy this contract and one to send a transaction to it.

Acceptance criteria

  • add a new section to the "Send Eth" card in the test dapp. Add a new <hr> below the current "Contract" section, the section can be very similar to the "Contract" section, except that it should have a new title "Failing Contract", and two buttons: "Deploy Failing Contract" and "Send Failing Transaction"
  • clicking the "Deploy Failing Contract" button should call code very similar to the current "Deploy" button code, but instead should deploy the contract data 0x6080604052348015600f57600080fd5b50608b8061001e6000396000f3fe6080604052610fff3411600e57fe5b3373ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f193505050501580156053573d6000803e3d6000fd5b5000fea265627a7a72315820631b0dbb6b871cdbfdec2773af15ebfb8e52c794cf836fe27ec21f1aed17180f64736f6c634300050c0032
  • clicking the "Send Failing Transaction" button should send a transaction with value 0x0 to the address of the new contract (the way that "Deposit" creates a transaction to the address of the contract created by "Deploy")
  • if done correctly, the transaction created by "Send Failing Transaction" should show an error message, but you should still be able to submit it. However, after submission, it should fail

Deploy issue: Error: error:0308010C:digital envelope routines::unsupported

I followed the readme and used nvm to switch to node 12 (previously I tried with node 16 LTS, same issue)

Environment: Fedora Linux (Fedora 36).

nvm use
Found '/test-dapp/.nvmrc' with version <v12>
Now using node v12.22.12 (npm v6.14.16)

yarn setup
yarn run v1.22.17
$ yarn install && yarn allow-scripts
[1/5] Validating package.json...
[2/5] Resolving packages...
[3/5] Fetching packages...
[4/5] Linking dependencies...
[5/5] Building fresh packages...
warning Ignored scripts due to flag.
$ /test-dapp/node_modules/.bin/allow-scripts
running lifecycle scripts for event "preinstall"
running lifecycle scripts for event "install"
- sha3
- secp256k1
- keccak
running lifecycle scripts for event "postinstall"
running lifecycle scripts for top level package
Done in 7.79s.

yarn
yarn install v1.22.17
[1/5] Validating package.json...
[2/5] Resolving packages...
success Already up-to-date.
Done in 0.62s.

yarn lint
yarn run v1.22.17
$ yarn lint:eslint && yarn lint:misc --check
$ eslint . --cache --ext js,ts
$ prettier '**/*.json' '**/*.md' '!CHANGELOG.md' '**/*.yml' --ignore-path .gitignore --check
Checking formatting...
All matched files use Prettier code style!
Done in 2.69s.

yarn deploy
yarn run v1.22.17
$ ./deploy.sh
$ yarn lint:eslint && yarn lint:misc --check
$ eslint . --cache --ext js,ts
$ prettier '**/*.json' '**/*.md' '!CHANGELOG.md' '**/*.yml' --ignore-path .gitignore --check
Checking formatting...
All matched files use Prettier code style!
$ webpack --mode production
node:internal/crypto/hash:67
  this[kHandle] = new _Hash(algorithm, xofLen);
                  ^

Error: error:0308010C:digital envelope routines::unsupported
    at new Hash (node:internal/crypto/hash:67:19)
    at Object.createHash (node:crypto:130:10)
    at module.exports (/test-dapp/node_modules/webpack/lib/util/createHash.js:135:53)
    at NormalModule._initBuildHash (/test-dapp/node_modules/webpack/lib/NormalModule.js:417:16)
    at handleParseError (/test-dapp/node_modules/webpack/lib/NormalModule.js:471:10)
    at /test-dapp/node_modules/webpack/lib/NormalModule.js:503:5
    at /test-dapp/node_modules/webpack/lib/NormalModule.js:358:12
    at /test-dapp/node_modules/loader-runner/lib/LoaderRunner.js:373:3
    at iterateNormalLoaders (/test-dapp/node_modules/loader-runner/lib/LoaderRunner.js:214:10)
    at Array.<anonymous> (/test-dapp/node_modules/loader-runner/lib/LoaderRunner.js:205:4)
    at Storage.finished (/test-dapp/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:55:16)
    at /test-dapp/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:91:9
    at /test-dapp/node_modules/graceful-fs/graceful-fs.js:115:16
    at FSReqCallback.readFileAfterClose [as oncomplete] (node:internal/fs/read_file_context:68:3) {
  opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
  library: 'digital envelope routines',
  reason: 'unsupported',
  code: 'ERR_OSSL_EVP_UNSUPPORTED'
}
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
ERROR: Failed to build
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Same issue with yarn build & yarn start

The Error: error:0308010C:digital envelope routines::unsupported issue seems a "well known" issue, in fact I remember I had this issue in a couple of other repos too, and the solution was to use node LTS. Well now I'm using node LTS and the issue is there.

I tried also what people suggest if you google search how to fix this:

export NODE_OPTIONS=--openssl-legacy-provider

Then tried again:

yarn deploy
/usr/bin/node: --openssl-legacy-provider is not allowed in NODE_OPTIONS

The option to use openssl legacy is not allowed.

Can you please suggest a fix or even better push a fix so that when users clone this repo on a fresh machine and follow the instructions in the README it works out of the box?

A plus would be to support also the actual LTS version v16.x since v12 is a bit oldish.

Thank you.

Watch 721/1155 on mobile

Was testing on multiple mobile devices today and observed that watch 721/1155 from the test dapp did not function as I expected after deploying contracts and minting. Was able to manually import NFTs though.

  • Samsung a515f running Android 12 with security 1/1/2024
  • Pixel 5a running Android 14 with security May 5, 2024
  • iPhone 13 mini running iOS 15.6.1
  • iPhone Xs running iOS 17.4.1

Will add a video and repro steps, just have to dig it out of my footage.

Wallet E2E Test API

The Web3 Frontend Brittleness Problem

Many of today's web3 apps feel brittle, partially because there is no robust e2e test framework API officially supported by MetaMask.

There are frequent ongoing UI flow breaks and misplacement or misrepresentation of user's crypto funds due to subpar UX. This is true even for top web3 apps like Uniswap, Axie and Sandbox. As users navigate between different web3 apps and interact with multiple blockchain networks and wallets, these web3 apps often get out of sync with the state of the current wallet and as a result, the user ends up looking at unexpected content.

Given web3's promise to better protect user's identity, privacy and provide more control over user's own assets, it is imperative to offer superior, trustworthy UX. That in turn requires improving on test automation practices and infrastructure.

Current Workarounds

Test frameworks like dappeteer and synpress are trying to bridge the gap, but they feel brittle as they are constantly chasing MetaMask's changing front end code. This test framework brittleness frustrates web3 developers who are used to sophisticated web2 tooling. Writing web3 e2e tests that frequently break due to underlying base layer problems, results in postponing these test automation initiatives, which then results in brittle web3 frontend apps and subpar web3 UX.

The following snippet is an example of web3 e2e test frameworks "screen scraping" metamask code.

const firstTimeFlowFormPage = '.first-time-flow__form';
const secretWordsInput = `${firstTimeFlowFormPage} .first-time-flow__seedphrase input`;
const passwordInput = `${firstTimeFlowFormPage} #password`;
const confirmPasswordInput = `${firstTimeFlowFormPage} #confirm-password`;
const termsCheckbox = `${firstTimeFlowFormPage} .first-time-flow__terms`;
const importButton = `${firstTimeFlowFormPage} .first-time-flow__button`;
const newPasswordInput = `${firstTimeFlowFormPage} #create-password`;
const newSignupCheckbox = `${firstTimeFlowFormPage} .first-time-flow__checkbox`;

and another example:

  const addressInput = await page.waitForSelector('#custom-address');
  addressInput.type(tokenAddress);

  await page.waitForTimeout(4000);

  const nextButton = await page.waitForSelector(`button[data-testid='page-container-footer-next']:not([disabled])`);
  await nextButton.click();

  const footerButtons = await page.$$('footer > button');

While web3 app test developers are looking for reliable API that looks like this:

  const browser = await dappeteer.launch(puppeteer, { metamaskVersion: 'v10.1.1' });
  const metamask = await dappeteer.setupMetamask(browser);

  // you can change the network if you want
  await metamask.switchNetwork('ropsten');

  // you can import a token
  await metamask.addToken('0x4f96fe3b7a6cf9725f59d353f723c1bdb64ca6aa');

  // go to a dapp and do something that prompts MetaMask to confirm a transaction
  const page = await browser.newPage();
  await page.goto('http://my-dapp.com');
  const payButton = await page.$('#pay-with-eth');
  await payButton.click();

  // 🏌
  await metamask.confirmTransaction();

Proposed Solution

MetaMask is the industry leading web3 wallet. It is in a position to establish a standardized API for e2e web3 app testings that improves web3 app UX and sets a high bar for the growing number of new L2&L1 specialized wallets.

This MetaMask test-dapp repo could be the starting point for standardizing web3 e2e testing by documenting and providing test-spec examples for the interaction between its page components and the metamask wallet in various browsers through a cross browser e2e framework such as playwright.

Thank you and Happy Holidays! 🎄 🎉

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.