mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-02-22 15:04:50 +01:00
Merge pull request #6208 from BlueWallet/tst-ms-import-cosigners
TST: e2e test to import individual multisig cosigners
This commit is contained in:
commit
409f43c165
7 changed files with 127 additions and 12 deletions
|
@ -68,7 +68,7 @@ const BottomModal: React.FC<BottomModalProps> = ({
|
||||||
{props.children}
|
{props.children}
|
||||||
{doneButton && (
|
{doneButton && (
|
||||||
<View style={[styles.hasDoneButton, stylesHook.hasDoneButton]}>
|
<View style={[styles.hasDoneButton, stylesHook.hasDoneButton]}>
|
||||||
<Button title={loc.send.input_done} onPress={onClose} />
|
<Button title={loc.send.input_done} onPress={onClose} testID="ModalDoneButton" />
|
||||||
<BlueSpacing10 />
|
<BlueSpacing10 />
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -106,6 +106,7 @@ const MultipleStepsListItem = props => {
|
||||||
{props.button.buttonType === undefined ||
|
{props.button.buttonType === undefined ||
|
||||||
(props.button.buttonType === MultipleStepsListItemButtohType.full && (
|
(props.button.buttonType === MultipleStepsListItemButtohType.full && (
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
|
testID={props.button.testID}
|
||||||
accessibilityRole="button"
|
accessibilityRole="button"
|
||||||
disabled={props.button.disabled}
|
disabled={props.button.disabled}
|
||||||
style={[styles.provideKeyButton, stylesHook.provideKeyButton, buttonOpacity]}
|
style={[styles.provideKeyButton, stylesHook.provideKeyButton, buttonOpacity]}
|
||||||
|
@ -120,6 +121,7 @@ const MultipleStepsListItem = props => {
|
||||||
{props.button.leftText}
|
{props.button.leftText}
|
||||||
</Text>
|
</Text>
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
|
testID={props.button.testID}
|
||||||
accessibilityRole="button"
|
accessibilityRole="button"
|
||||||
disabled={props.button.disabled}
|
disabled={props.button.disabled}
|
||||||
style={[styles.rowPartialRightButton, stylesHook.provideKeyButton, rightButtonOpacity]}
|
style={[styles.rowPartialRightButton, stylesHook.provideKeyButton, rightButtonOpacity]}
|
||||||
|
|
|
@ -65,9 +65,9 @@ const styles = StyleSheet.create({
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
},
|
},
|
||||||
backdoorButton: {
|
backdoorButton: {
|
||||||
width: 40,
|
width: 60,
|
||||||
height: 40,
|
height: 60,
|
||||||
backgroundColor: 'rgba(0,0,0,0.1)',
|
backgroundColor: 'rgba(0,0,0,0.01)',
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
},
|
},
|
||||||
backdoorInputWrapper: { position: 'absolute', left: '5%', top: '0%', width: '90%', height: '70%', backgroundColor: 'white' },
|
backdoorInputWrapper: { position: 'absolute', left: '5%', top: '0%', width: '90%', height: '70%', backgroundColor: 'white' },
|
||||||
|
|
|
@ -414,7 +414,12 @@ const WalletsAdd: React.FC = () => {
|
||||||
text="LDK"
|
text="LDK"
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
<VaultButton active={selectedWalletType === ButtonSelected.VAULT} onPress={handleOnVaultButtonPressed} style={styles.button} />
|
<VaultButton
|
||||||
|
testID="ActivateVaultButton"
|
||||||
|
active={selectedWalletType === ButtonSelected.VAULT}
|
||||||
|
onPress={handleOnVaultButtonPressed}
|
||||||
|
style={styles.button}
|
||||||
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={styles.advanced}>
|
<View style={styles.advanced}>
|
||||||
|
|
|
@ -142,7 +142,13 @@ const WalletsAddMultisig = () => {
|
||||||
<Icon name="chevron-up" size={22} type="font-awesome-5" color={n === 7 ? colors.buttonDisabledTextColor : '#007AFF'} />
|
<Icon name="chevron-up" size={22} type="font-awesome-5" color={n === 7 ? colors.buttonDisabledTextColor : '#007AFF'} />
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
<Text style={[styles.textM, stylesHook.textHeader]}>{n}</Text>
|
<Text style={[styles.textM, stylesHook.textHeader]}>{n}</Text>
|
||||||
<TouchableOpacity accessibilityRole="button" onPress={decreaseN} disabled={n === m} style={styles.chevron}>
|
<TouchableOpacity
|
||||||
|
accessibilityRole="button"
|
||||||
|
onPress={decreaseN}
|
||||||
|
disabled={n === m}
|
||||||
|
style={styles.chevron}
|
||||||
|
testID="DecreaseN"
|
||||||
|
>
|
||||||
<Icon name="chevron-down" size={22} type="font-awesome-5" color={n === m ? colors.buttonDisabledTextColor : '#007AFF'} />
|
<Icon name="chevron-down" size={22} type="font-awesome-5" color={n === m ? colors.buttonDisabledTextColor : '#007AFF'} />
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
|
@ -224,6 +230,7 @@ const WalletsAddMultisig = () => {
|
||||||
{isAdvancedModeEnabledRender && (
|
{isAdvancedModeEnabledRender && (
|
||||||
<View>
|
<View>
|
||||||
<ListItem
|
<ListItem
|
||||||
|
testID="VaultAdvancedCustomize"
|
||||||
onPress={showAdvancedOptionsModal}
|
onPress={showAdvancedOptionsModal}
|
||||||
title={loc.multisig.vault_advanced_customize}
|
title={loc.multisig.vault_advanced_customize}
|
||||||
subtitle={`${getCurrentlySelectedFormat('format')}, ${getCurrentlySelectedFormat('quorum')}`}
|
subtitle={`${getCurrentlySelectedFormat('format')}, ${getCurrentlySelectedFormat('quorum')}`}
|
||||||
|
@ -232,7 +239,12 @@ const WalletsAddMultisig = () => {
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
<View style={styles.buttonContainer}>
|
<View style={styles.buttonContainer}>
|
||||||
<Button buttonTextColor={colors.buttonAlternativeTextColor} title={loc.multisig.lets_start} onPress={onLetsStartPress} />
|
<Button
|
||||||
|
testID="LetsStart"
|
||||||
|
buttonTextColor={colors.buttonAlternativeTextColor}
|
||||||
|
title={loc.multisig.lets_start}
|
||||||
|
onPress={onLetsStartPress}
|
||||||
|
/>
|
||||||
</View>
|
</View>
|
||||||
{renderModal()}
|
{renderModal()}
|
||||||
</SafeArea>
|
</SafeArea>
|
||||||
|
|
|
@ -531,6 +531,7 @@ const WalletsAddMultisigStep2 = () => {
|
||||||
/>
|
/>
|
||||||
<MultipleStepsListItem
|
<MultipleStepsListItem
|
||||||
button={{
|
button={{
|
||||||
|
testID: 'VaultCosignerImport' + String(el.index + 1),
|
||||||
onPress: iHaveMnemonics,
|
onPress: iHaveMnemonics,
|
||||||
buttonType: MultipleStepsListItemButtohType.full,
|
buttonType: MultipleStepsListItemButtohType.full,
|
||||||
text: loc.wallets.import_do_import,
|
text: loc.wallets.import_do_import,
|
||||||
|
@ -627,9 +628,20 @@ const WalletsAddMultisigStep2 = () => {
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<ActivityIndicator />
|
<ActivityIndicator />
|
||||||
) : (
|
) : (
|
||||||
<Button disabled={importText.trim().length === 0} title={loc.wallets.import_do_import} onPress={useMnemonicPhrase} />
|
<Button
|
||||||
|
testID="DoImportKeyButton"
|
||||||
|
disabled={importText.trim().length === 0}
|
||||||
|
title={loc.wallets.import_do_import}
|
||||||
|
onPress={useMnemonicPhrase}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
<BlueButtonLink ref={openScannerButton} disabled={isLoading} onPress={scanOrOpenFile} title={loc.wallets.import_scan_qr} />
|
<BlueButtonLink
|
||||||
|
testID="ScanOrOpenFile"
|
||||||
|
ref={openScannerButton}
|
||||||
|
disabled={isLoading}
|
||||||
|
onPress={scanOrOpenFile}
|
||||||
|
title={loc.wallets.import_scan_qr}
|
||||||
|
/>
|
||||||
</View>
|
</View>
|
||||||
</KeyboardAvoidingView>
|
</KeyboardAvoidingView>
|
||||||
</BottomModal>
|
</BottomModal>
|
||||||
|
@ -651,7 +663,9 @@ const WalletsAddMultisigStep2 = () => {
|
||||||
<BottomModal isVisible={isRenderCosignersXpubModalVisible} onClose={hideCosignersXpubModal}>
|
<BottomModal isVisible={isRenderCosignersXpubModalVisible} onClose={hideCosignersXpubModal}>
|
||||||
<KeyboardAvoidingView enabled={!Platform.isPad} behavior={Platform.OS === 'ios' ? 'position' : null}>
|
<KeyboardAvoidingView enabled={!Platform.isPad} behavior={Platform.OS === 'ios' ? 'position' : null}>
|
||||||
<View style={[styles.modalContent, stylesHook.modalContent, styles.alignItemsCenter]}>
|
<View style={[styles.modalContent, stylesHook.modalContent, styles.alignItemsCenter]}>
|
||||||
<Text style={[styles.headerText, stylesHook.textDestination]}>{loc.multisig.this_is_cosigners_xpub} {Platform.OS === "ios" ? loc.multisig.this_is_cosigners_xpub_airdrop : ""}</Text>
|
<Text style={[styles.headerText, stylesHook.textDestination]}>
|
||||||
|
{loc.multisig.this_is_cosigners_xpub} {Platform.OS === 'ios' ? loc.multisig.this_is_cosigners_xpub_airdrop : ''}
|
||||||
|
</Text>
|
||||||
<BlueSpacing20 />
|
<BlueSpacing20 />
|
||||||
<QRCodeComponent value={cosignerXpubURv2} size={260} />
|
<QRCodeComponent value={cosignerXpubURv2} size={260} />
|
||||||
<BlueSpacing20 />
|
<BlueSpacing20 />
|
||||||
|
@ -681,7 +695,11 @@ const WalletsAddMultisigStep2 = () => {
|
||||||
|
|
||||||
const footer = (
|
const footer = (
|
||||||
<View style={styles.buttonBottom}>
|
<View style={styles.buttonBottom}>
|
||||||
{isLoading ? <ActivityIndicator /> : <Button title={loc.multisig.create} onPress={onCreate} disabled={cosigners.length !== n} />}
|
{isLoading ? (
|
||||||
|
<ActivityIndicator />
|
||||||
|
) : (
|
||||||
|
<Button testID="CreateButton" title={loc.multisig.create} onPress={onCreate} disabled={cosigners.length !== n} />
|
||||||
|
)}
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -452,6 +452,84 @@ describe('BlueWallet UI Tests - no wallets', () => {
|
||||||
process.env.TRAVIS && require('fs').writeFileSync(lockFile, '1');
|
process.env.TRAVIS && require('fs').writeFileSync(lockFile, '1');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('can import 2of2 multisig using individual cosigners (1 signer, 1 xpub)', async () => {
|
||||||
|
const lockFile = '/tmp/travislock.' + hashIt('can import 2of2 multisig using individual cosigners (1 signer, 1 xpub)');
|
||||||
|
if (process.env.TRAVIS) {
|
||||||
|
if (require('fs').existsSync(lockFile)) return console.warn('skipping as it previously passed on Travis');
|
||||||
|
}
|
||||||
|
await device.launchApp({ newInstance: true });
|
||||||
|
await helperSwitchAdvancedMode();
|
||||||
|
await yo('WalletsList');
|
||||||
|
await element(by.id('WalletsList')).swipe('left', 'fast', 1); // in case emu screen is small and it doesnt fit
|
||||||
|
// going to Import Wallet screen and importing Vault
|
||||||
|
await element(by.id('CreateAWallet')).tap();
|
||||||
|
await yo('ActivateVaultButton');
|
||||||
|
await element(by.id('ActivateVaultButton')).tap();
|
||||||
|
await element(by.id('Create')).tap();
|
||||||
|
// vault settings:
|
||||||
|
await element(by.id('VaultAdvancedCustomize')).tap();
|
||||||
|
await element(by.id('DecreaseN')).tap();
|
||||||
|
await element(by.id('ModalDoneButton')).tap();
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
await element(by.id('LetsStart')).tap();
|
||||||
|
|
||||||
|
// key1 - seed:
|
||||||
|
|
||||||
|
await element(by.id('VaultCosignerImport1')).tap();
|
||||||
|
await element(by.id('ScanOrOpenFile')).tap();
|
||||||
|
|
||||||
|
await sleep(5000); // wait for camera screen to initialize
|
||||||
|
for (let c = 0; c <= 5; c++) {
|
||||||
|
await element(by.id('ScanQrBackdoorButton')).tap();
|
||||||
|
}
|
||||||
|
await element(by.id('scanQrBackdoorInput')).replaceText(
|
||||||
|
'pipe goose bottom run seed curious thought kangaroo example family coral success',
|
||||||
|
);
|
||||||
|
await element(by.id('scanQrBackdoorOkButton')).tap();
|
||||||
|
await element(by.id('DoImportKeyButton')).tap(); // when seed - need to extra tap the button
|
||||||
|
|
||||||
|
// key2 - xpub:
|
||||||
|
|
||||||
|
await element(by.id('VaultCosignerImport2')).tap();
|
||||||
|
await element(by.id('ScanOrOpenFile')).tap();
|
||||||
|
|
||||||
|
await sleep(5000); // wait for camera screen to initialize
|
||||||
|
for (let c = 0; c <= 5; c++) {
|
||||||
|
await element(by.id('ScanQrBackdoorButton')).tap();
|
||||||
|
}
|
||||||
|
await element(by.id('scanQrBackdoorInput')).replaceText(
|
||||||
|
'ur:crypto-account/oeadcypdlouebgaolytaadmetaaddloxaxhdclaxfdyksnwkuypkfevlfzfroyiyecoeosbakbpdcldawzhtcarkwsndcphphsbsdsayaahdcxfgjyckryosmwtdptlbflonbkimlsmovolslbytonayisprvoieftgeflzcrtvesbamtaaddyotadlocsdyykaeykaeykaoykaocypdlouebgaxaaaycyttatrnolimvetsst',
|
||||||
|
);
|
||||||
|
await element(by.id('scanQrBackdoorOkButton')).tap();
|
||||||
|
// when xpub - it automatically closes the modal, so no need to tap the button
|
||||||
|
|
||||||
|
await element(by.id('CreateButton')).tap();
|
||||||
|
await yo('Multisig Vault');
|
||||||
|
await element(by.id('Multisig Vault')).tap(); // go inside the wallet
|
||||||
|
|
||||||
|
await element(by.id('ReceiveButton')).tap();
|
||||||
|
await element(by.text('Yes, I have.')).tap();
|
||||||
|
try {
|
||||||
|
// in case emulator has no google services and doesnt support pushes
|
||||||
|
// we just dont show this popup
|
||||||
|
await element(by.text(`No, and do not ask me again.`)).tap();
|
||||||
|
} catch (_) {}
|
||||||
|
|
||||||
|
await sup('bc1qmf06nt4jhvzz4387ak8fecs42k6jqygr2unumetfc7xkdup7ah9s8phlup');
|
||||||
|
|
||||||
|
await device.pressBack();
|
||||||
|
|
||||||
|
await element(by.id('WalletDetails')).tap();
|
||||||
|
await sup('2 / 2 (native segwit)');
|
||||||
|
|
||||||
|
await device.pressBack();
|
||||||
|
await helperDeleteWallet('Multisig Vault');
|
||||||
|
await helperSwitchAdvancedMode(); // turn off advanced mode
|
||||||
|
process.env.TRAVIS && require('fs').writeFileSync(lockFile, '1');
|
||||||
|
});
|
||||||
|
|
||||||
it('can import multisig setup from UR, and create tx, and sign on hw devices', async () => {
|
it('can import multisig setup from UR, and create tx, and sign on hw devices', async () => {
|
||||||
const lockFile = '/tmp/travislock.' + hashIt('t6');
|
const lockFile = '/tmp/travislock.' + hashIt('t6');
|
||||||
if (process.env.TRAVIS) {
|
if (process.env.TRAVIS) {
|
||||||
|
@ -583,7 +661,7 @@ describe('BlueWallet UI Tests - no wallets', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can discover wallet account and import it', async () => {
|
it('can discover wallet account and import it', async () => {
|
||||||
const lockFile = '/tmp/travislock.' + hashIt('t6');
|
const lockFile = '/tmp/travislock.' + hashIt('t7');
|
||||||
if (process.env.TRAVIS) {
|
if (process.env.TRAVIS) {
|
||||||
if (require('fs').existsSync(lockFile)) return console.warn('skipping', JSON.stringify('t6'), 'as it previously passed on Travis');
|
if (require('fs').existsSync(lockFile)) return console.warn('skipping', JSON.stringify('t6'), 'as it previously passed on Travis');
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue