- mid commit

This commit is contained in:
2024-06-27 10:41:45 +01:00
parent 7e405a5151
commit d79a31a9b5
12 changed files with 196 additions and 4 deletions

View File

@@ -111,6 +111,7 @@ android {
lint {
abortOnError false
}
testBuildType "debug"
}
dependencies {

View File

@@ -30,6 +30,7 @@ import org.junit.Before
import org.junit.Rule
import tools.fastlane.screengrab.Screengrab
import tools.fastlane.screengrab.UiAutomatorScreenshotStrategy
import tools.fastlane.screengrab.locale.LocaleTestRule
@Suppress("EmptyMethod")
open class BaseTest<A : Activity>(
@@ -47,9 +48,15 @@ open class BaseTest<A : Activity>(
@get:Rule
var permissionRule = GrantPermissionRule.grant(Manifest.permission.ACCESS_COARSE_LOCATION)
@get:Rule
var writePermissionRule = GrantPermissionRule.grant(Manifest.permission.WRITE_EXTERNAL_STORAGE)
@get:Rule
var snapshotRule: SnapshotRule = SnapshotRule()
@Rule @JvmField
val localeTestRule = LocaleTestRule()
@Before
fun setUp() {
Screengrab.setDefaultScreenshotStrategy(UiAutomatorScreenshotStrategy())

View File

@@ -129,6 +129,16 @@ open class BaseTestRobot {
)
}
fun <VH : ViewHolder> clickSubViewInRecycler(
recyclerId: Int,
position: Int,
) {
scrollToRecyclerItemByPosition<VH>(recyclerId, position)
?.perform(
RecyclerViewActions.actionOnItemAtPosition<VH>(position, click())
)
}
fun checkErrorOnTextEntry(resId: Int, errorMessage: String): ViewInteraction =
onView(withId(resId)).check(matches(checkErrorMessage(errorMessage)))

View File

@@ -0,0 +1,37 @@
package com.appttude.h_mal.monoWeather.robot
import com.appttude.h_mal.atlas_weather.BaseTestRobot
import com.appttude.h_mal.atlas_weather.R
import com.appttude.h_mal.monoWeather.ui.home.adapter.forecastDaily.ViewHolderForecastDaily
import com.appttude.h_mal.monoWeather.ui.home.adapter.further.ViewHolderFurtherDetails
fun furtherInfoScreen(func: FurtherInfoScreen.() -> Unit) = FurtherInfoScreen().apply { func() }
class FurtherInfoScreen : BaseTestRobot() {
fun verifyMaxTemperature(temperature: Int) =
matchText(R.id.maxtemp, StringBuilder().append(temperature).append("°").toString())
fun verifyAverageTemperature(temperature: Int) =
matchText(R.id.averagetemp, StringBuilder().append(temperature).append("°").toString())
fun verifyMinTemperature(temperature: Int) =
matchText(R.id.minimumtemp, StringBuilder().append(temperature).append("°").toString())
fun verifyWindSpeed(speedText: String) =
matchText(R.id.windtext, speedText)
fun verifyHumidity(humidity: Int) =
matchText(R.id.humiditytext, humidity.toString())
fun verifyPrecipitation(precipitation: Int) =
matchText(R.id.preciptext, precipitation.toString())
fun verifyCloudCoverage(coverage: Int) =
matchText(R.id.cloudtext, coverage.toString())
fun verifyUvIndex(uv: Int) =
matchText(R.id.uvtext, uv.toString())
fun verifySunrise(sunrise: String) =
matchText(R.id.sunrisetext, sunrise)
fun verifySunset(sunset: String) =
matchText(R.id.sunsettext, sunset)
fun refresh() = pullToRefresh(R.id.swipe_refresh)
fun isDisplayed() = matchViewWaitFor(R.id.maxtemp)
}

View File

@@ -11,6 +11,7 @@ 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.helpers.EspressoHelper.waitForView
import com.appttude.h_mal.atlas_weather.model.types.UnitType
@@ -45,4 +46,10 @@ class SettingsScreen : BaseTestRobot() {
matchText(R.id.header_text, R.string.retrieve_warning)
matchText(R.id.body_text, R.string.empty_retrieve_warning)
}
fun isDisplayed() {
waitForView(
withText("Metric")
)
}
}

View File

@@ -2,6 +2,8 @@ package com.appttude.h_mal.monoWeather.robot
import com.appttude.h_mal.atlas_weather.BaseTestRobot
import com.appttude.h_mal.atlas_weather.R
import com.appttude.h_mal.monoWeather.ui.home.adapter.forecastDaily.ViewHolderForecastDaily
import com.appttude.h_mal.monoWeather.ui.home.adapter.further.ViewHolderFurtherDetails
fun weatherScreen(func: WeatherScreen.() -> Unit) = WeatherScreen().apply { func() }
class WeatherScreen : BaseTestRobot() {
@@ -16,4 +18,8 @@ class WeatherScreen : BaseTestRobot() {
matchText(R.id.header_text, R.string.retrieve_warning)
matchText(R.id.body_text, R.string.empty_retrieve_warning)
}
fun tapDayInformationByPosition(position: Int) {
clickSubViewInRecycler<ViewHolderForecastDaily>(R.id.forecast_listview, position)
}
}

View File

@@ -5,9 +5,11 @@ 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.utils.Stubs
import com.appttude.h_mal.monoWeather.robot.furtherInfoScreen
import com.appttude.h_mal.monoWeather.robot.settingsScreen
import com.appttude.h_mal.monoWeather.robot.weatherScreen
import org.junit.Test
import tools.fastlane.screengrab.Screengrab
class HomePageUITest : BaseTest<MainActivity>(MainActivity::class.java) {
@@ -22,9 +24,27 @@ class HomePageUITest : BaseTest<MainActivity>(MainActivity::class.java) {
isDisplayed()
verifyCurrentTemperature(2)
verifyCurrentLocation("Mock Location")
Screengrab.screenshot("HomeScreen")
}
}
@Test
fun loadApp_validWeatherResponse_viewFurtherDetailsPage() {
weatherScreen {
isDisplayed()
verifyCurrentTemperature(2)
verifyCurrentLocation("Mock Location")
tapDayInformationByPosition(4)
}
furtherInfoScreen {
isDisplayed()
verifyMaxTemperature(12)
verifyAverageTemperature(9)
Screengrab.screenshot("FurtherInfoScreen")
}
}
@Test
fun loadApp_changeToImperial_returnsValidPage() {
weatherScreen {
@@ -37,6 +57,7 @@ class HomePageUITest : BaseTest<MainActivity>(MainActivity::class.java) {
settingsScreen {
selectWeatherUnits(UnitType.IMPERIAL)
goBack()
Screengrab.screenshot("SettingsScreen")
}
weatherScreen {
isDisplayed()

View File

@@ -0,0 +1,18 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- Allows storing screenshots on external storage, where it can be accessed by ADB -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- Allows changing locales -->
<uses-permission
android:name="android.permission.CHANGE_CONFIGURATION"
tools:ignore="ProtectedPermissions" />
<!-- Allows changing SystemUI demo mode -->
<uses-permission
android:name="android.permission.DUMP"
tools:ignore="ProtectedPermissions" />
</manifest>

View File

@@ -54,7 +54,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
tools:text="85%" />
tools:text="33" />
</LinearLayout>
<LinearLayout
@@ -73,7 +73,7 @@
android:layout_height="wrap_content"
android:layout_weight="3"
tools:ignore="InOrMmUsage"
tools:text="11mm" />
tools:text="30" />
</LinearLayout>
<LinearLayout
@@ -92,7 +92,7 @@
android:layout_height="wrap_content"
android:layout_weight="3"
tools:ignore="InOrMmUsage"
tools:text="11mm" />
tools:text="27" />
</LinearLayout>

View File

@@ -16,7 +16,7 @@ fun <T> LiveData<T>.getOrAwaitValue(
var data: T? = null
val latch = CountDownLatch(1)
val observer = object : Observer<T> {
override fun onChanged(o: T?) {
override fun onChanged(o: T) {
data = o
latch.countDown()
this@getOrAwaitValue.removeObserver(this)