diff --git a/app/components/UI/AccountOverview/index.js b/app/components/UI/AccountOverview/index.js index 1cbfdc57956..101bafc2f3e 100644 --- a/app/components/UI/AccountOverview/index.js +++ b/app/components/UI/AccountOverview/index.js @@ -326,6 +326,7 @@ class AccountOverview extends PureComponent { : { borderColor: colors.white } ]} numberOfLines={1} + testID={'edit-account-label'} > {name} diff --git a/app/components/UI/DrawerView/index.js b/app/components/UI/DrawerView/index.js index ebf002880fc..5f348aab50f 100644 --- a/app/components/UI/DrawerView/index.js +++ b/app/components/UI/DrawerView/index.js @@ -902,6 +902,7 @@ class DrawerView extends PureComponent { type={'rounded-normal'} onPress={this.onSend} containerStyle={[styles.button, styles.leftButton]} + testID={'drawer-send-button'} > + {backButtonText} ) : ( - + ) diff --git a/app/components/UI/NetworkList/__snapshots__/index.test.js.snap b/app/components/UI/NetworkList/__snapshots__/index.test.js.snap index f9a971fd11f..e93a2b0ff95 100644 --- a/app/components/UI/NetworkList/__snapshots__/index.test.js.snap +++ b/app/components/UI/NetworkList/__snapshots__/index.test.js.snap @@ -42,6 +42,7 @@ exports[`NetworkList should render correctly 1`] = ` "flex": 1, } } + testID="other-networks-scroll" > - + {this.renderMainnet()} diff --git a/app/components/Views/BrowserTab/__snapshots__/index.test.js.snap b/app/components/Views/BrowserTab/__snapshots__/index.test.js.snap index 20e5dcf04a1..be35fc8eb2d 100644 --- a/app/components/Views/BrowserTab/__snapshots__/index.test.js.snap +++ b/app/components/Views/BrowserTab/__snapshots__/index.test.js.snap @@ -181,7 +181,7 @@ exports[`Browser should render correctly 1`] = ` "marginTop": 7, } } - testID="cancel-url-button" + testID="ios-cancel-url-button" > { onPress={() => (!autocompleteValue ? setShowUrlModal(false) : setAutocompleteValue(''))} style={styles.iconCloseButton} > - + ) : ( {strings('browser.cancel')} diff --git a/app/components/Views/Settings/NetworksSettings/__snapshots__/index.test.js.snap b/app/components/Views/Settings/NetworksSettings/__snapshots__/index.test.js.snap index 7272f90e459..c377e72f308 100644 --- a/app/components/Views/Settings/NetworksSettings/__snapshots__/index.test.js.snap +++ b/app/components/Views/Settings/NetworksSettings/__snapshots__/index.test.js.snap @@ -268,7 +268,9 @@ exports[`NetworksSettings should render correctly 1`] = ` - + 0) { return ( - + {strings('app_settings.network_rpc_networks')} {this.renderRpcNetworks()} diff --git a/e2e/add-custom-rpc.spec.js b/e2e/add-custom-rpc.spec.js index 60efc364d04..d40b4db819a 100644 --- a/e2e/add-custom-rpc.spec.js +++ b/e2e/add-custom-rpc.spec.js @@ -129,30 +129,21 @@ describe('Custom RPC Tests', () => { await TestHelpers.tap('open-networks-button'); // Check that networks list is visible await TestHelpers.checkIfVisible('networks-list'); - // Swipe down on networks list - await TestHelpers.swipe('networks-list', 'up'); // Check that our network is added await TestHelpers.checkIfElementHasString('other-network-name', 'xDai'); - - // iOS change networks tests - if (device.getPlatform() === 'ios') { - // Change to Rinkeby Network - await TestHelpers.tapByText(RINKEBY); - // Check that we are on correct network - await TestHelpers.checkIfElementHasString('network-name', RINKEBY); - // Tap to prompt network list - await TestHelpers.tap('open-networks-button'); - // Check that networks list is visible - await TestHelpers.checkIfVisible('networks-list'); - // Swipe down on networks list - await TestHelpers.swipe('networks-list', 'up'); - // Change to back to xDai Network - await TestHelpers.tapByText('xDai'); - } else { - // Close list - await TestHelpers.tapByText('Close'); - } - + // Change to Rinkeby Network + await TestHelpers.tapByText(RINKEBY); + // Check that we are on correct network + await TestHelpers.checkIfElementHasString('network-name', RINKEBY); + // Tap to prompt network list + await TestHelpers.tap('open-networks-button'); + // Check that networks list is visible + await TestHelpers.checkIfVisible('networks-list'); + // Swipe up on networks list + await TestHelpers.swipe('other-networks-scroll', 'up', 'fast'); + await TestHelpers.delay(1000); + // Change to back to xDai Network + await TestHelpers.tapByText('xDai'); // Check that we are on the wallet screen await TestHelpers.checkIfVisible('wallet-screen'); // Check that we are on correct network @@ -171,22 +162,21 @@ describe('Custom RPC Tests', () => { // Check that we are on the networks screen await TestHelpers.checkIfVisible('networks-screen'); // Tap on xDai to remove network - await element(by.text('xDai')).longPress(); - // Tap remove + await TestHelpers.tapAndLongPressAtIndex('rpc-networks', 0); + //Remove xDAI and verify removed on wallet view + //Tap remove await TestHelpers.tapByText('Remove'); - // Go back to wallet screen if (device.getPlatform() === 'ios') { // Tap on back arrow - await TestHelpers.tapAtPoint('networks-screen', { x: 25, y: -22 }); + await TestHelpers.tap('nav-ios-back'); // Tap close await TestHelpers.tapByText('Close'); } else { // Go Back for android - await device.pressBack(); - await device.pressBack(); + await TestHelpers.tap('nav-android-back'); + await TestHelpers.tap('nav-android-back'); } - // Check that we are on the wallet screen await TestHelpers.checkIfExists('wallet-screen'); // Check that we are on Mainnet diff --git a/e2e/addressbook-tests.spec.js b/e2e/addressbook-tests.spec.js index 3fb208c3acc..0f0af8384dc 100644 --- a/e2e/addressbook-tests.spec.js +++ b/e2e/addressbook-tests.spec.js @@ -2,6 +2,7 @@ import TestHelpers from './helpers'; const INVALID_ADDRESS = '0xB8B4EE5B1b693971eB60bDa15211570df2dB221L'; +const TETHER_ADDRESS = '0xdac17f958d2ee523a2206206994597c13d831ec7'; const MYTH_ADDRESS = '0x1FDb169Ef12954F20A15852980e1F0C122BfC1D6'; const MEMO = 'Test adding ENS'; const PASSWORD = '12345678'; @@ -84,12 +85,12 @@ describe('Addressbook Tests', () => { it('should go to send view', async () => { // Check that we are on the wallet screen await TestHelpers.checkIfVisible('wallet-screen'); - // Tap on ETH asset - await TestHelpers.waitAndTap('eth-logo'); - // Check that we are on the token overview screen - await TestHelpers.checkIfVisible('token-asset-overview'); + // Open Drawer + await TestHelpers.tap('hamburger-menu-button-wallet'); + // Check that the drawer is visbile + await TestHelpers.checkIfVisible('drawer-screen'); // Tap on Send button - await TestHelpers.tapByText('SEND'); + await TestHelpers.tap('drawer-send-button'); // Check that we are on the send screen await TestHelpers.checkIfVisible('send-screen'); // Make sure view with my accounts visible @@ -97,15 +98,26 @@ describe('Addressbook Tests', () => { }); it('should input a valid address to send to', async () => { - // Input incorrect address + // Input incorrect address Currently commented out until https://github.com/MetaMask/metamask-mobile/issues/2533 is fixed + // if (device.getPlatform() === 'android') { + // await TestHelpers.replaceTextInField('txn-to-address-input', INVALID_ADDRESS); + // await element(by.id('txn-to-address-input')).tapReturnKey(); + // } else { + // await TestHelpers.typeTextAndHideKeyboard('txn-to-address-input', INVALID_ADDRESS); + // } + // // Check that the error is displayed + // await TestHelpers.checkIfVisible('address-error'); + //Input token address to test for error if (device.getPlatform() === 'android') { - await TestHelpers.replaceTextInField('txn-to-address-input', INVALID_ADDRESS); - await element(by.id('txn-to-address-input')).tapReturnKey(); + await TestHelpers.replaceTextInField('txn-to-address-input', TETHER_ADDRESS); } else { - await TestHelpers.typeTextAndHideKeyboard('txn-to-address-input', INVALID_ADDRESS); + await TestHelpers.typeTextAndHideKeyboard('txn-to-address-input', TETHER_ADDRESS); } // Check that the error is displayed await TestHelpers.checkIfVisible('address-error'); + // Tap x to remove address + await TestHelpers.tap('clear-address-button'); + await TestHelpers.delay(1000); // Input valid myth address if (device.getPlatform() === 'android') { await TestHelpers.replaceTextInField('txn-to-address-input', MYTH_ADDRESS); @@ -142,8 +154,6 @@ describe('Addressbook Tests', () => { it('should go to settings then select contacts', async () => { // Tap on cancel button await TestHelpers.tap('send-cancel-button'); - // Tap on back button to proceed to wallet view - await TestHelpers.tap('asset-back-button'); // Check that we are on the wallet screen await TestHelpers.checkIfVisible('wallet-screen'); // Open Drawer @@ -186,11 +196,10 @@ describe('Addressbook Tests', () => { await TestHelpers.replaceTextInField('contact-memo-input', MEMO); // Tap add contact button if (device.getPlatform() === 'android') { - await TestHelpers.tapByText('Add contact'); - await TestHelpers.delay(1000); - await TestHelpers.tapByText('Add contact'); - } else { await TestHelpers.tap('contact-add-contact-button'); + await TestHelpers.delay(700); + await TestHelpers.tap('contact-add-contact-button'); + } else { await TestHelpers.tap('contact-add-contact-button'); } // Check that we are on the contacts screen @@ -208,6 +217,9 @@ describe('Addressbook Tests', () => { await TestHelpers.replaceTextInField('contact-name-input', 'Moon'); // Tap on Edit contact button await TestHelpers.tapByText('Edit contact'); + if (device.getPlatform() === 'ios') { + await TestHelpers.tapByText('Edit contact'); + } // Check that we are on the contacts screen await TestHelpers.checkIfVisible('contacts-screen'); // Check that Ibrahim address is saved in the address book @@ -223,8 +235,11 @@ describe('Addressbook Tests', () => { await TestHelpers.tapByText('Edit'); // Tap on Delete await TestHelpers.tapByText('Delete'); - // Tap on Delete - await TestHelpers.tapByText('Delete'); + if (device.getPlatform() === 'ios') { + await TestHelpers.tapByText('Delete', 1); + } else { + await TestHelpers.tapByText('Delete'); + } // Ensure Moon is not visible await TestHelpers.checkIfElementWithTextIsNotVisible('Moon'); }); @@ -234,7 +249,7 @@ describe('Addressbook Tests', () => { await TestHelpers.tap('title-back-arrow-button'); // tap to get out of settings view if (device.getPlatform() === 'android') { - await device.pressBack(); + await TestHelpers.tap('nav-android-back'); } else { await TestHelpers.tapByText('Close'); } diff --git a/e2e/browser-tests.spec.js b/e2e/browser-tests.spec.js index 2f85fecd908..642e14790e7 100644 --- a/e2e/browser-tests.spec.js +++ b/e2e/browser-tests.spec.js @@ -3,7 +3,7 @@ import TestHelpers from './helpers'; const ENS_Example = 'https://brunobarbieri.eth'; const ENS_TLD = 'https://inbox.mailchain.xyz'; -const UNISWAP = 'https://uniswap.eth'; +const UNISWAP = 'https://uniswap.exchange'; const PASSWORD = '12345678'; describe('Browser Tests', () => { @@ -95,42 +95,46 @@ describe('Browser Tests', () => { }); it('should go to first explore tab and navigate back to homepage', async () => { - // Tap on first category - if (device.getPlatform() === 'android') { + // This can only be done on Android since we removed option for iOS due to Appstore + if (!device.getPlatform() === 'android') { + // Tap on first category await TestHelpers.tapAtPoint('browser-screen', { x: 100, y: 425 }); - } else { - await TestHelpers.tapAtPoint('browser-screen', { x: 100, y: 450 }); + // Tap on first option + await TestHelpers.tapAtPoint('browser-screen', { x: 80, y: 100 }); + // Tap back button + await TestHelpers.waitAndTap('go-back-button'); + // Tap back button + await TestHelpers.waitAndTap('go-back-button'); + // Wait for page to load + await TestHelpers.delay(1000); + // Check that we are on the browser screen + await TestHelpers.checkIfVisible('browser-screen'); } - // Tap on first option - await TestHelpers.tapAtPoint('browser-screen', { x: 80, y: 100 }); - // Tap back button - await TestHelpers.waitAndTap('go-back-button'); - // Tap back button - await TestHelpers.waitAndTap('go-back-button'); - // Wait for page to load - await TestHelpers.delay(1000); - // Check that we are on the browser screen - await TestHelpers.checkIfVisible('browser-screen'); }); it('should go to uniswap', async () => { // Tap on home on bottom navbar - await TestHelpers.tap('home-button'); + // await TestHelpers.tap('home-button'); // Wait for page to load - await TestHelpers.delay(1000); + await TestHelpers.delay(3000); // Tap on search in bottom navbar await TestHelpers.tap('search-button'); // Navigate to URL if (device.getPlatform() === 'ios') { + await TestHelpers.clearField('url-input'); await TestHelpers.typeTextAndHideKeyboard('url-input', UNISWAP); + await TestHelpers.delay(2000); } else { + await TestHelpers.tap('android-cancel-url-button'); await TestHelpers.replaceTextInField('url-input', UNISWAP); await element(by.id('url-input')).tapReturnKey(); } // Wait for page to load await TestHelpers.delay(5000); - // Check that the dapp title is correct - await TestHelpers.checkIfElementWithTextIsVisible('uniswap.eth', 0); + if (device.getPlatform() === 'android') { + // Check that the dapp title is correct + await TestHelpers.checkIfElementWithTextIsVisible('app.uniswap.org', 0); + } // Tap on CANCEL button await TestHelpers.tap('connect-cancel-button'); @@ -139,7 +143,11 @@ describe('Browser Tests', () => { // Wait for page to load await TestHelpers.delay(3000); await TestHelpers.tap('connect-cancel-button'); - + // Android has weird behavior where the URL modal stays open, so this closes it + // Close URL modal + if (device.getPlatform() === 'android') { + await device.pressBack(); + } // Check that we are still on the browser screen await TestHelpers.checkIfVisible('browser-screen'); }); @@ -166,7 +174,10 @@ describe('Browser Tests', () => { await TestHelpers.checkIfVisible('browser-screen'); // Tap on Favorites tab if (device.getPlatform() === 'ios') { - await TestHelpers.tapAtPoint('browser-screen', { x: 274, y: 227 }); + // Tap on options + await TestHelpers.waitAndTap('options-button'); + // Open new tab + await TestHelpers.tapByText('New tab'); await TestHelpers.tapAtPoint('browser-screen', { x: 174, y: 281 }); await TestHelpers.delay(1500); } else { @@ -220,7 +231,7 @@ describe('Browser Tests', () => { await TestHelpers.checkIfVisible('browser-screen'); // Tap on empowr from search results if (device.getPlatform() === 'ios') { - await TestHelpers.tapAtPoint('browser-screen', { x: 20, y: 245 }); + await TestHelpers.tapAtPoint('browser-screen', { x: 60, y: 270 }); } else { await TestHelpers.tapAtPoint('browser-screen', { x: 56, y: 284 }); await TestHelpers.delay(700); diff --git a/e2e/helpers.js b/e2e/helpers.js index 309f9ebba6a..f0818ea95ee 100644 --- a/e2e/helpers.js +++ b/e2e/helpers.js @@ -52,7 +52,13 @@ export default class TestHelpers { static async tapAndLongPress(elementId) { await TestHelpers.tap(elementId); - return element(by.id(elementId)).longPress(); + return element(by.id(elementId)).longPress(2000); + } + + static async tapAndLongPressAtIndex(elementId, index) { + return element(by.id(elementId, index)) + .atIndex(index || 0) + .longPress(2000); } static async replaceTextInField(elementId, text) { @@ -71,8 +77,8 @@ export default class TestHelpers { .tap(); } - static async swipe(elementId, direction) { - await element(by.id(elementId)).swipe(direction); + static async swipe(elementId, direction, speed, percentage) { + await element(by.id(elementId)).swipe(direction, speed, percentage); } static async scrollTo(scrollviewId, edge) { diff --git a/e2e/onboarding-wizard-opt-out.spec.js b/e2e/onboarding-wizard-opt-out.spec.js index 9246407301f..a282eccc314 100644 --- a/e2e/onboarding-wizard-opt-out.spec.js +++ b/e2e/onboarding-wizard-opt-out.spec.js @@ -84,28 +84,11 @@ describe('Onboarding wizard opt-out', () => { // Scroll to the bottom if (device.getPlatform() === 'android') { - await TestHelpers.swipe('change-password-section', 'up'); - TestHelpers.delay(1500); - await TestHelpers.swipe('change-password-section', 'up'); - TestHelpers.delay(1500); - await TestHelpers.swipe('auto-lock-section', 'up'); - TestHelpers.delay(1500); - await TestHelpers.swipe('clear-privacy-section', 'up'); - TestHelpers.delay(1500); - await TestHelpers.swipe('clear-cookies-section', 'up'); - TestHelpers.delay(1500); - await TestHelpers.swipe('privacy-mode-section', 'up'); - TestHelpers.delay(1500); - await TestHelpers.swipe('privacy-mode-section', 'up'); - TestHelpers.delay(1500); - await TestHelpers.swipe('privacy-mode-section', 'up'); - TestHelpers.delay(1500); - await TestHelpers.swipe('metametrics-section', 'up'); - TestHelpers.delay(1500); + await TestHelpers.swipe('security-settings-scrollview', 'up', 'fast'); + await TestHelpers.delay(1000); } else { - await TestHelpers.swipe('auto-lock-section', 'up'); + await TestHelpers.swipe('auto-lock-section', 'up', 'fast'); } - // Toggle Metametrics on await TestHelpers.tap('metametrics-switch'); TestHelpers.delay(1000); @@ -133,43 +116,40 @@ describe('Onboarding wizard opt-out', () => { await TestHelpers.checkIfNotVisible('onboarding-wizard-step1-view'); }); - // commenting this out as tapping on this take a tour prompt currently doesn't work - // once fixed I can add it back in - - // it('should take tour and skip tutorial', async () => { - // // Open Drawer - // await TestHelpers.tap('hamburger-menu-button-wallet'); - // // Check that the drawer is visbile - // await TestHelpers.checkIfVisible('drawer-screen'); - // // Tap on Browser - // await TestHelpers.tapByText('Browser'); - // // Wait for page to load - // await TestHelpers.delay(1000); - // // Check that we are on the browser screen - // await TestHelpers.checkIfVisible('browser-screen'); - // // Scroll on browser to show tutorial box and tap to skip - // if (device.getPlatform() === 'ios') { - // await TestHelpers.swipe('browser-screen', 'up'); - // } else { - // await TestHelpers.checkIfExists('browser-webview'); - // await TestHelpers.swipe('browser-webview', 'up'); - // await TestHelpers.delay(1000); - // } - // // Tap on the Take a tour box - // if (device.getPlatform() === 'ios') { - // await TestHelpers.tapAtPoint('browser-screen', { x: 215, y: 555 }); - // } else { - // await TestHelpers.tapAtPoint('browser-screen', { x: 175, y: 480 }); - // } - // // Check that we are on the wallet screen - // await TestHelpers.checkIfNotVisible('browser-screen'); - // // Check that the onboarding wizard is present - // await TestHelpers.checkIfVisible('onboarding-wizard-step1-view'); - // // Check that Take the tour CTA is visible and tap it - // await TestHelpers.waitAndTap('onboarding-wizard-next-button'); - // // Tap on Skip Tutorial - // await TestHelpers.tapByText('Skip Tutorial'); - // // Check that the wizard is not visible anymore - // await TestHelpers.checkIfNotVisible('onboarding-wizard-step1-view'); - // }); + it('should take tour and skip tutorial', async () => { + // Open Drawer + await TestHelpers.tap('hamburger-menu-button-wallet'); + // Check that the drawer is visbile + await TestHelpers.checkIfVisible('drawer-screen'); + // Tap on Browser + await TestHelpers.tapByText('Browser'); + // Wait for page to load + await TestHelpers.delay(1000); + // Check that we are on the browser screen + await TestHelpers.checkIfVisible('browser-screen'); + // Scroll on browser to show tutorial box and tap to skip + if (device.getPlatform() === 'ios') { + await TestHelpers.swipe('browser-screen', 'up'); + } else { + await TestHelpers.checkIfExists('browser-webview'); + await TestHelpers.swipe('browser-webview', 'up'); + await TestHelpers.delay(1000); + } + // Tap on the Take a tour box + if (device.getPlatform() === 'ios') { + await TestHelpers.tapAtPoint('browser-screen', { x: 215, y: 555 }); + } else { + await TestHelpers.tapAtPoint('browser-screen', { x: 175, y: 480 }); + } + // Check that we are on the wallet screen + await TestHelpers.checkIfNotVisible('browser-screen'); + // Check that the onboarding wizard is present + await TestHelpers.checkIfVisible('onboarding-wizard-step1-view'); + // Check that Take the tour CTA is visible and tap it + await TestHelpers.waitAndTap('onboarding-wizard-next-button'); + // Tap on Skip Tutorial + await TestHelpers.tapByText('Skip Tutorial'); + // Check that the wizard is not visible anymore + await TestHelpers.checkIfNotVisible('onboarding-wizard-step1-view'); + }); }); diff --git a/e2e/request-token-flow.spec.js b/e2e/request-token-flow.spec.js index 65bc6835692..3c4583dc3c8 100644 --- a/e2e/request-token-flow.spec.js +++ b/e2e/request-token-flow.spec.js @@ -90,7 +90,7 @@ describe('Request Token Flow', () => { await TestHelpers.checkIfVisible('receive-request-screen'); }); - it('should request ETH', async () => { + it('should request DAI', async () => { // Tap on request payment button await TestHelpers.tap('request-payment-button'); // Tap on ETH @@ -110,9 +110,13 @@ describe('Request Token Flow', () => { await TestHelpers.typeTextAndHideKeyboard('request-search-asset-input', 'DAI'); } else { await TestHelpers.replaceTextInField('request-search-asset-input', 'DAI'); + await TestHelpers.delay(1000); } // Select DAI from search results await TestHelpers.tapByText('DAI', 1); + if (device.getPlatform() === 'ios') { + await TestHelpers.tapByText('DAI', 1); + } // Request 5.50 DAI await TestHelpers.typeTextAndHideKeyboard('request-amount-input', 5.5); // Make sure we're on the right screen diff --git a/e2e/start-exploring.spec.js b/e2e/start-exploring.spec.js index 28dbf2d7b18..f940774bfc2 100644 --- a/e2e/start-exploring.spec.js +++ b/e2e/start-exploring.spec.js @@ -94,15 +94,13 @@ describe('Start Exploring', () => { // Ensure step 3 is shown correctly await TestHelpers.checkIfVisible('step3-title'); // Focus into account 1 name - await TestHelpers.tapAndLongPress('account-label'); - // Clear text - await TestHelpers.clearField('account-label-text-input'); - // Change account name if (device.getPlatform() === 'android') { + await TestHelpers.tapAndLongPress('edit-account-label'); + // Clear text + await TestHelpers.clearField('account-label-text-input'); + // Change account name await TestHelpers.replaceTextInField('account-label-text-input', ACCOUNT); await element(by.id('account-label-text-input')).tapReturnKey(); - } else { - await TestHelpers.typeTextAndHideKeyboard('account-label-text-input', ACCOUNT); } // Check that Got it! CTA is visible and tap it if (!device.getPlatform() === 'android') { @@ -133,6 +131,14 @@ describe('Start Exploring', () => { await TestHelpers.tapByText('Back'); // Ensure step 5 is shown correctly await TestHelpers.checkIfVisible('step5-title'); + // Tap on Back + await TestHelpers.tapByText('Back'); + // Ensure step 4 is shown correctly + await TestHelpers.checkIfVisible('step4-title'); + // Check that Got it! CTA is visible and tap it + await TestHelpers.tapByText('Got it!'); + // Ensure step 5 is shown correctly + await TestHelpers.checkIfVisible('step5-title'); // Check that Got it! CTA is visible and tap it await TestHelpers.tapByText('Got it!'); // Ensure step 6 is shown correctly diff --git a/e2e/wallet-tests.spec.js b/e2e/wallet-tests.spec.js index f7b3070484d..a582db45ffc 100644 --- a/e2e/wallet-tests.spec.js +++ b/e2e/wallet-tests.spec.js @@ -5,9 +5,10 @@ const CORRECT_SEED_WORDS = 'fold media south add since false relax immense pause const CORRECT_PASSWORD = `12345678`; const TEST_PUBLIC_ADDRESS = '0xd3B9Cbea7856AECf4A6F7c3F4E8791F79cBeeD62'; const RINKEBY = 'Rinkeby Test Network'; +const ETHEREUM = 'Ethereum Main Network'; const COLLECTIBLE_CONTRACT_ADDRESS = '0x16baf0de678e52367adc69fd067e5edd1d33e3bf'; const COLLECTIBLE_IDENTIFIER = '404'; -const TOKEN_ADDRESS = '0x12525e53a7fB9e072e60062D087b19a05442BD8f'; +const TOKEN_ADDRESS = '0x107c4504cd79c5d2696ea0030a8dd4e92601b82e'; const TEST_PRIVATE_KEY = 'cbfd798afcfd1fd8ecc48cbecb6dc7e876543395640b758a90e11d986e758ad1'; const VALID_ADDRESS = '0xebe6CcB6B55e1d094d9c58980Bc10Fed69932cAb'; @@ -68,7 +69,9 @@ describe('Wallet Tests', () => { // Tap on Create New Account await TestHelpers.waitAndTap('create-account-button'); // Check if account was added - await TestHelpers.checkIfElementWithTextIsVisible('Account 2'); + if (device.getPlatform() === 'android') { + await TestHelpers.checkIfElementWithTextIsVisible('Account 2'); + } }); it('should be able to import account', async () => { @@ -178,15 +181,8 @@ describe('Wallet Tests', () => { await TestHelpers.tapByText('ADD'); // Check that identifier warning appears await TestHelpers.checkIfVisible('collectible-identifier-warning'); - // Go Back one view - if (device.getPlatform() === 'android') { - await device.pressBack(); - await TestHelpers.delay(1000); - } else { - await TestHelpers.tapAtPoint('add-custom-token-screen', { x: 25, y: -22 }); - } - + await TestHelpers.tap('asset-back-button'); // Tap on the add collectibles button await TestHelpers.waitAndTap('add-collectible-button'); // Check that we are on the add collectible asset screen @@ -213,12 +209,7 @@ describe('Wallet Tests', () => { // Check that the asset is correct await TestHelpers.checkIfElementHasString('collectible-name', '1 CryptoKitties'); // Tap on back arrow - if (device.getPlatform() === 'android') { - await device.pressBack(); - await TestHelpers.delay(1000); - } else { - await TestHelpers.tapAtPoint('collectible-overview-screen', { x: 25, y: -22 }); - } + await TestHelpers.tap('asset-back-button'); }); it('should add a token', async () => { @@ -226,6 +217,14 @@ describe('Wallet Tests', () => { await TestHelpers.checkIfVisible('wallet-screen'); // Tap on TOKENS tab await TestHelpers.tapByText('TOKENS'); + // Switch to mainnet + await TestHelpers.waitAndTap('open-networks-button'); + // Check that the Networks modal pops up + await TestHelpers.checkIfVisible('networks-list'); + // Tap on Eth Mainnet + await TestHelpers.tapByText(ETHEREUM); + // Check that we are on Eth Mainnet + await TestHelpers.checkIfElementWithTextIsVisible(ETHEREUM); // Tap on Add Tokens await TestHelpers.tap('add-token-button'); // Search for SAI @@ -233,12 +232,8 @@ describe('Wallet Tests', () => { // Wait for results to load await TestHelpers.delay(2000); // Select SAI - if (device.getPlatform() === 'android') { - await TestHelpers.tapItemAtIndex('searched-token-result'); - await TestHelpers.delay(500); - } else { - await TestHelpers.tapAtPoint('search-token-screen', { x: 115, y: 160 }); - } + await TestHelpers.tapItemAtIndex('searched-token-result'); + await TestHelpers.delay(500); // Tap on Add Token button await TestHelpers.tapByText('ADD TOKEN'); // Check that we are on the wallet screen @@ -272,11 +267,11 @@ describe('Wallet Tests', () => { await TestHelpers.delay(700); // Check that token decimals warning is displayed await TestHelpers.checkIfVisible('token-decimals-warning'); - // Tap on cancel button + // Go back if (device.getPlatform() === 'android') { await device.pressBack(); } else { - await TestHelpers.tapByText('CANCEL'); + await TestHelpers.tap('asset-back-button'); } // Tap on Add Tokens await TestHelpers.tap('add-token-button'); @@ -303,18 +298,29 @@ describe('Wallet Tests', () => { // Check that we are on the wallet screen await TestHelpers.checkIfVisible('wallet-screen'); // Check that TENX is added to wallet - await TestHelpers.checkIfElementWithTextIsVisible('0 TENX'); + await TestHelpers.checkIfElementWithTextIsVisible('0 BLT'); + }); + + it('should switch back to Rinkeby network', async () => { + // Tap on Ethereum Main Network to prompt modal + await TestHelpers.waitAndTap('open-networks-button'); + // Check that the Networks modal pops up + await TestHelpers.checkIfVisible('networks-list'); + // Tap on Rinkeby Test Nework + await TestHelpers.tapByText(RINKEBY); + // Check that we are on Rinkeby network + await TestHelpers.checkIfElementWithTextIsVisible(RINKEBY); }); it('should input a valid address', async () => { // Check that we are on the wallet screen await TestHelpers.checkIfVisible('wallet-screen'); - // Tap on ETH asset - await TestHelpers.waitAndTap('eth-logo'); - // Check that we are on the token overview screen - await TestHelpers.checkIfVisible('token-asset-overview'); + // Open Drawer + await TestHelpers.tap('hamburger-menu-button-wallet'); + // Check that the drawer is visbile + await TestHelpers.checkIfVisible('drawer-screen'); // Tap on Send button - await TestHelpers.tapByText('SEND'); + await TestHelpers.tap('drawer-send-button'); // Check that we are on the send screen await TestHelpers.checkIfVisible('send-screen'); // Input test address @@ -327,11 +333,7 @@ describe('Wallet Tests', () => { it('should input and validate amount', async () => { // Input amount - if (device.getPlatform() === 'android') { - await TestHelpers.replaceTextInField('txn-amount-input', '5'); - } else { - await TestHelpers.typeTextAndHideKeyboard('txn-amount-input', '5'); - } + await TestHelpers.replaceTextInField('txn-amount-input', '5'); // Tap Next CTA await TestHelpers.tap('txn-amount-next-button'); // Check that the insufficient funds warning pops up @@ -349,7 +351,7 @@ describe('Wallet Tests', () => { await TestHelpers.checkIfHasText('confirm-txn-amount', '0.00004 ETH'); // Tap on the Send CTA await TestHelpers.tap('txn-confirm-send-button'); - // Check that we are on the token overview screen - await TestHelpers.checkIfVisible('token-asset-overview'); + // Check that we are on the wallet screen + await TestHelpers.checkIfVisible('wallet-screen'); }); }); diff --git a/index.js b/index.js index f6f0e7e43aa..45e25584a01 100644 --- a/index.js +++ b/index.js @@ -16,9 +16,10 @@ import { name } from './app.json'; // List of warnings that we're ignoring LogBox.ignoreLogs([ '{}', - // Uncomment the below line to run browser-tests.spec.js in debug mode + // Uncomment the below lines (21 and 22) to run browser-tests.spec.js in debug mode // in e2e tests until issue https://github.com/MetaMask/metamask-mobile/issues/1395 is resolved //"Error in RPC response", + // 'User rejected account access', "Can't perform a React state update", 'Error evaluating injectedJavaScript', 'createErrorFromErrorData', diff --git a/package.json b/package.json index 96ed4b44b85..924d50387c2 100644 --- a/package.json +++ b/package.json @@ -216,7 +216,7 @@ "babel-eslint": "10.1.0", "babel-jest": "^26.6.3", "concat-cli": "4.0.0", - "detox": "17.3.1", + "detox": "17.14.9", "enzyme": "3.9.0", "enzyme-adapter-react-16": "1.10.0", "enzyme-to-json": "3.3.5", diff --git a/yarn.lock b/yarn.lock index 582ba06b42b..e51ac8dd330 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3480,6 +3480,11 @@ camelcase@^5.0.0, camelcase@^5.3.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== +camelcase@^6.0.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" + integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== + capture-exit@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" @@ -3693,6 +3698,15 @@ cliui@^6.0.0: strip-ansi "^6.0.0" wrap-ansi "^6.2.0" +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + clone@^1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" @@ -4199,6 +4213,11 @@ decamelize@^1.1.1, decamelize@^1.2.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= +decamelize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== + decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" @@ -4387,10 +4406,10 @@ detect-newline@^3.0.0: resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== -detox@17.3.1: - version "17.3.1" - resolved "https://registry.yarnpkg.com/detox/-/detox-17.3.1.tgz#508a1358c3c0c56670d520b2ab7480dddbfc486f" - integrity sha512-UFhHxsjfaOdO0tf6tIMXYCEIClfhgHHfjU/XZmrLavL2GKSfS3udGu+EcQ/Iqt57C1GYCHfnxMi2pgghjASmRQ== +detox@17.14.9: + version "17.14.9" + resolved "https://registry.yarnpkg.com/detox/-/detox-17.14.9.tgz#e269de0937e615eac92ac283b2303751bcf2c072" + integrity sha512-WLpl7BJ2xecZJ02hFFWgzo61RnlO/LlsH/U8GWztoXsT0z0t9iKsBci8AhSSErQfH0IHnNtDcZknIxt0gzNhoQ== dependencies: bunyan "^1.8.12" bunyan-debug-stream "^1.1.0" @@ -4404,16 +4423,17 @@ detox@17.3.1: lodash "^4.17.5" minimist "^1.2.0" proper-lockfile "^3.0.2" + resolve-from "^5.0.0" sanitize-filename "^1.6.1" - shell-utils "^1.0.9" + shell-quote "^1.7.2" signal-exit "^3.0.3" tail "^2.0.0" telnet-client "1.2.8" tempfile "^2.0.0" which "^1.3.1" ws "^3.3.1" - yargs "^13.0.0" - yargs-parser "^13.0.0" + yargs "^16.0.3" + yargs-unparser "^2.0.0" diff-sequences@^25.2.6: version "25.2.6" @@ -4784,6 +4804,11 @@ es6-promisify@^5.0.0: dependencies: es6-promise "^4.0.3" +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -6336,6 +6361,11 @@ flat-cache@^3.0.4: flatted "^3.1.0" rimraf "^3.0.2" +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + flatted@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" @@ -6549,7 +6579,7 @@ get-caller-file@^1.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== -get-caller-file@^2.0.1: +get-caller-file@^2.0.1, get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== @@ -7388,6 +7418,11 @@ is-object@~0.1.2: resolved "https://registry.yarnpkg.com/is-object/-/is-object-0.1.2.tgz#00efbc08816c33cfc4ac8251d132e10dc65098d7" integrity sha1-AO+8CIFsM8/ErIJR0TLhDcZQmNc= +is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" @@ -8687,7 +8722,7 @@ lodash.truncate@^4.4.2: resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= -lodash@4.x.x, lodash@^4.0.0, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0: +lodash@^4.0.0, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0: version "4.17.19" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ== @@ -12257,18 +12292,11 @@ shell-quote@1.6.1: array-reduce "~0.0.0" jsonify "~0.0.0" -shell-quote@^1.6.1: +shell-quote@^1.6.1, shell-quote@^1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== -shell-utils@^1.0.9: - version "1.0.10" - resolved "https://registry.yarnpkg.com/shell-utils/-/shell-utils-1.0.10.tgz#7fe7b8084f5d6d21323d941267013bc38aed063e" - integrity sha512-p1xuqhj3jgcXiV8wGoF1eL/NOvapN9tyGDoObqKwvZTUZn7fIzK75swLTEHfGa7sObeN9vxFplHw/zgYUYRTsg== - dependencies: - lodash "4.x.x" - shellwords@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" @@ -13943,7 +13971,7 @@ xtend@~3.0.0: resolved "https://registry.yarnpkg.com/xtend/-/xtend-3.0.0.tgz#5cce7407baf642cba7becda568111c493f59665a" integrity sha1-XM50B7r2Qsunvs2laBEcST9ZZlo= -y18n@^3.2.0, "y18n@^3.2.1 || ^4.0.0", y18n@^3.2.2, y18n@^4.0.0: +y18n@^3.2.0, "y18n@^3.2.1 || ^4.0.0", y18n@^3.2.2, y18n@^4.0.0, y18n@^5.0.5: version "3.2.2" resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696" integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ== @@ -13976,7 +14004,7 @@ yargs-parser@^11.1.1: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^13.0.0, yargs-parser@^13.1.2: +yargs-parser@^13.1.2: version "13.1.2" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== @@ -14000,6 +14028,21 @@ yargs-parser@^18.1.1, yargs-parser@^18.1.2: camelcase "^5.0.0" decamelize "^1.2.0" +yargs-parser@^20.2.2: + version "20.2.7" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a" + integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw== + +yargs-unparser@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + yargs@^12.0.2: version "12.0.5" resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" @@ -14018,7 +14061,7 @@ yargs@^12.0.2: y18n "^3.2.1 || ^4.0.0" yargs-parser "^11.1.1" -yargs@^13.0.0, yargs@^13.2.2, yargs@^13.2.4: +yargs@^13.2.2, yargs@^13.2.4: version "13.3.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== @@ -14085,6 +14128,19 @@ yargs@^15.3.1: y18n "^4.0.0" yargs-parser "^18.1.1" +yargs@^16.0.3: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + yargs@^3.30.0: version "3.32.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.32.0.tgz#03088e9ebf9e756b69751611d2a5ef591482c995"