Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

feat!: update recommended metamask version #151

Merged
merged 15 commits into from
Oct 4, 2022
2 changes: 1 addition & 1 deletion src/helpers/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const clickOnSettingsSwitch = async (page: Page, text: string): Promise<v
export const openNetworkDropdown = async (page: Page): Promise<void> => {
const networkSwitcher = await page.waitForSelector('.network-display');
await networkSwitcher.click();
await page.waitForSelector('li.dropdown-menu-item');
await page.waitForSelector('.network-dropdown-list');
};

export const openProfileDropdown = async (page: Page): Promise<void> => {
Expand Down
10 changes: 10 additions & 0 deletions src/helpers/screenshot.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { writeFileSync } from 'fs';
import path from 'path';

import { Page } from 'puppeteer';

export const screenshot = async (page: Page, name: string): Promise<void> =>
writeFileSync(
path.resolve(__dirname, '../../', name + '.png'),
await page.screenshot({ encoding: 'binary', fullPage: true }),
);
2 changes: 1 addition & 1 deletion src/helpers/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,4 @@ export const getErrorMessage = async (page: Page): Promise<string | false> => {
};

export const getAccountMenuButton = (page: Page): Promise<ElementHandle | null> =>
page.waitForXPath(`//button[contains(@title,'Account Options')]`);
page.waitForXPath(`//button[contains(@title,'Account options')]`);
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ export * from './setup';
export { DappateerJestConfig } from './jest/global';

// default constants
export const RECOMMENDED_METAMASK_VERSION = 'v10.15.0';
export const RECOMMENDED_METAMASK_VERSION = 'v10.19.0';
9 changes: 6 additions & 3 deletions src/metamask/addNetwork.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,18 @@ export const addNetwork = (page: Page, version?: string) => async ({
}: AddNetwork): Promise<void> => {
await page.bringToFront();
await openNetworkDropdown(page);
await clickOnButton(page, 'Add Network');
await clickOnButton(page, 'Add network');

const responsePromise = page.waitForResponse(
(response) => new URL(response.url()).pathname === new URL(rpc).pathname,
);

await typeOnInputField(page, 'Network Name', networkName);
await page.waitForTimeout(500);

await typeOnInputField(page, 'Network name', networkName);
await typeOnInputField(page, 'New RPC URL', rpc);
await typeOnInputField(page, 'Chain ID', String(chainId));
await typeOnInputField(page, 'Currency Symbol', symbol);
await typeOnInputField(page, 'Currency symbol', symbol);

await responsePromise;
await page.waitForTimeout(500);
Expand All @@ -32,4 +34,5 @@ export const addNetwork = (page: Page, version?: string) => async ({
await clickOnButton(page, 'Save');

await page.waitForXPath(`//*[text() = '${networkName}']`);
await clickOnButton(page, 'Got it');
};
15 changes: 8 additions & 7 deletions src/metamask/addToken.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Page } from 'puppeteer';

import { clickOnButton, clickOnElement, getInputByLabel, typeOnInputField } from '../helpers';
import { clickOnButton, clickOnElement, clickOnLogo, getInputByLabel, typeOnInputField } from '../helpers';
import { AddToken } from '../index';

// eslint-disable-next-line @typescript-eslint/no-unused-vars
Expand All @@ -13,22 +13,23 @@ export const addToken = (page: Page, version?: string) => async ({
await clickOnButton(page, 'Assets');
await page.waitForSelector('.asset-list-item__token-button');
await clickOnElement(page, 'Import tokens');
await typeOnInputField(page, 'Token Contract Address', tokenAddress);
await typeOnInputField(page, 'Token contract address', tokenAddress);

// wait to metamask pull token data
// TODO: handle case when contract is not containing symbol
const symbolInput = await getInputByLabel(page, 'Token Symbol');
const symbolInput = await getInputByLabel(page, 'Token symbol');
await page.waitForFunction((node) => !!node.value, {}, symbolInput);

if (symbol) {
await clickOnElement(page, 'Edit');
await typeOnInputField(page, 'Token Symbol', symbol, true);
await typeOnInputField(page, 'Token symbol', symbol, true);
}

const decimalsInput = await getInputByLabel(page, 'Token Decimal');
const decimalsInput = await getInputByLabel(page, 'Token decimal');
const isDisabled = await page.evaluate((node) => node.disabled, decimalsInput);
if (!isDisabled) await decimalsInput.type(String(decimals));

await clickOnButton(page, 'Add Custom Token');
await clickOnButton(page, 'Import Tokens');
await clickOnButton(page, 'Add custom token');
await clickOnButton(page, 'Import tokens');
await clickOnLogo(page);
};
2 changes: 1 addition & 1 deletion src/metamask/importPk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const importPk = (page: Page, version?: string) => async (privateKey: str
await page.bringToFront();
await openProfileDropdown(page);

await clickOnElement(page, 'Import Account');
await clickOnElement(page, 'Import account');
await typeOnInputField(page, 'your private key', privateKey);
await clickOnButton(page, 'Import');

Expand Down
7 changes: 3 additions & 4 deletions src/metamask/switchNetwork.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const switchNetwork = (page: Page, version?: string) => async (network =
await openNetworkDropdown(page);

const networkIndex = await page.evaluate((network) => {
const elements = document.querySelectorAll('li.dropdown-menu-item');
const elements = document.querySelectorAll('.network-name-item');
for (let i = 0; i < elements.length; i++) {
const element = elements[i];
if ((element as HTMLLIElement).innerText.toLowerCase().includes(network.toLowerCase())) {
Expand All @@ -20,12 +20,11 @@ export const switchNetwork = (page: Page, version?: string) => async (network =
}, network);

const networkFullName = await page.evaluate((index) => {
const elements = document.querySelectorAll(`li.dropdown-menu-item > span`);
const elements = document.querySelectorAll(`.network-name-item`);
return (elements[index] as HTMLLIElement).innerText;
}, networkIndex);

const networkButton = (await page.$$('li.dropdown-menu-item'))[networkIndex];
const networkButton = (await page.$$('.network-name-item'))[networkIndex];
await networkButton.click();
await page.reload();
await page.waitForXPath(`//*[text() = '${networkFullName}']`);
};
1 change: 1 addition & 0 deletions src/setup/launch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export async function launch(puppeteerLib: typeof puppeteer, options: LaunchOpti

return puppeteerLib.launch({
headless: false,
slowMo: 10,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there any reason for using slowMo?

args: [`--disable-extensions-except=${METAMASK_PATH}`, `--load-extension=${METAMASK_PATH}`, ...(args || [])],
...rest,
});
Expand Down
23 changes: 20 additions & 3 deletions src/setup/setupActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ export async function showTestNets(metaMaskPage: Page): Promise<void> {
}

export async function confirmWelcomeScreen(metaMaskPage: Page): Promise<void> {
await clickOnButton(metaMaskPage, 'Get Started');
await clickOnButton(metaMaskPage, 'Get started');
}

export async function declineAnalytics(metaMaskPage: Page): Promise<void> {
await clickOnButton(metaMaskPage, 'No thanks');
}

export async function importAccount(
Expand All @@ -30,7 +34,6 @@ export async function importAccount(
}: MetaMaskOptions,
): Promise<void> {
await clickOnButton(metaMaskPage, 'Import wallet');
await clickOnButton(metaMaskPage, 'I Agree');

for (const [index, seedPart] of seed.split(' ').entries())
await typeOnInputField(metaMaskPage, `${index + 1}.`, seedPart);
Expand All @@ -43,7 +46,7 @@ export async function importAccount(
await acceptTerms.click();

await clickOnButton(metaMaskPage, 'Import');
await clickOnButton(metaMaskPage, 'All Done');
await clickOnButton(metaMaskPage, 'All done');
}

export const closePopup = async (page: Page): Promise<void> => {
Expand All @@ -52,3 +55,17 @@ export const closePopup = async (page: Page): Promise<void> => {
await new Promise((resolve) => setTimeout(resolve, 1000));
await page.$eval('.popover-header__button', (node: HTMLElement) => node.click());
};

export const closePortfolioTooltip = async (page: Page): Promise<void> => {
const closeButton = await page.waitForSelector(`div.home__subheader-link--tooltip-content-header > button`, {
timeout: 20000,
});
await closeButton.click();
await page.waitForTimeout(333);
};

export const closeWhatsNewModal = async (page: Page): Promise<void> => {
await page.reload();
await clickOnLogo(page);
await page.waitForTimeout(333);
};
29 changes: 25 additions & 4 deletions src/setup/setupMetaMask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,35 @@ import { Browser, BrowserContext, Page } from 'puppeteer';
import { getMetaMask } from '../metamask';
import { Dappeteer, MetaMaskOptions } from '../types';

import { closePopup, confirmWelcomeScreen, importAccount, showTestNets } from './setupActions';
import {
closePortfolioTooltip,
closeWhatsNewModal,
confirmWelcomeScreen,
declineAnalytics,
importAccount,
showTestNets,
} from './setupActions';

/**
* Setup MetaMask with base account
* */
type Step<Options> = (page: Page, options?: Options) => void;
const defaultMetaMaskSteps: Step<MetaMaskOptions>[] = [confirmWelcomeScreen, importAccount, closePopup, showTestNets];
const defaultMetaMaskSteps: Step<MetaMaskOptions>[] = [
confirmWelcomeScreen,
declineAnalytics,
importAccount,
showTestNets,
closePortfolioTooltip,
closeWhatsNewModal,
closeWhatsNewModal,
];

export async function setupMetaMask<Options = MetaMaskOptions>(
browser: Browser | BrowserContext,
options?: Options,
steps: Step<Options>[] = defaultMetaMaskSteps,
): Promise<Dappeteer> {
const page = await closeHomeScreen(browser);
const page = await getMetamaskPage(browser);
page.setViewport({ height: 1200, width: 800 });
// goes through the installation steps required by MetaMask
for (const step of steps) {
Expand All @@ -26,7 +41,13 @@ export async function setupMetaMask<Options = MetaMaskOptions>(
return getMetaMask(page);
}

async function closeHomeScreen(browser: Browser | BrowserContext): Promise<Page> {
async function getMetamaskPage(browser: Browser | BrowserContext): Promise<Page> {
const pages = await browser.pages();
for (const page of pages) {
if (page.url().match('chrome-extension://[a-z]+/home.html')) {
return page;
}
}
return new Promise((resolve, reject) => {
browser.on('targetcreated', async (target) => {
if (target.url().match('chrome-extension://[a-z]+/home.html')) {
Expand Down
15 changes: 1 addition & 14 deletions test/basic.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import chaiAsPromised from 'chai-as-promised';
import { Page } from 'puppeteer';

import * as dappeteer from '../src';
import { clickOnLogo, openProfileDropdown } from '../src/helpers';
import { openProfileDropdown } from '../src/helpers';

import { PASSWORD, TestContext } from './global';
import { clickElement } from './utils/utils';
Expand Down Expand Up @@ -83,19 +83,6 @@ describe('basic interactions', async function () {
await metamask.switchNetwork('local');
});

it('should fail to add network with wrong chain ID', async () => {
await expect(
metamask.addNetwork({
networkName: 'Optimistic Ethereum Testnet Kovan',
rpc: 'https://kovan.optimism.io/',
chainId: 420,
symbol: 'KUR',
}),
).to.be.rejectedWith(SyntaxError);

await clickOnLogo(metamask.page);
});

it('should import private key', async () => {
const countAccounts = async (): Promise<number> => {
await openProfileDropdown(metamask.page);
Expand Down