- 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)

View File

@@ -42,4 +42,25 @@ platform :android do
json_key: "google-play-key.json",
package_name: "com.appttude.h_mal.atlas_weather")
end
desc "Capture screenshots"
lane :screenGrabMonoWeather do
build_android_app(
task: 'assemble',
build_type: 'Debug',
flavor: 'MonoWeather',
)
build_android_app(
task: 'assemble',
build_type: 'AndroidTest',
flavor: 'MonoWeather',
)
screengrab(
app_package_name: "com.appttude.h_mal.monoWeather",
locales: ["en-UK"],
app_apk_path: "app/build/outputs/apk/monoWeather/debug/app-monoWeather-debug.apk",
tests_apk_path: "app/build/outputs/apk/androidTest/monoWeather/debug/app-monoWeather-debug-androidTest.apk",
test_instrumentation_runner: "com.appttude.h_mal.atlas_weather.application.TestRunner",
)
end
end

64
readme.md Normal file
View File

@@ -0,0 +1,64 @@
# Weather-apps
Weather-apps contains two weather apps - Atlas weather and Mono weather. They are both simple and user-friendly Android applications that provides current weather information and forecasts. With a sleek design and accurate data, to keeps you updated on the latest weather conditions in your area.
## Features
- **Current Weather**: Get real-time weather updates including temperature, humidity, wind speed, and atmospheric pressure.
- **Forecast**: View detailed weather forecasts for the next 7 days.
- **Location-Based Updates**: Automatically fetch weather data based on your current location.
- **Search Functionality**: Search for weather information in different cities around the world.
- **Notifications**: Receive weather alerts and notifications for significant weather changes.
- **Customizable Settings**: Choose between Celsius and Fahrenheit, and set your preferred update frequency.
- **Customizable Home screen widget**: Add a home screen widget to give you regular updates on forecast.
## Screenshots
### Atlas Weather
![Home Screen](screenshots/home.png)
![Forecast Screen](screenshots/forecast.png)
![Settings Screen](screenshots/settings.png)
### Mono Weather
![Home Screen](screenshots/home.png)
![Forecast Screen](screenshots/forecast.png)
![Settings Screen](screenshots/settings.png)
## Usage
1. Upon launching the app, you will be prompted to allow location access. Grant the necessary permissions.
2. The home screen will display the current weather information for your location.
3. Swipe left or tap on the forecast tab to view the 7-day weather forecast.
4. Use the search icon to look up weather information for other cities.
5. Access the settings menu to customize your preferences.
## Permissions
The app requires the following permissions:
- **Location**: To provide accurate weather information based on your current location.
- **Internet**: To fetch weather data from the server.
## API
Weather-apps
- uses the [OpenWeatherMap API](https://openweathermap.org/api) to retrieve weather data.
- uses the [TomTom Search API](https://developer.tomtom.com/search-api/documentation/product-information/introduction) to retrieve geolocation data.
## Contributing
Contributions are welcome! Please follow these steps:
1. Fork the repository.
2. Create a new branch: `git checkout -b feature/your-feature-name`
3. Make your changes and commit them: `git commit -m 'Add some feature'`
4. Push to the branch: `git push origin feature/your-feature-name`
5. Create a pull request.
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Acknowledgements
- [OpenWeatherMap](https://openweathermap.org) for the weather data API.
- [TomTom Search API](https://developer.tomtom.com/search-api/documentation/product-information/introduction) for the geolocation API.