ChainSafe / dappeteer

[DEPRECATED]🏌🏼‍E2E testing for dApps using Puppeteer + MetaMask
Other
490 stars 151 forks source link

metamask gets stuck on the "Let's get started" screen #344

Open pipks opened 10 months ago

pipks commented 10 months ago

I just started the dappeteer topic and wanted to test the codes on the home page as an example. I do not receive any errors when I run the codes, but after opening the Metamask page, the page hangs and closes without logging in.

My Code:

import dappeteer from '@chainsafe/dappeteer';

async function main() {
  const { metaMask, browser } = await dappeteer.bootstrap({
    headless: false, 
    seed: 'test test test test test test test test test test test test test test test test test test test test test test test test ', // 24 words
    password : 'my_password', 
    showTestNets: true,
  });

  // 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();

SS:

sssssss

kashifmanzer commented 10 months ago

try this

const browser = await dappeteer.launch({
    metaMaskVersion: "latest",
    automation: "puppeteer",
    headless: false,
  });
  const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
  await sleep(2000);

  const pages = await browser.pages();
  for (const page of pages) {
    if (page.url().startsWith("chrome-extension")) {
      await page.reload();
    }
  }

  const metaMask = await dappeteer.setupMetaMask(browser, {
    seed: "test test test test test test test test", // 24 words
    password: "xxxx",
    showTestNets: true,
    automation: "puppeteer",
  });
InfiniteCoder100 commented 10 months ago

The issue you're encountering where MetaMask gets stuck on the "Let's get started" screen might be due to the browser not having enough time to fully load the MetaMask extension.

you can try to add a delay after launching the browser and before setting up MetaMask. This can be achieved by creating a sleep function and waiting for a certain amount of time (e.g., 2000 milliseconds).

Try run this updated code in the file below: solution.zip

zixiang2018 commented 9 months ago

try this

const browser = await dappeteer.launch({
    metaMaskVersion: "latest",
    automation: "puppeteer",
    headless: false,
  });
  const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
  await sleep(2000);

  const pages = await browser.pages();
  for (const page of pages) {
    if (page.url().startsWith("chrome-extension")) {
      await page.reload();
    }
  }

  const metaMask = await dappeteer.setupMetaMask(browser, {
    seed: "test test test test test test test test", // 24 words
    password: "xxxx",
    showTestNets: true,
    automation: "puppeteer",
  });

This works (almost) but there's another error which says TargetCloseError: Waiting for selector `.network-display` failed: Protocol error (Runtime.callFunctionOn): Session closed. Most likely the page has been closed. when dappeteer.setupMetaMask is being performed.

Adding an await sleep(2000) does not work as well. Did anyone managed to get metaMask.switchNetwork to work before?

zixiang2018 commented 9 months ago

Hi, with reference to the above answers and the testcase here, I got it to work

export const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

// Ensure ganache is running first (can skip this if you're not using localhost testnet)
const addNetwork = async () => {
  const addNetworkRequest = window.ethereum.request({
    method: "wallet_addEthereumChain",
    params: [
      {
        chainId: "0x539",
        chainName: "Localhost 8545",
        nativeCurrency: {
          name: "ETH",
          symbol: "ETH",
          decimals: 18,
        },
        rpcUrls: ["http://localhost:8545"],
      },
    ],
  });

  return new Promise((resolve) => {
    addNetworkRequest
      .then(() => {
        resolve(true);
      })
      .catch(() => {
        resolve(false);
      });
  });
};

// get browser 
const browser = await dappeteer.launch({
  metaMaskVersion: "v10.31.0",
  automation: "puppeteer",
  headless: false,
});

await sleep(2000);
const pages = await browser.pages();
for (const page of pages) {
  if (page.url().startsWith("chrome-extension")) {
    await page.reload();
  }
}

// get metamask
const metamask = await dappeteer.setupMetaMask(browser, {
  seed: "<your seed>",
  showTestNets: true,
});

// code to switch network to local, or you can just skip this and use `metamask.switchNetwork("<testnet name>")`
const dappPage = await browser.newPage();
// can goto any valid website
await dappPage.goto("https://chainsafe.io", { waitUntil: "networkidle" });

const addNetworkPromise = dappPage.evaluate(addNetwork);
try {
  // this part hangs my browser, its a temp workaround to absorb the error and move on
    await metamask.acceptAddNetwork(true);
} catch (e) {
  // ignore error to prevent hanging
  for (const page of pages) {
    if (page.url().startsWith("chrome-extension")) {
      await page.reload();
    }
  }
}
const res = await addNetworkPromise;
// (end of) code to switch network to local, or you can just skip this and use metamask.switchNetwork("<testnet name>")

Hope this helps!

pipks commented 9 months ago
import dappeteer from '@chainsafe/dappeteer';
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
async function main() {
  const browser = await dappeteer.launch({
    metaMaskVersion: "v10.31.0",
    automation: "puppeteer",
    headless: false,
  });
  await sleep(5000);
  const pages = await browser.pages();
  for (const page of pages) {
    if (page.url().startsWith("chrome-extension")) {
      await page.reload();
    }
  }

  const metaMask = await dappeteer.setupMetaMask(browser, {
    seed: 'test test test test test test test test test test test test test test test test test test test test test test test test ', // 24 words
    password: 'my_password', 
    showTestNets: true,
  });
  // create a new page and visit your dapp
  const dappPage = await browser.newPage();
  await dappPage.goto("https://my-dapp.com");
    // you can change the network if you want
  await metaMask.switchNetwork('goerli');
}

main();

Damn I tried all the solutions but still couldn't connect. Metamask passes the loading screen, but then I encounter the error again.

TimeoutError: Waiting for selector.//label[contains(.,'13.')]/following-sibling::textarea|//label[contains(.,'13.')]/following-sibling:://input|//h6[contains(.,'13.')]/parent::node()/parent::node()/following-sibling::input|//h6[contains(.,'13.')]/parent::node()/parent::node()/following-sibling:://input|//span[contains(.,'13.')]/parent::node()/parent::node()/following-sibling:://input|//span[contains(.,'13.')]/following-sibling:://inputfailed: Waiting failed: 1000ms exceeded

zixiang2018 commented 9 months ago

Maybe you could try a valid website like https://chainsafe.io; i.e. replacing await dappPage.goto("https://my-dapp.com"); with await dappPage.goto("https://chainsafe.io"). I figured a valid site helped me to avoid some TimeoutErrors @pipks