diff --git a/test/e2e/tests/add-hide-token.spec.js b/test/e2e/tests/add-hide-token.spec.js
index eb18355dc56b..e86b5d1c870e 100644
--- a/test/e2e/tests/add-hide-token.spec.js
+++ b/test/e2e/tests/add-hide-token.spec.js
@@ -8,7 +8,7 @@ const {
} = require('../helpers');
const FixtureBuilder = require('../fixture-builder');
-describe('Hide token', function () {
+describe('Add hide token', function () {
it('hides the token when clicked', async function () {
await withFixtures(
{
@@ -60,14 +60,16 @@ describe('Hide token', function () {
await driver.clickElement('[data-testid="asset-options__hide"]');
// wait for confirm hide modal to be visible
- const confirmHideModal = await driver.findVisibleElement('span .modal');
+ const confirmHideModal =
+ '[data-testid="hide-token-confirmation-modal"]';
+ await driver.findVisibleElement(confirmHideModal);
await driver.clickElement(
'[data-testid="hide-token-confirmation__hide"]',
);
// wait for confirm hide modal to be removed from DOM.
- await confirmHideModal.waitForElementState('hidden');
+ await driver.waitForElementNotPresent(confirmHideModal);
assets = await driver.findElements('.multichain-token-list-item');
assert.equal(assets.length, 1);
diff --git a/test/e2e/tests/custom-rpc-history.spec.js b/test/e2e/tests/custom-rpc-history.spec.js
index f05bb77a1f26..ce8ed34185b5 100644
--- a/test/e2e/tests/custom-rpc-history.spec.js
+++ b/test/e2e/tests/custom-rpc-history.spec.js
@@ -8,7 +8,7 @@ const {
} = require('../helpers');
const FixtureBuilder = require('../fixture-builder');
-describe('Stores custom RPC history', function () {
+describe('Custom RPC history', function () {
it(`creates first custom RPC entry`, async function () {
const port = 8546;
const chainId = 1338;
@@ -268,47 +268,52 @@ describe('Stores custom RPC history', function () {
await unlockWallet(driver);
await driver.waitForElementNotPresent('.loading-overlay');
+ // Click add network from network options
await driver.clickElement('[data-testid="network-display"]');
-
await driver.clickElement({ text: 'Add network', tag: 'button' });
-
+ // Open network settings page
await driver.findElement('.add-network__networks-container');
-
+ // Click Add network manually to trigger form
await driver.clickElement({
text: 'Add a network manually',
tag: 'h6',
});
-
- // // cancel new custom rpc
+ // cancel new custom rpc
await driver.clickElement(
'.networks-tab__add-network-form-footer button.btn-secondary',
);
-
+ // find custom network http://127.0.0.1:8545/2
+ const networkItemClassName = '.networks-tab__networks-list-name';
+ const customNetworkName = 'http://127.0.0.1:8545/2';
const networkListItems = await driver.findClickableElements(
- '.networks-tab__networks-list-name',
+ networkItemClassName,
);
const lastNetworkListItem =
networkListItems[networkListItems.length - 1];
await lastNetworkListItem.click();
-
await driver.waitForSelector({
css: '.form-field .form-field__input:nth-of-type(1)',
- value: 'http://127.0.0.1:8545/2',
+ value: customNetworkName,
});
-
- await driver.clickElement('.btn-danger');
-
- // wait for confirm delete modal to be visible
- await driver.findVisibleElement('span .modal');
-
- await driver.clickElement(
- '.button.btn-danger-primary.modal-container__footer-button',
+ // delete custom network in a modal
+ await driver.clickElement('.networks-tab__network-form .btn-danger');
+ await driver.findVisibleElement(
+ '[data-testid="confirm-delete-network-modal"]',
);
+ await driver.clickElement({ text: 'Delete', tag: 'button' });
+ await driver.waitForElementNotPresent(
+ '[data-testid="confirm-delete-network-modal"]',
+ );
+ // There's a short slot to process deleting the network,
+ // hence there's a need to wait for the element to be removed to guarantee the action is executed completely
+ await driver.waitForElementNotPresent({
+ tag: 'div',
+ text: customNetworkName,
+ });
- await driver.waitForElementNotPresent('span .modal');
-
+ // custom network http://127.0.0.1:8545/2 is removed from network list
const newNetworkListItems = await driver.findElements(
- '.networks-tab__networks-list-name',
+ networkItemClassName,
);
assert.equal(networkListItems.length - 1, newNetworkListItems.length);
diff --git a/test/e2e/tests/import-flow.spec.js b/test/e2e/tests/import-flow.spec.js
index 03745977a1f3..bca7398e079c 100644
--- a/test/e2e/tests/import-flow.spec.js
+++ b/test/e2e/tests/import-flow.spec.js
@@ -67,15 +67,19 @@ describe('Import flow @no-mmi', function () {
await driver.findVisibleElement('.qr-code__wrapper');
// shows a QR code for the account
- await driver.findVisibleElement('.mm-modal');
+ await driver.findVisibleElement(
+ '[data-testid="account-details-modal"]',
+ );
// shows the correct account address
await driver.findElement({
css: '.multichain-address-copy-button',
text: '0x0Cc52...7afD3',
});
- await driver.clickElement('.mm-modal button[aria-label="Close"]');
-
+ await driver.clickElement('button[aria-label="Close"]');
+ await driver.waitForElementNotPresent(
+ '[data-testid="account-details-modal"]',
+ );
// logs out of the account
await driver.clickElement(
'[data-testid="account-options-menu-button"]',
diff --git a/test/e2e/tests/incremental-security.spec.js b/test/e2e/tests/incremental-security.spec.js
index 7c7346c52561..bc0b83c6fc55 100644
--- a/test/e2e/tests/incremental-security.spec.js
+++ b/test/e2e/tests/incremental-security.spec.js
@@ -19,6 +19,7 @@ describe('Incremental Security', function () {
},
],
};
+
it('Back up Secret Recovery Phrase from backup reminder @no-mmi', async function () {
await withFixtures(
{
@@ -80,11 +81,15 @@ describe('Incremental Security', function () {
const publicAddress = await address.getText();
// wait for account modal to be visible
- const accountModal = await driver.findVisibleElement('.mm-modal');
- await driver.clickElement('.mm-modal button[aria-label="Close"]');
+ await driver.findVisibleElement(
+ '[data-testid="account-details-modal"]',
+ );
+ await driver.clickElement('button[aria-label="Close"]');
// wait for account modal to be removed from DOM
- await accountModal.waitForElementState('hidden');
+ await driver.waitForElementNotPresent(
+ '[data-testid="account-details-modal"]',
+ );
// send to current account from dapp with different provider
const windowHandles = await driver.getAllWindowHandles();
@@ -128,8 +133,11 @@ describe('Incremental Security', function () {
await driver.clickElement('[data-testid="secure-wallet-recommended"]');
await driver.fill('[placeholder="Password"]', WALLET_PASSWORD);
+
await driver.clickElement({ text: 'Confirm', tag: 'button' });
- await driver.waitForElementNotPresent('.mm-modal-overlay');
+ await driver.waitForElementNotPresent(
+ '[data-testid="reveal-srp-modal"]',
+ );
const recoveryPhraseRevealButton = await driver.findClickableElement(
'[data-testid="recovery-phrase-reveal"]',
diff --git a/test/e2e/tests/onboarding.spec.js b/test/e2e/tests/onboarding.spec.js
index 173ff72ff072..d65bb26551af 100644
--- a/test/e2e/tests/onboarding.spec.js
+++ b/test/e2e/tests/onboarding.spec.js
@@ -281,6 +281,7 @@ describe('MetaMask onboarding @no-mmi', function () {
tag: 'button',
});
+ await driver.waitForSelector('[data-testid="add-network-modal"]');
const [
networkNameField,
networkUrlField,
@@ -293,7 +294,9 @@ describe('MetaMask onboarding @no-mmi', function () {
await currencySymbolField.sendKeys(currencySymbol);
await driver.clickElement({ text: 'Save', tag: 'button' });
- await driver.waitForElementNotPresent('span .modal');
+ await driver.waitForElementNotPresent(
+ '[data-testid="add-network-modal"]',
+ );
await driver.clickElement({ text: 'Done', tag: 'button' });
// After login, check that notification message for added network is displayed
diff --git a/test/e2e/tests/send-eth.spec.js b/test/e2e/tests/send-eth.spec.js
index 4d8a52cbf075..23ab2861a315 100644
--- a/test/e2e/tests/send-eth.spec.js
+++ b/test/e2e/tests/send-eth.spec.js
@@ -209,14 +209,16 @@ describe('Send ETH', function () {
await openActionMenuAndStartSendFlow(driver);
// choose to scan via QR code
await driver.clickElement('[data-testid="ens-qr-scan-button"]');
- await driver.findVisibleElement('.modal');
+ await driver.findVisibleElement('[data-testid="qr-scanner-modal"]');
// cancel action will close the dialog and shut down camera initialization
await driver.waitForSelector({
css: '.qr-scanner__error',
text: "We couldn't access your camera. Please give it another try.",
});
await driver.clickElement({ text: 'Cancel', tag: 'button' });
- await driver.waitForElementNotPresent('.modal');
+ await driver.waitForElementNotPresent(
+ '[data-testid="qr-scanner-modal"]',
+ );
},
);
});
diff --git a/test/e2e/webdriver/driver.js b/test/e2e/webdriver/driver.js
index 6326debb2f77..0400832411b2 100644
--- a/test/e2e/webdriver/driver.js
+++ b/test/e2e/webdriver/driver.js
@@ -79,17 +79,22 @@ function wrapElementWithAPI(element, driver) {
try {
await element.originalClick();
} catch (e) {
- if (
- e.name === 'ElementClickInterceptedError' &&
- e.message.includes('
')
- ) {
- // Wait for the loading overlay to disappear and try again
- await driver.wait(
- until.elementIsNotPresent(By.css('.loading-overlay')),
- );
+ if (e.name === 'ElementClickInterceptedError') {
+ if (e.message.includes('
')) {
+ // Wait for the loading overlay to disappear and try again
+ await driver.wait(
+ until.elementIsNotPresent(By.css('.loading-overlay')),
+ );
+ }
+ if (e.message.includes('
')) {
+ // Wait for the modal to disappear and try again
+ await driver.wait(
+ until.elementIsNotPresent(By.css('.modal__backdrop')),
+ );
+ }
await element.originalClick();
} else {
- throw e; // If the error is not related to the loading overlay, throw it
+ throw e; // If the error is not related to the loading overlay or modal backdrop, throw it
}
}
};
diff --git a/ui/components/app/modal/modal.component.js b/ui/components/app/modal/modal.component.js
index 18af8f98588c..29257c0591e9 100644
--- a/ui/components/app/modal/modal.component.js
+++ b/ui/components/app/modal/modal.component.js
@@ -16,6 +16,7 @@ export default class Modal extends PureComponent {
children: PropTypes.node,
contentClass: PropTypes.string,
containerClass: PropTypes.string,
+ testId: PropTypes.string,
// Header text
headerText: PropTypes.string,
onClose: PropTypes.func,
@@ -51,10 +52,14 @@ export default class Modal extends PureComponent {
contentClass,
containerClass,
hideFooter,
+ testId,
} = this.props;
return (
-
+
{headerText && (
{headerText}
diff --git a/ui/components/app/modals/confirm-delete-network/__snapshots__/confirm-delete-network.test.js.snap b/ui/components/app/modals/confirm-delete-network/__snapshots__/confirm-delete-network.test.js.snap
index 4f7cf9c922a1..e1566f6decb6 100644
--- a/ui/components/app/modals/confirm-delete-network/__snapshots__/confirm-delete-network.test.js.snap
+++ b/ui/components/app/modals/confirm-delete-network/__snapshots__/confirm-delete-network.test.js.snap
@@ -4,6 +4,7 @@ exports[`Confirm Delete Network should match snapshot 1`] = `