@@ -8,11 +8,13 @@ import android.graphics.Bitmap
8
8
import android.net.Uri
9
9
import android.os.Environment
10
10
import android.view.View
11
+ import androidx.recyclerview.widget.RecyclerView
11
12
import androidx.test.espresso.Espresso.onView
12
13
import androidx.test.espresso.NoMatchingViewException
13
14
import androidx.test.espresso.action.ViewActions.click
14
15
import androidx.test.espresso.action.ViewActions.replaceText
15
16
import androidx.test.espresso.assertion.ViewAssertions.matches
17
+ import androidx.test.espresso.contrib.RecyclerViewActions
16
18
import androidx.test.espresso.intent.Intents
17
19
import androidx.test.espresso.intent.Intents.intended
18
20
import androidx.test.espresso.intent.Intents.intending
@@ -24,6 +26,8 @@ import androidx.test.rule.ActivityTestRule
24
26
import androidx.test.rule.GrantPermissionRule
25
27
import androidx.test.runner.AndroidJUnit4
26
28
import fr.free.nrw.commons.auth.LoginActivity
29
+ import fr.free.nrw.commons.upload.DescriptionsAdapter
30
+ import fr.free.nrw.commons.util.MyViewAction
27
31
import fr.free.nrw.commons.utils.ConfigUtils
28
32
import org.hamcrest.core.AllOf.allOf
29
33
import org.junit.After
@@ -65,68 +69,154 @@ class UploadTest {
65
69
}
66
70
UITestHelper .skipWelcome()
67
71
UITestHelper .loginUser()
68
- saveToInternalStorage()
69
72
}
70
73
71
74
@After
72
75
fun teardown () {
73
76
Intents .release()
74
77
}
75
78
76
- private fun saveToInternalStorage () {
77
- val bitmapImage = randomBitmap
79
+ @Test
80
+ fun testUploadWithDescription () {
81
+ if (! ConfigUtils .isBetaFlavour()) {
82
+ throw Error (" This test should only be run in Beta!" )
83
+ }
78
84
79
- // path to /data/data/yourapp/app_data/imageDir
80
- val mypath = File (Environment .getExternalStorageDirectory(), " image.jpg" )
85
+ setupSingleUpload(" image.jpg" )
81
86
82
- Timber .d( " Filepath: %s " , mypath.path )
87
+ openGallery( )
83
88
84
- Timber .d(" Absolute Filepath: %s" , mypath.absolutePath)
89
+ // Validate that an intent to get an image is sent
90
+ intended(allOf(hasAction(Intent .ACTION_GET_CONTENT ), hasType(" image/*" )))
91
+
92
+ // Create filename with the current time (to prevent overwrites)
93
+ val dateFormat = SimpleDateFormat (" yyMMdd-hhmmss" )
94
+ val commonsFileName = " MobileTest " + dateFormat.format(Date ())
95
+
96
+ // Try to dismiss the error, if there is one (probably about duplicate files on Commons)
97
+ dismissWarning(" Yes" )
98
+
99
+ onView(allOf<View >(isDisplayed(), withId(R .id.et_title)))
100
+ .perform(replaceText(commonsFileName))
101
+
102
+ onView(allOf<View >(isDisplayed(), withId(R .id.description_item_edit_text)))
103
+ .perform(replaceText(commonsFileName))
104
+
105
+
106
+ onView(allOf(isDisplayed(), withId(R .id.btn_next)))
107
+ .perform(click())
108
+
109
+ UITestHelper .sleep(5000 )
110
+ dismissWarning(" Yes" )
111
+
112
+ UITestHelper .sleep(3000 )
113
+
114
+ onView(allOf(isDisplayed(), withId(R .id.et_search)))
115
+ .perform(replaceText(" Uploaded with Mobile/Android Tests" ))
116
+
117
+ UITestHelper .sleep(3000 )
85
118
86
- var fos: FileOutputStream ? = null
87
119
try {
88
- fos = FileOutputStream (mypath)
89
- // Use the compress method on the BitMap object to write image to the OutputStream
90
- bitmapImage.compress(Bitmap .CompressFormat .JPEG , 100 , fos)
91
- } catch (e: Exception ) {
92
- e.printStackTrace()
93
- } finally {
94
- try {
95
- fos?.close()
96
- } catch (e: IOException ) {
97
- e.printStackTrace()
98
- }
120
+ onView(allOf(isDisplayed(), UITestHelper .first(withParent(withId(R .id.rv_categories)))))
121
+ .perform(click())
122
+ } catch (ignored: NoMatchingViewException ) {
123
+ }
124
+
125
+ onView(allOf(isDisplayed(), withId(R .id.btn_next)))
126
+ .perform(click())
127
+
128
+ dismissWarning(" Yes, Submit" )
129
+
130
+ UITestHelper .sleep(500 )
131
+
132
+ onView(allOf(isDisplayed(), withId(R .id.btn_submit)))
133
+ .perform(click())
99
134
135
+ UITestHelper .sleep(10000 )
136
+
137
+ val fileUrl = " https://commons.wikimedia.beta.wmflabs.org/wiki/File:" +
138
+ commonsFileName.replace(' ' , ' _' ) + " .jpg"
139
+ Timber .i(" File should be uploaded to $fileUrl " )
140
+ }
141
+
142
+ private fun dismissWarning (warningText : String ) {
143
+ try {
144
+ onView(withText(warningText))
145
+ .check(matches(isDisplayed()))
146
+ .perform(click())
147
+ } catch (ignored: NoMatchingViewException ) {
100
148
}
101
149
}
102
150
103
151
@Test
104
- fun uploadTest () {
152
+ fun testUploadWithoutDescription () {
105
153
if (! ConfigUtils .isBetaFlavour()) {
106
154
throw Error (" This test should only be run in Beta!" )
107
155
}
108
156
109
- // Uri to return by our mock gallery selector
110
- // Requires file 'image.jpg' to be placed at root of file structure
111
- val imageUri = Uri .parse(" file://mnt/sdcard/image.jpg" )
157
+ setupSingleUpload(" image.jpg" )
112
158
113
- // Build a result to return from the Camera app
114
- val intent = Intent ()
115
- intent.data = imageUri
116
- val result = ActivityResult (Activity .RESULT_OK , intent)
159
+ openGallery()
117
160
118
- // Stub out the File picker. When an intent is sent to the File picker, this tells
119
- // Espresso to respond with the ActivityResult we just created
120
- intending(allOf(hasAction(Intent .ACTION_GET_CONTENT ), hasType(" image/*" ))).respondWith(result)
161
+ // Validate that an intent to get an image is sent
162
+ intended(allOf(hasAction(Intent .ACTION_GET_CONTENT ), hasType(" image/*" )))
121
163
122
- // Open FAB
123
- onView(allOf<View >(withId(R .id.fab_plus), isDisplayed()))
164
+ // Create filename with the current time (to prevent overwrites)
165
+ val dateFormat = SimpleDateFormat (" yyMMdd-hhmmss" )
166
+ val commonsFileName = " MobileTest " + dateFormat.format(Date ())
167
+
168
+ // Try to dismiss the error, if there is one (probably about duplicate files on Commons)
169
+ dismissWarning(" Yes" )
170
+
171
+ onView(allOf<View >(isDisplayed(), withId(R .id.et_title)))
172
+ .perform(replaceText(commonsFileName))
173
+
174
+ onView(allOf(isDisplayed(), withId(R .id.btn_next)))
124
175
.perform(click())
125
176
126
- // Click gallery
127
- onView(allOf<View >(withId(R .id.fab_gallery), isDisplayed()))
177
+ UITestHelper .sleep(10000 )
178
+ dismissWarning(" Yes" )
179
+
180
+ UITestHelper .sleep(3000 )
181
+
182
+ onView(allOf(isDisplayed(), withId(R .id.et_search)))
183
+ .perform(replaceText(" Test" ))
184
+
185
+ UITestHelper .sleep(3000 )
186
+
187
+ try {
188
+ onView(allOf(isDisplayed(), UITestHelper .first(withParent(withId(R .id.rv_categories)))))
189
+ .perform(click())
190
+ } catch (ignored: NoMatchingViewException ) {
191
+ }
192
+
193
+ onView(allOf(isDisplayed(), withId(R .id.btn_next)))
194
+ .perform(click())
195
+
196
+ dismissWarning(" Yes, Submit" )
197
+
198
+ UITestHelper .sleep(500 )
199
+
200
+ onView(allOf(isDisplayed(), withId(R .id.btn_submit)))
128
201
.perform(click())
129
202
203
+ UITestHelper .sleep(10000 )
204
+
205
+ val fileUrl = " https://commons.wikimedia.beta.wmflabs.org/wiki/File:" +
206
+ commonsFileName.replace(' ' , ' _' ) + " .jpg"
207
+ Timber .i(" File should be uploaded to $fileUrl " )
208
+ }
209
+
210
+ @Test
211
+ fun testUploadWithMultilingualDescription () {
212
+ if (! ConfigUtils .isBetaFlavour()) {
213
+ throw Error (" This test should only be run in Beta!" )
214
+ }
215
+
216
+ setupSingleUpload(" image.jpg" )
217
+
218
+ openGallery()
219
+
130
220
// Validate that an intent to get an image is sent
131
221
intended(allOf(hasAction(Intent .ACTION_GET_CONTENT ), hasType(" image/*" )))
132
222
@@ -135,14 +225,28 @@ class UploadTest {
135
225
val commonsFileName = " MobileTest " + dateFormat.format(Date ())
136
226
137
227
// Try to dismiss the error, if there is one (probably about duplicate files on Commons)
138
- dismissWarning( " Yes " )
228
+ dismissWarningDialog( )
139
229
140
230
onView(allOf<View >(isDisplayed(), withId(R .id.et_title)))
141
231
.perform(replaceText(commonsFileName))
142
232
143
- onView(allOf<View >(isDisplayed(), withId(R .id.description_item_edit_text)))
144
- .perform(replaceText(commonsFileName))
233
+ onView(withId(R .id.rv_descriptions)).perform(
234
+ RecyclerViewActions
235
+ .actionOnItemAtPosition<DescriptionsAdapter .ViewHolder >(0 ,
236
+ MyViewAction .typeTextInChildViewWithId(R .id.description_item_edit_text, " Test description" )))
237
+
238
+ onView(withId(R .id.btn_add_description))
239
+ .perform(click())
240
+
241
+ onView(withId(R .id.rv_descriptions)).perform(
242
+ RecyclerViewActions
243
+ .actionOnItemAtPosition<DescriptionsAdapter .ViewHolder >(1 ,
244
+ MyViewAction .selectSpinnerItemInChildViewWithId(R .id.spinner_description_languages, 2 )))
145
245
246
+ onView(withId(R .id.rv_descriptions)).perform(
247
+ RecyclerViewActions
248
+ .actionOnItemAtPosition<DescriptionsAdapter .ViewHolder >(1 ,
249
+ MyViewAction .typeTextInChildViewWithId(R .id.description_item_edit_text, " Description" )))
146
250
147
251
onView(allOf(isDisplayed(), withId(R .id.btn_next)))
148
252
.perform(click())
@@ -153,12 +257,12 @@ class UploadTest {
153
257
UITestHelper .sleep(3000 )
154
258
155
259
onView(allOf(isDisplayed(), withId(R .id.et_search)))
156
- .perform(replaceText(" Uploaded with Mobile/Android Tests " ))
260
+ .perform(replaceText(" Test " ))
157
261
158
262
UITestHelper .sleep(3000 )
159
263
160
264
try {
161
- onView(allOf(isDisplayed(), withParent(withId(R .id.rv_categories))))
265
+ onView(allOf(isDisplayed(), UITestHelper .first( withParent(withId(R .id.rv_categories) ))))
162
266
.perform(click())
163
267
} catch (ignored: NoMatchingViewException ) {
164
268
}
@@ -180,12 +284,69 @@ class UploadTest {
180
284
Timber .i(" File should be uploaded to $fileUrl " )
181
285
}
182
286
183
- private fun dismissWarning (warningText : String ) {
287
+ private fun setupSingleUpload (imageName : String ) {
288
+ saveToInternalStorage(imageName)
289
+ singleImageIntent(imageName)
290
+ }
291
+
292
+ private fun saveToInternalStorage (imageName : String ) {
293
+ val bitmapImage = randomBitmap
294
+
295
+ // path to /data/data/yourapp/app_data/imageDir
296
+ val mypath = File (Environment .getExternalStorageDirectory(), imageName)
297
+
298
+ Timber .d(" Filepath: %s" , mypath.path)
299
+
300
+ Timber .d(" Absolute Filepath: %s" , mypath.absolutePath)
301
+
302
+ var fos: FileOutputStream ? = null
184
303
try {
185
- onView(withText(warningText))
304
+ fos = FileOutputStream (mypath)
305
+ // Use the compress method on the BitMap object to write image to the OutputStream
306
+ bitmapImage.compress(Bitmap .CompressFormat .JPEG , 100 , fos)
307
+ } catch (e: Exception ) {
308
+ e.printStackTrace()
309
+ } finally {
310
+ try {
311
+ fos?.close()
312
+ } catch (e: IOException ) {
313
+ e.printStackTrace()
314
+ }
315
+
316
+ }
317
+ }
318
+
319
+ private fun singleImageIntent (imageName : String ) {
320
+ // Uri to return by our mock gallery selector
321
+ // Requires file 'image.jpg' to be placed at root of file structure
322
+ val imageUri = Uri .parse(" file://mnt/sdcard/$imageName " )
323
+
324
+ // Build a result to return from the Camera app
325
+ val intent = Intent ()
326
+ intent.data = imageUri
327
+ val result = ActivityResult (Activity .RESULT_OK , intent)
328
+
329
+ // Stub out the File picker. When an intent is sent to the File picker, this tells
330
+ // Espresso to respond with the ActivityResult we just created
331
+ intending(allOf(hasAction(Intent .ACTION_GET_CONTENT ), hasType(" image/*" ))).respondWith(result)
332
+ }
333
+
334
+ private fun dismissWarningDialog () {
335
+ try {
336
+ onView(withText(" Yes" ))
186
337
.check(matches(isDisplayed()))
187
338
.perform(click())
188
339
} catch (ignored: NoMatchingViewException ) {
189
340
}
190
341
}
342
+
343
+ private fun openGallery () {
344
+ // Open FAB
345
+ onView(allOf<View >(withId(R .id.fab_plus), isDisplayed()))
346
+ .perform(click())
347
+
348
+ // Click gallery
349
+ onView(allOf<View >(withId(R .id.fab_gallery), isDisplayed()))
350
+ .perform(click())
351
+ }
191
352
}
0 commit comments