Skip to content

Commit

Permalink
Detox: Address Book Tests (#1441)
Browse files Browse the repository at this point in the history
* start flow of address book

* make addressbook great again
  • Loading branch information
ibrahimtaveras00 authored Mar 23, 2020
1 parent b082ae4 commit 201cd7e
Show file tree
Hide file tree
Showing 10 changed files with 213 additions and 10 deletions.
10 changes: 5 additions & 5 deletions app/components/UI/Navbar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ export function getNavigationOptionsTitle(title, navigation) {
},
headerTintColor: colors.blue,
headerLeft: (
<TouchableOpacity onPress={navigationPop} style={styles.backButton}>
<TouchableOpacity onPress={navigationPop} style={styles.backButton} testID={'title-back-arrow-button'}>
<IonicIcon
name={Device.isAndroid() ? 'md-arrow-back' : 'ios-arrow-back'}
size={Device.isAndroid() ? 24 : 28}
Expand Down Expand Up @@ -221,7 +221,7 @@ export function getEditableOptions(title, navigation) {
},
headerTintColor: colors.blue,
headerLeft: (
<TouchableOpacity onPress={navigationPop} style={styles.backButton}>
<TouchableOpacity onPress={navigationPop} style={styles.backButton} testID={'edit-contact-back-button'}>
<IonicIcon
name={Device.isAndroid() ? 'md-arrow-back' : 'ios-arrow-back'}
size={Device.isAndroid() ? 24 : 28}
Expand Down Expand Up @@ -358,13 +358,13 @@ export function getSendFlowTitle(title, navigation) {
headerTitle: <NavbarTitle title={title} disableNetwork />,
headerRight: (
// eslint-disable-next-line react/jsx-no-bind
<TouchableOpacity onPress={rightAction} style={styles.closeButton}>
<TouchableOpacity onPress={rightAction} style={styles.closeButton} testID={'send-cancel-button'}>
<Text style={styles.closeButtonText}>{'Cancel'}</Text>
</TouchableOpacity>
),
headerLeft: canGoBack ? (
// eslint-disable-next-line react/jsx-no-bind
<TouchableOpacity onPress={leftAction} style={styles.closeButton}>
<TouchableOpacity onPress={leftAction} style={styles.closeButton} testID={'send-back-button'}>
<Text style={styles.closeButtonText}>{'Back'}</Text>
</TouchableOpacity>
) : (
Expand Down Expand Up @@ -708,7 +708,7 @@ export function getNetworkNavbarOptions(title, translate, navigation) {
headerTitle: <NavbarTitle title={title} translate={translate} />,
headerLeft: (
// eslint-disable-next-line react/jsx-no-bind
<TouchableOpacity onPress={() => navigation.pop()} style={styles.backButton}>
<TouchableOpacity onPress={() => navigation.pop()} style={styles.backButton} testID={'asset-back-button'}>
<IonicIcon
name={Device.isAndroid() ? 'md-arrow-back' : 'ios-arrow-back'}
size={Device.isAndroid() ? 24 : 28}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ exports[`ErrorMessage should render correctly 1`] = `
"padding": 15,
}
}
testID="error-message-warning"
>
<Text
style={
Expand Down
2 changes: 1 addition & 1 deletion app/components/Views/SendFlow/ErrorMessage/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const styles = StyleSheet.create({
export default function ErrorMessage(props) {
const { errorMessage } = props;
return (
<View style={styles.wrapper}>
<View style={styles.wrapper} testID={'error-message-warning'}>
<Text style={styles.errorMessage}>{errorMessage}</Text>
</View>
);
Expand Down
2 changes: 1 addition & 1 deletion app/components/Views/SendFlow/SendTo/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ class SendFlow extends PureComponent {
</Text>
</TouchableOpacity>
)}
<View style={styles.footerContainer}>
<View style={styles.footerContainer} testID={'no-eth-message'}>
{balanceIsZero && (
<View style={styles.warningContainer}>
<WarningMessage warningMessage={strings('transaction.not_enough_for_gas')} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ exports[`ContactForm should render correctly 1`] = `
"flexDirection": "column",
}
}
testID="add-contact-screen"
>
<KeyboardAwareScrollViewMock
enableAutomaticScroll={true}
Expand Down Expand Up @@ -76,6 +77,7 @@ exports[`ContactForm should render correctly 1`] = `
Object {},
]
}
testID="contact-name-input"
underlineColorAndroid="transparent"
/>
<Text
Expand Down Expand Up @@ -142,6 +144,7 @@ exports[`ContactForm should render correctly 1`] = `
Object {},
]
}
testID="contact-address-input"
underlineColorAndroid="transparent"
/>
</View>
Expand Down Expand Up @@ -232,6 +235,7 @@ exports[`ContactForm should render correctly 1`] = `
Object {},
]
}
testID="contact-memo-input"
underlineColorAndroid="transparent"
/>
</View>
Expand Down Expand Up @@ -275,6 +279,7 @@ exports[`ContactForm should render correctly 1`] = `
"opacity": 0.6,
}
}
testID="contact-add-contact-button"
type="confirm"
>
Add contact
Expand Down
6 changes: 5 additions & 1 deletion app/components/Views/Settings/Contacts/ContactForm/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ class ContactForm extends PureComponent {
render = () => {
const { address, addressError, toEnsName, name, mode, addressReady, memo, editable, inputWidth } = this.state;
return (
<SafeAreaView style={styles.wrapper}>
<SafeAreaView style={styles.wrapper} testID={'add-contact-screen'}>
<KeyboardAwareScrollView style={styles.informationWrapper}>
<View style={styles.scrollWrapper}>
<Text style={styles.label}>{strings('address_book.name')}</Text>
Expand All @@ -272,6 +272,7 @@ class ContactForm extends PureComponent {
]}
value={name}
onSubmitEditing={this.jumpToAddressInput}
testID={'contact-name-input'}
/>

<Text style={styles.label}>{strings('address_book.address')}</Text>
Expand All @@ -290,6 +291,7 @@ class ContactForm extends PureComponent {
value={toEnsName || address}
ref={this.addressInput}
onSubmitEditing={this.jumpToMemoInput}
testID={'contact-address-input'}
/>
{toEnsName && <Text style={styles.resolvedInput}>{renderShortAddress(address)}</Text>}
</View>
Expand Down Expand Up @@ -317,6 +319,7 @@ class ContactForm extends PureComponent {
style={[styles.textInput, inputWidth ? { width: inputWidth } : {}]}
value={memo}
ref={this.memoInput}
testID={'contact-memo-input'}
/>
</View>
</View>
Expand All @@ -332,6 +335,7 @@ class ContactForm extends PureComponent {
type={'confirm'}
disabled={!addressReady || !name || !!addressError}
onPress={this.saveContact}
testID={'contact-add-contact-button'}
>
{strings(`address_book.${mode}_contact`)}
</StyledButton>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ exports[`Contacts should render correctly 1`] = `
"flex": 1,
}
}
testID="contacts-screen"
>
<Connect(AddressList)
onAccountLongPress={[Function]}
Expand All @@ -33,6 +34,7 @@ exports[`Contacts should render correctly 1`] = `
"opacity": 0.6,
}
}
testID="add-contact-button"
type="confirm"
>
Add contact
Expand Down
9 changes: 7 additions & 2 deletions app/components/Views/Settings/Contacts/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,19 @@ class Contacts extends PureComponent {
render = () => {
const { reloadAddressList } = this.state;
return (
<SafeAreaView style={styles.wrapper}>
<SafeAreaView style={styles.wrapper} testID={'contacts-screen'}>
<AddressList
onlyRenderAddressBook
reloadAddressList={reloadAddressList}
onAccountPress={this.onAddressPress}
onAccountLongPress={this.onAddressLongPress}
/>
<StyledButton type={'confirm'} containerStyle={styles.addContact} onPress={this.goToAddContact}>
<StyledButton
type={'confirm'}
containerStyle={styles.addContact}
onPress={this.goToAddContact}
testID={'add-contact-button'}
>
{strings('address_book.add_contact')}
</StyledButton>
<ActionSheet
Expand Down
182 changes: 182 additions & 0 deletions e2e/addressbook-tests.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
'use strict';
import TestHelpers from './helpers';

const INVALID_ADDRESS = '0xB8B4EE5B1b693971eB60bDa15211570df2dB221L';
const MYTH_ADDRESS = '0x1FDb169Ef12954F20A15852980e1F0C122BfC1D6';
const MEMO = 'Test adding ENS';

describe('Addressbook Tests', () => {
beforeEach(() => {
jest.setTimeout(150000);
});

it('should create new wallet and dismiss tutorial', async () => {
// Check that we are on the onboarding carousel screen
await TestHelpers.checkIfVisible('onboarding-carousel-screen');
// Check that Get started CTA is visible & tap it
await TestHelpers.waitAndTap('onboarding-get-started-button');
// Check that we are on the onboarding screen
await TestHelpers.checkIfVisible('onboarding-screen');
// Check that Start Exploring CTA is visible & tap it
await TestHelpers.waitAndTap('start-exploring-button');
// Check that we are on the metametrics optIn screen
await TestHelpers.checkIfVisible('metaMetrics-OptIn');
// Check that I Agree CTA is visible and tap it
await TestHelpers.waitAndTap('agree-button');
// Check that we are on the wallet screen
if (!device.getPlatform() === 'android') {
// Check that we are on the wallet screen
await TestHelpers.checkIfExists('wallet-screen');
}
// Check that the onboarding wizard is present
await TestHelpers.checkIfVisible('onboarding-wizard-step1-view');
// Check that No thanks CTA is visible and tap it
await TestHelpers.waitAndTap('onboarding-wizard-back-button');
// Check that the onboarding wizard is gone
await TestHelpers.checkIfNotVisible('onboarding-wizard-step1-view');
});

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');
// Tap on Send button
await TestHelpers.tapByText('SEND');
// Check that we are on the send screen
await TestHelpers.checkIfVisible('send-screen');
// Make sure view with my accounts visible
await TestHelpers.checkIfExists('my-accounts-button');
});

it('should input a valid address to send to', async () => {
// Input incorrect address
await TestHelpers.typeTextAndHideKeyboard('txn-to-address-input', INVALID_ADDRESS);
// Check that the error is displayed
await TestHelpers.checkIfVisible('address-error');
// Clear text
await TestHelpers.clearField('txn-to-address-input');
// Input valid myth address
await TestHelpers.typeTextAndHideKeyboard('txn-to-address-input', MYTH_ADDRESS);
// Check that the warning appears at the bottom of the screen
await TestHelpers.checkIfVisible('no-eth-message');
});

it('should add a new address to address book via send flow', async () => {
// Tap on add this address to your address book
await TestHelpers.waitAndTap('add-address-button');
// Make sure address book modal is displayed
await TestHelpers.checkIfExists('add-address-modal');
// Input alias
await TestHelpers.typeTextAndHideKeyboard('address-alias-input', 'Myth');
// Save contact
await TestHelpers.tapByText('Save');
// Clear address
await TestHelpers.tap('clear-address-button');
// Check that the new account is on the address list
await TestHelpers.checkIfElementWithTextIsVisible('Myth');
});

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
await TestHelpers.tap('hamburger-menu-button-wallet');
// Check that the drawer is visbile
await TestHelpers.checkIfVisible('drawer-screen');
// Tap on settings
await TestHelpers.tap('settings-button');
// Tap on the "Contacts" option
await TestHelpers.tapByText('Contacts');
// Check that we are on the contacts screen
await TestHelpers.checkIfVisible('contacts-screen');
// Check that Myth address is saved in the address book
await TestHelpers.checkIfElementWithTextIsVisible('Myth');
});

it('should add an address via the contacts view', async () => {
// Tap on add contact button
await TestHelpers.tap('add-contact-button');
// Check that we are on the add contact screen
await TestHelpers.checkIfVisible('add-contact-screen');
// Input a name
await TestHelpers.typeTextAndHideKeyboard('contact-name-input', 'Ibrahim');
// Input invalid address
await TestHelpers.replaceTextInField('contact-address-input', INVALID_ADDRESS);
// Check that warning is shown
await TestHelpers.checkIfVisible('error-message-warning');
// Check warning is for the right reason
await TestHelpers.checkIfElementHasString('error-message-warning', 'Invalid address');
// Clear address input field
await TestHelpers.clearField('contact-address-input');
// Replace address with valid ENS address
await TestHelpers.replaceTextInField('contact-address-input', 'ibrahim.team.mask.eth');
// Add a memo
await TestHelpers.typeTextAndHideKeyboard('contact-memo-input', MEMO);
// Tap add contact button
await TestHelpers.tap('contact-add-contact-button');
// Tap add contact button
await TestHelpers.tap('contact-add-contact-button');
// Check that we are on the contacts screen
await TestHelpers.checkIfVisible('contacts-screen');
// Check that Ibrahim address is saved in the address book
await TestHelpers.checkIfElementWithTextIsVisible('Ibrahim');
});

it('should edit a contact', async () => {
// Tap on Myth address
await TestHelpers.tapByText('Myth');
// Tap on edit
await TestHelpers.tapByText('Edit');
// Change name from Myth to Moon
await TestHelpers.replaceTextInField('contact-name-input', 'Moon');
// Tap on Edit contact button
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
await TestHelpers.checkIfElementWithTextIsVisible('Moon');
// Ensure Myth is not visible
await TestHelpers.checkIfElementWithTextIsNotVisible('Myth');
});

it('should remove a contact', async () => {
// Tap on Moon address
await TestHelpers.tapByText('Moon');
// Tap on edit
await TestHelpers.tapByText('Edit');
// Tap on Delete
await TestHelpers.tapByText('Delete');
// Tap on Delete
await TestHelpers.tapByText('Delete');
// Ensure Moon is not visible
await TestHelpers.checkIfElementWithTextIsNotVisible('Moon');
});

it('should go back to send flow to validate newly added address is displayed', async () => {
// tap on the back arrow
await TestHelpers.tap('title-back-arrow-button');
// tap to get out of settings view
if (device.getPlatform() === 'android') {
await device.pressBack();
} else {
await TestHelpers.tapByText('Close');
}
// check we are on wallet screen
await TestHelpers.checkIfVisible('wallet-screen');
// Open Drawer
await TestHelpers.tap('hamburger-menu-button-wallet');
// Check that the drawer is visbile
await TestHelpers.checkIfVisible('drawer-screen');
// Tap on send
await TestHelpers.tapByText('Send');
// Check that the new account is on the address list
await TestHelpers.checkIfElementWithTextIsVisible('Ibrahim');
});
});
4 changes: 4 additions & 0 deletions e2e/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ export default class TestHelpers {
.withTimeout(10000);
}

static checkIfElementWithTextIsNotVisible(text) {
return expect(element(by.text(text)).atIndex(0)).toBeNotVisible();
}

static checkIfExists(elementId) {
return expect(element(by.id(elementId))).toExist();
}
Expand Down

0 comments on commit 201cd7e

Please sign in to comment.