ChainSafe
dappeteer
TypeScript

[DEPRECATED]๐ŸŒ๐Ÿผโ€E2E testing for dApps using Puppeteer + MetaMask

Last updated May 28, 2026
482
Stars
149
Forks
42
Issues
0
Stars/day
Attention Score
75
Language breakdown
TypeScript 94.6%
HTML 4.7%
JavaScript 0.5%
Solidity 0.1%
โ–ธ Files click to expand
README

Deprecation Notice

Notice: dAppeteer is deprecated and is no longer actively maintained. Due to ongoing changes in the MetaMask ecosystem and constraints in our resources, we have decided to discontinue development. This repository will remain available in a read-only, archived state.

Alternatives: We encourage users to explore the following alternatives, which provide continued support and active development for dApp testing:

We thank our community for the support and contributions over the years. For any additional questions or guidance on transitioning to new tools, please feel free to reach out.

Thank you for your understanding and collaboration.

dAppeteer

E2E testing for dApps using Puppeteer + MetaMask

Installation

$ npm install -s @chainsafe/dappeteer
or
$ yarn add @chainsafe/dappeteer

Usage

import dappeteer from '@chainsafe/dappeteer';

async function main() { const { metaMask, browser } = await dappeteer.bootstrap();

// create a new page and visit your dapp const dappPage = await browser.newPage(); await dappPage.goto('http://my-dapp.com');

// you can change the network if you want await metaMask.switchNetwork('goerli');

// do something in your dapp that prompts MetaMask to add a Token const addTokenButton = await dappPage.$('#add-token'); await addTokenButton.click(); // instruct MetaMask to accept this request await metaMask.acceptAddToken();

// do something that prompts MetaMask to confirm a transaction const payButton = await dappPage.$('#pay-with-eth'); await payButton.click();

// ๐ŸŒ await metaMask.confirmTransaction(); }

main();

Usage with Snaps

import dappeteer from '@chainsafe/dappeteer';
import { exec } from "child_process";

async function buildSnap(): Promise<string> { console.log(Building my-snap...); await new Promise((resolve, reject) => { exec(cd ./my-snap &amp;&amp; npx mm-snap build, (error, stdout) => { if (error) { reject(error); return; } resolve(stdout); }); });

return "./my-snap"; }

async function main() { // build your local snap const builtSnapDir = await buildSnap()

// setup dappateer and install your snap const { metaMask, snapId, browser } = await dappeteer.initSnapEnv({ snapIdOrLocation: builtSnapDir, });

// you need to have a webpage open to interact with MetaMask, you can also visit a dApp page const dappPage = await browser.newPage(); await dappPage.goto('http://example.org/');

// invoke a method from your snap that prompts users with approve/reject dialog await metaMask.snaps.invokeSnap(dappPage, snapId, "my-method")

// instruct MetaMask to accept this request await metaMask.snaps.dialog.positive();

// get the notification emitter and the promise that will receive the notifications const emitter = await metaMask.snaps.getNotificationEmitter(); const notificationPromise = emitter.waitForNotification();

// do something that prompts your snap to emit notifications await metaMask.snaps.invokeSnap(dappPage, snapId, "notify");

// Make sure the notification promise has resolved await notificationPromise;

// You can now read the snap notifications and run tests against them const notifications = await metaMask.snaps.getAllNotifications(); }

main();

๐Ÿ”— More in this category

ยฉ 2026 GitRepoTrend ยท ChainSafe/dappeteer ยท Updated daily from GitHub