Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detox: Import seed phrase and validate via settings #1056

Merged
merged 3 commits into from Sep 4, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 5 additions & 1 deletion app/components/UI/DrawerView/index.js
Expand Up @@ -831,7 +831,11 @@ class DrawerView extends PureComponent {
<Image source={metamask_fox} style={styles.metamaskFox} resizeMethod={'auto'} />
<Image source={metamask_name} style={styles.metamaskName} resizeMethod={'auto'} />
</View>
<TouchableOpacity style={styles.settings} onPress={this.showSettings}>
<TouchableOpacity
style={styles.settings}
testID={`settings-button`}
onPress={this.showSettings}
>
<FeatherIcon name="settings" size={22} style={styles.settingsIcon} />
</TouchableOpacity>
</View>
Expand Down
8 changes: 7 additions & 1 deletion app/components/Views/ImportFromSeed/index.js
Expand Up @@ -519,6 +519,7 @@ class ImportFromSeed extends PureComponent {
<TextInput
ref={this.passwordInput}
style={styles.input}
testID={'input-password-field'}
value={this.state.password}
onChangeText={this.onPasswordChange} // eslint-disable-line react/jsx-no-bind
secureTextEntry={this.state.secureTextEntry}
Expand Down Expand Up @@ -564,6 +565,7 @@ class ImportFromSeed extends PureComponent {
<TextInput
ref={this.confirmPasswordInput}
style={styles.input}
testID={'input-password-field-confirm'}
value={this.state.confirmPassword}
onChangeText={this.onPasswordConfirmChange} // eslint-disable-line react/jsx-no-bind
secureTextEntry={this.state.secureTextEntry}
Expand All @@ -587,7 +589,11 @@ class ImportFromSeed extends PureComponent {

{this.renderSwitch()}

{!!this.state.error && <Text style={styles.errorMsg}>{this.state.error}</Text>}
{!!this.state.error && (
<Text style={styles.errorMsg} testID={'invalid-seed-phrase'}>
{this.state.error}
</Text>
)}

<View style={styles.ctaWrapper}>
<StyledButton
Expand Down
8 changes: 2 additions & 6 deletions app/components/Views/ImportWallet/index.js
Expand Up @@ -465,13 +465,9 @@ class ImportWallet extends PureComponent {

render() {
return (
<View style={baseStyles.flexGrow}>
<View style={baseStyles.flexGrow} testID={'import-wallet-screen'}>
<OnboardingScreenWithBg screen={'a'}>
<ScrollView
style={baseStyles.flexGrow}
contentContainerStyle={styles.scroll}
testID={'import-wallet-screen'}
>
<ScrollView style={baseStyles.flexGrow} contentContainerStyle={styles.scroll}>
<View style={styles.wrapper}>
{!this.state.loading && (
<View style={styles.foxWrapper}>
Expand Down
9 changes: 7 additions & 2 deletions app/components/Views/Login/index.js
Expand Up @@ -301,6 +301,7 @@ class Login extends PureComponent {
<Text style={styles.label}>{strings('login.password')}</Text>
<TextInput
style={styles.input}
testID={'login-password-input'}
value={this.state.password}
onChangeText={this.setPassword}
secureTextEntry
Expand All @@ -314,9 +315,13 @@ class Login extends PureComponent {

{this.renderSwitch()}

{!!this.state.error && <Text style={styles.errorMsg}>{this.state.error}</Text>}
{!!this.state.error && (
<Text style={styles.errorMsg} testID={'invalid-password-error'}>
{this.state.error}
</Text>
)}

<View style={styles.ctaWrapper}>
<View style={styles.ctaWrapper} testID={'log-in-button'}>
<StyledButton type={'confirm'} onPress={this.onLogin}>
{this.state.loading ? (
<ActivityIndicator size="small" color="white" />
Expand Down
7 changes: 5 additions & 2 deletions app/components/Views/RevealPrivateCredential/index.js
Expand Up @@ -267,6 +267,7 @@ class RevealPrivateCredential extends PureComponent {
cancelText={strings('reveal_credential.cancel')}
confirmText={strings('reveal_credential.confirm')}
onCancelPress={this.cancel}
testID={`next-button`}
onConfirmPress={this.tryUnlock}
showConfirmButton={!unlocked}
>
Expand Down Expand Up @@ -326,13 +327,15 @@ class RevealPrivateCredential extends PureComponent {
</Text>
<TextInput
style={styles.input}
testID={'private-credential-password-text-input'}
placeholder={'Password'}
onChangeText={this.onPasswordChange}
secureTextEntry
onSubmitEditing={this.tryUnlock}
testID={'private-credential-password-text-input'}
/>
<Text style={styles.warningText}>{this.state.warningIncorrectPassword}</Text>
<Text style={styles.warningText} testID={'password-warning'}>
{this.state.warningIncorrectPassword}
</Text>
</View>
)}
</View>
Expand Down
9 changes: 6 additions & 3 deletions app/components/Views/Settings/SecuritySettings/index.js
Expand Up @@ -466,7 +466,7 @@ class Settings extends PureComponent {
/>
</View>
</View>
<View style={styles.setting}>
<View style={styles.setting} testID={'clear-privacy'}>
<Text style={styles.title}>{strings('app_settings.clear_privacy_title')}</Text>
<Text style={styles.desc}>{strings('app_settings.clear_privacy_desc')}</Text>
<StyledButton
Expand Down Expand Up @@ -505,7 +505,7 @@ class Settings extends PureComponent {
</View>
</View>
{biometryType && (
<View style={styles.setting}>
<View style={styles.setting} testID={'biometrics-option'}>
<Text style={styles.title}>
{strings(`biometrics.enable_${this.state.biometryType.toLowerCase()}`)}
</Text>
Expand Down Expand Up @@ -560,10 +560,13 @@ class Settings extends PureComponent {
</StyledButton>
</View>
<View style={styles.setting}>
<Text style={styles.title}>{strings('reveal_credential.seed_phrase_title')}</Text>
<Text style={styles.title} testID={'reveal-seed-title'}>
{strings('reveal_credential.seed_phrase_title')}
</Text>
<Text style={[styles.desc, styles.red]}>{strings('reveal_credential.seed_warning')}</Text>
<StyledButton
type="danger"
testID={'reveal-seedphrase-button'}
onPress={this.goToRevealPrivateCredential}
containerStyle={styles.clearHistoryConfirm}
>
Expand Down
12 changes: 11 additions & 1 deletion e2e/helpers.js
Expand Up @@ -2,7 +2,7 @@ export default class TestHelpers {
static async waitAndTap(elementId) {
await waitFor(element(by.id(elementId)))
.toBeVisible()
.withTimeout(5000);
.withTimeout(8000);

return element(by.id(elementId)).tap();
}
Expand Down Expand Up @@ -48,6 +48,16 @@ export default class TestHelpers {
}
}

static async selectAllAndClear(elementId) {
await TestHelpers.tapByText('Select All');
return element(by.id(elementId)).tapBackspaceKey();
}

static async tapAndLongPress(elementId) {
await TestHelpers.tap(elementId);
return element(by.id(elementId)).longPress();
}

static tapAlertWithButton(text) {
if (device.getPlatform() === 'android') {
return element(by.text(text))
Expand Down
107 changes: 107 additions & 0 deletions e2e/import-seed-phrase.spec.js
@@ -0,0 +1,107 @@
'use strict';
import TestHelpers from './helpers';

const Incorrect_Seed_Words = 'fold media south add since false relax immense pause cloth just falcon';
const Correct_Seed_Words = 'fold media south add since false relax immense pause cloth just raven';
const Incorrect_Password_Length = 'The password needs to be at least 8 characters long';
const Invalid_Seed_Error = `Error: Seed phrase is invalid.`;
const Correct_Password = `12345678`;
const Incorrect_Password = `1234567`;
const Password_Warning = "Couldn't unlock your account. Please try again.";

describe('Import seedphrase flow', () => {
beforeEach(() => {
jest.setTimeout(90000);
});

it('should import via seed phrase and validate in settings', async () => {
// Check that we are on the home screen
await TestHelpers.checkIfVisible('home-screen');
// Check that Sync or import your wallet CTA is visible & tap it
await TestHelpers.waitAndTap('onboarding-import-button');
// Check that we are on the import wallet screen
await TestHelpers.checkIfVisible('import-wallet-screen');
// Check that Import using seed phrase CTA is visible & tap it
await TestHelpers.waitAndTap('import-wallet-import-from-seed-button');
// Check that we are on the import from seed screen
await TestHelpers.checkIfVisible('import-from-seed-screen');
// Input incorrect seed phrase
await TestHelpers.typeTextAndHideKeyboard(`input-seed-phrase`, Incorrect_Seed_Words);
// Input short password
await TestHelpers.typeTextAndHideKeyboard(`input-password-field`, Incorrect_Password);
// Input short password confirm
await TestHelpers.typeTextAndHideKeyboard(`input-password-field-confirm`, Incorrect_Password);
// ensure alert box is displayed with correct text
await TestHelpers.checkIfElementByTextIsVisible(Incorrect_Password_Length);
// dismiss alert by tapping ok
await element(by.label('OK'))
.atIndex(0)
.tap();
// Input password
await TestHelpers.typeTextAndHideKeyboard(`input-password-field`, Correct_Password);
// Input password confirm
await TestHelpers.typeTextAndHideKeyboard(`input-password-field-confirm`, Correct_Password);
// Ensure error is displayed
await TestHelpers.checkIfHasText('invalid-seed-phrase', Invalid_Seed_Error);
// Tap back into seed phrase text input and long press
await TestHelpers.tapAndLongPress('input-seed-phrase');
// Select all and delete
await TestHelpers.selectAllAndClear('input-seed-phrase');
// Input correct seed phrase
await TestHelpers.typeTextAndHideKeyboard(`input-seed-phrase`, Correct_Seed_Words);
// Tap outside of box
await TestHelpers.tapAtPoint('import-from-seed-screen', { x: 40, y: 20 });
// Tap import to continue
await TestHelpers.waitAndTap('submit');
// 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
await TestHelpers.checkIfExists('wallet-screen');
// 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');
// Open Drawer
await TestHelpers.tapAtPoint('wallet-screen', { x: 30, y: -5 });
// Check that the drawer is visbile
await TestHelpers.checkIfVisible('drawer-screen');
// Tap on settings
await TestHelpers.tap('settings-button');
// Tap on the "Security & Privacy" option
await TestHelpers.tapByText('Security & Privacy');
// Swipe up the screen
await TestHelpers.swipe('clear-privacy', 'up');
// Check that you are on bottom of screen
await TestHelpers.checkIfVisible('reveal-seed-title');
// Tap on Reveal Seed Phrase Button
await TestHelpers.waitAndTap('reveal-seedphrase-button');
// Check that we are on the reveal seed phrase screen
await TestHelpers.checkIfVisible('reveal-private-credential-screen');
// Input incorrect password
await TestHelpers.typeTextAndHideKeyboard('private-credential-password-text-input', Incorrect_Password);
// Ensure error is displayed
await TestHelpers.checkIfHasText('password-warning', Password_Warning);
// Input correct password
await TestHelpers.typeTextAndHideKeyboard('private-credential-password-text-input', Correct_Password);
// Ensure password field no longer is shown
await TestHelpers.checkIfNotVisible('private-credential-password-text-input');
// Seed phrase should now be revealed
await TestHelpers.checkIfVisible('private-credential-touchable');
// Check that the seed phrase displayed matches what we inputted in the beginning
await TestHelpers.checkIfHasText('private-credential-text', Correct_Seed_Words);
// Relaunch app
await TestHelpers.relaunchApp();
// Check that we are on login screen
await TestHelpers.checkIfVisible('login');
// Tap on log in button
await TestHelpers.tap('log-in-button');
// Check that the invalid error is displayed
await TestHelpers.checkIfVisible('invalid-password-error');
// Log in
await TestHelpers.typeTextAndHideKeyboard('login-password-input', Correct_Password);
// Check that we are on the Browser page
await TestHelpers.checkIfVisible('browser-screen');
});
});