Skip to content

Commit

Permalink
Merge pull request #21 from Synthetixio/refactor-commands
Browse files Browse the repository at this point in the history
refactor: commands
  • Loading branch information
drptbl authored Dec 11, 2020
2 parents c051aea + 3ae1ab3 commit 09eb16f
Show file tree
Hide file tree
Showing 5 changed files with 331 additions and 288 deletions.
191 changes: 191 additions & 0 deletions commands/metamask.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
const puppeteer = require('./puppeteer');

const { pageElements } = require('../pages/metamask/page');
const {
welcomePageElements,
firstTimeFlowPageElements,
metametricsPageElements,
firstTimeFlowFormPageElements,
revealSeedPageElements,
} = require('../pages/metamask/first-time-flow-page');
const { mainPageElements } = require('../pages/metamask/main-page');
const { unlockPageElements } = require('../pages/metamask/unlock-page');
const {
notificationPageElements,
permissionsPageElements,
confirmPageElements,
} = require('../pages/metamask/notification-page');

let walletAddress;

module.exports = {
walletAddress,
// workaround for metamask random blank page on first run
fixBlankPage: async () => {
await puppeteer.metamaskWindow.waitForTimeout(1000);
for (let times = 0; times < 5; times++) {
if (
(await puppeteer.metamaskWindow.$(welcomePageElements.app)) === null
) {
await puppeteer.metamaskWindow.reload();
await puppeteer.metamaskWindow.waitForTimeout(2000);
} else {
break;
}
}
},
confirmWelcomePage: async () => {
await this.fixBlankPage();
await puppeteer.waitAndClick(welcomePageElements.confirmButton);
return true;
},
unlock: async password => {
await this.fixBlankPage();
await puppeteer.waitAndType(unlockPageElements.passwordInput, password);
await puppeteer.waitAndClick(unlockPageElements.unlockButton);
return true;
},
importWallet: async (secretWords, password) => {
await puppeteer.waitAndClick(firstTimeFlowPageElements.importWalletButton);
await puppeteer.waitAndClick(metametricsPageElements.optOutAnalyticsButton);
await puppeteer.waitAndType(
firstTimeFlowFormPageElements.secretWordsInput,
secretWords,
);
await puppeteer.waitAndType(
firstTimeFlowFormPageElements.passwordInput,
password,
);
await puppeteer.waitAndType(
firstTimeFlowFormPageElements.confirmPasswordInput,
password,
);
await puppeteer.waitAndClick(firstTimeFlowFormPageElements.termsCheckbox);
await puppeteer.waitAndClick(firstTimeFlowFormPageElements.importButton);

// metamask hangs, reload as workaround
// await puppeteer.waitAndClick(endOfFlowPageElements.allDoneButton);
await puppeteer.waitFor(pageElements.loadingSpinner);
await puppeteer.metamaskWindow.reload();
await puppeteer.waitAndClick(revealSeedPageElements.remindLaterButton);
await puppeteer.waitFor(mainPageElements.walletOverview);

// close popup if present
if (
(await puppeteer.metamaskWindow.$(mainPageElements.popup.container)) !==
null
) {
await puppeteer.waitAndClick(mainPageElements.popup.closeButton);
}
return true;
},
changeNetwork: async network => {
await puppeteer.waitAndClick(mainPageElements.networkSwitcher.button);
if (network === 'main') {
await puppeteer.waitAndClick(
mainPageElements.networkSwitcher.networkButton(0),
);
} else if (network === 'ropsten') {
await puppeteer.waitAndClick(
mainPageElements.networkSwitcher.networkButton(1),
);
} else if (network === 'kovan') {
await puppeteer.waitAndClick(
mainPageElements.networkSwitcher.networkButton(2),
);
} else if (network === 'rinkeby') {
await puppeteer.waitAndClick(
mainPageElements.networkSwitcher.networkButton(3),
);
} else if (network === 'goerli') {
await puppeteer.waitAndClick(
mainPageElements.networkSwitcher.networkButton(4),
);
} else if (network === 'localhost') {
await puppeteer.waitAndClick(
mainPageElements.networkSwitcher.networkButton(5),
);
}
await puppeteer.waitForText(
mainPageElements.networkSwitcher.networkName,
network,
);
return true;
},
acceptAccess: async () => {
await puppeteer.metamaskWindow.waitForTimeout(3000);
const notificationPage = await puppeteer.switchToMetamaskNotification();
await puppeteer.waitAndClick(
notificationPageElements.nextButton,
notificationPage,
);
await puppeteer.waitAndClick(
permissionsPageElements.connectButton,
notificationPage,
);
await puppeteer.metamaskWindow.waitForTimeout(3000);
return true;
},
confirmTransaction: async () => {
await puppeteer.metamaskWindow.waitForTimeout(3000);
const notificationPage = await puppeteer.switchToMetamaskNotification();
const currentGasFee = await puppeteer.waitAndGetValue(
confirmPageElements.gasFeeInput,
notificationPage,
);
const newGasFee = (Number(currentGasFee) + 10).toString();
await puppeteer.waitAndSetValue(
newGasFee,
confirmPageElements.gasFeeInput,
notificationPage,
);
await puppeteer.waitAndClick(
confirmPageElements.confirmButton,
notificationPage,
);
await puppeteer.metamaskWindow.waitForTimeout(3000);
return true;
},
rejectTransaction: async () => {
await puppeteer.metamaskWindow.waitForTimeout(3000);
const notificationPage = await puppeteer.switchToMetamaskNotification();
await puppeteer.waitAndClick(
confirmPageElements.rejectButton,
notificationPage,
);
await puppeteer.metamaskWindow.waitForTimeout(3000);
return true;
},
getWalletAddress: async () => {
await puppeteer.waitAndClick(mainPageElements.options.button);
await puppeteer.waitAndClick(mainPageElements.options.accountDetailsButton);
walletAddress = await puppeteer.waitAndGetValue(
mainPageElements.accountModal.walletAddressInput,
);
await puppeteer.waitAndClick(mainPageElements.accountModal.closeButton);
return walletAddress;
},
initialSetup: async ({ secretWords, network, password }) => {
if (secretWords === undefined && process.env.SECRET_WORDS) {
secretWords = process.env.SECRET_WORDS;
}
await puppeteer.init();
await puppeteer.assignWindows();
await puppeteer.metamaskWindow.waitForTimeout(1000);
if (
(await puppeteer.metamaskWindow.$(unlockPageElements.unlockPage)) === null
) {
await this.confirmWelcomePage();
await this.importWallet(secretWords, password);
await this.changeNetwork(network);
walletAddress = await this.getWalletAddress();
await puppeteer.switchToCypressWindow();
return true;
} else {
await this.unlock(password);
walletAddress = await this.getWalletAddress();
await puppeteer.switchToCypressWindow();
return true;
}
},
};
106 changes: 106 additions & 0 deletions commands/puppeteer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
const puppeteer = require('puppeteer-core');
const fetch = require('node-fetch');

let puppeteerBrowser;
let mainWindow;
let metamaskWindow;

module.exports = {
puppeteerBrowser,
mainWindow,
metamaskWindow,
init: async () => {
const debuggerDetails = await fetch('http://localhost:9222/json/version');
const debuggerDetailsConfig = await debuggerDetails.json();
const webSocketDebuggerUrl = debuggerDetailsConfig.webSocketDebuggerUrl;

puppeteerBrowser = await puppeteer.connect({
browserWSEndpoint: webSocketDebuggerUrl,
ignoreHTTPSErrors: true,
// eslint-disable-next-line unicorn/no-null
defaultViewport: null,
});
return puppeteerBrowser.isConnected();
},
assignWindows: async () => {
let pages = await puppeteerBrowser.pages();
for (const page of pages) {
if (page.url().includes('integration')) {
mainWindow = page;
} else if (page.url().includes('extension')) {
metamaskWindow = page;
}
}
return true;
},
getBrowser: async () => {
return {
puppeteerBrowser,
};
},
getWindows: async () => {
return {
mainWindow,
metamaskWindow,
};
},
switchToCypressWindow: async () => {
await mainWindow.bringToFront();
return true;
},
switchToMetamaskWindow: async () => {
await metamaskWindow.bringToFront();
return true;
},
switchToMetamaskNotification: async () => {
let pages = await puppeteerBrowser.pages();
for (const page of pages) {
if (page.url().includes('notification')) {
await page.bringToFront();
return page;
}
}
},
waitFor: async (selector, page = metamaskWindow) => {
await page.waitForFunction(
`document.querySelector('${selector}') && document.querySelector('${selector}').clientHeight != 0`,
{ visible: true },
);
// puppeteer going too fast breaks metamask in corner cases
await page.waitForTimeout(300);
},
waitAndClick: async (selector, page = metamaskWindow) => {
await this.waitFor(selector, page);
await page.evaluate(
selector => document.querySelector(selector).click(),
selector,
);
},
waitAndType: async (selector, value, page = metamaskWindow) => {
await this.waitFor(selector, page);
const element = await page.$(selector);
await element.type(value);
},
waitAndGetValue: async (selector, page = metamaskWindow) => {
await this.waitFor(selector, page);
const element = await page.$(selector);
const property = await element.getProperty('value');
const value = await property.jsonValue();
return value;
},
waitAndSetValue: async (text, selector, page = metamaskWindow) => {
await this.waitFor(selector, page);
await page.evaluate(
selector => (document.querySelector(selector).value = ''),
selector,
);
await page.focus(selector);
await page.keyboard.type(text);
},
waitForText: async (selector, text, page = metamaskWindow) => {
await this.waitFor(selector, page);
await page.waitForFunction(
`document.querySelector('${selector}').innerText.toLowerCase().includes('${text}')`,
);
},
};
1 change: 1 addition & 0 deletions commands/synthetix.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = {};
13 changes: 13 additions & 0 deletions helpers.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const axios = require('axios');
const fs = require('fs');
const unzip = require('unzipper');
const path = require('path');

module.exports = {
getSynpressPath: () => {
Expand Down Expand Up @@ -34,4 +35,16 @@ module.exports = {
stream.pipe(unzip.Extract({ path: destination }).on('close', resolve)),
);
},
prepareMetamask: async () => {
const release = await this.getMetamaskReleases();
const downloadsDirectory = path.resolve(__dirname, 'downloads');
if (!fs.existsSync(downloadsDirectory)) {
fs.mkdirSync(downloadsDirectory);
}
const downloadDestination = path.join(downloadsDirectory, release.filename);
await this.download(release.downloadUrl, downloadDestination);
const metamaskDirectory = path.join(downloadsDirectory, 'metamask');
await this.extract(downloadDestination, metamaskDirectory);
return metamaskDirectory;
},
};
Loading

0 comments on commit 09eb16f

Please sign in to comment.