mirror of
https://github.com/hmalik144/Weather-apps.git
synced 2025-12-10 02:05:20 +00:00
- mid commit
This commit is contained in:
@@ -111,6 +111,7 @@ android {
|
||||
lint {
|
||||
abortOnError false
|
||||
}
|
||||
testBuildType "debug"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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)))
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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")
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
|
||||
18
app/src/debug/AndroidManifest.xml
Normal file
18
app/src/debug/AndroidManifest.xml
Normal 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>
|
||||
@@ -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>
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
64
readme.md
Normal 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
|
||||

|
||||

|
||||

|
||||
### Mono Weather
|
||||

|
||||

|
||||

|
||||
|
||||
## 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.
|
||||
Reference in New Issue
Block a user