Skip to content

Commit 3b3e027

Browse files
committed
tests: add test for sending coins.
1 parent 0c09c42 commit 3b3e027

File tree

2 files changed

+148
-1
lines changed

2 files changed

+148
-1
lines changed

frontends/web/src/components/transactions/transaction.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export const Transaction = ({
5252
onShowDetail(internalID);
5353
}
5454
}}>
55-
<div className={styles.txContent}>
55+
<div className={styles.txContent} data-testid="transaction" data-tx-type={type}>
5656
<span className={styles.txIcon}>
5757
<Arrow status={status} type={type} />
5858
</span>

frontends/web/tests/send.test.ts

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
/**
2+
* Copyright 2025 Shift Crypto AG
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { expect } from '@playwright/test';
18+
import { test } from './helpers/fixtures';
19+
import { ServeWallet } from './helpers/servewallet';
20+
import { launchRegtest, setupRegtestWallet, sendCoins, mineBlocks, cleanupRegtest } from './helpers/regtest';
21+
import { ChildProcess } from 'child_process';
22+
import { deleteAccountsFile } from './helpers/fs';
23+
24+
let servewallet: ServeWallet;
25+
let regtest: ChildProcess;
26+
27+
test('Send BTC', async ({ page, host, frontendPort, servewalletPort }, testInfo) => {
28+
29+
await test.step('Start regtest and init wallet', async () => {
30+
regtest = await launchRegtest();
31+
// Give regtest some time to start
32+
await new Promise((resolve) => setTimeout(resolve, 3000));
33+
await setupRegtestWallet();
34+
});
35+
36+
37+
await test.step('Start servewallet', async () => {
38+
servewallet = new ServeWallet(page, servewalletPort, frontendPort, host, testInfo.title, testInfo.project.name, { regtest: true, testnet: false });
39+
await servewallet.start();
40+
});
41+
42+
43+
let recvAdd: string;
44+
await test.step('Grab receive address', async () => {
45+
await page.getByRole('button', { name: 'Test wallet' }).click();
46+
await page.getByRole('button', { name: 'Unlock' }).click();
47+
await page.getByRole('link', { name: 'Bitcoin Regtest Bitcoin' }).click();
48+
await page.getByRole('button', { name: 'Receive RBTC' }).click();
49+
await page.getByRole('button', { name: 'Verify address on BitBox' }).click();
50+
const addressLocator = page.locator('[data-testid="receive-address"]');
51+
recvAdd = await addressLocator.inputValue();
52+
expect(recvAdd).toContain('bcrt1');
53+
console.log(`Receive address: ${recvAdd}`);
54+
});
55+
56+
await test.step('Verify there are no transactions yet', async () => {
57+
await page.goto('/#/account-summary');
58+
mineBlocks(12);
59+
await page.locator('[data-label="Account name"]').nth(0).click();
60+
await expect(page.getByTestId('transaction')).toHaveCount(0);
61+
});
62+
63+
await test.step('Add second RBTC account', async () => {
64+
await page.goto('/#/account-summary');
65+
await page.getByRole('link', { name: 'Settings' }).click();
66+
await page.getByRole('link', { name: 'Manage Accounts' }).click();
67+
await page.getByRole('button', { name: 'Add account' }).click();
68+
await page.getByRole('button', { name: 'Add account' }).click();
69+
await expect(page.locator('body')).toContainText('Bitcoin Regtest 2 has now been added to your accounts.');
70+
await page.getByRole('button', { name: 'Done' }).click();
71+
});
72+
73+
await test.step('Send RBTC to receive address', async () => {
74+
console.log('Sending RBTC to first account');
75+
await page.waitForTimeout(2000);
76+
const sendAmount = '10';
77+
sendCoins(recvAdd, sendAmount);
78+
mineBlocks(12);
79+
});
80+
81+
await test.step('Verify that the first account has a transaction', async () => {
82+
await page.goto('/#/account-summary');
83+
await page.locator('[data-label="Account name"]').nth(0).click();
84+
await expect(page.getByTestId('transaction')).toHaveCount(1);
85+
86+
// It should be an incoming tx
87+
const tx = page.getByTestId('transaction').nth(0);
88+
await expect(tx).toHaveAttribute('data-tx-type', 'receive');
89+
90+
});
91+
92+
await test.step('Grab receive address for second account', async () => {
93+
await page.goto('/#/account-summary');
94+
await page.getByRole('link', { name: 'Bitcoin Regtest 2' }).click();
95+
96+
await page.getByRole('button', { name: 'Receive RBTC' }).click();
97+
await page.getByRole('button', { name: 'Verify address on BitBox' }).click();
98+
const addressLocator = page.locator('[data-testid="receive-address"]');
99+
recvAdd = await addressLocator.inputValue();
100+
expect(recvAdd).toContain('bcrt1');
101+
console.log(`Receive address: ${recvAdd}`);
102+
});
103+
104+
await test.step('Send RBTC to second account receive address', async () => {
105+
await page.goto('/#/account-summary');
106+
await page.getByRole('link', { name: 'Bitcoin Regtest Bitcoin' }).click();
107+
console.log('Sending RBTC to second account');
108+
await page.getByRole('link', { name: 'Send' }).click();
109+
await page.fill('#recipientAddress', recvAdd);
110+
await page.click('#sendAll');
111+
await page.getByRole('button', { name: 'Review' }).click();
112+
await page.getByRole('button', { name: 'Done' }).click();
113+
mineBlocks(12);
114+
});
115+
116+
await test.step('Verify that first account now has two transactions', async () => {
117+
await page.goto('/#/account-summary');
118+
await page.locator('td[data-label="Account name"]').nth(0).click();
119+
await expect(page.getByTestId('transaction')).toHaveCount(2);
120+
// Verify that the second one is outgoing
121+
// Txs are shown in reverse order
122+
const oldTx = page.getByTestId('transaction').nth(1);
123+
await expect(oldTx).toHaveAttribute('data-tx-type', 'receive');
124+
125+
const newTx = page.getByTestId('transaction').nth(0);
126+
await expect(newTx).toHaveAttribute('data-tx-type', 'send');
127+
});
128+
129+
await test.step('Verify that the second account has a transaction', async () => {
130+
await page.goto('/#/account-summary');
131+
await page.locator('td[data-label="Account name"]').nth(1).click();
132+
await expect(page.getByTestId('transaction')).toHaveCount(1);
133+
134+
const tx = page.getByTestId('transaction').nth(0);
135+
await expect(tx).toHaveAttribute('data-tx-type', 'receive');
136+
});
137+
138+
});
139+
140+
test.beforeEach(async () => {
141+
deleteAccountsFile();
142+
});
143+
144+
test.afterAll(async () => {
145+
await servewallet.stop();
146+
await cleanupRegtest(regtest);
147+
});

0 commit comments

Comments
 (0)