Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions test/e2e/tests/add-hide-token.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(
{
Expand Down Expand Up @@ -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);
Expand Down
47 changes: 26 additions & 21 deletions test/e2e/tests/custom-rpc-history.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
10 changes: 7 additions & 3 deletions test/e2e/tests/import-flow.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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"]',
Expand Down
16 changes: 12 additions & 4 deletions test/e2e/tests/incremental-security.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ describe('Incremental Security', function () {
},
],
};

it('Back up Secret Recovery Phrase from backup reminder @no-mmi', async function () {
await withFixtures(
{
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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"]',
Expand Down
5 changes: 4 additions & 1 deletion test/e2e/tests/onboarding.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ describe('MetaMask onboarding @no-mmi', function () {
tag: 'button',
});

await driver.waitForSelector('[data-testid="add-network-modal"]');
const [
networkNameField,
networkUrlField,
Expand All @@ -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
Expand Down
6 changes: 4 additions & 2 deletions test/e2e/tests/send-eth.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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"]',
);
},
);
});
Expand Down
23 changes: 14 additions & 9 deletions test/e2e/webdriver/driver.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,17 +79,22 @@ function wrapElementWithAPI(element, driver) {
try {
await element.originalClick();
} catch (e) {
if (
e.name === 'ElementClickInterceptedError' &&
e.message.includes('<div class="mm-box loading-overlay">')
) {
// 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('<div class="mm-box loading-overlay">')) {
// Wait for the loading overlay to disappear and try again
await driver.wait(
until.elementIsNotPresent(By.css('.loading-overlay')),
);
}
if (e.message.includes('<div class="modal__backdrop">')) {
// Wait for the modal to disappear and try again
await driver.wait(
until.elementIsNotPresent(By.css('.modal__backdrop')),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Similar methodology as #22672, we would wait for modal to be completed removed and then perform clicking actions.

PS: Once we completely migrated modal component, we can remove this await.

);
}
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
}
}
};
Expand Down
7 changes: 6 additions & 1 deletion ui/components/app/modal/modal.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -51,10 +52,14 @@ export default class Modal extends PureComponent {
contentClass,
containerClass,
hideFooter,
testId,
} = this.props;

return (
<div className={classnames('modal-container', containerClass)}>
<div
className={classnames('modal-container', containerClass)}
data-testid={testId}
>
{headerText && (
<div className="modal-container__header">
<div className="modal-container__header-text">{headerText}</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ exports[`Confirm Delete Network should match snapshot 1`] = `
<div>
<div
class="modal-container"
data-testid="confirm-delete-network-modal"
>
<div
class="modal-container__content"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export default class ConfirmDeleteNetwork extends PureComponent {
submitText={t('delete')}
cancelText={t('cancel')}
submitType="danger-primary"
testId="confirm-delete-network-modal"
>
<ModalContent
title={t('deleteNetworkTitle', [networkNickname])}
Expand Down
6 changes: 4 additions & 2 deletions ui/components/app/modals/fade-modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,11 @@ class FadeModal extends Component {
onShow: PropTypes.func,
onHide: PropTypes.func,
children: PropTypes.node,
testId: PropTypes.string,
};

static defaultProps = {
testId: '',
onShow: () => undefined,
onHide: () => undefined,
keyboard: true,
Expand Down Expand Up @@ -177,7 +179,7 @@ class FadeModal extends Component {
}

const { willHide } = this.state;
const { modalStyle } = this.props;
const { modalStyle, testId } = this.props;
const backdropStyle = {
animationName: willHide
? animation.hideBackdropAnimation
Expand Down Expand Up @@ -211,7 +213,7 @@ class FadeModal extends Component {

return (
<span>
<div className="modal" style={modalStyle}>
<div className="modal" style={modalStyle} data-testid={testId}>
<div
className="modal__content"
ref={(el) => (this.content = el)}
Expand Down
Loading