1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-10-22 19:26:13 +02:00
metamask-extension/test/e2e/from-import-ui.spec.js

426 lines
14 KiB
JavaScript
Raw Normal View History

const assert = require('assert');
const webdriver = require('selenium-webdriver');
const { By, Key, until } = webdriver;
const enLocaleMessages = require('../../app/_locales/en/messages.json');
const { regularDelayMs, largeDelayMs } = require('./helpers');
const { buildWebDriver } = require('./webdriver');
const Ganache = require('./ganache');
const ganacheServer = new Ganache();
2018-05-25 03:17:26 +02:00
describe('Using MetaMask with an existing account', function () {
let driver;
2018-05-25 03:17:26 +02:00
2020-11-03 00:41:28 +01:00
const testSeedPhrase =
'forum vessel pink push lonely enact gentle tail admit parrot grunt dress';
const testAddress = '0x0Cc5261AB8cE458dc977078A3623E2BaDD27afD3';
2020-11-03 00:41:28 +01:00
const testPrivateKey2 =
'14abe6f4aab7f9f626fe981c864d0adeb5685f289ac9270c27b8fd790b4235d6';
2020-11-03 00:41:28 +01:00
const testPrivateKey3 =
'F4EC2590A0C10DE95FBF4547845178910E40F5035320C516A18C117DE02B5669';
2018-05-25 03:17:26 +02:00
this.timeout(0);
this.bail(true);
2018-05-25 03:17:26 +02:00
before(async function () {
await ganacheServer.start({
accounts: [
{
2020-11-03 00:41:28 +01:00
secretKey:
'0x53CB0AB5226EEBF4D872113D98332C1555DC304443BEE1CF759D15798D3C55A9',
balance: 25000000000000000000,
},
],
});
const result = await buildWebDriver();
driver = result.driver;
await driver.navigate();
});
2018-05-25 03:17:26 +02:00
afterEach(async function () {
if (process.env.SELENIUM_BROWSER === 'chrome') {
const errors = await driver.checkBrowserForConsoleErrors(driver);
2018-05-25 03:17:26 +02:00
if (errors.length) {
const errorReports = errors.map((err) => err.message);
2020-11-03 00:41:28 +01:00
const errorMessage = `Errors found in browser console:\n${errorReports.join(
'\n',
)}`;
console.error(new Error(errorMessage));
2018-05-25 03:17:26 +02:00
}
}
if (this.currentTest.state === 'failed') {
await driver.verboseReportOnFailure(this.currentTest.title);
2018-05-25 03:17:26 +02:00
}
});
2018-05-25 03:17:26 +02:00
after(async function () {
await ganacheServer.quit();
await driver.quit();
});
2018-05-25 03:17:26 +02:00
describe('First time flow starting from an existing seed phrase', function () {
it('clicks the continue button on the welcome screen', async function () {
await driver.findElement(By.css('.welcome-page__header'));
2020-11-03 00:41:28 +01:00
await driver.clickElement(
By.xpath(
`//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`,
),
);
await driver.delay(largeDelayMs);
});
2018-05-25 03:17:26 +02:00
it('clicks the "Import Wallet" option', async function () {
2020-11-03 00:41:28 +01:00
await driver.clickElement(
By.xpath(`//button[contains(text(), 'Import wallet')]`),
);
await driver.delay(largeDelayMs);
});
2018-05-25 03:17:26 +02:00
it('clicks the "No thanks" option on the metametrics opt-in screen', async function () {
await driver.clickElement(By.css('.btn-default'));
await driver.delay(largeDelayMs);
});
Metametrics (#6171) * Add metametrics provider and util. * Add backend api and state for participating in metametrics. * Add frontend action for participating in metametrics. * Add metametrics opt-in screen. * Add metametrics events to first time flow. * Add metametrics events for route changes * Add metametrics events for send and confirm screens * Add metametrics events to dropdowns, transactions, log in and out, settings, sig requests and main screen * Ensures each log in is measured as a new visit by metametrics. * Ensure metametrics is called with an empty string for dimensions params if specified * Adds opt in metametrics modal after unlock for existing users * Adds settings page toggle for opting in and out of MetaMetrics * Switch metametrics dimensions to page level scope * Lint, test and translation fixes for metametrics. * Update design for metametrics opt-in screen * Complete responsive styling of metametrics-opt-in modal * Use new chart image on metrics opt in screens * Incorporate the metametrics opt-in screen into the new onboarding flow * Update e2e tests to accomodate metametrics changes * Mock out metametrics network requests in integration tests * Fix tx-list integration test to support metametrics provider. * Send number of tokens and accounts data with every metametrics event. * Update metametrics event descriptor schema and add new events. * Fix import tos bug and send gas button bug due to metametrics changes. * Various small fixes on the metametrics branch. * Add origin custom variable type to metametrics.util * Fix names of onboarding complete actions (metametrics). * Fix names of Metrics Options actions (metametrics). * Clean up code related to metametrics. * Fix bad merge conflict resolution and improve promise handling in sendMetaMetrics event and confrim tx base * Don't send a second metrics event if user has gone back during first time flow. * Collect metametrics on going back from onboarding create/import. * Add missing custom variable constants for metametrics * Fix metametrics provider * Make height of opt-in modal responsive. * Adjust text content for opt-in modal. * Update metametrics event names and clean up code in opt-in-modal * Put phishing warning step next to last in onboarding flow * Link terms of service on create and import screens of first time flow * Add subtext to options on the onboarding select action screen. * Fix styling of bullet points on end of onboarding screen. * Combine phishing warning and congratulations screens. * Fix placement of users if unlocking after an incomplete onboarding import flow. * Fix capitalization in opt-in screen * Fix last onboarding screen translations * Add link to 'Learn More' on the last screen of onboarding * Code clean up: metametrics branch * Update e2e tests for phishing warning step removal * e2e tests passing on metametrics branch * Different tracking urls for metametrics on development and prod
2019-03-05 16:45:01 +01:00
it('imports a seed phrase', async function () {
2020-11-03 00:41:28 +01:00
const [seedTextArea] = await driver.findElements(
By.css('input[placeholder="Paste seed phrase from clipboard"]'),
);
await seedTextArea.sendKeys(testSeedPhrase);
await driver.delay(regularDelayMs);
2018-05-25 03:17:26 +02:00
const [password] = await driver.findElements(By.id('password'));
await password.sendKeys('correct horse battery staple');
2020-11-03 00:41:28 +01:00
const [confirmPassword] = await driver.findElements(
By.id('confirm-password'),
);
confirmPassword.sendKeys('correct horse battery staple');
2018-05-25 03:17:26 +02:00
await driver.clickElement(By.css('.first-time-flow__terms'));
2020-11-03 00:41:28 +01:00
await driver.clickElement(
By.xpath(`//button[contains(text(), 'Import')]`),
);
await driver.delay(regularDelayMs);
});
2018-05-25 03:17:26 +02:00
it('clicks through the success screen', async function () {
2020-11-03 00:41:28 +01:00
await driver.findElement(
By.xpath(`//div[contains(text(), 'Congratulations')]`),
);
2020-11-03 00:41:28 +01:00
await driver.clickElement(
By.xpath(
`//button[contains(text(), '${enLocaleMessages.endOfFlowMessage10.message}')]`,
),
);
await driver.delay(regularDelayMs);
});
});
2018-05-25 03:17:26 +02:00
describe('Show account information', function () {
it('shows the correct account address', async function () {
2020-11-03 00:41:28 +01:00
await driver.clickElement(
By.css('[data-testid="account-options-menu-button"]'),
);
2020-11-03 00:41:28 +01:00
await driver.clickElement(
By.css('[data-testid="account-options-menu__account-details"]'),
);
await driver.findVisibleElement(By.css('.qr-code__wrapper'));
await driver.delay(regularDelayMs);
2018-05-25 03:17:26 +02:00
2020-11-03 00:41:28 +01:00
const [address] = await driver.findElements(
By.css('.readonly-input__input'),
);
assert.equal(await address.getAttribute('value'), testAddress);
2018-05-25 03:17:26 +02:00
await driver.clickElement(By.css('.account-modal__close'));
await driver.delay(largeDelayMs);
});
2018-05-25 03:17:26 +02:00
it('shows a QR code for the account', async function () {
2020-11-03 00:41:28 +01:00
await driver.clickElement(
By.css('[data-testid="account-options-menu-button"]'),
);
2020-11-03 00:41:28 +01:00
await driver.clickElement(
By.css('[data-testid="account-options-menu__account-details"]'),
);
await driver.findVisibleElement(By.css('.qr-code__wrapper'));
const detailModal = await driver.findElement(By.css('span .modal'));
await driver.delay(regularDelayMs);
2018-05-25 03:17:26 +02:00
await driver.clickElement(By.css('.account-modal__close'));
await driver.wait(until.stalenessOf(detailModal));
await driver.delay(regularDelayMs);
});
});
2018-05-25 03:17:26 +02:00
describe('Lock and unlock', function () {
it('logs out of the account', async function () {
await driver.clickElement(By.css('.account-menu__icon .identicon'));
await driver.delay(regularDelayMs);
2018-05-25 03:17:26 +02:00
2020-11-03 00:41:28 +01:00
const lockButton = await driver.findClickableElement(
By.css('.account-menu__lock-button'),
);
assert.equal(await lockButton.getText(), 'Lock');
await lockButton.click();
await driver.delay(regularDelayMs);
});
2018-05-25 03:17:26 +02:00
it('accepts the account password after lock', async function () {
const passwordField = await driver.findElement(By.id('password'));
await passwordField.sendKeys('correct horse battery staple');
await passwordField.sendKeys(Key.ENTER);
await driver.delay(largeDelayMs);
});
});
2018-05-25 03:17:26 +02:00
describe('Add an account', function () {
it('switches to localhost', async function () {
await driver.clickElement(By.css('.network-display'));
await driver.delay(regularDelayMs);
2020-11-03 00:41:28 +01:00
await driver.clickElement(
By.xpath(`//span[contains(text(), 'Localhost')]`),
);
await driver.delay(largeDelayMs);
});
it('choose Create Account from the account menu', async function () {
await driver.clickElement(By.css('.account-menu__icon'));
await driver.delay(regularDelayMs);
2018-05-25 03:17:26 +02:00
2020-11-03 00:41:28 +01:00
await driver.clickElement(
By.xpath(`//div[contains(text(), 'Create Account')]`),
);
await driver.delay(regularDelayMs);
});
2018-05-25 03:17:26 +02:00
it('set account name', async function () {
2020-11-03 00:41:28 +01:00
const [accountName] = await driver.findElements(
By.css('.new-account-create-form input'),
);
await accountName.sendKeys('2nd account');
await driver.delay(regularDelayMs);
2018-05-25 03:17:26 +02:00
2020-11-03 00:41:28 +01:00
await driver.clickElement(
By.xpath(`//button[contains(text(), 'Create')]`),
);
await driver.delay(regularDelayMs);
});
2018-05-25 03:17:26 +02:00
it('should show the correct account name', async function () {
2020-11-03 00:41:28 +01:00
const accountName = await driver.findElement(
By.css('.selected-account__name'),
);
assert.equal(await accountName.getText(), '2nd account');
await driver.delay(regularDelayMs);
});
});
2018-05-25 03:17:26 +02:00
describe('Switch back to original account', function () {
it('chooses the original account from the account menu', async function () {
await driver.clickElement(By.css('.account-menu__icon'));
await driver.delay(regularDelayMs);
2018-05-25 03:17:26 +02:00
await driver.clickElement(By.css('.account-menu__name'));
await driver.delay(regularDelayMs);
});
});
2018-05-25 03:17:26 +02:00
describe('Send ETH from inside MetaMask', function () {
it('starts a send transaction', async function () {
await driver.clickElement(By.css('[data-testid="eth-overview-send"]'));
await driver.delay(regularDelayMs);
2018-05-25 03:17:26 +02:00
2020-11-03 00:41:28 +01:00
const inputAddress = await driver.findElement(
By.css('input[placeholder="Search, public address (0x), or ENS"]'),
);
await inputAddress.sendKeys('0x2f318C334780961FB129D2a6c30D0763d9a5C970');
Address book send plus contact list (#6914) * Style Send Header * Move Send to-row to send view and restyle * Add "Recents" group to select recipient view * Rename SendToRow to AddRecipient * Basic UI and Layout * New ENSInput component * wip - fuzzy search for input * small refactor * Add Dialog * contact list initial * initial error on invalid address * clean up edit * Click to open modal * Create AddToAddressBookModal component * Modal styling and layout * modal i18n * Add to Addressbook * ens wip * ens wip * ENS Resolution * Reset input * Send to explicit address * Happy Path Complete * Add back error checking * Reset send-to when emptying input * Add back warning object * Fix linter * Fix unit test #1 - fix import paths * Remove dead tests * One more to go * Fix all unit tests * add unit test for reducers and actions * test rendering AddRecipient * Add tests for dialog boxes in AddRecipient * Add test for validating * Fix linter * Fix e2e tests * Token send e2e fix * Style View Contact * Style edit-contact * Fix e2e * Fix from-import-beta-ui e2e spec * Make section header say "add recipient” by default * Auto-focus add recipient input * Update placeholder text * Update input title font size * Auto advance to next step if user paste a valid address * Ellipsify address when recipient is selected * Fix app header background color on desktop * Give each form row a margin of 16px * Use .container/.component naming pattern for ens-input * Auto-focus on input when add to addressbook modal is opened; Save on Enter * Fix and add unit test * Fix selectors name in e2e tests * Correct e2e test token amount for address-book-send changes * Adds e2e test for editing a transaction * Delete test/integration/lib/send-new-ui.js * Add tests for amount max button and high value error on send screen to test/e2e/metamask-ui.spec.js * lint and revert to address as object keys * add chainId based on current network to address book entry * fix test * only display contacts for the current network * Improve ENS message when not found on current network * Add error to indicate when network does not support ENS * bump gaba * address book, resolve comments * Move contact-list to its own component * De-duplicate getaddressbook selector and refactor name selection logic in contact-list-tab/ * Use contact-list component in contact-list-tab.component (i.e. in settings) * Improve/fix settings headers for popup and browser views * Lint fixes related to address book updates * Add 'My accounts' page to settings address book * Update add new contact button in settings to match floating circular design * Improve styles of view contact page * Improve styles and labels of the add-contact.component * Further lint fixes related to address book updates * Update unit tests as per address book updates * Ensure that contact list groups are sorted alphabetically * Refactor settings component to use a container for connection to redux; allow display of addressbook name in settings header * Decouple ens-input.component from send context * Add ens resolution to add contact screen in settings * Switching networks when an ens address is shown on send form removes the ens address. * Resolve send screen search for ensAddress to matching address book entry if it exists * Show resolved ens icon and address if exists (settings: add-contact.component) * Make the displayed and copied address in view-contact.component the checksummed address * Default alias state prop in AddToAddressBookModal to empty string * Use keyCode to detect enter key in AddToAddressBookModal * Ensure add-contact component properly updates after QR code detection * Fix display of all recents after clicking 'Load More' in contact list * Fix send screen contact searching after network switching * Code cleanup related to address book changes * Update unit tests for address book changes * Update ENS name not found on network message * Add ens registration error message * Cancel on edit mode takes user back to view screen * Adds support for memo to settings contact list view and edit screens * Modify designs of edit and view contact in popup environment * Update settings content list UX to show split columns in fullscreen and proper internal navigation * Correct background address book API usages in UI
2019-07-31 21:56:44 +02:00
const inputAmount = await driver.findElement(
By.css('.unit-input__input'),
);
await inputAmount.sendKeys('1');
2018-05-25 03:17:26 +02:00
// Set the gas limit
await driver.clickElement(By.css('.advanced-gas-options-btn'));
await driver.delay(regularDelayMs);
2018-05-25 03:17:26 +02:00
const gasModal = await driver.findElement(By.css('span .modal'));
await driver.clickElement(By.xpath(`//button[contains(text(), 'Save')]`));
await driver.wait(until.stalenessOf(gasModal));
await driver.delay(regularDelayMs);
2018-05-25 03:17:26 +02:00
// Continue to next screen
await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`));
await driver.delay(regularDelayMs);
});
2018-05-25 03:17:26 +02:00
it('confirms the transaction', async function () {
2020-11-03 00:41:28 +01:00
await driver.clickElement(
By.xpath(`//button[contains(text(), 'Confirm')]`),
);
await driver.delay(regularDelayMs);
});
2018-05-25 03:17:26 +02:00
it('finds the transaction in the transactions list', async function () {
await driver.clickElement(By.css('[data-testid="home__activity-tab"]'));
Cleanup beforeunload handler after transaction is resolved (#7333) * Cleanup beforeunload handler after transaction is resolved The notification window was updated to reject transactions upon close in #6340. A handler that rejects the transaction was added to `window.onbeforeunload`, and it was cleared in `actions.js` if it was confirmed or rejected. However, the `onbeforeunload` handler remained uncleared if the transaction was resolved in another window. This results in the transaction being rejected when the notification window closes, even long after the transaction is submitted and confirmed. This has been the cause of many problems with the Firefox e2e tests. Instead the `onbeforeunload` handler is cleared in the `componentWillUnmount` lifecycle function, alongside where it's set in the first place. This ensures that it's correctly unset regardless of how the transaction was resolved, and it better matches user expectations. * Fix indentation and remove redundant export The `run-all.sh` Bash script now uses consistent indentation, and is consistent about only re-exporting the Ganache arguments when they change. * Ensure transactions are completed before checking balance Various intermittent e2e test failures appear to be caused by React re-rendering the transaction list during the test, as the transaction goes from pending to confirmed. To avoid this race condition, the transaction is now explicitly looked for in the confirmed transaction list in each of the tests using this pattern. * Enable all e2e tests on Firefox The remaining tests that were disabled on Firefox now work correctly. Only a few timing adjustments were needed. * Update Firefox used in CI Firefox v70 is now used on CI instead of v68. This necessitated rewriting the function where the extension ID was obtained because the Firefox extensions page was redesigned.
2019-10-31 17:27:22 +01:00
await driver.wait(async () => {
2020-11-03 00:41:28 +01:00
const confirmedTxes = await driver.findElements(
By.css(
'.transaction-list__completed-transactions .transaction-list-item',
),
);
return confirmedTxes.length === 1;
}, 10000);
2018-05-25 03:17:26 +02:00
2020-11-03 00:41:28 +01:00
const txValues = await driver.findElements(
By.css('.transaction-list-item__primary-currency'),
);
assert.equal(txValues.length, 1);
assert.ok(/-1\s*ETH/u.test(await txValues[0].getText()));
});
});
2018-05-25 03:17:26 +02:00
describe('Imports an account with private key', function () {
it('choose Create Account from the account menu', async function () {
await driver.clickElement(By.css('.account-menu__icon'));
await driver.delay(regularDelayMs);
2018-05-25 03:17:26 +02:00
2020-11-03 00:41:28 +01:00
await driver.clickElement(
By.xpath(`//div[contains(text(), 'Import Account')]`),
);
await driver.delay(regularDelayMs);
});
2018-05-25 03:17:26 +02:00
it('enter private key', async function () {
2020-11-03 00:41:28 +01:00
const privateKeyInput = await driver.findElement(
By.css('#private-key-box'),
);
await privateKeyInput.sendKeys(testPrivateKey2);
await driver.delay(regularDelayMs);
2020-11-03 00:41:28 +01:00
await driver.clickElement(
By.xpath(`//button[contains(text(), 'Import')]`),
);
await driver.delay(regularDelayMs);
});
2018-05-25 03:17:26 +02:00
it('should show the correct account name', async function () {
2020-11-03 00:41:28 +01:00
const accountName = await driver.findElement(
By.css('.selected-account__name'),
);
assert.equal(await accountName.getText(), 'Account 4');
await driver.delay(regularDelayMs);
});
2018-05-25 03:17:26 +02:00
it('should show the imported label', async function () {
await driver.clickElement(By.css('.account-menu__icon'));
// confirm 4th account is account 4, as expected
const accountMenuItemSelector = '.account-menu__account:nth-child(4)';
2020-11-03 00:41:28 +01:00
const accountName = await driver.findElement(
By.css(`${accountMenuItemSelector} .account-menu__name`),
);
assert.equal(await accountName.getText(), 'Account 4');
// confirm label is present on the same menu item
2020-11-03 00:41:28 +01:00
const importedLabel = await driver.findElement(
By.css(`${accountMenuItemSelector} .keyring-label`),
);
assert.equal(await importedLabel.getText(), 'IMPORTED');
});
});
2018-07-03 00:49:33 +02:00
describe('Imports and removes an account', function () {
it('choose Create Account from the account menu', async function () {
2020-11-03 00:41:28 +01:00
await driver.clickElement(
By.xpath(`//div[contains(text(), 'Import Account')]`),
);
await driver.delay(regularDelayMs);
});
it('enter private key', async function () {
2020-11-03 00:41:28 +01:00
const privateKeyInput = await driver.findElement(
By.css('#private-key-box'),
);
await privateKeyInput.sendKeys(testPrivateKey3);
await driver.delay(regularDelayMs);
2020-11-03 00:41:28 +01:00
await driver.clickElement(
By.xpath(`//button[contains(text(), 'Import')]`),
);
await driver.delay(regularDelayMs);
});
it('should see new account in account menu', async function () {
2020-11-03 00:41:28 +01:00
const accountName = await driver.findElement(
By.css('.selected-account__name'),
);
assert.equal(await accountName.getText(), 'Account 5');
await driver.delay(regularDelayMs);
await driver.clickElement(By.css('.account-menu__icon'));
await driver.delay(regularDelayMs);
2020-11-03 00:41:28 +01:00
const accountListItems = await driver.findElements(
By.css('.account-menu__account'),
);
assert.equal(accountListItems.length, 5);
await driver.clickPoint(By.css('.account-menu__icon'), 0, 0);
});
it('should open the remove account modal', async function () {
2020-11-03 00:41:28 +01:00
await driver.clickElement(
By.css('[data-testid="account-options-menu-button"]'),
);
2020-11-03 00:41:28 +01:00
await driver.clickElement(
By.css('[data-testid="account-options-menu__remove-account"]'),
);
await driver.findElement(By.css('.confirm-remove-account__account'));
});
it('should remove the account', async function () {
2020-11-03 00:41:28 +01:00
await driver.clickElement(
By.xpath(`//button[contains(text(), 'Remove')]`),
);
await driver.delay(regularDelayMs);
2020-11-03 00:41:28 +01:00
const accountName = await driver.findElement(
By.css('.selected-account__name'),
);
assert.equal(await accountName.getText(), 'Account 1');
await driver.delay(regularDelayMs);
await driver.clickElement(By.css('.account-menu__icon'));
2020-11-03 00:41:28 +01:00
const accountListItems = await driver.findElements(
By.css('.account-menu__account'),
);
assert.equal(accountListItems.length, 4);
});
});
describe('Connects to a Hardware wallet', function () {
it('choose Connect Hardware Wallet from the account menu', async function () {
2020-11-03 00:41:28 +01:00
await driver.clickElement(
By.xpath(`//div[contains(text(), 'Connect Hardware Wallet')]`),
);
await driver.delay(regularDelayMs);
});
2018-07-18 03:54:04 +02:00
it('should open the TREZOR Connect popup', async function () {
await driver.clickElement(By.css('.hw-connect__btn:nth-of-type(2)'));
await driver.delay(regularDelayMs);
2020-11-03 00:41:28 +01:00
await driver.clickElement(
By.xpath(`//button[contains(text(), 'Connect')]`),
);
await driver.delay(regularDelayMs);
const allWindows = await driver.getAllWindowHandles();
assert.equal(allWindows.length, 2);
});
});
});