dev
dart 338 lines 11.3 KB
Raw
1 import 'package:cake_wallet/generated/i18n.dart';
2 import 'package:cake_wallet/src/screens/exchange/exchange_page.dart';
3 import 'package:cake_wallet/src/screens/exchange/widgets/present_provider_picker.dart';
4 import 'package:cw_core/crypto_currency.dart';
5 import 'package:flutter/foundation.dart';
6 import 'package:flutter_test/flutter_test.dart';
7
8 import '../components/common_test_cases.dart';
9 import '../components/common_test_constants.dart';
10 import 'auth_page_robot.dart';
11
12 class ExchangePageRobot {
13 ExchangePageRobot(this.tester)
14 : commonTestCases = CommonTestCases(tester),
15 authPageRobot = AuthPageRobot(tester);
16
17 WidgetTester tester;
18 AuthPageRobot authPageRobot;
19 CommonTestCases commonTestCases;
20
21 Future<void> isExchangePage() async {
22 await commonTestCases.isSpecificPage<ExchangePage>();
23 await commonTestCases.takeScreenshots('exchange_page');
24 await commonTestCases.defaultSleepTime();
25 }
26
27 void hasResetButton() {
28 commonTestCases.hasText(S.current.reset);
29 }
30
31 void displaysPresentProviderPicker() {
32 commonTestCases.hasType<PresentProviderPicker>();
33 }
34
35 Future<void> displayBothExchangeCards() async {
36 final ExchangePage exchangeCard = tester.widget<ExchangePage>(
37 find.byType(ExchangePage),
38 );
39
40 final depositKey = exchangeCard.depositKey;
41 final receiveKey = exchangeCard.receiveKey;
42
43 final depositExchangeCard = find.byKey(depositKey);
44 expect(depositExchangeCard, findsOneWidget);
45
46 final receiveExchangeCard = find.byKey(receiveKey);
47 expect(receiveExchangeCard, findsOneWidget);
48 }
49
50 void confirmRightComponentsDisplayOnDepositExchangeCards() {
51 ExchangePage exchangePage = tester.widget(find.byType(ExchangePage));
52 final exchangeViewModel = exchangePage.exchangeViewModel;
53 final depositCardPrefix = 'deposit_exchange_card';
54
55 commonTestCases.hasValueKey('${depositCardPrefix}_title_key');
56 commonTestCases.hasValueKey('${depositCardPrefix}_currency_picker_button_key');
57 commonTestCases.hasValueKey('${depositCardPrefix}_selected_currency_text_key');
58 commonTestCases.hasValueKey('${depositCardPrefix}_amount_textfield_key');
59
60 exchangePage.depositKey.currentState!.changeLimits(min: '0.1');
61
62 commonTestCases.hasValueKey('${depositCardPrefix}_min_limit_text_key');
63
64 final initialCurrency = exchangeViewModel.depositCurrency;
65 if (initialCurrency.tag != null) {
66 commonTestCases.hasValueKey('${depositCardPrefix}_selected_currency_tag_text_key');
67 }
68
69 if (exchangeViewModel.hasAllAmount) {
70 commonTestCases.hasValueKey('${depositCardPrefix}_send_all_button_key');
71 }
72
73 if (exchangeViewModel.isMoneroWallet) {
74 commonTestCases.hasValueKey('${depositCardPrefix}_address_book_button_key');
75 }
76
77 if (exchangeViewModel.isDepositAddressEnabled) {
78 commonTestCases.hasValueKey('${depositCardPrefix}_editable_address_textfield_key');
79 } else {
80 commonTestCases.hasValueKey('${depositCardPrefix}_non_editable_address_textfield_key');
81 commonTestCases.hasValueKey('${depositCardPrefix}_copy_refund_address_button_key');
82 }
83
84 // commonTestCases.hasValueKey('${depositCardPrefix}_max_limit_text_key');
85 }
86
87 void confirmRightComponentsDisplayOnReceiveExchangeCards() {
88 ExchangePage exchangePage = tester.widget(find.byType(ExchangePage));
89 final exchangeViewModel = exchangePage.exchangeViewModel;
90 final receiveCardPrefix = 'receive_exchange_card';
91
92 commonTestCases.hasValueKey('${receiveCardPrefix}_title_key');
93 commonTestCases.hasValueKey('${receiveCardPrefix}_currency_picker_button_key');
94 commonTestCases.hasValueKey('${receiveCardPrefix}_selected_currency_text_key');
95 commonTestCases.hasValueKey('${receiveCardPrefix}_amount_textfield_key');
96 commonTestCases.hasValueKey('${receiveCardPrefix}_min_limit_text_key');
97
98 final initialCurrency = exchangeViewModel.receiveCurrency;
99 if (initialCurrency.tag != null) {
100 commonTestCases.hasValueKey('${receiveCardPrefix}_selected_currency_tag_text_key');
101 }
102
103 if (exchangeViewModel.hasAllAmount) {
104 commonTestCases.hasValueKey('${receiveCardPrefix}_send_all_button_key');
105 }
106
107 if (exchangeViewModel.isMoneroWallet) {
108 commonTestCases.hasValueKey('${receiveCardPrefix}_address_book_button_key');
109 }
110
111 commonTestCases.hasValueKey('${receiveCardPrefix}_editable_address_textfield_key');
112 }
113
114 Future<void> selectDepositCurrency(CryptoCurrency depositCurrency) async {
115 final depositPrefix = 'deposit_exchange_card';
116 final currencyPickerKey = '${depositPrefix}_currency_picker_button_key';
117 final currencyPickerDialogKey = '${depositPrefix}_currency_picker_dialog_button_key';
118
119 await commonTestCases.tapItemByKey(currencyPickerKey);
120 commonTestCases.hasValueKey(currencyPickerDialogKey);
121
122 ExchangePage exchangePage = tester.widget(find.byType(ExchangePage));
123 final exchangeViewModel = exchangePage.exchangeViewModel;
124
125 if (depositCurrency == exchangeViewModel.depositCurrency) {
126 await commonTestCases.defaultSleepTime();
127 await commonTestCases
128 .tapItemByKey('picker_items_index_${depositCurrency.name}_selected_item_button_key');
129 return;
130 }
131
132 await commonTestCases.enterText(depositCurrency.name, 'search_bar_widget_key');
133
134 await commonTestCases.defaultSleepTime();
135
136 await commonTestCases.tapItemByKey('picker_items_index_${depositCurrency.name}_button_key');
137 }
138
139 Future<void> selectReceiveCurrency(CryptoCurrency receiveCurrency) async {
140 final receivePrefix = 'receive_exchange_card';
141 final currencyPickerKey = '${receivePrefix}_currency_picker_button_key';
142 final currencyPickerDialogKey = '${receivePrefix}_currency_picker_dialog_button_key';
143
144 await commonTestCases.tapItemByKey(currencyPickerKey);
145 commonTestCases.hasValueKey(currencyPickerDialogKey);
146
147 ExchangePage exchangePage = tester.widget(find.byType(ExchangePage));
148 final exchangeViewModel = exchangePage.exchangeViewModel;
149
150 if (receiveCurrency == exchangeViewModel.receiveCurrency) {
151 await commonTestCases
152 .tapItemByKey('picker_items_index_${receiveCurrency.name}_selected_item_button_key');
153 return;
154 }
155
156 await commonTestCases.enterText(receiveCurrency.name, 'search_bar_widget_key');
157
158 await commonTestCases.defaultSleepTime();
159
160 await commonTestCases.tapItemByKey('picker_items_index_${receiveCurrency.name}_button_key');
161 }
162
163 Future<void> enterDepositAmount(String amount) async {
164 await commonTestCases.enterText(amount, 'deposit_exchange_card_amount_textfield_key');
165 }
166
167 Future<void> enterDepositRefundAddress({String? depositAddress}) async {
168 ExchangePage exchangePage = tester.widget(find.byType(ExchangePage));
169 final exchangeViewModel = exchangePage.exchangeViewModel;
170
171 if (exchangeViewModel.isDepositAddressEnabled && depositAddress != null) {
172 await commonTestCases.enterText(
173 depositAddress, 'deposit_exchange_card_editable_address_textfield_key');
174 }
175 }
176
177 Future<void> enterReceiveAddress(String receiveAddress) async {
178 await commonTestCases.enterText(
179 receiveAddress,
180 'receive_exchange_card_editable_address_textfield_key',
181 );
182 await commonTestCases.defaultSleepTime();
183 }
184
185 Future<void> onExchangeButtonPressed() async {
186 await commonTestCases.tapItemByKey('exchange_page_exchange_button_key');
187 await commonTestCases.defaultSleepTime();
188 }
189
190 bool hasMaxLimitError() {
191 final maxErrorText = find.text(S.current.error_text_input_above_maximum_limit);
192
193 bool hasMaxError = maxErrorText.tryEvaluate();
194
195 return hasMaxError;
196 }
197
198 bool hasMinLimitError() {
199 final minErrorText = find.text(S.current.error_text_input_below_minimum_limit);
200
201 bool hasMinError = minErrorText.tryEvaluate();
202
203 return hasMinError;
204 }
205
206 bool hasTradeCreationFailureError() {
207 final tradeCreationFailureDialogButton =
208 find.byKey(ValueKey('exchange_page_trade_creation_failure_dialog_button_key'));
209
210 bool hasTradeCreationFailure = tradeCreationFailureDialogButton.tryEvaluate();
211 tester.printToConsole('Trade not created error: $hasTradeCreationFailure');
212 return hasTradeCreationFailure;
213 }
214
215 Future<void> onTradeCreationFailureDialogButtonPressed() async {
216 await commonTestCases.tapItemByKey('exchange_page_trade_creation_failure_dialog_button_key');
217 }
218
219 /// Handling Trade Failure Errors or errors shown through the Failure Dialog.
220 ///
221 /// Simulating the user's flow and response when this error comes up.
222 /// Examples are:
223 /// - No provider can handle this trade error,
224 /// - Trade amount below limit error.
225 Future<void> _handleTradeCreationFailureErrors() async {
226 tester.printToConsole('Inside trade creation failure handle');
227 bool isTradeCreationFailure = false;
228
229 isTradeCreationFailure = hasTradeCreationFailureError();
230
231 int maxRetries = 3;
232 int retries = 0;
233
234 while (isTradeCreationFailure && retries < maxRetries) {
235 await tester.pumpAndSettle();
236
237 await onTradeCreationFailureDialogButtonPressed();
238
239 await commonTestCases.defaultSleepTime(seconds: 5);
240
241 await onExchangeButtonPressed();
242
243 await _handleAuthPage();
244
245 isTradeCreationFailure = hasTradeCreationFailureError();
246 retries++;
247 }
248 }
249
250 /// Handles the min limit error.
251 ///
252 /// Simulates the user's flow and response when it comes up.
253 ///
254 /// Has a max retry of 20 times.
255 Future<void> _handleMinLimitError(String initialAmount) async {
256 double amount;
257
258 amount = double.parse(initialAmount);
259
260 ExchangePage exchangePage = tester.widget(find.byType(ExchangePage));
261 final exchangeViewModel = exchangePage.exchangeViewModel;
262
263 amount = (exchangeViewModel.limits.min ?? 0.0) + 1.0;
264
265 await enterDepositAmount(amount.toString());
266
267 await tester.pumpAndSettle();
268
269 await onExchangeButtonPressed();
270
271 await tester.pumpAndSettle();
272 }
273
274 /// Handles the max limit error.
275 ///
276 /// Simulates the user's flow and response when it comes up.
277 ///
278 /// Has a max retry of 20 times.
279 Future<void> _handleMaxLimitError(String initialAmount) async {
280 double amount;
281
282 amount = double.parse(initialAmount);
283
284 ExchangePage exchangePage = tester.widget(find.byType(ExchangePage));
285 final exchangeViewModel = exchangePage.exchangeViewModel;
286
287 amount = (exchangeViewModel.limits.max ?? 0.0) - 1.0;
288
289 await enterDepositAmount(amount.toString());
290
291 await tester.pumpAndSettle();
292
293 await onExchangeButtonPressed();
294
295 await tester.pumpAndSettle();
296 }
297
298 Future<void> handleErrors(String initialAmount) async {
299 await tester.pumpAndSettle();
300
301 bool isMinLimitError = hasMinLimitError();
302
303 if (isMinLimitError) {
304 tester.printToConsole('Has min limit error');
305 await _handleMinLimitError(initialAmount);
306 }
307
308 bool isMaxLimitError = hasMaxLimitError();
309
310 if (isMaxLimitError) {
311 await _handleMaxLimitError(initialAmount);
312 }
313
314 tester.printToConsole('No limits error, proceeding with flow');
315
316 await _handleAuthPage();
317
318 await tester.pumpAndSettle();
319
320 await _handleTradeCreationFailureErrors();
321
322 await tester.pumpAndSettle();
323
324 await commonTestCases.defaultSleepTime();
325 }
326
327 Future<void> _handleAuthPage() async {
328 final onAuthPage = authPageRobot.onAuthPage();
329 if (onAuthPage) {
330 await authPageRobot.enterPinCode(CommonTestConstants.pin);
331 }
332
333 final onAuthPageDesktop = authPageRobot.onAuthPageDesktop();
334 if (onAuthPageDesktop) {
335 await authPageRobot.enterPassword(CommonTestConstants.pin.join(""));
336 }
337 }
338 }