Skip to content

Commit

Permalink
change dappeteer version and apply patch
Browse files Browse the repository at this point in the history
  • Loading branch information
moussaDoumbia9219 committed Jun 14, 2022
1 parent cd8160d commit f9b3528
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 98 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import puppeteer from 'puppeteer';
import dappeteer from '@chainsafe/dappeteer';

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

// you can change the network if you want
Expand Down
9 changes: 1 addition & 8 deletions docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ For additional information read root [readme](../README.md)
- [unlock](#unlock)
- [switchNetwork](#switchNetwork)
- [addNetwork](#addNetwork)
- [addToken](#addToken)
- [confirmTransaction](#confirmTransaction)
- [sign](#sign)
- [approve](#approve)
Expand All @@ -39,8 +38,6 @@ returns an instance of `browser`, same as `puppeteer.launch`, but it also instal
interface MetamaskOptions {
seed?: string;
password?: string;
showTestNets?: boolean;
hideSeed?: boolean;
}
```

Expand Down Expand Up @@ -85,10 +82,6 @@ interface AddNetwork {
```
it adds a custom network to MetaMask.

<a name="addToken"></a>
## `metamask.addToken(tokenAddress: string): Promise<void>`
it adds a custom token to MetaMask.

<a name="confirmTransaction"></a>
## `metamask.confirmTransaction(options?: TransactionOptions): Promise<void>`
```typescript
Expand All @@ -110,4 +103,4 @@ enables the app to connect to MetaMask account in privacy mode

<a name="page"></a>
## `metamask.page` is Metamask plugin `Page`
**for advanced usages** in case you need custom features.
**for advanced usages** in case you need custom features.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@chainsafe/dappeteer",
"version": "2.4.1",
"version": "2.3.0",
"description": "E2E testing for dApps using Puppeteer + MetaMask",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
Expand Down
66 changes: 11 additions & 55 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,13 @@ import { isNewerVersion } from './utils';
export { getMetamask };

export type LaunchOptions = Parameters<typeof puppeteer['launch']>[0] & {
metamaskVersion: 'v10.8.1' | 'latest' | string;
metamaskVersion: 'v10.1.1' | 'latest' | string;
metamaskLocation?: Path;
};

export type MetamaskOptions = {
seed?: string;
password?: string;
showTestNets?: boolean;
hideSeed?: boolean;
};

export type AddNetwork = {
Expand Down Expand Up @@ -48,7 +46,7 @@ export type TransactionOptions = {
gasLimit?: number;
};

export const RECOMMENDED_METAMASK_VERSION = 'v10.8.1';
export const RECOMMENDED_METAMASK_VERSION = 'v10.1.1';

/**
* Launch Puppeteer chromium instance with MetaMask plugin installed
Expand All @@ -60,6 +58,7 @@ export async function launch(puppeteerLib: typeof puppeteer, options: LaunchOpti
);

const { args, metamaskVersion, metamaskLocation, ...rest } = options;
const idx = 1;

/* eslint-disable no-console */
console.log(); // new line
Expand All @@ -86,7 +85,7 @@ export async function launch(puppeteerLib: typeof puppeteer, options: LaunchOpti
/* eslint-enable no-console */

// eslint-disable-next-line @typescript-eslint/naming-convention
const METAMASK_PATH = await downloader(metamaskVersion, metamaskLocation);
const METAMASK_PATH = await downloader(metamaskVersion, metamaskLocation, idx);

return puppeteerLib.launch({
headless: false,
Expand All @@ -98,33 +97,18 @@ export async function launch(puppeteerLib: typeof puppeteer, options: LaunchOpti
/**
* Setup MetaMask with base account
* */
const defaultMetamaskOptions: MetamaskOptions = {
showTestNets: true,
};

export async function setupMetamask(
browser: puppeteer.Browser,
options: MetamaskOptions = defaultMetamaskOptions,
): Promise<Dappeteer> {
// set default values of not provided values (but required)
for (const key of Object.keys(defaultMetamaskOptions)) {
if (options[key] === undefined) options[key] = defaultMetamaskOptions[key];
}

export async function setupMetamask(browser: puppeteer.Browser, options: MetamaskOptions = {}): Promise<Dappeteer> {
const page = await closeHomeScreen(browser);
await confirmWelcomeScreen(page);

await importAccount(
page,
options.seed || 'already turtle birth enroll since owner keep patch skirt drift any dinner',
options.password || 'password1234',
options.hideSeed,
);

await closeNotificationPage(browser);

await showTestNets(page);

return getMetamask(page);
}

Expand Down Expand Up @@ -171,51 +155,23 @@ async function closeNotificationPage(browser: puppeteer.Browser): Promise<void>
});
}

async function showTestNets(metamaskPage: puppeteer.Page): Promise<void> {
const networkSwitcher = await metamaskPage.waitForSelector('.network-display');
await networkSwitcher.click();
await metamaskPage.waitForSelector('li.dropdown-menu-item');

const showHideButton = await metamaskPage.waitForSelector('.network-dropdown-content--link');
await showHideButton.click();

const option = await metamaskPage.waitForSelector(
'.settings-page__body > div:nth-child(7) > div:nth-child(2) > div > div > div:nth-child(1)',
);
await option.click();

const header = await metamaskPage.waitForSelector('.app-header__logo-container');
await header.click();
}

async function confirmWelcomeScreen(metamaskPage: puppeteer.Page): Promise<void> {
const continueButton = await metamaskPage.waitForSelector('.welcome-page button');
await continueButton.click();
}

async function importAccount(
metamaskPage: puppeteer.Page,
seed: string,
password: string,
hideSeed: boolean,
): Promise<void> {
async function importAccount(metamaskPage: puppeteer.Page, seed: string, password: string): Promise<void> {
const importLink = await metamaskPage.waitForSelector('.first-time-flow button');
await importLink.click();

const metricsOptOut = await metamaskPage.waitForSelector('.metametrics-opt-in button.btn-primary');
await metricsOptOut.click();

if (hideSeed) {
const seedPhraseInput = await metamaskPage.waitForSelector('.first-time-flow__seedphrase input[type=password]');
await seedPhraseInput.click();
await seedPhraseInput.type(seed);
} else {
const showSeedPhraseInput = await metamaskPage.waitForSelector('#ftf-chk1-label');
await showSeedPhraseInput.click();

const seedPhraseInput = await metamaskPage.waitForSelector('.first-time-flow textarea');
await seedPhraseInput.type(seed);
}
const showSeedPhraseInput = await metamaskPage.waitForSelector('#ftf-chk1-label');
await showSeedPhraseInput.click();

const seedPhraseInput = await metamaskPage.waitForSelector('.first-time-flow textarea');
await seedPhraseInput.type(seed);

const passwordInput = await metamaskPage.waitForSelector('#password');
await passwordInput.type(password);
Expand Down
42 changes: 22 additions & 20 deletions src/metamask/addNetwork.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,41 +14,43 @@ export const addNetwork = (page: Page, version?: string) => async ({
const networkSwitcher = await page.waitForSelector('.network-display');
await networkSwitcher.click();
await page.waitForSelector('li.dropdown-menu-item');

const networkButton = await page.waitForSelector('.menu-droppo > button');
const networkIndex = await page.evaluate((network) => {
const elements = document.querySelectorAll('li.dropdown-menu-item');
for (let i = 0; i < elements.length; i++) {
const element = elements[i];
if ((element as HTMLLIElement).innerText.toLowerCase().includes(network.toLowerCase())) {
return i;
}
}
return elements.length - 1;
}, 'Custom RPC');
const networkButton = (await page.$$('li.dropdown-menu-item'))[networkIndex];
await networkButton.click();

const networkNameInput = await page.waitForSelector(
'.networks-tab__add-network-form-body > div:nth-child(1) > label > input',
);
const networkNameInput = await page.waitForSelector('input#network-name');
await networkNameInput.type(networkName);

const rpcInput = await page.waitForSelector(
'.networks-tab__add-network-form-body > div:nth-child(2) > label > input',
);
const rpcInput = await page.waitForSelector('input#rpc-url');
await rpcInput.type(rpc);

const chainIdInput = await page.waitForSelector(
'.networks-tab__add-network-form-body > div:nth-child(3) > label > input',
);
const chainIdInput = await page.waitForSelector('input#chainId');
await chainIdInput.type(String(chainId));

if (symbol) {
const symbolInput = await page.waitForSelector(
'.networks-tab__add-network-form-body > div:nth-child(4) > label > input',
);
const symbolInput = await page.waitForSelector('input#network-ticker');
await symbolInput.type(symbol);
}
if (explorer) {
const explorerInput = await page.waitForSelector(
'.networks-tab__add-network-form-body > div:nth-child(5) > label > input',
);
const explorerInput = await page.waitForSelector('input#block-explorer-url');
await explorerInput.type(explorer);
}

const saveButton = await page.waitForSelector(
'.networks-tab__add-network-form-footer > button.button.btn--rounded.btn-primary',
);
const saveButton = await page.waitForSelector('.network-form__footer > button.button.btn-secondary');
await saveButton.click();

await page.waitForSelector('button.button.btn-danger');
const logo = await page.waitForSelector('.app-header__logo-container.app-header__logo-container--clickable');
await logo.click();

await page.waitForXPath(`//*[text() = '${networkName}']`);
};
6 changes: 2 additions & 4 deletions src/metamask/addToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@ import { Page } from 'puppeteer';
export const addToken = (page: Page) => async (tokenAddress: string): Promise<void> => {
await page.bringToFront();

const addTokenButton = await page.waitForSelector(
'.box.import-token-link.box--flex-direction-row.box--text-align-center > a',
);
const addTokenButton = await page.waitForSelector('.add-token-button > button');
await addTokenButton.click();

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

await page.waitForTimeout(4000);

Expand Down
2 changes: 1 addition & 1 deletion src/metamask/importPk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ export const importPk = (page: Page, version?: string) => async (privateKey: str
await addAccount.click();
const pKInput = await page.waitForSelector('input#private-key-box');
await pKInput.type(privateKey);
const importButton = await page.waitForSelector('button.btn-primary');
const importButton = await page.waitForSelector('button.btn-secondary');
await importButton.click();
};
33 changes: 25 additions & 8 deletions src/metamaskDownloader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ const defaultDirectory = path.resolve(__dirname, '..', 'metamask');
export type Path =
| string
| {
download: string;
extract: string;
};
download: string;
extract: string;
};

export default async (version: string, location?: Path): Promise<string> => {
export default async (version: string, location?: Path, idx?: number): Promise<string> => {
const metamaskDirectory = typeof location === 'string' ? location : location?.extract || defaultDirectory;
const downloadDirectory =
typeof location === 'string' ? location : location?.download || path.resolve(defaultDirectory, 'download');
Expand All @@ -23,7 +23,7 @@ export default async (version: string, location?: Path): Promise<string> => {
const extractDestination = path.resolve(metamaskDirectory, version.replace(/\./g, '_'));
if (fs.existsSync(extractDestination)) return extractDestination;
}
const { filename, downloadUrl, tag } = await getMetamaskReleases(version);
const { filename, downloadUrl, tag } = await getMetamaskReleases(version, idx);
const extractDestination = path.resolve(metamaskDirectory, tag.replace(/\./g, '_'));
if (!fs.existsSync(extractDestination)) {
const downloadedFile = await downloadMetamaskReleases(filename, downloadUrl, downloadDirectory);
Expand Down Expand Up @@ -73,15 +73,15 @@ const downloadMetamaskReleases = (name: string, url: string, location: string):

type MetamaskReleases = { downloadUrl: string; filename: string; tag: string };
const metamaskReleasesUrl = 'https://api.github.com/repos/metamask/metamask-extension/releases';
const getMetamaskReleases = (version: string): Promise<MetamaskReleases> =>
const getMetamaskReleases = (version: string, idx: number): Promise<MetamaskReleases> =>
new Promise((resolve, reject) => {
// eslint-disable-next-line @typescript-eslint/naming-convention
const request = get(metamaskReleasesUrl, { headers: { 'User-Agent': 'Mozilla/5.0' } }, (response) => {
let body = '';
response.on('data', (chunk) => {
body += chunk;
});
response.on('end', () => {
response.on('end', async () => {
const data = JSON.parse(body);
if (data.message) return reject(data.message);
for (const result of data) {
Expand All @@ -97,7 +97,24 @@ const getMetamaskReleases = (version: string): Promise<MetamaskReleases> =>
}
}
}
reject(`Version ${version} not found!`);
if (data.length === 0) {
reject(`Version ${version} not found!`);
} else {

try {
idx++;
const { filename, downloadUrl, tag } = await getMetamaskReleases(version, idx);
resolve({
downloadUrl: downloadUrl,
filename: filename,
tag: tag,
});
} catch (error) {
console.warn('getMetamaskReleases error:', error);
throw error;
}

}
});
});
request.on('error', (error) => {
Expand Down

0 comments on commit f9b3528

Please sign in to comment.