dev
dart 414 lines 15 KB
Raw
1 import 'dart:io';
2
3 import 'package:cake_wallet/entities/seed_type.dart';
4 import 'package:cake_wallet/reactions/wallet_utils.dart';
5 import 'package:cake_wallet/wallet_types.g.dart';
6 import 'package:cw_core/currency_for_wallet_type.dart';
7 import 'package:cw_core/wallet_type.dart';
8 import 'package:flutter/material.dart';
9 import 'package:flutter_test/flutter_test.dart';
10
11 import 'package:cake_wallet/main.dart' as app;
12
13 import '../robots/create_pin_welcome_page_robot.dart';
14 import '../robots/new_wallet_page_robot.dart';
15 import '../robots/new_wallet_type_page_robot.dart';
16 import '../robots/pre_seed_page_robot.dart';
17 import '../robots/restore_from_seed_or_key_robot.dart';
18 import '../robots/restore_options_page_robot.dart';
19 import '../robots/seed_verification_page_robot.dart';
20 import '../robots/setup_pin_code_robot.dart';
21 import '../robots/wallet_group_description_page_robot.dart';
22 import '../robots/wallet_list_page_robot.dart';
23 import '../robots/wallet_seed_page_robot.dart';
24 import '../robots/welcome_page_robot.dart';
25 import 'common_test_cases.dart';
26 import 'package:cake_wallet/.secrets.g.dart' as secrets;
27
28 import 'common_test_constants.dart';
29
30 class CommonTestFlows {
31 CommonTestFlows(this._tester)
32 : _commonTestCases = CommonTestCases(_tester),
33 _welcomePageRobot = WelcomePageRobot(_tester),
34 _preSeedPageRobot = PreSeedPageRobot(_tester),
35 _setupPinCodeRobot = SetupPinCodeRobot(_tester),
36 _newWalletPageRobot = NewWalletPageRobot(_tester),
37 _walletSeedPageRobot = WalletSeedPageRobot(_tester),
38 _walletListPageRobot = WalletListPageRobot(_tester),
39 _newWalletTypePageRobot = NewWalletTypePageRobot(_tester),
40 _restoreOptionsPageRobot = RestoreOptionsPageRobot(_tester),
41 _seedVerificationPageRobot = SeedVerificationPageRobot(_tester),
42 _createPinWelcomePageRobot = CreatePinWelcomePageRobot(_tester),
43 _restoreFromSeedOrKeysPageRobot = RestoreFromSeedOrKeysPageRobot(_tester),
44 _walletGroupDescriptionPageRobot = WalletGroupDescriptionPageRobot(_tester);
45
46 final WidgetTester _tester;
47 final CommonTestCases _commonTestCases;
48
49 final WelcomePageRobot _welcomePageRobot;
50 final PreSeedPageRobot _preSeedPageRobot;
51 final SetupPinCodeRobot _setupPinCodeRobot;
52 final NewWalletPageRobot _newWalletPageRobot;
53 final WalletSeedPageRobot _walletSeedPageRobot;
54 final WalletListPageRobot _walletListPageRobot;
55 final NewWalletTypePageRobot _newWalletTypePageRobot;
56 final RestoreOptionsPageRobot _restoreOptionsPageRobot;
57 final CreatePinWelcomePageRobot _createPinWelcomePageRobot;
58 final SeedVerificationPageRobot _seedVerificationPageRobot;
59 final RestoreFromSeedOrKeysPageRobot _restoreFromSeedOrKeysPageRobot;
60 final WalletGroupDescriptionPageRobot _walletGroupDescriptionPageRobot;
61
62 //* ========== Handles flow to start the app afresh and accept disclaimer =============
63 Future<void> startAppFlow(Key key) async {
64 await app.main(topLevelKey: key);
65
66 await _tester.pump(Duration(seconds: 2));
67
68 // // --------- Disclaimer Page ------------
69 // // Tap checkbox to accept disclaimer
70 // await _disclaimerPageRobot.tapDisclaimerCheckbox();
71
72 // // Tap accept button
73 // await _disclaimerPageRobot.tapAcceptButton();
74 }
75
76 //* ========== Handles flow from welcome to creating a new wallet ===============
77 Future<void> welcomePageToCreateNewWalletFlow(
78 WalletType walletTypeToCreate,
79 List<int> walletPin,
80 ) async {
81 await _welcomeToCreateWalletPath(walletTypeToCreate, walletPin);
82
83 await _generateNewWalletDetails();
84
85 await _confirmPreSeedInfo();
86
87 await _confirmWalletDetails();
88
89 await _verifyWalletSeed();
90 }
91
92 //* ========== Handles flow from welcome to restoring wallet from seeds ===============
93 Future<void> welcomePageToRestoreWalletThroughSeedsFlow(
94 WalletType walletTypeToRestore,
95 String walletSeed,
96 List<int> walletPin,
97 ) async {
98 await _welcomeToRestoreFromSeedsOrKeysPath(walletTypeToRestore, walletPin);
99 await _restoreFromSeeds(walletTypeToRestore, walletSeed);
100 }
101
102 //* ========== Handles flow from welcome to restoring wallet from keys ===============
103 Future<void> welcomePageToRestoreWalletThroughKeysFlow(
104 WalletType walletTypeToRestore,
105 List<int> walletPin,
106 ) async {
107 await _welcomeToRestoreFromSeedsOrKeysPath(walletTypeToRestore, walletPin);
108 await _restoreFromKeys();
109 }
110
111 void confirmAllAvailableWalletTypeIconsDisplayCorrectly() {
112 for (var walletType in availableWalletTypes) {
113 final imageUrl = walletTypeToCryptoCurrency(walletType).iconPath;
114
115 final walletIconFinder = find.image(
116 Image.asset(
117 imageUrl!,
118 width: 32,
119 height: 32,
120 ).image,
121 );
122
123 expect(walletIconFinder, findsAny);
124 }
125 }
126
127 //* ========== Handles creating new wallet flow from wallet list/menu ===============
128 Future<void> createNewWalletFromWalletMenu(WalletType walletTypeToCreate) async {
129 _tester.printToConsole('Creating ${walletTypeToCreate.name} Wallet');
130
131 await _tester.pumpAndSettle(Duration(milliseconds: 1000));
132
133 await _walletListPageRobot.navigateToCreateNewWalletPage();
134 await _commonTestCases.defaultSleepTime();
135
136 await _selectWalletTypeForWallet(walletTypeToCreate);
137 await _commonTestCases.defaultSleepTime();
138
139 // ---- Wallet Group/New Seed Implementation Comes here
140 await _walletGroupDescriptionPageFlow(true, walletTypeToCreate);
141
142 await _generateNewWalletDetails();
143
144 await _confirmPreSeedInfo();
145
146 await _confirmWalletDetails();
147
148 await _verifyWalletSeed();
149
150 await _commonTestCases.defaultSleepTime();
151 }
152
153 Future<void> _walletGroupDescriptionPageFlow(bool isNewSeed, WalletType walletType) async {
154 if (!isBIP39Wallet(walletType)) return;
155
156 await _walletGroupDescriptionPageRobot.isWalletGroupDescriptionPage();
157
158 if (isNewSeed) {
159 await _walletGroupDescriptionPageRobot.navigateToCreateNewSeedPage();
160 } else {
161 await _walletGroupDescriptionPageRobot.navigateToChooseWalletGroup();
162 }
163 }
164
165 //* ========== Handles restore wallet flow from wallet list/menu ===============
166 Future<void> restoreWalletFromWalletMenu(WalletType walletType, String walletSeed) async {
167 _tester.printToConsole('Restoring ${walletType.name} Wallet');
168 await _walletListPageRobot.navigateToRestoreWalletOptionsPage();
169 await _commonTestCases.defaultSleepTime();
170
171 if (!Platform.isLinux) await _restoreOptionsPageRobot.navigateToRestoreFromSeedsOrKeysPage();
172 if (!Platform.isLinux) await _commonTestCases.defaultSleepTime();
173
174 await _selectWalletTypeForWallet(walletType);
175 await _commonTestCases.defaultSleepTime();
176
177 await _restoreFromSeeds(walletType, walletSeed);
178 await _commonTestCases.defaultSleepTime();
179 }
180
181 //* ========== Handles setting up pin code for wallet on first install ===============
182 Future<void> setupPinCodeForWallet(List<int> pin) async {
183 if (Platform.isLinux) return;
184 // ----------- SetupPinCode Page -------------
185 // Confirm initial defaults - Widgets to be displayed etc
186 await _setupPinCodeRobot.isSetupPinCodePage();
187
188 await _setupPinCodeRobot.enterPinCode(pin);
189 await _setupPinCodeRobot.enterPinCode(pin);
190 await _setupPinCodeRobot.tapSuccessButton();
191 }
192
193 Future<void> _welcomeToCreateWalletPath(
194 WalletType walletTypeToCreate,
195 List<int> pin,
196 ) async {
197 await _createPinWelcomePageRobot.tapSetAPinButton();
198
199 await setupPinCodeForWallet(pin);
200
201 await _welcomePageRobot.navigateToCreateNewWalletPage();
202
203 await _selectWalletTypeForWallet(walletTypeToCreate);
204
205 if (_welcomePageRobot.hasNewSingleSeedButton()) {
206 await _welcomePageRobot.tapNewSingleSeed();
207 }
208 }
209
210 Future<void> _welcomeToRestoreFromSeedsOrKeysPath(
211 WalletType walletTypeToRestore,
212 List<int> pin,
213 ) async {
214 await _createPinWelcomePageRobot.tapSetAPinButton();
215
216 await setupPinCodeForWallet(pin);
217
218 await _welcomePageRobot.navigateToRestoreWalletPage();
219
220 if (!Platform.isLinux) await _restoreOptionsPageRobot.navigateToRestoreFromSeedsOrKeysPage();
221
222 await _selectWalletTypeForWallet(walletTypeToRestore);
223 }
224
225 //* ============ Handles New Wallet Type Page ==================
226 Future<void> _selectWalletTypeForWallet(WalletType type) async {
227 // ----------- NewWalletType Page -------------
228 _tester.printToConsole('Selecting wallet type: ${type.name}');
229
230 await _tester.pumpAndSettle(Duration(milliseconds: 1000));
231
232 await _newWalletTypePageRobot.findParticularWalletTypeInScrollableList(type);
233
234 // Tapping the wallet type navigates directly (no separate Next button).
235 _tester.printToConsole('Tapping wallet type: ${type.name}');
236 await _newWalletTypePageRobot.selectWalletType(type);
237
238 await _tester.pumpAndSettle(Duration(milliseconds: 2000));
239
240 _tester.printToConsole('Wallet type selection completed for: ${type.name}');
241 }
242
243 //* ============ Handles New Wallet Page ==================
244 Future<void> _generateNewWalletDetails() async {
245 _tester.printToConsole('Attempting to find NewWalletPage...');
246
247 await _tester.pumpAndSettle(Duration(milliseconds: 1000));
248
249 await _newWalletPageRobot.isNewWalletPage();
250 _tester.printToConsole('NewWalletPage found successfully');
251
252 await _newWalletPageRobot.generateWalletName();
253
254 if (Platform.isLinux) {
255 // manual pin input
256 await _restoreFromSeedOrKeysPageRobot
257 .enterPasswordForWalletRestore(CommonTestConstants.pin.join(""));
258 await _restoreFromSeedOrKeysPageRobot
259 .enterPasswordRepeatForWalletRestore(CommonTestConstants.pin.join(""));
260 }
261
262 await _newWalletPageRobot.onNextButtonPressed();
263 }
264
265 //* ============ Handles Pre Seed Page =====================
266 Future<void> _confirmPreSeedInfo() async {
267 await _preSeedPageRobot.isPreSeedPage();
268
269 await _preSeedPageRobot.onConfirmButtonPressed();
270 }
271
272 //* ============ Handles Wallet Seed Page ==================
273 Future<void> _confirmWalletDetails() async {
274 await _walletSeedPageRobot.isWalletSeedPage();
275
276 _walletSeedPageRobot.confirmWalletDetailsDisplayCorrectly();
277
278 _walletSeedPageRobot.confirmWalletSeedReminderDisplays();
279
280 // await _walletSeedPageRobot.onCopySeedsButtonPressed();
281
282 await _walletSeedPageRobot.onVerifySeedButtonPressed();
283 }
284
285 //* ============ Handles Wallet Seed Verification Page ==================
286
287 Future<void> _verifyWalletSeed() async {
288 await _seedVerificationPageRobot.isSeedVerificationPage();
289
290 _seedVerificationPageRobot.hasTitle();
291
292 await _seedVerificationPageRobot.verifyWalletSeeds();
293 }
294
295 //* Main Restore Actions - On the RestoreFromSeed/Keys Page - Restore from Seeds Action
296 Future<void> _restoreFromSeeds(WalletType type, String walletSeed) async {
297 // ----------- RestoreFromSeedOrKeys Page -------------
298
299 await _restoreFromSeedOrKeysPageRobot.selectWalletNameFromAvailableOptions();
300 await _restoreFromSeedOrKeysPageRobot.enterSeedPhraseForWalletRestore(walletSeed);
301
302 final numberOfWords = walletSeed.split(' ').length;
303
304 if (numberOfWords == 25 && (type == WalletType.monero)) {
305 await _restoreFromSeedOrKeysPageRobot
306 .chooseSeedTypeForMoneroOrWowneroWallets(MoneroSeedType.legacy);
307
308 // Using a constant value of 2831400 for the blockheight as its the restore blockheight for our testing wallet
309 await _restoreFromSeedOrKeysPageRobot
310 .enterBlockHeightForWalletRestore(secrets.moneroTestWalletBlockHeight);
311 }
312
313 if (Platform.isLinux) {
314 // manual pin input
315 await _restoreFromSeedOrKeysPageRobot
316 .enterPasswordForWalletRestore(CommonTestConstants.pin.join(""));
317 await _restoreFromSeedOrKeysPageRobot
318 .enterPasswordRepeatForWalletRestore(CommonTestConstants.pin.join(""));
319 }
320
321 await _restoreFromSeedOrKeysPageRobot.onRestoreWalletButtonPressed();
322 }
323
324 //* Main Restore Actions - On the RestoreFromSeed/Keys Page - Restore from Keys Action
325 Future<void> _restoreFromKeys() async {
326 await _commonTestCases.swipePage();
327 await _commonTestCases.defaultSleepTime();
328
329 await _restoreFromSeedOrKeysPageRobot.selectWalletNameFromAvailableOptions(
330 isSeedFormEntry: false,
331 );
332
333 await _restoreFromSeedOrKeysPageRobot.enterSeedPhraseForWalletRestore('');
334 await _restoreFromSeedOrKeysPageRobot.onRestoreWalletButtonPressed();
335 }
336
337 //* ====== Utility Function to get test wallet seeds for each wallet type ========
338 String getWalletSeedsByWalletType(WalletType walletType) {
339 switch (walletType) {
340 case WalletType.monero:
341 return secrets.moneroTestWalletSeeds;
342 case WalletType.bitcoin:
343 return secrets.bitcoinTestWalletSeeds;
344 case WalletType.ethereum:
345 return secrets.ethereumTestWalletSeeds;
346 case WalletType.litecoin:
347 return secrets.litecoinTestWalletSeeds;
348 case WalletType.bitcoinCash:
349 return secrets.bitcoinCashTestWalletSeeds;
350 case WalletType.polygon:
351 return secrets.polygonTestWalletSeeds;
352 case WalletType.solana:
353 return secrets.solanaTestWalletSeeds;
354 case WalletType.base:
355 return secrets.baseTestWalletSeeds;
356 case WalletType.arbitrum:
357 return secrets.arbitrumTestWalletSeeds;
358 case WalletType.bsc:
359 return secrets.bscTestWalletSeeds;
360 case WalletType.tron:
361 return secrets.tronTestWalletSeeds;
362 case WalletType.nano:
363 return secrets.nanoTestWalletSeeds;
364 case WalletType.wownero:
365 return secrets.wowneroTestWalletSeeds;
366 case WalletType.zano:
367 return secrets.zanoTestWalletSeeds;
368 case WalletType.decred:
369 return secrets.decredTestWalletSeeds;
370 case WalletType.dogecoin:
371 return secrets.dogeTestWalletSeeds;
372 case WalletType.zcash:
373 return secrets.zcashTestWalletSeeds;
374 case WalletType.none:
375 case WalletType.haven:
376 case WalletType.banano:
377 throw Exception("Unable to get seeds for ${walletType}");
378 }
379 }
380
381 //* ====== Utility Function to get test receive address for each wallet type ========
382 String getReceiveAddressByWalletType(WalletType walletType) {
383 switch (walletType) {
384 case WalletType.monero:
385 return secrets.moneroTestWalletReceiveAddress;
386 case WalletType.bitcoin:
387 return secrets.bitcoinTestWalletReceiveAddress;
388 case WalletType.ethereum:
389 return secrets.ethereumTestWalletReceiveAddress;
390 case WalletType.litecoin:
391 return secrets.litecoinTestWalletReceiveAddress;
392 case WalletType.bitcoinCash:
393 return secrets.bitcoinCashTestWalletReceiveAddress;
394 case WalletType.polygon:
395 return secrets.polygonTestWalletReceiveAddress;
396 case WalletType.base:
397 return secrets.baseTestWalletReceiveAddress;
398 case WalletType.arbitrum:
399 return secrets.arbitrumTestWalletReceiveAddress;
400 case WalletType.bsc:
401 return secrets.bscTestWalletReceiveAddress;
402 case WalletType.solana:
403 return secrets.solanaTestWalletReceiveAddress;
404 case WalletType.tron:
405 return secrets.tronTestWalletReceiveAddress;
406 case WalletType.nano:
407 return secrets.nanoTestWalletReceiveAddress;
408 case WalletType.wownero:
409 return secrets.wowneroTestWalletReceiveAddress;
410 default:
411 return '';
412 }
413 }
414 }