1
+ import 'package:flutter/foundation.dart' ;
2
+ import 'package:flutter_test/flutter_test.dart' ;
3
+ import 'package:patrol/patrol.dart' ;
4
+
5
+ import 'utils/utils.dart' ;
6
+
7
+ Future <void > assertOptionsPromptIsDisplayed (PatrolIntegrationTester $) async {
8
+ final floatingButton = await $.native2.getNativeViews (NativeSelector (
9
+ ios: IOSSelector (
10
+ identifier: 'IBGReportBugPromptOptionAccessibilityIdentifier' ),
11
+ android: AndroidSelector (
12
+ resourceName:
13
+ 'com.instabug.flutter.example:id/instabug_main_prompt_container' )));
14
+
15
+ expect (
16
+ isAndroid
17
+ ? floatingButton.androidViews.length
18
+ : floatingButton.iosViews.length,
19
+ greaterThanOrEqualTo (1 ));
20
+ }
21
+
22
+ void main () {
23
+ group ('Bug reporting end-to-end test' , () {
24
+ patrolTest (
25
+ 'Report a bug' ,
26
+ ($) async {
27
+ await init ($);
28
+
29
+ await $.native2.tap (NativeSelector (
30
+ ios: IOSSelector (
31
+ identifier: 'IBGFloatingButtonAccessibilityIdentifier' ),
32
+ android: AndroidSelector (
33
+ resourceName:
34
+ 'com.instabug.flutter.example:id/instabug_floating_button' )));
35
+
36
+ await $.native2.tap (NativeSelector (
37
+ ios: IOSSelector (labelContains: 'Report a bug' ),
38
+ android: AndroidSelector (textContains: 'Report a bug' )));
39
+
40
+ await $.native2.enterText (
41
+ NativeSelector (
42
+ ios: IOSSelector (
43
+ identifier:
44
+ 'IBGBugInputViewEmailFieldAccessibilityIdentifier' ),
45
+ android: AndroidSelector (
46
+ resourceName:
47
+ 'com.instabug.flutter.example:id/instabug_edit_text_email' )),
48
+
49
+ );
50
+
51
+ await $.native2.tap (NativeSelector (
52
+ ios: IOSSelector (
53
+ identifier: 'IBGBugVCNextButtonAccessibilityIdentifier' ),
54
+ android: AndroidSelector (
55
+ resourceName:
56
+ 'com.instabug.flutter.example:id/instabug_bugreporting_send' )));
57
+
58
+ bool isAndroid = defaultTargetPlatform == TargetPlatform .android;
59
+ if (isAndroid == false ) {
60
+ await Future .delayed (const Duration (milliseconds: 500 ));
61
+ }
62
+ final thankyou =
63
+ await $.native .getNativeViews (Selector (textContains: "Thank you" ));
64
+
65
+ expect (thankyou.length, greaterThanOrEqualTo (1 ));
66
+ },
67
+ framePolicy: LiveTestWidgetsFlutterBindingFramePolicy .fullyLive,
68
+ );
69
+
70
+ patrolTest (
71
+ 'Floating Button Invocation Event' ,
72
+ ($) async {
73
+ await init ($);
74
+
75
+ await $.native2.tap (NativeSelector (
76
+ ios: IOSSelector (
77
+ identifier: 'IBGFloatingButtonAccessibilityIdentifier' ),
78
+ android: AndroidSelector (
79
+ resourceName:
80
+ 'com.instabug.flutter.example:id/instabug_floating_button' )));
81
+
82
+ assertOptionsPromptIsDisplayed ($);
83
+ },
84
+ framePolicy: LiveTestWidgetsFlutterBindingFramePolicy .fullyLive,
85
+ );
86
+
87
+ patrolTest (
88
+ 'TwoFingers Swipe Left Invocation Event' ,
89
+ ($) async {
90
+ await init ($);
91
+
92
+ await $("Two Fingers Swipe Left" ).scrollTo ().tap ();
93
+ await wait (second: 1 );
94
+ final gesture1 = await $.tester.startGesture (const Offset (300 , 400 )); // finger 1
95
+ final gesture2 = await $.tester.startGesture (const Offset (300 , 600 )); // finger 2
96
+
97
+ // Swipe both fingers to the left (same direction)
98
+ await gesture1.moveBy (const Offset (- 150 , 0 ));
99
+ await gesture2.moveBy (const Offset (- 150 , 0 ));
100
+
101
+ // End gestures
102
+ await gesture1.up ();
103
+ await gesture2.up ();
104
+
105
+ await wait (second: 1 );
106
+ assertOptionsPromptIsDisplayed ($);
107
+ },
108
+ framePolicy: LiveTestWidgetsFlutterBindingFramePolicy .fullyLive,
109
+ );
110
+ patrolTest ('None Invocation Event hides floating button' , ($) async {
111
+ await init ($);
112
+
113
+ await $('None' ).scrollTo ().tap ();
114
+
115
+ await wait (second: 1 );
116
+ final floatingButton = await $.native2.getNativeViews (NativeSelector (
117
+ ios: IOSSelector (identifier: 'IBGFloatingButtonAccessibilityIdentifier' ),
118
+ android: AndroidSelector (
119
+ resourceName:
120
+ 'com.instabug.flutter.example:id/instabug_floating_button' ),
121
+ ));
122
+
123
+ expect (
124
+ isAndroid
125
+ ? floatingButton.androidViews.length
126
+ : floatingButton.iosViews.length,
127
+ equals (0 ));
128
+ });
129
+
130
+ patrolTest ('Manual Invocation shows prompt options' , ($) async {
131
+ await init ($);
132
+
133
+ await $('Invoke' ).scrollTo ().tap ();
134
+
135
+ await assertOptionsPromptIsDisplayed ($);
136
+ });
137
+
138
+ patrolTest ('Multiple Screenshots in Repro Steps' , ($) async {
139
+ await init ($);
140
+
141
+ await $(#screen_name_input).scrollTo ().enterText ('My Screen' );
142
+
143
+ await wait (miliSeconds: 500 );
144
+
145
+ await $('Report Screen Change' ).scrollTo ().tap ();
146
+ await wait (miliSeconds: 500 );
147
+ await $('Send Bug Report' ).scrollTo ().tap ();
148
+
149
+ await $.native2.tap (NativeSelector (
150
+ ios: IOSSelector (
151
+ identifier: 'IBGBugVCReproStepsDisclaimerAccessibilityIdentifier' ),
152
+ android: AndroidSelector (
153
+ resourceName:
154
+ 'com.instabug.flutter.example:id/instabug_text_view_repro_steps_disclaimer' ),
155
+ ));
156
+
157
+ await wait (miliSeconds: 1000 );
158
+
159
+ final screenshots = await $.native2.getNativeViews (NativeSelector (
160
+ ios: IOSSelector (
161
+ identifier: 'IBGReproStepsTableCellViewAccessibilityIdentifier' ),
162
+ android: AndroidSelector (
163
+ resourceName:
164
+ 'com.instabug.flutter.example:id/ib_bug_repro_step_screenshot' ),
165
+ ));
166
+
167
+ final count = isAndroid
168
+ ? screenshots.androidViews.length
169
+ : screenshots.iosViews.length;
170
+
171
+ expect (count, 2 );
172
+ });
173
+
174
+ patrolTest ('Floating Button moves to left edge' , ($) async {
175
+ await init ($);
176
+
177
+ await $('Move Floating Button to Left' ).scrollTo ().tap ();
178
+
179
+
180
+ await wait (second: 5 );
181
+
182
+ final floatingButton = await $.native2.getNativeViews (NativeSelector (
183
+ ios: IOSSelector (
184
+ identifier: 'IBGFloatingButtonAccessibilityIdentifier' ),
185
+ android: AndroidSelector (
186
+ resourceName:
187
+ 'com.instabug.flutter.example:id/instabug_floating_button' ),
188
+ ));
189
+
190
+
191
+ await wait (second: 2 );
192
+
193
+ final size = $.tester.view.physicalSize / $.tester.view.devicePixelRatio;
194
+ final width = size.width;
195
+ $.log (floatingButton.androidViews.length.toString ());
196
+
197
+ $.log (floatingButton.androidViews.first.visibleBounds.minX.toString ());
198
+ $.log (floatingButton.androidViews.first.visibleBounds.maxX.toString ());
199
+ $.log ((width / 2 ).toString ());
200
+
201
+
202
+ bool isLeft = false ;
203
+ if (isAndroid &&
204
+ floatingButton.androidViews.isNotEmpty) {
205
+
206
+
207
+ $.log (floatingButton.androidViews.first.visibleBounds.minX.toString ());
208
+ $.log (floatingButton.androidViews.first.visibleBounds.maxX.toString ());
209
+ $.log ((width / 2 ).toString ());
210
+
211
+ isLeft = floatingButton.androidViews.first.visibleBounds.minX <
212
+ (width / 2 );
213
+ } else if ((! isAndroid) &&
214
+ floatingButton.iosViews.isNotEmpty) {
215
+ isLeft = floatingButton.iosViews.first.frame.minX <
216
+ (width / 2 );
217
+ }
218
+
219
+ expect (isLeft, true );
220
+ });
221
+
222
+ patrolTest (
223
+ 'onDismiss callback triggers when prompt is cancelled' , ($) async {
224
+ await init ($);
225
+
226
+ await $('Set On Dismiss Callback' ).scrollTo ().tap ();
227
+ await wait (second: 4 );
228
+ await $('Invoke' ).scrollTo ().tap ();
229
+
230
+ await wait (second: 4 );
231
+
232
+ await $.native2.tap (NativeSelector (
233
+ android: AndroidSelector (text: 'Cancel' ),
234
+ ios: IOSSelector (label: 'Cancel' ),
235
+ ));
236
+
237
+ await wait (second: 4 );
238
+
239
+ final callbackWidget = $('onDismiss callback called with DismissType.cancel and ReportType.other' );
240
+ expect (callbackWidget, findsOneWidget);
241
+ });
242
+
243
+ });
244
+
245
+ }
0 commit comments