Skip to content

Commit

Permalink
merge
Browse files Browse the repository at this point in the history
  • Loading branch information
duckception committed Sep 11, 2023
2 parents da9df17 + b6637c1 commit f29a5a2
Show file tree
Hide file tree
Showing 11 changed files with 420 additions and 36 deletions.
197 changes: 186 additions & 11 deletions commands/metamask.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const log = require('debug')('synpress:metamask');
const playwright = require('./playwright');
const sleep = require('util').promisify(setTimeout);

const {
onboardingWelcomePageElements,
Expand Down Expand Up @@ -380,7 +381,9 @@ const metamask = {
mainPageElements.createAccount.createAccountError,
);
const formErrorTxt = await formErrorEl.innerText();
const accountExists = 'This account name already exists' === formErrorTxt;
const accountExists =
'This account name already exists' === formErrorTxt ||
'This account name is reserved' === formErrorTxt;

if (accountExists) {
log(`[createAccount] ${formErrorTxt}`);
Expand All @@ -397,6 +400,40 @@ const metamask = {
await switchToCypressIfNotActive();
return accountExists ? formErrorTxt : true;
},
async renameAccount(newAccountName) {
await switchToMetamaskIfNotActive();

await playwright.waitAndClick(mainPageElements.optionsMenu.button);
await playwright.waitAndClick(
mainPageElements.optionsMenu.accountDetailsButton,
);

await playwright.waitAndClick(mainPageElements.renameAccount.invokeInput);
await playwright.waitClearAndType(
newAccountName,
mainPageElements.renameAccount.input,
);

const formErrorEl = await playwright.waitFor(
mainPageElements.renameAccount.error,
);
const formErrorTxt = await formErrorEl.innerText();
const accountExists =
'This account name already exists' === formErrorTxt ||
'This account name is reserved' === formErrorTxt;

if (accountExists) {
log(`[createAccount] ${formErrorTxt}`);
} else {
await playwright.waitAndClick(
mainPageElements.renameAccount.confirmButton,
);
}

await playwright.waitAndClick(mainPageElements.accountModal.closeButton);
await switchToCypressIfNotActive();
return accountExists ? formErrorTxt : true;
},
async switchAccount(accountNameOrAccountNumber) {
if (typeof accountNameOrAccountNumber === 'string') {
accountNameOrAccountNumber = accountNameOrAccountNumber.toLowerCase();
Expand Down Expand Up @@ -1052,18 +1089,34 @@ const metamask = {
.count()) > 0
) {
log('[confirmTransaction] Getting recipient address..');
await playwright.waitAndClick(
confirmPageElements.recipientButton,
notificationPage,
);
txData.recipientPublicAddress = await playwright.waitAndGetValue(
recipientPopupElements.recipientPublicAddress,
notificationPage,
);
await playwright.waitAndClick(
recipientPopupElements.popupCloseButton,

const tooltip = await playwright.waitAndGetAttributeValue(
confirmPageElements.recipientAddressTooltipContainerButton,
'aria-describedby',
notificationPage,
true,
);

// Handles the case where the recipient address is saved and has a "nickname".
if (tooltip === 'tippy-tooltip-2') {
txData.recipientPublicAddress = await playwright.waitAndGetValue(
confirmPageElements.recipientButton,
notificationPage,
);
} else {
await playwright.waitAndClick(
confirmPageElements.recipientButton,
notificationPage,
);
txData.recipientPublicAddress = await playwright.waitAndGetValue(
recipientPopupElements.recipientPublicAddress,
notificationPage,
);
await playwright.waitAndClick(
recipientPopupElements.popupCloseButton,
notificationPage,
);
}
}
log('[confirmTransaction] Checking if network name is present..');
if (
Expand Down Expand Up @@ -1128,6 +1181,70 @@ const metamask = {
log('[confirmTransaction] Transaction confirmed!');
return txData;
},
async confirmTransactionAndWaitForMining(gasConfig) {
// Before we switch to MetaMask tab we have to make sure the notification window has opened.
//
// Chaining `confirmTransactionAndWaitForMining` results in quick tabs switching
// which breaks MetaMask and the notification window does not open
// until we switch back to the "Cypress" tab.
await playwright.switchToMetamaskNotification();

await switchToMetamaskIfNotActive();
await playwright
.metamaskWindow()
.locator(mainPageElements.tabs.activityButton)
.click();

let retries = 0;
const retiresLimit = 600;

// 120 seconds
while (retries < retiresLimit) {
const unapprovedTxs = await playwright
.metamaskWindow()
.getByText('Unapproved')
.count();
if (unapprovedTxs === 1) {
break;
}
await sleep(200);
retries++;
}

if (retries === retiresLimit) {
throw new Error(
'New unapproved transaction was not detected in 120 seconds.',
);
}

const txData = await module.exports.confirmTransaction(gasConfig);

// 120 seconds
while (retries < retiresLimit) {
const pendingTxs = await playwright
.metamaskWindow()
.getByText('Pending')
.count();
const queuedTxs = await playwright
.metamaskWindow()
.getByText('Queued')
.count();
if (pendingTxs === 0 && queuedTxs === 0) {
break;
}
await sleep(200);
retries++;
}

if (retries === retiresLimit) {
throw new Error('Transaction was not mined in 120 seconds.');
}

await switchToCypressIfNotActive();

log('[confirmTransactionAndWaitForMining] Transaction confirmed!');
return txData;
},
async rejectTransaction() {
const notificationPage = await playwright.switchToMetamaskNotification();
await playwright.waitAndClick(
Expand All @@ -1137,6 +1254,64 @@ const metamask = {
);
return true;
},
async openTransactionDetails(txIndex) {
await switchToMetamaskIfNotActive();
await playwright
.metamaskWindow()
.locator(mainPageElements.tabs.activityButton)
.click();

let visibleTxs = await playwright
.metamaskWindow()
.locator(
`${mainPageElements.activityTab.completedTransactionsList} > div`,
)
.filter({
has: playwright.metamaskWindow().locator('div.list-item__heading'),
})
.all();

while (txIndex >= visibleTxs.length) {
try {
await playwright
.metamaskWindow()
.locator(
`${mainPageElements.activityTab.completedTransactionsList} > button`,
)
.click();
} catch (error) {
log('[openTransactionDetails] Clicking "View more" failed!');
throw new Error(
`Transaction with index ${txIndex} is not found. There are only ${visibleTxs.length} transactions.`,
);
}

visibleTxs = await playwright
.metamaskWindow()
.locator(
`${mainPageElements.activityTab.completedTransactionsList} > div`,
)
.filter({
has: playwright.metamaskWindow().locator('div.list-item__heading'),
})
.all();
}

await visibleTxs[txIndex].click();

await playwright
.metamaskWindow()
.locator(mainPageElements.popup.container)
.waitFor({ state: 'visible', timeout: 10000 });

return true;
},
async closeTransactionDetailsPopup() {
await switchToMetamaskIfNotActive();
await module.exports.closePopupAndTooltips();
await switchToCypressIfNotActive();
return true;
},
async confirmEncryptionPublicKeyRequest() {
const notificationPage = await playwright.switchToMetamaskNotification();
await playwright.waitAndClick(
Expand Down
11 changes: 9 additions & 2 deletions commands/playwright.js
Original file line number Diff line number Diff line change
Expand Up @@ -275,12 +275,19 @@ module.exports = {
const value = await element.inputValue();
return value;
},
async waitAndGetAttributeValue(selector, attribute, page = metamaskWindow) {
async waitAndGetAttributeValue(
selector,
attribute,
page = metamaskWindow,
skipValidation = false,
) {
const expect = expectInstance
? expectInstance
: require('@playwright/test').expect;
const element = await module.exports.waitFor(selector, page);
await expect(element).toHaveAttribute(attribute, /[a-zA-Z0-9]/);
if (!skipValidation) {
await expect(element).toHaveAttribute(attribute, /[a-zA-Z0-9]/);
}
const attrValue = await element.getAttribute(attribute);
return attrValue;
},
Expand Down
32 changes: 32 additions & 0 deletions docs/synpress-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,14 @@ Create new account in metamask.
createMetamaskAccount(accountName?: string): Chainable<Subject>;
```

#### `cy.renameMetamaskAccount()`

Rename current account in metamask.

```ts
createMetamaskAccount(newAccountName: string): Chainable<Subject>;
```

#### `cy.switchMetamaskAccount()`

Switch metamask account.
Expand Down Expand Up @@ -360,6 +368,14 @@ Confirm metamask transaction (auto-detects eip-1559 and legacy transactions).
confirmMetamaskTransaction(gasConfig?: object | string): Chainable<Subject>;
```

#### `cy.confirmMetamaskTransactionAndWaitForMining()`

Confirm metamask transaction (auto-detects eip-1559 and legacy transactions) and wait for ALL pending transactions to be mined.

```ts
confirmMetamaskTransactionAndWaitForMining(gasConfig?: object | string): Chainable<Subject>;
```

#### `cy.rejectMetamaskTransaction()`

Reject metamask transaction.
Expand All @@ -368,6 +384,22 @@ Reject metamask transaction.
rejectMetamaskTransaction(): Chainable<Subject>;
```

#### `cy.openMetamaskTransactionDetails()`

Open metamask transaction details based on the index of the transaction in the list on the activity tab.

```ts
openMetamaskTransactionDetails(txIndex: number): Chainable<Subject>;
```

#### `cy.closeMetamaskTransactionDetailsPopup()`

Close currently open transaction details popup.

```ts
closeMetamaskTransactionDetailsPopup(): Chainable<Subject>;
```

#### `cy.allowMetamaskToAddNetwork()`

Allow site to add new network in metamask.
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@synthetixio/synpress",
"version": "3.7.2-beta.3",
"version": "3.7.2-beta.6",
"packageManager": "[email protected]",
"description": "Synpress is e2e testing framework based around Cypress.io & playwright with included MetaMask support. Test your dapps with ease.",
"keywords": [
Expand Down Expand Up @@ -69,7 +69,7 @@
"babel-plugin-transform-react-styled-components-qa": "^2.1.0",
"bytes32": "^0.0.3",
"commander": "^11.0.0",
"cypress": "^12.17.4",
"cypress": "12.17.3",
"cypress-wait-until": "^2.0.1",
"debug": "^4.3.4",
"dotenv": "^16.3.1",
Expand Down
14 changes: 13 additions & 1 deletion pages/metamask/main-page.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,13 @@ const tabs = {
const transactionList = '.transaction-list__transactions';
const pendingTransactionsList = `${transactionList} .transaction-list__pending-transactions`;
const completedTransactionsList = `${transactionList} .transaction-list__completed-transactions`;
const completedTransaction = txIndex =>
`${completedTransactionsList} > div:nth-child(${txIndex + 1})`;
const activityTab = {
transactionList,
pendingTransactionsList,
completedTransactionsList,
completedTransaction,
unconfirmedTransaction: `${pendingTransactionsList} .transaction-list-item--unconfirmed`,
confirmedTransaction: `${completedTransactionsList} .transaction-list-item`,
};
Expand Down Expand Up @@ -84,11 +87,19 @@ const connectedSites = {
closeButton: `${connectedSitesSelector} [data-testid="popover-close"]`,
};

const accountModalSelector = '.account-modal';
const accountModal = {
walletAddressInput: '.account-modal .qr-code__address',
walletAddressInput: `${accountModalSelector} .qr-code__address`,
closeButton: '.account-modal__close',
};

const renameAccount = {
invokeInput: `${accountModalSelector} [data-testid="editable-label-button"]`,
input: `${accountModalSelector} [data-testid="editable-input"]`,
confirmButton: `${accountModalSelector} .editable-label__icon-button`,
error: `${accountModalSelector} .editable-label__error`,
};

const importAccountSelector = '.new-account';
const importAccount = {
page: importAccountSelector,
Expand Down Expand Up @@ -135,6 +146,7 @@ module.exports.mainPageElements = {
optionsMenu,
connectedSites,
accountModal,
renameAccount,
importAccount,
createAccount,
importToken,
Expand Down
2 changes: 2 additions & 0 deletions pages/metamask/notification-page.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ const confirmPageContent = `${notificationPage} .confirm-page-container-content`
const networkLabel = `${confirmPageHeader} .network-display`;
const senderButton = `${confirmPageHeader} .sender-to-recipient__party--sender`;
const recipientButton = `${confirmPageHeader} .sender-to-recipient__party--recipient-with-address`;
const recipientAddressTooltipContainerButton = `${confirmPageHeader} .sender-to-recipient__party--recipient .sender-to-recipient__tooltip-container`;
const editGasFeeLegacyButton = `${notificationPage} .transaction-detail-edit button`;
const editGasFeeLegacyOverrideAckButton = `${notificationPage} .edit-gas-display .edit-gas-display__dapp-acknowledgement-button`;
const editGasLegacyPopup = `${notificationPage} .edit-gas-popover__wrapper`;
Expand Down Expand Up @@ -102,6 +103,7 @@ module.exports.confirmPageElements = {
networkLabel,
senderButton,
recipientButton,
recipientAddressTooltipContainerButton,
editGasFeeLegacyButton,
editGasFeeLegacyOverrideAckButton,
editGasLegacyPopup,
Expand Down
Loading

0 comments on commit f29a5a2

Please sign in to comment.