test: update integration test config

This commit is contained in:
Matias de Andrea
2023-03-02 10:58:19 +01:00
parent fc51fbbe20
commit 729f13e135
6 changed files with 106 additions and 76 deletions

View File

@ -10,7 +10,6 @@
## TV Randshow - App to choose a random TV show episode
[![Tests](https://api.codemagic.io/apps/5ea04fef2173e4001d6d6c75/6210143b0b28f63215deee7d/status_badge.svg)](https://codemagic.io/apps/5ea04fef2173e4001d6d6c75/6210143b0b28f63215deee7d/latest_build)
[![Deploy](https://api.codemagic.io/apps/5ea04fef2173e4001d6d6c75/5ea04fef2173e4001d6d6c74/status_badge.svg)](https://codemagic.io/apps/5ea04fef2173e4001d6d6c75/5ea04fef2173e4001d6d6c74/latest_build)
[![Releases](https://img.shields.io/github/v/release/deandreamatias/tv-randshow)](https://github.com/deandreamatias/tv-randshow/releases)
[![Google Play](https://img.shields.io/badge/google--play-Google--Play-green?label=App)](https://play.google.com/store/apps/details?id=deandrea.matias.tv_randshow)
[![Website](https://img.shields.io/website?up_message=online&url=https%3A%2F%2Ftvrandshow.com%2F)](https://tvrandshow.com/)
@ -33,10 +32,11 @@ This project has been built using the [Flutter](https://flutter.dev/) framework,
## Features
- **Save your favorites TV shows**
- **Save your favorites TV shows with available streamings links**
- **Choose a random episode from a single TV show**
- **Support to Android and Web**
- **Dark mode**
- **Material 3**
- **Support to deeplink `https://tvrandshow.com/getRandomEpisode?tvshow=friends`**
- **Roadmap in [public Trello](https://trello.com/b/ib0jdUzK)**
@ -45,23 +45,30 @@ This project has been built using the [Flutter](https://flutter.dev/) framework,
### Requirements
1. Clone repository with 'git clone' command or just download the zip. `git clone git@github.com:deandreamatias/tv-randshow.git`
2. Then, download either Android Studio or Visual Studio Code, with their respective [Flutter editor plugins](https://flutter.dev/docs/get-started/editor). For more information about Flutter installation procedure, check the [official install guide](https://flutter.dev/docs/get-started/install).
3. Install dependencies from pubspec.yaml by running `flutter pub get` from the project root (see [using packages documentation](https://flutter.dev/docs/development/packages-and-plugins/using-packages#adding-a-package-dependency-to-an-app) for details and how to do this in the editor).
2. Prepare your develop enviroment
1. Flutter (see version in ./fvm/fvm_config.json). Use [FVM](https://fvm.app/docs/getting_started/installation) to install Flutter versions
2. When build to iOS, follow [this steps](https://docs.flutter.dev/get-started/install/macos#install-xcode)
3. When build to Android, follow [this steps](https://docs.flutter.dev/get-started/install/macos#install-android-studio)
4. (Recommended) [Just](https://github.com/casey/just) to use commands
3. Install dependencies from pubspec.yaml using `just get` or running `flutter pub get` from the project root (see [using packages documentation](https://flutter.dev/docs/development/packages-and-plugins/using-packages#adding-a-package-dependency-to-an-app) for details and how to do this in the editor).
4. Get your API Key from TMDB (see [this FAQ](https://www.themoviedb.org/faq/api) for more details) and paste in file `lib/config/env.dart`
5. (Optional) If you want build to web, do you need follow [this steps](https://flutter.dev/docs/get-started/web)
5. Get your APi Key from Streaming Availabilty (on [RapidApi](https://rapidapi.com/movie-of-the-night-movie-of-the-night-default/api/streaming-availability)) and paste in file `lib/config/env.dart`
6. (Optional) If you want build to web, do you need follow [this steps](https://flutter.dev/docs/get-started/web)
### Run
CLI Debug: `flutter run --flavor dev -t lib/main_dev.dart`
Run `just run dev DEVICE_ID` command or copy the command from `./justfile`
### Tests
Integration tests (only mobile): `flutter drive --driver=test_driver/integration_test.dart --target=integration_test/app_test.dart -d [DEVICE_ID] --flavor dev --dart-define API_KEY=xxxxxxxxxxxxx`
Unit tests: `flutter test --dart-define API_KEY=xxxxxxxxxxxxx`
Integration tests (only mobile): run `just integration-test TMDB_API_KEY STREAMING_API_KEY DEVICE_ID` command or copy the command from `./justfile`
Unit tests: run `just unit-test TMDB_API_KEY STREAMING_API_KEY` command or copy the command from `./justfile`
> Replace screaming snake case with your values
## Author
- **Matias de Andrea** - Mobile developer: [Website](https://deandreamatias.com), [GitHub](https://github.com/deandreamatias) and [Twitter](https://twitter.com/deandreamatias).
- **Matias de Andrea** - Mobile developer: [Website](https://deandreamatias.com) and [GitHub](https://github.com/deandreamatias)
## Contributing

View File

@ -1,12 +1,12 @@
buildscript {
ext.kotlin_version = '1.6.10'
ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.2.0'
classpath 'com.android.tools.build:gradle:7.1.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

View File

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip

View File

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_translate/flutter_translate.dart';
import 'package:integration_test/integration_test.dart';
import 'package:tv_randshow/main_prod.dart' as mainProd;
import 'package:tv_randshow/main_prod.dart' as main_prod;
import 'package:tv_randshow/ui/app.dart' as app;
Future<void> main() async {
@ -10,106 +10,119 @@ Future<void> main() async {
final List<String> tvshows = ['The Office'];
testWidgets('initial app', (WidgetTester tester) async {
await mainProd.main();
await main_prod.main();
await tester.pumpAndSettle();
expect(find.byKey(Key('app.fav.title')), findsOneWidget);
expect(find.byKey(Key('app.fav.empty_message')), findsOneWidget);
expect(find.byKey(Key('app.fav.save')), findsOneWidget);
expect(find.byKey(const Key('app.fav.title')), findsOneWidget);
expect(find.byKey(const Key('app.fav.empty_message')), findsOneWidget);
expect(find.byKey(const Key('app.fav.save')), findsOneWidget);
expect(find.text('Favorites'), findsOneWidget);
expect(find.text('Search'), findsOneWidget);
expect(find.text('Info'), findsOneWidget);
// Navigate to info tab
await tester.tap(find.byKey(Key('app.info.tab')));
await tester.tap(find.byKey(const Key('app.info.tab')));
await tester.pumpAndSettle();
expect(find.byKey(Key('app.info.title')), findsOneWidget);
expect(find.byKey(Key('app.info.dark_title')), findsOneWidget);
expect(find.byKey(Key('app.info.web_title')), findsOneWidget);
expect(find.byKey(Key('app.info.rate_title')), findsOneWidget);
expect(find.byKey(Key('app.info.feedback_title')), findsOneWidget);
expect(find.byKey(Key('app.info.version.title')), findsOneWidget);
expect(find.byKey(const Key('app.info.title')), findsOneWidget);
expect(find.byKey(const Key('app.info.dark_title')), findsOneWidget);
expect(find.byKey(const Key('app.info.web_title')), findsOneWidget);
expect(find.byKey(const Key('app.info.rate_title')), findsOneWidget);
expect(find.byKey(const Key('app.info.feedback_title')), findsOneWidget);
expect(find.byKey(const Key('app.info.version.title')), findsOneWidget);
// Show version dialog
await tester.tap(find.byKey(Key('app.info.version.title')));
await tester.tap(find.byKey(const Key('app.info.version.title')));
await tester.pumpAndSettle();
expect(find.byKey(Key('app.info.version.dialog_title')), findsOneWidget);
await tester.tap(find.byKey(Key('app.info.version.dialog_button')));
expect(
find.byKey(const Key('app.info.version.dialog_title')),
findsOneWidget,
);
await tester.tap(find.byKey(const Key('app.info.version.dialog_button')));
});
testWidgets('tv show flow', (WidgetTester tester) async {
final LocalizationDelegate delegate = await LocalizationDelegate.create(
fallbackLocale: 'en',
supportedLocales: <String>['en', 'es', 'pt'],
);
await tester.pumpWidget(LocalizedApp(delegate, app.App()));
await tester.pumpWidget(LocalizedApp(delegate, const app.App()));
await tester.pumpAndSettle();
// Navigate to search tab
await tester.tap(find.byKey(Key('app.search.tab')));
await tester.tap(find.byKey(const Key('app.search.tab')));
await tester.pumpAndSettle();
expect(find.byKey(Key('app.search.message')), findsOneWidget);
expect(find.byKey(const Key('app.search.message')), findsOneWidget);
expect(find.text('Write a TV show name'), findsOneWidget);
// Search tv show
expect(find.byKey(Key('app.search.search_bar')), findsOneWidget);
expect(find.byKey(const Key('app.search.search_bar')), findsOneWidget);
await tester.enterText(find.byType(TextField), tvshows.first);
await waitUntil(
tester: tester,
conditionMet: () => find
.byKey(Key('app.search.button_fav.2316'))
.evaluate()
.isNotEmpty);
tester: tester,
conditionMet: () => find
.byKey(const Key('app.search.button_fav.2316'))
.evaluate()
.isNotEmpty,
);
// Save tv show
expect(find.byKey(Key('app.search.button_fav.2316')), findsOneWidget);
await tester.tap(find.byKey(Key('app.search.button_fav.2316')));
expect(find.byKey(const Key('app.search.button_fav.2316')), findsOneWidget);
await tester.tap(find.byKey(const Key('app.search.button_fav.2316')));
await tester.pumpAndSettle();
expect(find.byKey(Key('app.search.button_delete.2316')), findsOneWidget);
expect(
find.byKey(const Key('app.search.button_delete.2316')),
findsOneWidget,
);
// Navigate to favorites tab
await tester.tap(find.byKey(Key('app.fav.tab')));
await tester.tap(find.byKey(const Key('app.fav.tab')));
await tester.pumpAndSettle();
expect(find.byKey(Key('app.fav.button_random.2316')), findsOneWidget);
expect(find.byKey(const Key('app.fav.button_random.2316')), findsOneWidget);
// Get random episode
await tester.tap(find.byKey(Key('app.fav.button_random.2316')));
await tester.tap(find.byKey(const Key('app.fav.button_random.2316')));
await waitUntil(
tester: tester,
conditionMet: () =>
find.byKey(Key('app.result.title')).evaluate().isNotEmpty);
expect(find.byKey(Key('app.result.title')), findsOneWidget);
tester: tester,
conditionMet: () =>
find.byKey(const Key('app.result.title')).evaluate().isNotEmpty,
);
expect(find.byKey(const Key('app.result.title')), findsOneWidget);
await tester.tap(find.byKey(Key('app.result.button_random')));
await tester.tap(find.byKey(const Key('app.result.button_random')));
await waitUntil(
tester: tester,
conditionMet: () =>
find.byKey(Key('app.result.button_fav')).evaluate().isNotEmpty);
expect(find.byKey(Key('app.result.title')), findsOneWidget);
expect(find.byKey(Key('app.result.button_fav')), findsOneWidget);
tester: tester,
conditionMet: () =>
find.byKey(const Key('app.result.button_fav')).evaluate().isNotEmpty,
);
expect(find.byKey(const Key('app.result.title')), findsOneWidget);
expect(find.byKey(const Key('app.result.button_fav')), findsOneWidget);
await tester.pumpAndSettle();
// Delete tv show
await tester.tap(find.byKey(Key('app.result.button_fav')));
await tester.tap(find.byKey(const Key('app.result.button_fav')));
await waitUntil(
tester: tester,
conditionMet: () => find
.byKey(Key('app.fav.button_random.2316'))
.evaluate()
.isNotEmpty);
expect(find.byKey(Key('app.fav.button_random.2316')), findsOneWidget);
tester: tester,
conditionMet: () => find
.byKey(const Key('app.fav.button_random.2316'))
.evaluate()
.isNotEmpty,
);
expect(find.byKey(const Key('app.fav.button_random.2316')), findsOneWidget);
await tester.tap(find.byKey(Key('delete:2316')));
await tester.tap(find.byKey(const Key('delete:2316')));
await tester.pumpAndSettle();
expect(find.byKey(Key('app.delete_dialog.title')), findsOneWidget);
await tester.tap(find.byKey(Key('app.delete_dialog.button_delete')));
expect(find.byKey(const Key('app.delete_dialog.title')), findsOneWidget);
await tester.tap(find.byKey(const Key('app.delete_dialog.button_delete')));
await waitUntil(
tester: tester,
conditionMet: () =>
find.byKey(Key('app.fav.button_random.2316')).evaluate().isEmpty);
expect(find.byKey(Key('app.fav.button_random.2316')), findsNothing);
tester: tester,
conditionMet: () => find
.byKey(const Key('app.fav.button_random.2316'))
.evaluate()
.isEmpty,
);
expect(find.byKey(const Key('app.fav.button_random.2316')), findsNothing);
});
}

View File

@ -1,19 +1,36 @@
# Show all commands
default:
just --list
# Show all commands
help:
just --list
# Run project with {{flavor}}
run flavor device:
fvm flutter run --flavor {{flavor}} -t lib/main_{{flavor}}.dart -d {{device}}
# Generate all auto generate code
codegen-build:
fvm flutter pub run build_runner build --delete-conflicting-outputs
# Clean project
clean:
fvm flutter clean
# Get dependencies
get:
fvm flutter pub get
fvm flutter pub get
# Run integration tests on {{device}} with {{apikey}} and {{streamingApiKey}}
integration-test apiKey streamingApiKey device:
fvm flutter test integration_test/app_test.dart --flavor prod --dart-define API_KEY={{apiKey}} --dart-define STREAMING_API_KEY={{streamingApiKey}} -d {{device}}
# Run unit tests with {{apikey}} and {{streamingApiKey}}
unit-test apiKey streamingApiKey:
fvm flutter test --dart-define API_KEY={{apiKey}} --dart-define STREAMING_API_KEY={{streamingApiKey}}
# Initial setup project
setup:
just clean
just get
just codegen-build
just get

View File

@ -1,7 +0,0 @@
import 'package:flutter_driver/driver_extension.dart';
import 'package:tv_randshow/main_dev.dart' as app;
void main() {
enableFlutterDriverExtension();
app.main();
}