mirror of
https://github.com/hmalik144/Weather-apps.git
synced 2025-12-10 02:05:20 +00:00
- UI test for unit change
This commit is contained in:
@@ -8,10 +8,9 @@ import android.content.Intent
|
|||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.WindowManager
|
|
||||||
import androidx.test.core.app.ActivityScenario
|
import androidx.test.core.app.ActivityScenario
|
||||||
|
import androidx.test.core.app.ApplicationProvider
|
||||||
import androidx.test.espresso.Espresso
|
import androidx.test.espresso.Espresso
|
||||||
import androidx.test.espresso.Root
|
|
||||||
import androidx.test.espresso.UiController
|
import androidx.test.espresso.UiController
|
||||||
import androidx.test.espresso.ViewAction
|
import androidx.test.espresso.ViewAction
|
||||||
import androidx.test.espresso.assertion.ViewAssertions
|
import androidx.test.espresso.assertion.ViewAssertions
|
||||||
@@ -20,15 +19,12 @@ import androidx.test.espresso.matcher.ViewMatchers
|
|||||||
import androidx.test.platform.app.InstrumentationRegistry
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
import androidx.test.rule.GrantPermissionRule
|
import androidx.test.rule.GrantPermissionRule
|
||||||
import com.appttude.h_mal.atlas_weather.application.TestAppClass
|
import com.appttude.h_mal.atlas_weather.application.TestAppClass
|
||||||
import com.appttude.h_mal.atlas_weather.helpers.BaseCustomMatcher
|
import com.appttude.h_mal.atlas_weather.data.prefs.PreferenceProvider
|
||||||
import com.appttude.h_mal.atlas_weather.helpers.BaseViewAction
|
|
||||||
import com.appttude.h_mal.atlas_weather.helpers.SnapshotRule
|
import com.appttude.h_mal.atlas_weather.helpers.SnapshotRule
|
||||||
import com.appttude.h_mal.atlas_weather.utils.Stubs
|
import com.appttude.h_mal.atlas_weather.utils.Stubs
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.hamcrest.Description
|
|
||||||
import org.hamcrest.Matcher
|
import org.hamcrest.Matcher
|
||||||
import org.hamcrest.Matchers
|
import org.hamcrest.Matchers
|
||||||
import org.hamcrest.TypeSafeMatcher
|
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
@@ -46,6 +42,8 @@ open class BaseTest<A : Activity>(
|
|||||||
private lateinit var testActivity: Activity
|
private lateinit var testActivity: Activity
|
||||||
private lateinit var decorView: View
|
private lateinit var decorView: View
|
||||||
|
|
||||||
|
private val prefs by lazy { PreferenceProvider(ApplicationProvider.getApplicationContext()) }
|
||||||
|
|
||||||
@get:Rule
|
@get:Rule
|
||||||
var permissionRule = GrantPermissionRule.grant(Manifest.permission.ACCESS_COARSE_LOCATION)
|
var permissionRule = GrantPermissionRule.grant(Manifest.permission.ACCESS_COARSE_LOCATION)
|
||||||
|
|
||||||
@@ -87,6 +85,8 @@ open class BaseTest<A : Activity>(
|
|||||||
testApp.stubLocation(location, lat, long)
|
testApp.stubLocation(location, lat, long)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun clearPrefs() = prefs.clearPrefs()
|
||||||
|
|
||||||
fun getActivity() = testActivity
|
fun getActivity() = testActivity
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import android.view.View
|
|||||||
import android.widget.DatePicker
|
import android.widget.DatePicker
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
||||||
|
import androidx.test.espresso.Espresso
|
||||||
import androidx.test.espresso.Espresso.onData
|
import androidx.test.espresso.Espresso.onData
|
||||||
import androidx.test.espresso.Espresso.onView
|
import androidx.test.espresso.Espresso.onView
|
||||||
import androidx.test.espresso.UiController
|
import androidx.test.espresso.UiController
|
||||||
@@ -28,6 +29,8 @@ import org.hamcrest.Matcher
|
|||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
open class BaseTestRobot {
|
open class BaseTestRobot {
|
||||||
|
|
||||||
|
fun goBack() = Espresso.pressBack()
|
||||||
|
|
||||||
fun fillEditText(resId: Int, text: String?): ViewInteraction =
|
fun fillEditText(resId: Int, text: String?): ViewInteraction =
|
||||||
onView(withId(resId)).perform(
|
onView(withId(resId)).perform(
|
||||||
ViewActions.replaceText(text),
|
ViewActions.replaceText(text),
|
||||||
@@ -151,4 +154,8 @@ open class BaseTestRobot {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun openMenuItem() {
|
||||||
|
matchView(R.id.settings_fragment).perform(click())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package com.appttude.h_mal.monoWeather.robot
|
||||||
|
|
||||||
|
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
||||||
|
import androidx.test.espresso.Espresso.onView
|
||||||
|
import androidx.test.espresso.action.ViewActions.click
|
||||||
|
import androidx.test.espresso.assertion.ViewAssertions
|
||||||
|
import androidx.test.espresso.contrib.RecyclerViewActions
|
||||||
|
import androidx.test.espresso.matcher.RootMatchers.isDialog
|
||||||
|
import androidx.test.espresso.matcher.ViewMatchers
|
||||||
|
import androidx.test.espresso.matcher.ViewMatchers.withId
|
||||||
|
import androidx.test.espresso.matcher.ViewMatchers.withText
|
||||||
|
import com.appttude.h_mal.atlas_weather.BaseTestRobot
|
||||||
|
import com.appttude.h_mal.atlas_weather.R
|
||||||
|
import com.appttude.h_mal.atlas_weather.model.types.UnitType
|
||||||
|
|
||||||
|
|
||||||
|
fun settingsScreen(func: SettingsScreen.() -> Unit) = SettingsScreen().apply { func() }
|
||||||
|
class SettingsScreen : BaseTestRobot() {
|
||||||
|
|
||||||
|
fun selectWeatherUnits(unitType: UnitType) {
|
||||||
|
onView(withId(androidx.preference.R.id.recycler_view))
|
||||||
|
.perform(
|
||||||
|
RecyclerViewActions.actionOnItem<ViewHolder>(
|
||||||
|
ViewMatchers.hasDescendant(withText(R.string.weather_units)),
|
||||||
|
click()))
|
||||||
|
val label = when (unitType) {
|
||||||
|
UnitType.METRIC -> "Metric"
|
||||||
|
UnitType.IMPERIAL -> "Imperial"
|
||||||
|
}
|
||||||
|
|
||||||
|
onView(withText(label))
|
||||||
|
.inRoot(isDialog())
|
||||||
|
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
|
||||||
|
.perform(click())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun verifyCurrentTemperature(temperature: Int) =
|
||||||
|
matchText(R.id.temp_main_4, temperature.toString())
|
||||||
|
|
||||||
|
fun verifyCurrentLocation(location: String) = matchText(R.id.location_main_4, location)
|
||||||
|
fun refresh() = pullToRefresh(R.id.swipe_refresh)
|
||||||
|
|
||||||
|
fun verifyUnableToRetrieve() {
|
||||||
|
matchText(R.id.header_text, R.string.retrieve_warning)
|
||||||
|
matchText(R.id.body_text, R.string.empty_retrieve_warning)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,8 +2,10 @@ package com.appttude.h_mal.monoWeather.tests
|
|||||||
|
|
||||||
|
|
||||||
import com.appttude.h_mal.atlas_weather.BaseTest
|
import com.appttude.h_mal.atlas_weather.BaseTest
|
||||||
|
import com.appttude.h_mal.atlas_weather.model.types.UnitType
|
||||||
import com.appttude.h_mal.atlas_weather.ui.MainActivity
|
import com.appttude.h_mal.atlas_weather.ui.MainActivity
|
||||||
import com.appttude.h_mal.atlas_weather.utils.Stubs
|
import com.appttude.h_mal.atlas_weather.utils.Stubs
|
||||||
|
import com.appttude.h_mal.monoWeather.robot.settingsScreen
|
||||||
import com.appttude.h_mal.monoWeather.robot.weatherScreen
|
import com.appttude.h_mal.monoWeather.robot.weatherScreen
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
@@ -11,6 +13,7 @@ class HomePageUITest : BaseTest<MainActivity>(MainActivity::class.java) {
|
|||||||
|
|
||||||
override fun beforeLaunch() {
|
override fun beforeLaunch() {
|
||||||
stubEndpoint("https://api.openweathermap.org/data/2.5/onecall", Stubs.Metric)
|
stubEndpoint("https://api.openweathermap.org/data/2.5/onecall", Stubs.Metric)
|
||||||
|
clearPrefs()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -21,4 +24,25 @@ class HomePageUITest : BaseTest<MainActivity>(MainActivity::class.java) {
|
|||||||
verifyCurrentLocation("Mock Location")
|
verifyCurrentLocation("Mock Location")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun loadApp_changeToImperial_returnsValidPage() {
|
||||||
|
weatherScreen {
|
||||||
|
isDisplayed()
|
||||||
|
verifyCurrentTemperature(2)
|
||||||
|
verifyCurrentLocation("Mock Location")
|
||||||
|
stubEndpoint("https://api.openweathermap.org/data/2.5/onecall", Stubs.Imperial)
|
||||||
|
openMenuItem()
|
||||||
|
}
|
||||||
|
settingsScreen {
|
||||||
|
selectWeatherUnits(UnitType.IMPERIAL)
|
||||||
|
goBack()
|
||||||
|
}
|
||||||
|
weatherScreen {
|
||||||
|
isDisplayed()
|
||||||
|
refresh()
|
||||||
|
verifyCurrentTemperature(58)
|
||||||
|
verifyCurrentLocation("Mock Location")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.appttude.h_mal.atlas_weather.data.prefs
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
|
import androidx.annotation.VisibleForTesting
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import com.appttude.h_mal.atlas_weather.data.room.entity.CURRENT_LOCATION
|
import com.appttude.h_mal.atlas_weather.data.room.entity.CURRENT_LOCATION
|
||||||
import com.appttude.h_mal.atlas_weather.model.types.UnitType
|
import com.appttude.h_mal.atlas_weather.model.types.UnitType
|
||||||
@@ -61,4 +62,9 @@ class PreferenceProvider(
|
|||||||
return UnitType.getByName(unit) ?: UnitType.METRIC
|
return UnitType.getByName(unit) ?: UnitType.METRIC
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
fun clearPrefs() {
|
||||||
|
preference.edit().clear().apply()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -9,7 +9,7 @@ import com.appttude.h_mal.atlas_weather.data.room.entity.EntityItem
|
|||||||
|
|
||||||
@Database(
|
@Database(
|
||||||
entities = [EntityItem::class],
|
entities = [EntityItem::class],
|
||||||
version = 2,
|
version = 1,
|
||||||
exportSchema = false
|
exportSchema = false
|
||||||
)
|
)
|
||||||
@TypeConverters(Converter::class)
|
@TypeConverters(Converter::class)
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package com.appttude.h_mal.atlas_weather.viewmodel
|
|||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import androidx.annotation.RequiresPermission
|
import androidx.annotation.RequiresPermission
|
||||||
import androidx.lifecycle.viewModelScope
|
|
||||||
import com.appttude.h_mal.atlas_weather.base.baseViewModels.BaseViewModel
|
import com.appttude.h_mal.atlas_weather.base.baseViewModels.BaseViewModel
|
||||||
import com.appttude.h_mal.atlas_weather.data.WeatherSource
|
import com.appttude.h_mal.atlas_weather.data.WeatherSource
|
||||||
import com.appttude.h_mal.atlas_weather.data.location.LocationProvider
|
import com.appttude.h_mal.atlas_weather.data.location.LocationProvider
|
||||||
@@ -35,6 +34,7 @@ class MainViewModel(
|
|||||||
val latLong = locationProvider.getCurrentLatLong()
|
val latLong = locationProvider.getCurrentLatLong()
|
||||||
weatherSource.getWeather(latLon = latLong)
|
weatherSource.getWeather(latLon = latLong)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
onError(e.message ?: "Retrieving weather failed")
|
onError(e.message ?: "Retrieving weather failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,9 @@ import android.appwidget.AppWidgetManager
|
|||||||
import android.content.ComponentName
|
import android.content.ComponentName
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import androidx.annotation.RequiresPermission
|
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import com.appttude.h_mal.atlas_weather.R
|
import com.appttude.h_mal.atlas_weather.R
|
||||||
import com.appttude.h_mal.atlas_weather.application.AppClass
|
import com.appttude.h_mal.atlas_weather.application.BaseAppClass
|
||||||
import com.appttude.h_mal.atlas_weather.base.baseViewModels.BaseAndroidViewModel
|
import com.appttude.h_mal.atlas_weather.base.baseViewModels.BaseAndroidViewModel
|
||||||
import com.appttude.h_mal.atlas_weather.data.WeatherSource
|
import com.appttude.h_mal.atlas_weather.data.WeatherSource
|
||||||
import com.appttude.h_mal.atlas_weather.data.location.LocationProvider
|
import com.appttude.h_mal.atlas_weather.data.location.LocationProvider
|
||||||
@@ -27,7 +26,7 @@ class SettingsViewModel(
|
|||||||
private val settingsRepository: SettingsRepository
|
private val settingsRepository: SettingsRepository
|
||||||
) : BaseAndroidViewModel(application) {
|
) : BaseAndroidViewModel(application) {
|
||||||
|
|
||||||
private fun getContext() = getApplication<AppClass>().applicationContext
|
private fun getContext() = getApplication<BaseAppClass>().applicationContext
|
||||||
|
|
||||||
fun updateWidget() {
|
fun updateWidget() {
|
||||||
val context = getContext()
|
val context = getContext()
|
||||||
@@ -63,6 +62,7 @@ class SettingsViewModel(
|
|||||||
val units = settingsRepository.getUnitType().name.lowercase(Locale.ROOT)
|
val units = settingsRepository.getUnitType().name.lowercase(Locale.ROOT)
|
||||||
onSuccess("Units have been changes to $units")
|
onSuccess("Units have been changes to $units")
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
onError(e.message ?: "Retrieving weather failed")
|
onError(e.message ?: "Retrieving weather failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
<string name="no_weather_to_display">No weather to display</string>
|
<string name="no_weather_to_display">No weather to display</string>
|
||||||
<string name="unit_key">Units</string>
|
<string name="unit_key">Units</string>
|
||||||
<string name="widget_black_background">widget_black_background</string>
|
<string name="widget_black_background">widget_black_background</string>
|
||||||
|
<string name="weather_units">Weather units</string>
|
||||||
|
|
||||||
<string-array name="units">
|
<string-array name="units">
|
||||||
<item>Metric</item>
|
<item>Metric</item>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
<ListPreference
|
<ListPreference
|
||||||
android:title="Weather units"
|
android:title="@string/weather_units"
|
||||||
android:entries="@array/units"
|
android:entries="@array/units"
|
||||||
android:entryValues="@array/units"
|
android:entryValues="@array/units"
|
||||||
android:defaultValue="Metric"
|
android:defaultValue="Metric"
|
||||||
|
|||||||
Reference in New Issue
Block a user