diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 28ce636..f1ce523 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,13 +1,8 @@ on: - pull_request: - branches: - - main - - master push: branches: - main - master - - dev name: "Build & Release" diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..8e14751 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,36 @@ +on: + pull_request: + branches: + - main + - master + push: + branches: + - main + - master + + +name: "Integration Tests" + +jobs: + run_tests: + name: Run Integration Tests + runs-on: windows-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-java@v3 + with: + java-version: '11' + distribution: 'temurin' + - uses: subosito/flutter-action@v2 + with: + channel: stable + flutter-version: '3.19.5' + - name: Test Connectivity + run: | + ping jiosaavn.com + - name: Dependencies install + run: flutter pub get + - name: Test For Windows + run: flutter test -d windows integration_test\app_test.dart + - name: Build For Windows + run: flutter build windows diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart new file mode 100644 index 0000000..e5c44e4 --- /dev/null +++ b/integration_test/app_test.dart @@ -0,0 +1,68 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:sangeet/core/widgets/top_details.dart'; +import 'package:sangeet/functions/explore/widgets/browse_card.dart'; +import 'package:integration_test/integration_test.dart'; + +import 'package:sangeet/main.dart' as app; + +void main() { + group("e2e Testing", () { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + testWidgets('Explore Cards Working', (WidgetTester tester) async { + String mediaName = ""; + String mediaTopName = ""; + Finder backBtn; + await app.main(); + await tester.pumpAndSettle(); + + final albumCard = find.byKey(const Key("album_card_0")); + mediaName = (albumCard.evaluate().first.widget as BrowseCard).title; + await tester.tap(albumCard); + await tester.pumpAndSettle(); + + mediaTopName = (find.byKey(const Key("album_top")).evaluate().first.widget + as TopDetailsContainer) + .title; + + backBtn = find.byKey(const Key("back_btn")); + await tester.tap(backBtn); + await tester.pumpAndSettle(); + expect(mediaTopName, mediaName); + + final chartCard = find.byKey(const Key("chart_card_0")); + await tester.ensureVisible(chartCard); + mediaName = (chartCard.evaluate().first.widget as BrowseCard).title; + await tester.tap(chartCard); + await tester.pumpAndSettle(); + + mediaTopName = (find.byKey(const Key("chart_top")).evaluate().first.widget + as TopDetailsContainer) + .title; + + backBtn = find.byKey(const Key("back_btn")); + await tester.tap(backBtn); + await tester.pumpAndSettle(); + expect(mediaTopName, mediaName); + + final playlistCard = find.byKey(const Key("playlist_card_0")); + await tester.ensureVisible(playlistCard); + mediaName = (playlistCard.evaluate().first.widget as BrowseCard).title; + await tester.tap(playlistCard); + await tester.pumpAndSettle(); + + mediaTopName = (find + .byKey(const Key("playlist_top")) + .evaluate() + .first + .widget as TopDetailsContainer) + .title; + + backBtn = find.byKey(const Key("back_btn")); + await tester.tap(backBtn); + await tester.pumpAndSettle(); + expect(mediaTopName, mediaName); + }); + }); +} diff --git a/lib/core/skeletions/explore_loading_skeletion.dart b/lib/core/skeletions/explore_loading_skeletion.dart index 06af166..c577f7f 100644 --- a/lib/core/skeletions/explore_loading_skeletion.dart +++ b/lib/core/skeletions/explore_loading_skeletion.dart @@ -9,6 +9,7 @@ class ExploreLoader extends StatelessWidget { return Scaffold( backgroundColor: Colors.black, body: SingleChildScrollView( + physics: const NeverScrollableScrollPhysics(), child: Skeletonizer( ignoreContainers: true, enabled: true, @@ -143,51 +144,6 @@ class ExploreLoader extends StatelessWidget { ), ), ), - Container( - margin: const EdgeInsets.symmetric(vertical: 20.0), - height: 200.0, - child: ListView.builder( - scrollDirection: Axis.horizontal, - physics: const BouncingScrollPhysics(), - itemCount: 5, - itemBuilder: (context, index) { - return Container( - width: 200, - margin: const EdgeInsets.all(8.0), - child: Column( - children: [ - ClipRRect( - borderRadius: BorderRadius.circular(8.0), - child: Container( - width: 150, - height: 150, - color: Colors.grey[300], - ), - ), - const SizedBox(height: 8), - ClipRRect( - borderRadius: BorderRadius.circular(8.0), - child: Container( - width: 100, - height: 20, - color: Colors.grey[300], - ), - ), - const SizedBox(height: 8), - ClipRRect( - borderRadius: BorderRadius.circular(8.0), - child: Container( - width: 80, - height: 20, - color: Colors.grey[300], - ), - ), - ], - ), - ); - }, - ), - ), // Radios section Padding( diff --git a/lib/functions/album/view/album_view.dart b/lib/functions/album/view/album_view.dart index bb94868..3cf02ef 100644 --- a/lib/functions/album/view/album_view.dart +++ b/lib/functions/album/view/album_view.dart @@ -35,6 +35,7 @@ class AlbumView extends ConsumerWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ TopDetailsContainer( + key: const Key("album_top"), image: album.images[2].url, subtitle: album.subtitle, title: album.title, @@ -62,7 +63,9 @@ class AlbumView extends ConsumerWidget { children: [ Wrap( children: [ - const BackButton(), + const BackButton( + key: Key("back_btn"), + ), IconButton( tooltip: "More", onPressed: () {}, diff --git a/lib/functions/charts/view/charts_view.dart b/lib/functions/charts/view/charts_view.dart index f8332f6..e187d53 100644 --- a/lib/functions/charts/view/charts_view.dart +++ b/lib/functions/charts/view/charts_view.dart @@ -36,6 +36,7 @@ class ChartView extends ConsumerWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ TopDetailsContainer( + key: const Key('chart_top'), title: chart.title, subtitle: chart.subtitle, image: chart.images[2].url, @@ -54,7 +55,9 @@ class ChartView extends ConsumerWidget { children: [ Wrap( children: [ - const BackButton(), + const BackButton( + key: Key("back_btn"), + ), IconButton( tooltip: "More", onPressed: () {}, diff --git a/lib/functions/explore/widgets/explore_list.dart b/lib/functions/explore/widgets/explore_list.dart index 9496966..86c0aa2 100644 --- a/lib/functions/explore/widgets/explore_list.dart +++ b/lib/functions/explore/widgets/explore_list.dart @@ -27,6 +27,7 @@ class ExploreList extends ConsumerWidget { final albums = data.albums; final playlists = data.topPlaylists; final trendings = data.trending; + return SingleChildScrollView( physics: const BouncingScrollPhysics(), child: Column( @@ -54,7 +55,7 @@ class ExploreList extends ConsumerWidget { children: trendings .map( (item) => TrendCard( - key: Key(item.id), + key: Key("trend_${item.id}"), onPlay: () => ref .watch(playerControllerProvider.notifier) .runRadio( @@ -131,6 +132,7 @@ class ExploreList extends ConsumerWidget { itemBuilder: (context, index) { final album = albums[index]; return BrowseCard( + key: Key("album_card_$index"), accentColor: album.accentColor, explicitContent: album.explicitContent, image: album.images[1].url, @@ -166,6 +168,7 @@ class ExploreList extends ConsumerWidget { itemBuilder: (context, index) { final chart = charts[index]; return BrowseCard( + key: Key("chart_card_$index"), explicitContent: chart.explicitContent, image: chart.image, subtitle: chart.subtitle == "" @@ -247,6 +250,7 @@ class ExploreList extends ConsumerWidget { itemBuilder: (context, index) { final playlist = playlists[index]; return BrowseCard( + key: Key("playlist_card_$index"), explicitContent: playlist.explicitContent, image: playlist.images[1].url, subtitle: playlist.subtitle, diff --git a/lib/functions/playlist/view/playlist_view.dart b/lib/functions/playlist/view/playlist_view.dart index 2013025..8c4bdc6 100644 --- a/lib/functions/playlist/view/playlist_view.dart +++ b/lib/functions/playlist/view/playlist_view.dart @@ -36,6 +36,7 @@ class PlaylistView extends ConsumerWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ TopDetailsContainer( + key: const Key("playlist_top"), image: playlist.images[2].url, subtitle: playlist.subtitle, title: playlist.title, @@ -53,7 +54,9 @@ class PlaylistView extends ConsumerWidget { children: [ Wrap( children: [ - const BackButton(), + const BackButton( + key: Key("back_btn"), + ), IconButton( tooltip: "More", onPressed: () {}, diff --git a/lib/main.dart b/lib/main.dart index e09da1c..099b234 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -8,7 +8,7 @@ import 'package:hotkey_manager/hotkey_manager.dart'; import 'package:sangeet/frame/home.dart'; import 'package:sangeet/initialization.dart'; -void main() async { +Future main() async { WidgetsFlutterBinding.ensureInitialized(); await hotKeyManager.unregisterAll(); await initialiseAppFunctions(); diff --git a/pubspec.lock b/pubspec.lock index 4546fa2..9872e59 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -206,6 +206,11 @@ packages: url: "https://pub.dev" source: hosted version: "3.3.2" + flutter_driver: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" flutter_launcher_icons: dependency: "direct dev" description: @@ -240,6 +245,11 @@ packages: description: flutter source: sdk version: "0.0.0" + fuchsia_remote_debug_protocol: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" google_fonts: dependency: "direct main" description: @@ -312,6 +322,11 @@ packages: url: "https://pub.dev" source: hosted version: "4.2.0" + integration_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" intl: dependency: "direct main" description: @@ -508,10 +523,10 @@ packages: dependency: transitive description: name: platform - sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65" + sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" url: "https://pub.dev" source: hosted - version: "3.1.5" + version: "3.1.4" plugin_platform_interface: dependency: transitive description: @@ -520,6 +535,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.8" + process: + dependency: transitive + description: + name: process + sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32" + url: "https://pub.dev" + source: hosted + version: "5.0.2" rename_app: dependency: "direct dev" description: @@ -702,6 +725,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.0" + sync_http: + dependency: transitive + description: + name: sync_http + sha256: "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961" + url: "https://pub.dev" + source: hosted + version: "0.3.1" synchronized: dependency: transitive description: @@ -790,6 +821,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.5.1" + webdriver: + dependency: transitive + description: + name: webdriver + sha256: "003d7da9519e1e5f329422b36c4dcdf18d7d2978d1ba099ea4e45ba490ed845e" + url: "https://pub.dev" + source: hosted + version: "3.0.3" win32: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index b8123d7..c56741e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -63,6 +63,8 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter + integration_test: + sdk: flutter # The "flutter_lints" package below contains a set of recommended lints to # encourage good coding practices. The lint set provided by the package is diff --git a/test/widget_test.dart b/test/widget_test.dart deleted file mode 100644 index 7f1dd12..0000000 --- a/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility in the flutter_test package. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:sangeet/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(const MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/test_driver/integration_test_driver.dart b/test_driver/integration_test_driver.dart new file mode 100644 index 0000000..090280d --- /dev/null +++ b/test_driver/integration_test_driver.dart @@ -0,0 +1,4 @@ +import 'dart:async'; +import 'package:integration_test/integration_test_driver.dart'; + +Future main() async => integrationDriver();