REF: scanQr to TS

This commit is contained in:
overtorment 2025-02-23 11:27:25 +00:00 committed by Overtorment
parent 46a78e8dfb
commit 34db010bde
5 changed files with 102 additions and 106 deletions

View file

@ -1,4 +1,4 @@
import { StackActions, useFocusEffect, useIsFocused, useRoute } from '@react-navigation/native';
import { RouteProp, StackActions, useFocusEffect, useIsFocused, useRoute } from '@react-navigation/native';
import * as bitcoin from 'bitcoinjs-lib';
import createHash from 'create-hash';
import React, { useCallback, useEffect, useState } from 'react';
@ -17,8 +17,11 @@ import { useExtendedNavigation } from '../../hooks/useExtendedNavigation';
import CameraScreen from '../../components/CameraScreen';
import SafeArea from '../../components/SafeArea';
import presentAlert from '../../components/Alert';
import { SendDetailsStackParamList } from '../../navigation/SendDetailsStackParamList.ts';
let decoder = false;
let decoder: BlueURDecoder | undefined;
type RouteProps = RouteProp<SendDetailsStackParamList, 'ScanQRCode'>;
const styles = StyleSheet.create({
root: {
@ -56,13 +59,13 @@ const ScanQRCode = () => {
const [isLoading, setIsLoading] = useState(false);
const { setIsDrawerShouldHide } = useSettings();
const navigation = useExtendedNavigation();
const route = useRoute();
const route = useRoute<RouteProps>();
const navigationState = navigation.getState();
const previousRoute = navigationState.routes[navigationState.routes.length - 2];
const defaultLaunchedBy = previousRoute ? previousRoute.name : undefined;
const { launchedBy = defaultLaunchedBy, showFileImportButton } = route.params || {};
const scannedCache = {};
const scannedCache: Record<string, number> = {};
const { colors } = useTheme();
const isFocused = useIsFocused();
const [backdoorPressed, setBackdoorPressed] = useState(0);
@ -70,8 +73,8 @@ const ScanQRCode = () => {
const [urHave, setUrHave] = useState(0);
const [backdoorText, setBackdoorText] = useState('');
const [backdoorVisible, setBackdoorVisible] = useState(false);
const [animatedQRCodeData, setAnimatedQRCodeData] = useState({});
const [cameraStatusGranted, setCameraStatusGranted] = useState(undefined);
const [animatedQRCodeData, setAnimatedQRCodeData] = useState<Record<string, string>>({});
const [cameraStatusGranted, setCameraStatusGranted] = useState<boolean | undefined>(undefined);
const stylesHook = StyleSheet.create({
openSettingsContainer: {
backgroundColor: colors.brandingColor,
@ -89,7 +92,7 @@ const ScanQRCode = () => {
isCameraAuthorizationStatusGranted().then(setCameraStatusGranted);
}, []);
const HashIt = function (s) {
const HashIt = function (s: string): string {
return createHash('sha256').update(s).digest().toString('hex');
};
@ -103,13 +106,13 @@ const ScanQRCode = () => {
}, [setIsDrawerShouldHide]),
);
const _onReadUniformResourceV2 = part => {
const _onReadUniformResourceV2 = (part: string) => {
if (!decoder) decoder = new BlueURDecoder();
try {
decoder.receivePart(part);
if (decoder.isComplete()) {
const data = decoder.toString();
decoder = false; // nullify for future use (?)
decoder = undefined; // nullify for future use (?)
if (launchedBy) {
const merge = true;
const popToAction = StackActions.popTo(launchedBy, { onBarScanned: data }, merge);
@ -123,11 +126,8 @@ const ScanQRCode = () => {
} catch (error) {
setIsLoading(true);
presentAlert({
title: loc.send.scan_error,
title: loc.errors.error,
message: loc._.invalid_animated_qr_code_fragment,
onPress: () => {
setIsLoading(false);
},
});
}
};
@ -136,7 +136,7 @@ const ScanQRCode = () => {
*
* @deprecated remove when we get rid of URv1 support
*/
const _onReadUniformResource = ur => {
const _onReadUniformResource = (ur: string) => {
try {
const [index, total] = extractSingleWorkload(ur);
animatedQRCodeData[index + 'of' + total] = ur;
@ -145,13 +145,13 @@ const ScanQRCode = () => {
if (Object.values(animatedQRCodeData).length === total) {
const payload = decodeUR(Object.values(animatedQRCodeData));
// lets look inside that data
let data = false;
if (Buffer.from(payload, 'hex').toString().startsWith('psbt')) {
let data: false | string = false;
if (Buffer.from(String(payload), 'hex').toString().startsWith('psbt')) {
// its a psbt, and whoever requested it expects it encoded in base64
data = Buffer.from(payload, 'hex').toString('base64');
data = Buffer.from(String(payload), 'hex').toString('base64');
} else {
// its something else. probably plain text is expected
data = Buffer.from(payload, 'hex').toString();
data = Buffer.from(String(payload), 'hex').toString();
}
if (launchedBy) {
const merge = true;
@ -166,16 +166,13 @@ const ScanQRCode = () => {
setIsLoading(true);
presentAlert({
title: loc.send.scan_error,
title: loc.errors.error,
message: loc._.invalid_animated_qr_code_fragment,
onPress: () => {
setIsLoading(false);
},
});
}
};
const onBarCodeRead = ret => {
const onBarCodeRead = (ret: { data: string }) => {
const h = HashIt(ret.data);
if (scannedCache[h]) {
// this QR was already scanned by this ScanQRCode, lets prevent firing duplicate callbacks
@ -219,7 +216,7 @@ const ScanQRCode = () => {
}
return;
} catch (_) {
if (!isLoading) {
if (!isLoading && launchedBy) {
setIsLoading(true);
try {
const merge = true;
@ -257,7 +254,7 @@ const ScanQRCode = () => {
navigation.goBack();
};
const handleReadCode = event => {
const handleReadCode = (event: any) => {
onBarCodeRead({ data: event?.nativeEvent?.codeStringValue });
};
@ -296,7 +293,6 @@ const ScanQRCode = () => {
) : isFocused && cameraStatusGranted ? (
<CameraScreen
onReadCode={handleReadCode}
showFrame={false}
showFilePickerButton={showFileImportButton}
showImagePickerButton={true}
onFilePickerButtonPress={showFilePicker}

View file

@ -8,11 +8,11 @@ import {
helperCreateWallet,
helperDeleteWallet,
sleep,
sup,
waitForText,
tapAndTapAgainIfElementIsNotVisible,
tapIfPresent,
tapIfTextPresent,
yo,
waitForId,
} from './helperz';
import { element } from 'detox';
@ -58,7 +58,7 @@ describe('BlueWallet UI Tests - no wallets', () => {
if (require('fs').existsSync(lockFile)) return console.warn('skipping', JSON.stringify('t2'), 'as it previously passed on Travis');
}
await device.launchApp({ delete: true }); // reinstalling the app just for any case to clean up app's storage
await yo('WalletsList');
await waitForId('WalletsList');
// go to settings, press SelfTest and wait for OK
await element(by.id('SettingsButton')).tap();
@ -110,12 +110,12 @@ describe('BlueWallet UI Tests - no wallets', () => {
await element(by.id('PortInput')).replaceText('50001\n');
await element(by.id('ElectrumSettingsScrollView')).swipe('up', 'fast', 1); // in case emu screen is small and it doesnt fit
await element(by.id('Save')).tap();
await sup('OK');
await waitForText('OK');
await element(by.text('OK')).tap();
await element(by.id('HeaderMenuButton')).tap();
await element(by.text('Reset to default')).tap();
await element(by.text('RESET TO DEFAULT')).tap();
await sup('OK');
await waitForText('OK');
await element(by.text('OK')).tap();
await element(by.id('ElectrumSettingsScrollView')).swipe('up', 'fast', 1); // in case emu screen is small and it doesnt fit
await expect(element(by.id('HostInput'))).toHaveText('');
@ -129,17 +129,17 @@ describe('BlueWallet UI Tests - no wallets', () => {
await element(by.id('LightningSettings')).tap();
await element(by.id('URIInput')).replaceText('invalid\n');
await element(by.id('Save')).tap();
await sup('OK');
await waitForText('OK');
await expect(element(by.text('Invalid LNDHub URI'))).toBeVisible();
await element(by.text('OK')).tap();
await element(by.id('URIInput')).replaceText('https://lndhub.herokuapp.com\n');
await element(by.id('Save')).tap();
await sup('OK');
await waitForText('OK');
await expect(element(by.text('Your changes have been saved successfully.'))).toBeVisible();
await element(by.text('OK')).tap();
await element(by.id('URIInput')).replaceText('\n');
await element(by.id('Save')).tap();
await sup('OK');
await waitForText('OK');
await expect(element(by.text('Your changes have been saved successfully.'))).toBeVisible();
await element(by.text('OK')).tap();
await device.pressBack();
@ -147,7 +147,7 @@ describe('BlueWallet UI Tests - no wallets', () => {
// notifications
// turn on notifications if available
// console.warn('yo');
// console.warn('waitForId');
// await sleep(300000);
if (await expectToBeVisible('NotificationSettings')) {
await element(by.id('NotificationSettings')).tap();
@ -168,7 +168,7 @@ describe('BlueWallet UI Tests - no wallets', () => {
await element(by.id('Broadcast')).tap();
await element(by.id('TxHex')).replaceText('invalid\n');
await element(by.id('BroadcastButton')).tap();
await sup('OK');
await waitForText('OK');
// await expect(element(by.text('the transaction was rejected by network rules....'))).toBeVisible();
await element(by.text('OK')).tap();
await device.pressBack();
@ -195,12 +195,12 @@ describe('BlueWallet UI Tests - no wallets', () => {
if (require('fs').existsSync(lockFile)) return console.warn('skipping', JSON.stringify('t3'), 'as it previously passed on Travis');
}
await device.launchApp({ delete: true }); // reinstalling the app just for any case to clean up app's storage
await yo('WalletsList');
await waitForId('WalletsList');
await helperCreateWallet();
await device.launchApp({ newInstance: true });
await yo('WalletsList');
await waitForId('WalletsList');
await expect(element(by.id('cr34t3d'))).toBeVisible();
await tapAndTapAgainIfElementIsNotVisible('cr34t3d', 'ReceiveButton');
await element(by.id('ReceiveButton')).tap();
@ -211,8 +211,8 @@ describe('BlueWallet UI Tests - no wallets', () => {
await element(by.text(`No, and do not ask me again.`)).tap();
await element(by.text(`No, and do not ask me again.`)).tap(); // sometimes the first click doesnt work (detox issue, not app's)
} catch (_) {}
await yo('BitcoinAddressQRCodeContainer');
await yo('CopyTextToClipboard');
await waitForId('BitcoinAddressQRCodeContainer');
await waitForId('CopyTextToClipboard');
await element(by.id('SetCustomAmountButton')).tap();
await element(by.id('BitcoinAmountInput')).replaceText('1');
await element(by.id('CustomAmountDescription')).replaceText('test');
@ -221,8 +221,8 @@ describe('BlueWallet UI Tests - no wallets', () => {
await expect(element(by.id('CustomAmountDescriptionText'))).toHaveText('test');
await expect(element(by.id('BitcoinAmountText'))).toHaveText('1 BTC');
await yo('BitcoinAddressQRCodeContainer');
await yo('CopyTextToClipboard');
await waitForId('BitcoinAddressQRCodeContainer');
await waitForId('CopyTextToClipboard');
await device.pressBack();
await device.pressBack();
await helperDeleteWallet('cr34t3d');
@ -235,7 +235,7 @@ describe('BlueWallet UI Tests - no wallets', () => {
if (require('fs').existsSync(lockFile)) return console.warn('skipping', JSON.stringify('t4'), 'as it previously passed on Travis');
}
await device.launchApp({ delete: true }); // reinstalling the app just for any case to clean up app's storage
await yo('WalletsList');
await waitForId('WalletsList');
// lets create a wallet
await helperCreateWallet();
@ -283,7 +283,7 @@ describe('BlueWallet UI Tests - no wallets', () => {
await device.launchApp({ newInstance: true });
// trying to decrypt with incorrect password
await sup('Your storage is encrypted. Password is required to decrypt it.');
await waitForText('Your storage is encrypted. Password is required to decrypt it.');
await element(by.type('android.widget.EditText')).typeText('wrong');
await element(by.text('OK')).tap();
await expect(element(by.text('Incorrect password. Please try again.'))).toBeVisible();
@ -291,7 +291,7 @@ describe('BlueWallet UI Tests - no wallets', () => {
// correct password
await element(by.type('android.widget.EditText')).typeText('qqq');
await element(by.text('OK')).tap();
await yo('WalletsList');
await waitForId('WalletsList');
// previously created wallet should be visible
await expect(element(by.id('cr34t3d'))).toBeVisible();
@ -354,10 +354,10 @@ describe('BlueWallet UI Tests - no wallets', () => {
// relaunch app
await device.launchApp({ newInstance: true });
//
await sup('Your storage is encrypted. Password is required to decrypt it.');
await waitForText('Your storage is encrypted. Password is required to decrypt it.');
await element(by.type('android.widget.EditText')).typeText('qqq');
await element(by.text('OK')).tap();
await yo('WalletsList');
await waitForId('WalletsList');
// previously created wallet IN MAIN STORAGE should be visible
await expect(element(by.id('cr34t3d'))).toBeVisible();
@ -365,10 +365,10 @@ describe('BlueWallet UI Tests - no wallets', () => {
// relaunch app
await device.launchApp({ newInstance: true });
//
await sup('Your storage is encrypted. Password is required to decrypt it.');
await waitForText('Your storage is encrypted. Password is required to decrypt it.');
await element(by.type('android.widget.EditText')).typeText('passwordForFakeStorage');
await element(by.text('OK')).tap();
await yo('WalletsList');
await waitForId('WalletsList');
// previously created wallet in FAKE storage should be visible
await expect(element(by.id('fake_wallet'))).toBeVisible();
@ -397,7 +397,7 @@ describe('BlueWallet UI Tests - no wallets', () => {
if (require('fs').existsSync(lockFile)) return console.warn('skipping', JSON.stringify('t5'), 'as it previously passed on Travis');
}
await device.launchApp({ delete: true }); // reinstalling the app just for any case to clean up app's storage
await yo('WalletsList');
await waitForId('WalletsList');
await helperCreateWallet();
await element(by.id('SettingsButton')).tap();
await element(by.id('SecurityButton')).tap();
@ -438,10 +438,10 @@ describe('BlueWallet UI Tests - no wallets', () => {
// relaunch app
await device.launchApp({ newInstance: true });
//
await sup('Your storage is encrypted. Password is required to decrypt it.');
await waitForText('Your storage is encrypted. Password is required to decrypt it.');
await element(by.type('android.widget.EditText')).typeText('pass');
await element(by.text('OK')).tap();
await yo('WalletsList');
await waitForId('WalletsList');
// previously created wallet IN MAIN STORAGE should be visible
await expect(element(by.id('cr34t3d'))).toBeVisible();
@ -468,7 +468,7 @@ describe('BlueWallet UI Tests - no wallets', () => {
// relaunch app
await device.launchApp({ newInstance: true });
await yo('cr34t3d'); // success
await waitForId('cr34t3d'); // success
await helperDeleteWallet('cr34t3d');
process.env.TRAVIS && require('fs').writeFileSync(lockFile, '1');
});
@ -479,7 +479,7 @@ describe('BlueWallet UI Tests - no wallets', () => {
if (require('fs').existsSync(lockFile)) return console.warn('skipping as it previously passed on Travis');
}
await device.launchApp({ delete: true }); // reinstalling the app just for any case to clean up app's storage
await yo('WalletsList');
await waitForId('WalletsList');
await element(by.id('WalletsList')).swipe('left', 'fast', 1); // in case emu screen is small and it doesnt fit
await sleep(200); // Wait until bounce animation finishes.
// going to Import Wallet screen and importing Vault
@ -501,7 +501,7 @@ describe('BlueWallet UI Tests - no wallets', () => {
await element(by.id('ScanOrOpenFile')).tap();
await sleep(5000); // wait for camera screen to initialize
await yo('ScanQrBackdoorButton');
await waitForId('ScanQrBackdoorButton');
for (let c = 0; c <= 5; c++) {
await element(by.id('ScanQrBackdoorButton')).tap();
}
@ -527,11 +527,11 @@ describe('BlueWallet UI Tests - no wallets', () => {
// when xpub - it automatically closes the modal, so no need to tap the button
await element(by.id('CreateButton')).tap();
await sup('OK');
await waitForText('OK');
await tapIfTextPresent('OK');
await yo('Multisig Vault');
await waitForId('Multisig Vault');
await element(by.id('Multisig Vault')).tap(); // go inside the wallet
await yo('ReceiveButton');
await waitForId('ReceiveButton');
await element(by.id('ReceiveButton')).tap();
try {
// in case emulator has no google services and doesnt support pushes
@ -540,12 +540,12 @@ describe('BlueWallet UI Tests - no wallets', () => {
await element(by.text(`No, and do not ask me again.`)).tap(); // sometimes the first click doesnt work (detox issue, not app's)
} catch (_) {}
await sup('bc1qmf06nt4jhvzz4387ak8fecs42k6jqygr2unumetfc7xkdup7ah9s8phlup');
await waitForText('bc1qmf06nt4jhvzz4387ak8fecs42k6jqygr2unumetfc7xkdup7ah9s8phlup');
await device.pressBack();
await element(by.id('WalletDetails')).tap();
await sup('2 / 2 (native segwit)');
await waitForText('2 / 2 (native segwit)');
await device.pressBack();
await helperDeleteWallet('Multisig Vault');
@ -558,7 +558,7 @@ describe('BlueWallet UI Tests - no wallets', () => {
if (require('fs').existsSync(lockFile)) return console.warn('skipping', JSON.stringify('t6'), 'as it previously passed on Travis');
}
await device.launchApp({ delete: true }); // reinstalling the app just for any case to clean up app's storage
await yo('WalletsList');
await waitForId('WalletsList');
await element(by.id('WalletsList')).swipe('left', 'fast', 1); // in case emu screen is small and it doesnt fit
await sleep(200); // Wait until bounce animation finishes.
// going to Import Wallet screen and importing mnemonic
@ -585,7 +585,7 @@ describe('BlueWallet UI Tests - no wallets', () => {
}
if (process.env.TRAVIS) await sleep(60000);
await sup('OK', 3 * 61000); // waiting for wallet import
await waitForText('OK', 3 * 61000); // waiting for wallet import
await element(by.text('OK')).tap();
// ok, wallet imported
@ -595,7 +595,7 @@ describe('BlueWallet UI Tests - no wallets', () => {
// sending...
await yo('SendButton');
await waitForId('SendButton');
await element(by.id('SendButton')).tap();
await element(by.id('AddressInput')).replaceText('bc1q063ctu6jhe5k4v8ka99qac8rcm2tzjjnuktyrl');
@ -666,7 +666,7 @@ describe('BlueWallet UI Tests - no wallets', () => {
await element(by.id('PsbtMultisigConfirmButton')).tap();
// created. verifying:
await yo('TransactionValue');
await waitForId('TransactionValue');
await expect(element(by.id('TransactionValue'))).toHaveText('0.0005');
await element(by.id('TransactionDetailsButton')).tap();
@ -693,7 +693,7 @@ describe('BlueWallet UI Tests - no wallets', () => {
if (require('fs').existsSync(lockFile)) return console.warn('skipping', JSON.stringify('t6'), 'as it previously passed on Travis');
}
await device.launchApp({ delete: true }); // reinstalling the app just for any case to clean up app's storage
await yo('WalletsList');
await waitForId('WalletsList');
await element(by.id('WalletsList')).swipe('left', 'fast', 1); // in case emu screen is small and it doesnt fit
await sleep(500); // Wait until bounce animation finishes.

View file

@ -7,11 +7,11 @@ import {
hashIt,
helperImportWallet,
sleep,
sup,
waitForText,
tapAndTapAgainIfElementIsNotVisible,
tapAndTapAgainIfTextIsNotVisible,
tapIfTextPresent,
yo,
waitForId,
} from './helperz';
/**
@ -51,7 +51,7 @@ describe('BlueWallet UI Tests - import BIP84 wallet', () => {
await element(by.text('Imported HD SegWit (BIP84 Bech32 Native)')).tap();
// lets create real transaction:
await yo('SendButton');
await waitForId('SendButton');
await element(by.id('SendButton')).tap();
await element(by.id('AddressInput')).replaceText('bc1q063ctu6jhe5k4v8ka99qac8rcm2tzjjnuktyrl');
await element(by.id('BitcoinAmountInput')).typeText('0.0001\n');
@ -69,7 +69,7 @@ describe('BlueWallet UI Tests - import BIP84 wallet', () => {
} catch (_) {}
// created. verifying:
await yo('TransactionValue');
await waitForId('TransactionValue');
await expect(element(by.id('TransactionValue'))).toHaveText('0.0001');
const transactionFee = await extractTextFromElementById('TransactionFee');
assert.ok(transactionFee.startsWith('Fee: 0.00000292 BTC'), 'Unexpected tx fee: ' + transactionFee);
@ -117,8 +117,8 @@ describe('BlueWallet UI Tests - import BIP84 wallet', () => {
await element(by.id('CreateTransactionButton')).tap();
} catch (_) {}
// created. verifying:
await yo('TransactionValue');
await yo('PayjoinSwitch');
await waitForId('TransactionValue');
await waitForId('PayjoinSwitch');
await element(by.id('TransactionDetailsButton')).tap();
txhex = await extractTextFromElementById('TxhexInput');
transaction = bitcoin.Transaction.fromHex(txhex);
@ -148,8 +148,8 @@ describe('BlueWallet UI Tests - import BIP84 wallet', () => {
await element(by.id('CreateTransactionButton')).tap();
} catch (_) {}
// created. verifying:
await yo('TransactionValue');
await yo('PayjoinSwitch');
await waitForId('TransactionValue');
await waitForId('PayjoinSwitch');
await element(by.id('TransactionDetailsButton')).tap();
txhex = await extractTextFromElementById('TxhexInput');
transaction = bitcoin.Transaction.fromHex(txhex);
@ -176,7 +176,7 @@ describe('BlueWallet UI Tests - import BIP84 wallet', () => {
await element(by.id('CreateTransactionButton')).tap();
} catch (_) {}
// created. verifying:
await yo('TransactionValue');
await waitForId('TransactionValue');
await element(by.id('TransactionDetailsButton')).tap();
txhex = await extractTextFromElementById('TxhexInput');
transaction = bitcoin.Transaction.fromHex(txhex);
@ -200,7 +200,7 @@ describe('BlueWallet UI Tests - import BIP84 wallet', () => {
// Go inside the wallet
await element(by.text('Imported HD SegWit (BIP84 Bech32 Native)')).tap();
await yo('SendButton');
await waitForId('SendButton');
await element(by.id('SendButton')).tap();
// Add a few recipients initially
@ -209,7 +209,7 @@ describe('BlueWallet UI Tests - import BIP84 wallet', () => {
await element(by.id('HeaderMenuButton')).tap();
await element(by.text('Add Recipient')).tap();
await yo('Transaction1');
await waitForId('Transaction1');
await element(by.id('AddressInput').withAncestor(by.id('Transaction1'))).replaceText('bc1q063ctu6jhe5k4v8ka99qac8rcm2tzjjnuktyrl');
await element(by.id('BitcoinAmountInput').withAncestor(by.id('Transaction1'))).replaceText('0.0002\n');
@ -233,25 +233,25 @@ describe('BlueWallet UI Tests - import BIP84 wallet', () => {
// Let's add another two outputs
await element(by.id('HeaderMenuButton')).tap();
await element(by.text('Add Recipient')).tap();
await yo('Transaction1'); // Adding a recipient autoscrolls it to the last one
await waitForId('Transaction1'); // Adding a recipient autoscrolls it to the last one
await element(by.id('AddressInput').withAncestor(by.id('Transaction1'))).replaceText('bc1q063ctu6jhe5k4v8ka99qac8rcm2tzjjnuktyrl');
await element(by.id('BitcoinAmountInput').withAncestor(by.id('Transaction1'))).replaceText('0.0002\n');
await element(by.id('HeaderMenuButton')).tap();
await element(by.text('Add Recipient')).tap();
await yo('Transaction2'); // Adding a recipient autoscrolls it to the last one
await waitForId('Transaction2'); // Adding a recipient autoscrolls it to the last one
await element(by.id('AddressInput').withAncestor(by.id('Transaction2'))).replaceText('bc1qh6tf004ty7z7un2v5ntu4mkf630545gvhs45u7');
await element(by.id('BitcoinAmountInput').withAncestor(by.id('Transaction2'))).replaceText('0.0003\n');
// Remove last output, check if second output is shown
await element(by.id('HeaderMenuButton')).tap();
await element(by.text('Remove Recipient')).tap();
await yo('Transaction1');
await waitForId('Transaction1');
// Add it again
await element(by.id('HeaderMenuButton')).tap();
await element(by.text('Add Recipient')).tap();
await yo('Transaction2'); // Adding a recipient autoscrolls it to the last one
await waitForId('Transaction2'); // Adding a recipient autoscrolls it to the last one
await element(by.id('AddressInput').withAncestor(by.id('Transaction2'))).replaceText('bc1qh6tf004ty7z7un2v5ntu4mkf630545gvhs45u7');
await element(by.id('BitcoinAmountInput').withAncestor(by.id('Transaction2'))).replaceText('0.0003\n');
@ -293,7 +293,7 @@ describe('BlueWallet UI Tests - import BIP84 wallet', () => {
// go inside the wallet
await element(by.text('Imported HD SegWit (BIP84 Bech32 Native)')).tap();
await yo('SendButton');
await waitForId('SendButton');
await element(by.id('SendButton')).tap();
// set fee rate
@ -315,7 +315,7 @@ describe('BlueWallet UI Tests - import BIP84 wallet', () => {
await element(by.id('CreateTransactionButton')).tap();
} catch (_) {}
// created. verifying:
await yo('TransactionDetailsButton');
await waitForId('TransactionDetailsButton');
await element(by.id('TransactionDetailsButton')).tap();
let txhex = await extractTextFromElementById('TxhexInput');
let transaction = bitcoin.Transaction.fromHex(txhex);
@ -327,7 +327,7 @@ describe('BlueWallet UI Tests - import BIP84 wallet', () => {
await device.pressBack();
await element(by.id('HeaderMenuButton')).tap();
await element(by.text('Add Recipient')).tap();
await yo('Transaction1');
await waitForId('Transaction1');
await element(by.id('AddressInput').withAncestor(by.id('Transaction1'))).replaceText('bc1q063ctu6jhe5k4v8ka99qac8rcm2tzjjnuktyrl');
await element(by.id('BitcoinAmountInput').withAncestor(by.id('Transaction1'))).typeText('0.0001\n');
@ -336,7 +336,7 @@ describe('BlueWallet UI Tests - import BIP84 wallet', () => {
await element(by.id('CreateTransactionButton')).tap();
} catch (_) {}
// created. verifying:
await yo('TransactionDetailsButton');
await waitForId('TransactionDetailsButton');
await element(by.id('TransactionDetailsButton')).tap();
txhex = await extractTextFromElementById('TxhexInput');
transaction = bitcoin.Transaction.fromHex(txhex);
@ -363,7 +363,7 @@ describe('BlueWallet UI Tests - import BIP84 wallet', () => {
// go inside the wallet
await element(by.text('Imported HD SegWit (BIP84 Bech32 Native)')).tap();
await yo('SendButton');
await waitForId('SendButton');
await element(by.id('SendButton')).tap();
await element(by.id('HeaderMenuButton')).tap();
@ -381,7 +381,7 @@ describe('BlueWallet UI Tests - import BIP84 wallet', () => {
await element(by.id('scanQrBackdoorOkButton')).tap();
// this is fully-signed tx, "this is tx hex" help text should appear
await yo('DynamicCode');
await waitForId('DynamicCode');
const txhex = await extractTextFromElementById('TxhexInput');
console.warn(txhex);
@ -423,7 +423,7 @@ describe('BlueWallet UI Tests - import BIP84 wallet', () => {
// go to receive screen and check that payment code is there
await yo('ReceiveButton');
await waitForId('ReceiveButton');
await element(by.id('ReceiveButton')).tap();
try {
@ -467,7 +467,7 @@ describe('BlueWallet UI Tests - import BIP84 wallet', () => {
);
await element(by.text('OK')).tap();
await sup('On-chain transaction needed');
await waitForText('On-chain transaction needed');
await element(by.text('Cancel')).tap();
// testing renaming contact:
@ -483,7 +483,7 @@ describe('BlueWallet UI Tests - import BIP84 wallet', () => {
await device.pressBack();
await device.pressBack();
await element(by.text('Imported HD SegWit (BIP84 Bech32 Native)')).tap();
await yo('SendButton');
await waitForId('SendButton');
await tapAndTapAgainIfElementIsNotVisible('SendButton', 'HeaderMenuButton');
await element(by.id('HeaderMenuButton')).tap();
@ -541,7 +541,7 @@ describe('BlueWallet UI Tests - import BIP84 wallet', () => {
await element(by.id('WalletNameInput')).replaceText('testname');
await element(by.id('WalletNameInput')).typeText('\n'); // newline is what triggers saving the wallet
await device.pressBack();
await sup('testname');
await waitForText('testname');
await expect(element(by.id('WalletLabel'))).toHaveText('testname');
await element(by.id('WalletDetails')).tap();
@ -549,7 +549,7 @@ describe('BlueWallet UI Tests - import BIP84 wallet', () => {
await element(by.id('WalletNameInput')).replaceText('Imported HD SegWit (BIP84 Bech32 Native)');
await element(by.id('WalletNameInput')).typeText('\n'); // newline is what triggers saving the wallet
await device.pressBack();
await sup('Imported HD SegWit (BIP84 Bech32 Native)');
await waitForText('Imported HD SegWit (BIP84 Bech32 Native)');
await expect(element(by.id('WalletLabel'))).toHaveText('Imported HD SegWit (BIP84 Bech32 Native)');
await element(by.id('WalletDetails')).tap();
@ -598,7 +598,7 @@ describe('BlueWallet UI Tests - import BIP84 wallet', () => {
} catch (_) {}
// created. verifying:
await yo('TransactionValue');
await waitForId('TransactionValue');
await expect(element(by.id('TransactionValue'))).toHaveText('0.0001');
await expect(element(by.id('TransactionAddress'))).toHaveText('BC1QH6TF004TY7Z7UN2V5NTU4MKF630545GVHS45U7');
@ -632,9 +632,9 @@ describe('BlueWallet UI Tests - import BIP84 wallet', () => {
// Terminate and reopen the app to confirm the note is persisted
await device.launchApp({ newInstance: true });
await yo('WalletsList');
await waitForId('WalletsList');
await element(by.text('Imported HD SegWit (BIP84 Bech32 Native)')).tap();
await yo('SendButton');
await waitForId('SendButton');
await element(by.id('SendButton')).tap();
await element(by.id('HeaderMenuButton')).tap();
await element(by.text('Coin Control')).tap();
@ -684,7 +684,7 @@ describe('BlueWallet UI Tests - import BIP84 wallet', () => {
await device.pressBack();
// create tx with unfrozen input
await yo('SendButton');
await waitForId('SendButton');
await element(by.id('SendButton')).tap();
await element(by.id('AddressInput')).replaceText('bc1q063ctu6jhe5k4v8ka99qac8rcm2tzjjnuktyrl');
await element(by.id('HeaderMenuButton')).tap();

View file

@ -1,4 +1,4 @@
import { hashIt, helperDeleteWallet, helperImportWallet, sleep, yo } from './helperz';
import { hashIt, helperDeleteWallet, helperImportWallet, sleep, waitForId } from './helperz';
beforeAll(async () => {
// reinstalling the app just for any case to clean up app's storage
@ -87,7 +87,7 @@ describe('BlueWallet UI Tests - import Watch-only wallet (zpub)', () => {
await element(by.id('scanQrBackdoorInput')).replaceText(signedPsbt);
await element(by.id('scanQrBackdoorOkButton')).tap();
await expect(element(by.id('ScanQrBackdoorButton'))).toBeNotVisible();
await yo('PsbtWithHardwareWalletBroadcastTransactionButton');
await waitForId('PsbtWithHardwareWalletBroadcastTransactionButton');
await device.pressBack();
await device.pressBack();

View file

@ -1,7 +1,7 @@
import createHash from 'create-hash';
import { element } from 'detox';
export async function yo(id, timeout = 33000) {
export async function waitForId(id, timeout = 33000) {
try {
await waitFor(element(by.id(id)))
.toBeVisible()
@ -21,7 +21,7 @@ export async function yo(id, timeout = 33000) {
}
}
export async function sup(text, timeout = 33000) {
export async function waitForText(text, timeout = 33000) {
try {
await waitFor(element(by.text(text)))
.toBeVisible()
@ -52,7 +52,7 @@ export async function getSwitchValue(switchId) {
}
export async function helperImportWallet(importText, walletType, expectedWalletLabel, expectedBalance, passphrase) {
await yo('WalletsList');
await waitForId('WalletsList');
await element(by.id('WalletsList')).swipe('left', 'fast', 1); // in case emu screen is small and it doesnt fit
await sleep(500); // Wait until bounce animation finishes.
@ -70,7 +70,7 @@ export async function helperImportWallet(importText, walletType, expectedWalletL
await element(by.id('SpeedDoImport')).tap();
// waiting for import result
await sup('OK', 3 * 61000);
await waitForText('OK', 3 * 61000);
await element(by.text('OK')).tap();
// lets go inside wallet
@ -93,7 +93,7 @@ export async function helperDeleteWallet(label, remainingBalanceSat = false) {
await element(by.id('WalletDetailsScroll')).swipe('up', 'fast', 1);
await element(by.id('HeaderMenuButton')).tap();
await element(by.text('Delete')).tap();
await sup('Yes, delete');
await waitForText('Yes, delete');
await element(by.text('Yes, delete')).tap();
if (remainingBalanceSat) {
await element(by.type('android.widget.EditText')).typeText(remainingBalanceSat);
@ -105,8 +105,8 @@ export async function helperDeleteWallet(label, remainingBalanceSat = false) {
/*
module.exports.helperImportWallet = helperImportWallet;
module.exports.yo = yo;
module.exports.sup = sup;
module.exports.waitForId = waitForId;
module.exports.waitForText = waitForText;
module.exports.sleep = sleep;
module.exports.hashIt = hashIt;
module.exports.helperDeleteWallet = helperDeleteWallet;
@ -158,7 +158,7 @@ export async function helperCreateWallet(walletName) {
await sleep(200); // Wait until bounce animation finishes.
await tapAndTapAgainIfElementIsNotVisible('CreateAWallet', 'WalletNameInput');
await element(by.id('WalletNameInput')).replaceText(walletName || 'cr34t3d');
await yo('ActivateBitcoinButton');
await waitForId('ActivateBitcoinButton');
await element(by.id('ActivateBitcoinButton')).tap();
await element(by.id('ActivateBitcoinButton')).tap();
// why tf we need 2 taps for it to work..? mystery
@ -166,7 +166,7 @@ export async function helperCreateWallet(walletName) {
await element(by.id('PleaseBackupScrollView')).swipe('up', 'fast', 1); // in case emu screen is small and it doesnt fit
await yo('PleasebackupOk');
await waitForId('PleasebackupOk');
await element(by.id('PleasebackupOk')).tap();
await expect(element(by.id('WalletsList'))).toBeVisible();
await element(by.id('WalletsList')).swipe('right', 'fast', 1); // in case emu screen is small and it doesnt fit