ADD: e2e tests

This commit is contained in:
Ivan Vershigora 2020-11-03 16:18:46 +03:00
parent d7b025d5a8
commit 72a9086515
6 changed files with 140 additions and 11 deletions

View file

@ -655,7 +655,7 @@ export const BluePrivateBalance = () => {
export const BlueCopyToClipboardButton = ({ stringToCopy, displayText = false }) => { export const BlueCopyToClipboardButton = ({ stringToCopy, displayText = false }) => {
return ( return (
<TouchableOpacity onPress={() => Clipboard.setString(stringToCopy)}> <TouchableOpacity testID="CopyToClipboard" onPress={() => Clipboard.setString(stringToCopy)}>
<Text style={{ fontSize: 13, fontWeight: '400', color: '#68bbe1' }}>{displayText || loc.transactions.details_copy}</Text> <Text style={{ fontSize: 13, fontWeight: '400', color: '#68bbe1' }}>{displayText || loc.transactions.details_copy}</Text>
</TouchableOpacity> </TouchableOpacity>
); );

View file

@ -133,6 +133,7 @@ const OutputModalContent = ({ output, wallet, onUseCoin }) => {
<Output item={output} full /> <Output item={output} full />
<BlueSpacing20 /> <BlueSpacing20 />
<TextInput <TextInput
testID="OutputMemo"
placeholder={loc.send.details_note_placeholder} placeholder={loc.send.details_note_placeholder}
value={memo} value={memo}
placeholderTextColor="#81868e" placeholderTextColor="#81868e"
@ -148,7 +149,7 @@ const OutputModalContent = ({ output, wallet, onUseCoin }) => {
/> />
<BlueListItem title={loc.cc.freezeLabel} Component={TouchableWithoutFeedback} switch={switchValue} /> <BlueListItem title={loc.cc.freezeLabel} Component={TouchableWithoutFeedback} switch={switchValue} />
<BlueSpacing20 /> <BlueSpacing20 />
<BlueButton title={loc.cc.useCoin} onPress={() => onUseCoin([output])} /> <BlueButton testID="UseCoin" title={loc.cc.useCoin} onPress={() => onUseCoin([output])} />
</> </>
); );
}; };
@ -210,6 +211,10 @@ const CoinControl = () => {
Keyboard.dismiss(); Keyboard.dismiss();
setOutput(false); setOutput(false);
}} }}
onBackButtonPress={() => {
Keyboard.dismiss();
setOutput(false);
}}
> >
<KeyboardAvoidingView behavior={Platform.OS === 'ios' ? 'position' : null}> <KeyboardAvoidingView behavior={Platform.OS === 'ios' ? 'position' : null}>
<View style={[styles.modalContent, { backgroundColor: colors.elevated }]}> <View style={[styles.modalContent, { backgroundColor: colors.elevated }]}>

View file

@ -1087,7 +1087,13 @@ export default class SendDetails extends Component {
/> />
</> </>
)} )}
<BlueListItem title={loc.cc.header} hideChevron component={TouchableOpacity} onPress={this.handleCoinControl} /> <BlueListItem
testID="CoinControl"
title={loc.cc.header}
hideChevron
component={TouchableOpacity}
onPress={this.handleCoinControl}
/>
</View> </View>
</KeyboardAvoidingView> </KeyboardAvoidingView>
</Modal> </Modal>

View file

@ -119,6 +119,10 @@ const styles = StyleSheet.create({
justifyContent: 'center', justifyContent: 'center',
alignItems: 'center', alignItems: 'center',
}, },
hidden: {
width: 0,
height: 0,
},
}); });
export default class PsbtWithHardwareWallet extends Component { export default class PsbtWithHardwareWallet extends Component {
@ -366,6 +370,9 @@ export default class PsbtWithHardwareWallet extends Component {
<BlueCard> <BlueCard>
<BlueText testID="TextHelperForPSBT">{loc.send.psbt_this_is_psbt}</BlueText> <BlueText testID="TextHelperForPSBT">{loc.send.psbt_this_is_psbt}</BlueText>
<BlueSpacing20 /> <BlueSpacing20 />
<Text testID="PSBTHex" style={styles.hidden}>
{this.state.psbt.toHex()}
</Text>
<DynamicQRCode value={this.state.psbt.toHex()} capacity={200} /> <DynamicQRCode value={this.state.psbt.toHex()} capacity={200} />
<BlueSpacing20 /> <BlueSpacing20 />
<SecondButton <SecondButton

View file

@ -215,7 +215,18 @@ const WalletTransactions = () => {
}; };
const renderListHeaderComponent = () => { const renderListHeaderComponent = () => {
const style = { opacity: isLoading ? 0.5 : 1.0 }; const style = {};
if (!isDesktop) {
// we need this button for testing
style.opacity = 0;
style.height = 1;
style.width = 1;
} else if (isLoading) {
style.opacity = 0.5;
} else {
style.opacity = 1.0;
}
return ( return (
<View style={styles.flex}> <View style={styles.flex}>
<View style={styles.listHeader}> <View style={styles.listHeader}>
@ -239,11 +250,9 @@ const WalletTransactions = () => {
</View> </View>
<View style={[styles.listHeaderTextRow, stylesHook.listHeaderTextRow]}> <View style={[styles.listHeaderTextRow, stylesHook.listHeaderTextRow]}>
<Text style={[styles.listHeaderText, stylesHook.listHeaderText]}>{loc.transactions.list_title}</Text> <Text style={[styles.listHeaderText, stylesHook.listHeaderText]}>{loc.transactions.list_title}</Text>
{isDesktop && ( <TouchableOpacity testID="refreshTransactions" style={style} onPress={refreshTransactions} disabled={isLoading}>
<TouchableOpacity style={style} onPress={refreshTransactions} disabled={isLoading}> <Icon name="refresh" type="font-awesome" color={colors.feeText} />
<Icon name="refresh" type="font-awesome" color={colors.feeText} /> </TouchableOpacity>
</TouchableOpacity>
)}
</View> </View>
</View> </View>
); );
@ -616,7 +625,9 @@ const WalletTransactions = () => {
{!isLightning() && ( {!isLightning() && (
<TouchableOpacity onPress={navigateToBuyBitcoin} style={styles.buyBitcoin}> <TouchableOpacity onPress={navigateToBuyBitcoin} style={styles.buyBitcoin}>
<Text style={styles.buyBitcoinText}>{loc.wallets.list_tap_here_to_buy}</Text> <Text testID="NoTxBuyBitcoin" style={styles.buyBitcoinText}>
{loc.wallets.list_tap_here_to_buy}
</Text>
</TouchableOpacity> </TouchableOpacity>
)} )}
</ScrollView> </ScrollView>

View file

@ -9,7 +9,107 @@ jasmine.getEnv().addReporter({
specDone: result => (jasmine.currentTest = result), specDone: result => (jasmine.currentTest = result),
}); });
describe('BlueWallet UI Tests', () => { describe.only('BlueWallet UI Tests', () => {
it.only('can manage UTXO', async () => {
await helperImportWallet(
'zpub6qoWjSiZRHzSYPGYJ6EzxEXJXP1b2Rj9syWwJZFNCmupMwkbSAWSBk3UvSkJyQLEhQpaBAwvhmNj3HPKpwCJiTBB9Tutt46FtEmjL2DoU3J',
'Imported Watch-only',
'0.00105526 BTC',
);
// refresh transactions
await element(by.id('refreshTransactions')).tap();
await waitFor(element(by.id('NoTxBuyBitcoin')))
.not.toExist()
.withTimeout(300 * 1000);
// change note of 0.001 tx output
await element(by.text('0.001')).atIndex(0).tap();
await element(by.text('details')).tap();
await expect(element(by.text('49944e90fe917952e36b1967cdbc1139e60c89b4800b91258bf2345a77a8b888'))).toBeVisible();
await element(by.type('android.widget.EditText')).typeText('test1');
await element(by.text('Save')).tap();
await element(by.text('OK')).tap();
// back to wallet screen
await device.pressBack();
await device.pressBack();
// open CoinControl
await element(by.id('SendButton')).tap();
await element(by.text('OK')).tap();
await element(by.id('advancedOptionsMenuButton')).tap();
await element(by.id('CoinControl')).tap();
await waitFor(element(by.id('Loading'))) // wait for outputs to be loaded
.not.toExist()
.withTimeout(300 * 1000);
await expect(element(by.text('test1')).atIndex(0)).toBeVisible();
// change output note and freeze it
await element(by.text('test1')).atIndex(0).tap();
await element(by.id('OutputMemo')).replaceText('test2');
await element(by.type('android.widget.CompoundButton')).tap(); // freeze switch
await device.pressBack(); // closing modal
await expect(element(by.text('test2')).atIndex(0)).toBeVisible();
await expect(element(by.text('freeze')).atIndex(0)).toBeVisible();
// use frozen output to create tx using "Use coin" feature
await element(by.text('test2')).atIndex(0).tap();
await element(by.id('UseCoin')).tap();
await element(by.id('AddressInput')).replaceText('bc1q063ctu6jhe5k4v8ka99qac8rcm2tzjjnuktyrl');
await element(by.id('advancedOptionsMenuButton')).tap();
await element(by.id('sendMaxButton')).tap();
await element(by.text('OK')).tap();
// setting fee rate:
await element(by.id('chooseFee')).tap();
await element(by.id('feeCustom')).tap();
await element(by.type('android.widget.EditText')).typeText('1');
await element(by.text('OK')).tap();
await element(by.id('CreateTransactionButton')).tap();
await yo('TextHelperForPSBT');
const psbthex1 = await extractTextFromElementById('PSBTHex');
const psbt1 = bitcoin.Psbt.fromHex(psbthex1);
assert.strictEqual(psbt1.txOutputs.length, 1);
assert.strictEqual(psbt1.txOutputs[0].address, 'bc1q063ctu6jhe5k4v8ka99qac8rcm2tzjjnuktyrl');
assert.strictEqual(psbt1.txOutputs[0].value, 99808);
assert.strictEqual(psbt1.data.inputs.length, 1);
assert.strictEqual(psbt1.data.inputs[0].witnessUtxo.value, 100000);
// back to wallet screen
await device.pressBack();
await device.pressBack();
// create tx with unfrozen input
await element(by.id('SendButton')).tap();
await element(by.id('AddressInput')).replaceText('bc1q063ctu6jhe5k4v8ka99qac8rcm2tzjjnuktyrl');
await element(by.id('advancedOptionsMenuButton')).tap();
await element(by.id('sendMaxButton')).tap();
await element(by.text('OK')).tap();
// setting fee rate:
await element(by.id('chooseFee')).tap();
await element(by.id('feeCustom')).tap();
await element(by.type('android.widget.EditText')).typeText('1');
await element(by.text('OK')).tap();
await element(by.id('CreateTransactionButton')).tap();
await yo('TextHelperForPSBT');
const psbthex2 = await extractTextFromElementById('PSBTHex');
const psbt2 = bitcoin.Psbt.fromHex(psbthex2);
console.info('psbthex2', psbthex2)
assert.strictEqual(psbt2.txOutputs.length, 1);
assert.strictEqual(psbt2.txOutputs[0].address, 'bc1q063ctu6jhe5k4v8ka99qac8rcm2tzjjnuktyrl');
assert.strictEqual(psbt2.txOutputs[0].value, 99808);
assert.strictEqual(psbt2.data.inputs.length, 1);
assert.strictEqual(psbt2.data.inputs[0].witnessUtxo.value, 5526);
});
it('selftest passes', async () => { it('selftest passes', async () => {
const lockFile = '/tmp/travislock.' + hashIt(jasmine.currentTest.fullName); const lockFile = '/tmp/travislock.' + hashIt(jasmine.currentTest.fullName);
if (process.env.TRAVIS) { if (process.env.TRAVIS) {