Skip to content

Commit

Permalink
integration_test: add screen shots
Browse files Browse the repository at this point in the history
  • Loading branch information
wfleischer committed Jan 9, 2025
1 parent d504693 commit b013f84
Show file tree
Hide file tree
Showing 40 changed files with 172 additions and 41 deletions.
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
A Bible reading schedule app for the New World Translation of the Holy Scriptures
for Jehovah's Witnesses.

<img src="docs/screenshots/plans.png" width="400">
<img src="docs/screenshots/schedule.png" width="400">
<img src="docs/screenshots/edit.png" width="400">
<img src="assets/store_presence/screenshots/ios-1-plans-overlay.png" alt="Plans" width="400">
<img src="assets/store_presence/screenshots/ios-2-schedule-overlay.png" alt="Schedule" width="400">
<img src="assets/store_presence/screenshots/ios-3-schedule-dark-overlay.png" alt="Schedule Dark Mode" width="400">
<img src="assets/store_presence/screenshots/ios-4-new-overlay.png" alt="New" width="400">
<img src="assets/store_presence/screenshots/ios-5-edit-overlay.png" alt="Edit" width="400">
<img src="assets/store_presence/screenshots/ios-6-settings-overlay.png" alt="Settings" width="400">
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 28 additions & 0 deletions assets/store_presence/store-listing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Store Listing

## App name

NWT Reading

## Short description

Bible reading schedule for the New World Translation, designed for Jehovah's Witnesses.
Bible reading schedule for the New World Translation of Jehovah's Witnesses.

## Full description

NWT Reading provides a Bible reading schedule for the New World Translation of the Holy Scriptures, specifically for Jehovah's Witnesses.

• Supports reading the Bible in all available languages of the complete New World Translation, including sign languages.
• Scriptures open in the JW Library® app.
• Tracks your reading progress and shows the number of days you are ahead or behind schedule.
• Offers several reading plans: canonical, in the order the Bible books were written, and chronologically, as the events took place.
• Allows you to select the reading speed or read without a specific end date.
• Highlights dates with key events in the chronological plan.
• Shows locations mentioned in each section and where to find them in the brochure “See the Good Land.”
• NEW: Use multiple Bible reading plans in parallel.
• NEW: Enjoy a dark mode theme for a more comfortable reading experience.
• NEW: NWT Reading is now open source! Find us on GitHub and contribute.
• User interface available in Czech, English, French, German, Hungarian, Italian, Polish, Portuguese (Brazil), Romanian, Russian, and Spanish.

JW Library is a registered trademark of the Watch Tower Bible and Tract Society of Pennsylvania.
Binary file removed docs/screenshots/edit.png
Diff not rendered.
Binary file removed docs/screenshots/plans.png
Diff not rendered.
Binary file removed docs/screenshots/schedule.png
Diff not rendered.
7 changes: 0 additions & 7 deletions integration_test/app_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import 'package:shared_preferences/shared_preferences.dart';

import '../test/test_data.dart';
import 'settled_tester.dart';
import 'take_screenshot.dart';

Future<ProviderContainer> getDefaultProviderContainer(
WidgetTester tester) async =>
Expand Down Expand Up @@ -130,7 +129,6 @@ void main() async {

await tester.tap(find.byType(FloatingActionButton));
await tester.pumpAndSettle();
await takeScreenshot(tester: tester, binding: binding, filename: 'new');

BuildContext buildContext =
tester.firstElement(find.byKey(const Key('plan-name')));
Expand Down Expand Up @@ -328,7 +326,6 @@ void main() async {
final providerContainer = await getDefaultProviderContainer(tester);
final lastPlanCardFinder = find.byKey(
Key('plan-${providerContainer.read(plansProvider).plans.last.id}'));
await takeScreenshot(tester: tester, binding: binding, filename: 'plans');
await tester.tap(find.byType(PlanCard).first);
await tester.pumpAndSettle();

Expand Down Expand Up @@ -723,8 +720,6 @@ void main() async {
expect(find.byKey(const Key('day-33')), findsOneWidget);
expect(find.byIcon(Icons.check_circle), findsAtLeastNWidgets(3));
expect(find.byIcon(Icons.check_circle_outline), findsWidgets);
await takeScreenshot(
tester: tester, binding: binding, filename: 'schedule');
});

testWidgets('Change plan name', (tester) async {
Expand All @@ -733,7 +728,6 @@ void main() async {
await tester.pumpAndSettle();
await tester.tap(find.byIcon(Icons.edit));
await tester.pumpAndSettle();
await takeScreenshot(tester: tester, binding: binding, filename: 'edit');

Plan plan = providerContainer.read(plansProvider).plans.first;
BuildContext buildContext =
Expand Down Expand Up @@ -828,7 +822,6 @@ void main() async {
await tester.pumpAndSettle();
await tester.tap(find.byIcon(Icons.edit));
await tester.pumpAndSettle();
await takeScreenshot(tester: tester, binding: binding, filename: 'edit');
await tester.tap(find.byKey(const Key('language')));
await tester.pumpAndSettle();
await tester.scrollUntilVisible(
Expand Down
13 changes: 0 additions & 13 deletions integration_test/take_screenshot.dart

This file was deleted.

122 changes: 122 additions & 0 deletions integration_test/take_screenshots.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';

import 'package:nwt_reading/src/plans/presentations/plan_card.dart';

import '../test/test_data.dart';
import 'settled_tester.dart';

// Consider implementing
// https://medium.com/@mregnauld/generate-screenshots-for-a-flutter-app-with-golden-testing-and-upload-them-to-the-stores-1-2-45f8df777aef.

Future<ProviderContainer> getDefaultProviderContainer(
WidgetTester tester) async =>
SettledTester(tester, sharedPreferences: {
...testPlansPreferences,
...await getWhatsNewSeenPreference()
}).providerContainer;

final os = Platform.operatingSystem;

void takeScreenshot(
{required IntegrationTestWidgetsFlutterBinding binding,
required String filename}) async {
await binding.takeScreenshot('assets/store_presence/screenshots/$os-$filename.png');
await Future<void>.delayed(const Duration(seconds: 5));
}

void main() async {
final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized();
WidgetController.hitTestWarningShouldBeFatal = true;

testWidgets('Take the plans list screenshot', (tester) async {
await getDefaultProviderContainer(tester);
await binding.convertFlutterSurfaceToImage();
await tester.pumpAndSettle();
takeScreenshot(binding: binding, filename: '1-plans');
});

testWidgets('Take the schedule screenshot', (tester) async {
await getDefaultProviderContainer(tester);
await tester.tap(find.byType(PlanCard).first);
await tester.pumpAndSettle();
await tester.scrollUntilVisible(
find.byKey(const Key('day-33')),
-500.0,
);
await tester.pumpAndSettle();
await tester.tap(find
.descendant(
of: find.byKey(const Key('day-34')),
matching: find.byType(IconButton))
.first);
await tester.pumpAndSettle();
await tester.tap(find.byKey(const Key('confirm-toggle-read')));
await tester.pumpAndSettle();
await tester.scrollUntilVisible(
find.byKey(const Key('day-70')),
500.0,
);
await tester.pumpAndSettle();
await tester.tap(find.byType(FloatingActionButton));
await tester.pumpAndSettle();
await binding.convertFlutterSurfaceToImage();
await tester.pumpAndSettle();
takeScreenshot(binding: binding, filename: '2-schedule');
await tester.tap(find.byType(BackButton));
await tester.pumpAndSettle();
await tester.tap(find.byIcon(Icons.settings));
await tester.pumpAndSettle();
await tester.tap(find.byIcon(Icons.dark_mode));
await tester.pumpAndSettle();
await tester.tap(find.byType(BackButton));
await tester.pumpAndSettle();
await tester.tap(find.byType(PlanCard).first);
await tester.pumpAndSettle();
takeScreenshot(binding: binding, filename: '3-schedule-dark');
});

testWidgets('Take the new plan screenshot', (tester) async {
await SettledTester(tester,
sharedPreferences: await getWhatsNewSeenPreference())
.providerContainer;
await tester.tap(find.byType(FloatingActionButton));
await tester.pumpAndSettle();

// Hide the keyboard.
SystemChannels.textInput.invokeMethod('TextInput.hide');
await binding.convertFlutterSurfaceToImage();
await tester.pumpAndSettle();
takeScreenshot(binding: binding, filename: '4-new');
});

testWidgets('Take the plan edit screenshot', (tester) async {
await getDefaultProviderContainer(tester);
await tester.tap(find.byType(PlanCard).first);
await tester.pumpAndSettle();
await tester.tap(find.byIcon(Icons.edit));
await tester.pumpAndSettle();

// Hide the keyboard.
SystemChannels.textInput.invokeMethod('TextInput.hide');
await binding.convertFlutterSurfaceToImage();
await tester.pumpAndSettle();
takeScreenshot(binding: binding, filename: '5-edit');
});

testWidgets('Take the settings screenshot', (tester) async {
await getDefaultProviderContainer(tester);
await tester.tap(find.byIcon(Icons.settings));
await tester.pumpAndSettle();
await tester.tap(find.byIcon(Icons.dark_mode));
await tester.pumpAndSettle();
await binding.convertFlutterSurfaceToImage();
await tester.pumpAndSettle();
takeScreenshot(binding: binding, filename: '6-settings');
});
}
18 changes: 0 additions & 18 deletions test_driver/integration_test.dart

This file was deleted.

16 changes: 16 additions & 0 deletions test_driver/take_screenshots_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import 'dart:io';
import 'package:integration_test/integration_test_driver_extended.dart';

Future<void> main() async {
await integrationDriver(
onScreenshot: (String screenshotName, List<int> screenshotBytes,
[Map<String, Object?>? args]) async {
// ignore: avoid_print
print('Saving screen shot $screenshotName.');
final File image = File(screenshotName);
image.writeAsBytesSync(screenshotBytes);
// Return false if the screenshot is invalid.
return true;
},
);
}

0 comments on commit b013f84

Please sign in to comment.