Issue #26097: use mock location in UI tests
This commit is contained in:
parent
f3ef15800c
commit
3111c8bf8b
|
@ -0,0 +1,111 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.fenix.helpers
|
||||
|
||||
import android.content.Context
|
||||
import android.location.Location
|
||||
import android.location.LocationManager
|
||||
import android.os.Build
|
||||
import android.os.SystemClock
|
||||
import android.util.Log
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import org.junit.rules.ExternalResource
|
||||
import java.util.Date
|
||||
import kotlin.random.Random
|
||||
import org.mozilla.fenix.helpers.TestHelper.mDevice
|
||||
|
||||
private const val mockProviderName = LocationManager.GPS_PROVIDER
|
||||
|
||||
/**
|
||||
* Rule that sets up a mock location provider that can inject location samples
|
||||
* straight to the device that the test is running on.
|
||||
*
|
||||
* Credit to the mapbox team
|
||||
* https://github.com/mapbox/mapbox-navigation-android/blob/87fab7ea1152b29533ee121eaf6c05bc202adf02/libtesting-ui/src/main/java/com/mapbox/navigation/testing/ui/MockLocationUpdatesRule.kt
|
||||
*
|
||||
*/
|
||||
class MockLocationUpdatesRule : ExternalResource() {
|
||||
private val appContext = (ApplicationProvider.getApplicationContext() as Context)
|
||||
val latitude = Random.nextDouble(-90.0, 90.0)
|
||||
val longitude = Random.nextDouble(-180.0, 180.0)
|
||||
|
||||
private val locationManager: LocationManager by lazy {
|
||||
(appContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager)
|
||||
}
|
||||
|
||||
override fun before() {
|
||||
/* ADB command to enable the mock location setting on the device.
|
||||
* Will not be turned back off due to limitations on knowing its initial state.
|
||||
*/
|
||||
mDevice.executeShellCommand(
|
||||
"appops set " +
|
||||
appContext.packageName +
|
||||
" android:mock_location allow"
|
||||
)
|
||||
|
||||
// To mock locations we need a location provider, so we generate and set it here.
|
||||
try {
|
||||
locationManager.addTestProvider(
|
||||
mockProviderName,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
3,
|
||||
2
|
||||
)
|
||||
} catch (ex: Exception) {
|
||||
// unstable
|
||||
Log.w("MockLocationUpdatesRule", "addTestProvider failed")
|
||||
}
|
||||
locationManager.setTestProviderEnabled(mockProviderName, true)
|
||||
}
|
||||
|
||||
// Cleaning up the location provider after the test.
|
||||
override fun after() {
|
||||
locationManager.setTestProviderEnabled(mockProviderName, false)
|
||||
locationManager.removeTestProvider(mockProviderName)
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a valid mock location data and set with the help of a test provider.
|
||||
*
|
||||
* @param modifyLocation optional callback for modifying the constructed location before setting it.
|
||||
*/
|
||||
fun setMockLocation(modifyLocation: (Location.() -> Unit)? = null) {
|
||||
check(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
"MockLocationUpdatesRule is supported only on Android devices " +
|
||||
"running version >= Build.VERSION_CODES.M"
|
||||
}
|
||||
|
||||
val location = Location(mockProviderName)
|
||||
location.time = Date().time
|
||||
location.elapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos()
|
||||
location.accuracy = 5f
|
||||
location.altitude = 0.0
|
||||
location.bearing = 0f
|
||||
location.speed = 5f
|
||||
location.latitude = latitude
|
||||
location.longitude = longitude
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
location.verticalAccuracyMeters = 5f
|
||||
location.bearingAccuracyDegrees = 5f
|
||||
location.speedAccuracyMetersPerSecond = 5f
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
location.elapsedRealtimeUncertaintyNanos = 0.0
|
||||
}
|
||||
|
||||
modifyLocation?.let {
|
||||
location.apply(it)
|
||||
}
|
||||
|
||||
locationManager.setTestProviderLocation(mockProviderName, location)
|
||||
}
|
||||
}
|
|
@ -15,12 +15,12 @@ import androidx.test.rule.GrantPermissionRule
|
|||
import org.junit.After
|
||||
import org.junit.Assume.assumeTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.customannotations.SmokeTest
|
||||
import org.mozilla.fenix.helpers.FeatureSettingsHelper
|
||||
import org.mozilla.fenix.helpers.HomeActivityTestRule
|
||||
import org.mozilla.fenix.helpers.MockLocationUpdatesRule
|
||||
import org.mozilla.fenix.helpers.RetryTestRule
|
||||
import org.mozilla.fenix.helpers.TestHelper.appContext
|
||||
import org.mozilla.fenix.ui.robots.browserScreen
|
||||
|
@ -44,11 +44,14 @@ class SitePermissionsTest {
|
|||
@get:Rule
|
||||
val grantPermissionRule: GrantPermissionRule = GrantPermissionRule.grant(
|
||||
Manifest.permission.RECORD_AUDIO,
|
||||
Manifest.permission.CAMERA
|
||||
Manifest.permission.CAMERA,
|
||||
Manifest.permission.ACCESS_COARSE_LOCATION
|
||||
)
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
@get: Rule
|
||||
val mockLocationUpdatesRule = MockLocationUpdatesRule()
|
||||
|
||||
@get: Rule
|
||||
val retryTestRule = RetryTestRule(3)
|
||||
|
||||
@Before
|
||||
|
@ -282,20 +285,20 @@ class SitePermissionsTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Ignore("Needs mocking location for Firebase - to do: https://github.com/mozilla-mobile/mobile-test-eng/issues/585")
|
||||
@Test
|
||||
fun allowLocationPermissionsTest() {
|
||||
mockLocationUpdatesRule.setMockLocation()
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(testPage.toUri()) {
|
||||
}.clickGetLocationButton {
|
||||
verifyLocationPermissionPrompt(testPageSubstring)
|
||||
}.clickPagePermissionButton(true) {
|
||||
verifyPageContent("longitude")
|
||||
verifyPageContent("latitude")
|
||||
verifyPageContent("${mockLocationUpdatesRule.latitude}")
|
||||
verifyPageContent("${mockLocationUpdatesRule.longitude}")
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore("Needs mocking location for Firebase - to do: https://github.com/mozilla-mobile/mobile-test-eng/issues/585")
|
||||
@Test
|
||||
fun blockLocationPermissionsTest() {
|
||||
navigationToolbar {
|
||||
|
|
Loading…
Reference in New Issue