Skip to content

Commit

Permalink
chore: configure automatic screenshots
Browse files Browse the repository at this point in the history
  • Loading branch information
AsCress committed Jan 29, 2025
1 parent 585b158 commit 7d57a9d
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 10 deletions.
54 changes: 54 additions & 0 deletions .github/actions/screenshot-ios/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: "iOS Screenshots Workflow"

inputs:
IPHONE_DEVICE_MODEL:
description: 'Model of the iPhone device to be used when running tests'
required: false
default: iPhone 16 Pro Max
IPAD_DEVICE_MODEL:
description: 'Model of the iPad device to be used when running tests'
required: false
default: iPad Pro 13-inch (M4)

runs:
using: "composite"
steps:
- name: Set up Flutter
uses: subosito/flutter-action@v2
with:
cache: true

- name: Update Podfile
shell: bash
run: |
cd ./iOS
flutter pub get
pod install --repo-update
- name: Create iPhone Simulator
uses: futureware-tech/simulator-action@v4
with:
model: ${{ inputs.IPHONE_DEVICE_MODEL }}
wait_for_boot: true

- name: Create iPad Simulator
uses: futureware-tech/simulator-action@v4
with:
model: ${{ inputs.IPAD_DEVICE_MODEL }}
wait_for_boot: true

- name: Capture iPhone Screenshots
shell: bash
run: |
flutter drive --driver=test_integration/test_driver.dart --target=test_integration/screenshots.dart -d "${{ inputs.IPHONE_DEVICE_MODEL }}"
- name: Capture iPad Screenshots
shell: bash
run: |
flutter drive --driver=test_integration/test_driver.dart --target=test_integration/screenshots.dart -d "${{ inputs.IPAD_DEVICE_MODEL }}"
- name: Upload Screenshots
uses: actions/upload-artifact@v4
with:
name: iOS Screenshots
path: screenshots/*
18 changes: 16 additions & 2 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ name: Badge Magic PR CI

on:
pull_request:
branches: ["flutter_app"]
branches: [ "flutter_app" ]

env:
ANDROID_EMULATOR_API: 34
ANDROID_EMULATOR_ARCH: x86_64
IPHONE_DEVICE_MODEL: iPhone 16 Pro Max
IPAD_DEVICE_MODEL: iPad Pro 13-inch (M4)

jobs:
common:
Expand Down Expand Up @@ -48,7 +50,7 @@ jobs:
- name: iOS Workflow
uses: ./.github/actions/ios

screenshots:
screenshots-android:
name: Screenshots (Android)
runs-on: ubuntu-latest
steps:
Expand All @@ -59,4 +61,16 @@ jobs:
with:
ANDROID_EMULATOR_API: ${{ env.ANDROID_EMULATOR_API }}
ANDROID_EMULATOR_ARCH: ${{ env.ANDROID_EMULATOR_ARCH }}

screenshots-ios:
name: Screenshots (iOS)
runs-on: macos-latest
steps:
- uses: actions/checkout@v4

- name: iOS Screenshot Workflow
uses: ./.github/actions/screenshot-ios
with:
IPHONE_DEVICE_MODEL: ${{ env.IPHONE_DEVICE_MODEL }}
IPAD_DEVICE_MODEL: ${{ env.IPAD_DEVICE_MODEL }}

16 changes: 15 additions & 1 deletion .github/workflows/push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ANDROID_EMULATOR_API: 34
ANDROID_EMULATOR_ARCH: x86_64
IPHONE_DEVICE_MODEL: iPhone 16 Pro Max
IPAD_DEVICE_MODEL: iPad Pro 13-inch (M4)

jobs:
common:
Expand Down Expand Up @@ -208,7 +210,7 @@ jobs:
git clone --branch=apk https://${{ github.repository_owner }}:${{ github.token }}@github.com/${{ github.repository }} apk
gh release upload ${{ steps.run-release-drafter.outputs.tag_name }} apk/badge-magic-flutter_app-release.apk ./versionCode.txt --clobber
screenshots:
screenshots-android:
name: Screenshots (Android)
runs-on: ubuntu-latest
steps:
Expand All @@ -219,3 +221,15 @@ jobs:
with:
ANDROID_EMULATOR_API: ${{ env.ANDROID_EMULATOR_API }}
ANDROID_EMULATOR_ARCH: ${{ env.ANDROID_EMULATOR_ARCH }}

screenshots-ios:
name: Screenshots (iOS)
runs-on: macos-latest
steps:
- uses: actions/checkout@v4

- name: iOS Screenshot Workflow
uses: ./.github/actions/screenshot-ios
with:
IPHONE_DEVICE_MODEL: ${{ env.IPHONE_DEVICE_MODEL }}
IPAD_DEVICE_MODEL: ${{ env.IPAD_DEVICE_MODEL }}
4 changes: 0 additions & 4 deletions lib/view/widgets/navigation_drawer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,6 @@ class _BMDrawerState extends State<BMDrawer> {
aspectRatio: 16 / 9,
child: const DrawerHeader(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/icons/drawer_headre.PNG'),
fit: BoxFit.cover,
),
color: Colors.red,
),
child: Center(
Expand Down
103 changes: 102 additions & 1 deletion test_integration/screenshots.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'dart:io';
import 'package:extended_text_field/extended_text_field.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
Expand All @@ -20,12 +21,112 @@ void main() async {
group('E2E Group', () {
testWidgets('Take Screenshots', (tester) async {
app.main();
await tester.pumpAndSettle();

final homeScreenTitle = find.byKey(const ValueKey(homeScreenTitleKey));
final savedBadgeScreenTitle =
find.byKey(const ValueKey(savedBadgeScreen));
final drawBadgeScreenTitle = find.byKey(const ValueKey(drawBadgeScreen));

await pumpUntilFound(tester, homeScreenTitle);
await tester.pump(const Duration(seconds: 10));
await binding.takeScreenshot('01');

final animationTabText = find.text('Animation');
await tester.tap(animationTabText);
await tester.pumpAndSettle();

final fixedAnimationContainer = find.text('Fixed');
await tester.tap(fixedAnimationContainer);
await tester.pumpAndSettle();

final speedTabText = find.text('Speed');
await tester.tap(speedTabText);
await tester.pumpAndSettle();

final inputField = find.byType(ExtendedTextField);
await tester.tap(inputField);
await tester.pumpAndSettle();
tester.testTextInput.enterText('Hello');
await tester.pump(const Duration(seconds: 5));
await tester.pumpAndSettle();
await tester.testTextInput.receiveAction(TextInputAction.done);
await tester.pumpAndSettle();
await tester.pump(const Duration(seconds: 5));
await tester.pumpAndSettle();
await tester.pump(const Duration(seconds: 5));
await binding.takeScreenshot('02');

await tester.tap(inputField);
await tester.pumpAndSettle();
tester.testTextInput.enterText('');
await tester.pumpAndSettle();
await tester.testTextInput.receiveAction(TextInputAction.done);
await tester.pumpAndSettle();

final prefixIcon = find.byIcon(Icons.tag_faces_outlined);
await tester.tap(prefixIcon);
await tester.pump(const Duration(seconds: 5));
await tester.pumpAndSettle();
await tester.pump(const Duration(seconds: 5));
await tester.pumpAndSettle();

final gridViewCard = find.byWidgetPredicate(
(widget) =>
widget is Card &&
widget.child is Padding &&
(widget.child as Padding).child is Image,
);

final targetCard = gridViewCard.at(18);
await tester.tap(targetCard);
await tester.pumpAndSettle();
await tester.tap(prefixIcon);
await tester.pumpAndSettle();

final effectsTabText = find.text('Effects');
await tester.tap(effectsTabText);
await tester.pump(const Duration(seconds: 5));
await tester.pumpAndSettle();
await tester.pump(const Duration(seconds: 5));
await tester.pumpAndSettle();
await binding.takeScreenshot('03');

final invertEffectContainer = find.text('Invert');
await tester.tap(invertEffectContainer);
await tester.pump(const Duration(seconds: 5));
await tester.pumpAndSettle();
await tester.pump(const Duration(seconds: 5));
await tester.pumpAndSettle();
await binding.takeScreenshot('04');

await tester.tap(invertEffectContainer);
await tester.pumpAndSettle();
await tester.tap(speedTabText);
await tester.pumpAndSettle();

ScaffoldState state = tester.firstState(find.byType(Scaffold));
state.openDrawer();
await tester.pumpAndSettle();
final savedBadgesText = find.text('Saved Badges');
await tester.tap(savedBadgesText);
await pumpUntilFound(tester, savedBadgeScreenTitle);
await tester.pump(const Duration(seconds: 5));
await tester.pumpAndSettle();
await tester.pump(const Duration(seconds: 5));
await tester.pumpAndSettle();
await binding.takeScreenshot('05');

state = tester.firstState(find.byType(Scaffold));
state.openDrawer();
await tester.pumpAndSettle();
final drawBadgeText = find.text('Draw Clipart');
await tester.tap(drawBadgeText);
await pumpUntilFound(tester, drawBadgeScreenTitle);
await tester.pump(const Duration(seconds: 5));
await tester.pumpAndSettle();
await tester.pump(const Duration(seconds: 5));
await tester.pumpAndSettle();
await binding.takeScreenshot('06');
});
});
}
3 changes: 2 additions & 1 deletion test_integration/test_driver.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ Future<void> main() async {
await integrationDriver(
onScreenshot: (String screenshotName, List<int> screenshotBytes,
[Map<String, Object?>? args]) async {
final filePath = 'screenshots/$screenshotName.png';
final timeStamp = DateTime.now().millisecondsSinceEpoch.toString();
final filePath = 'screenshots/$screenshotName-$timeStamp.png';
print('Writing screenshot to $filePath');

final File image = await File(filePath).create(recursive: true);
Expand Down
2 changes: 1 addition & 1 deletion test_integration/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Future<void> pumpUntilFound(
bool timerDone = false;
final timer = Timer(timeout, () => timerDone = true);
while (timerDone != true) {
await tester.pump();
await tester.pumpAndSettle();

final found = tester.any(finder);
if (found) {
Expand Down

0 comments on commit 7d57a9d

Please sign in to comment.