diff --git a/app/CONTRIBUTING.md b/app/CONTRIBUTING.md
index 0bd19e71..ec741343 100644
--- a/app/CONTRIBUTING.md
+++ b/app/CONTRIBUTING.md
@@ -126,50 +126,8 @@ Another option is to use, e.g., .
_version (login without redirect) βΒ can adopt once different login types are_
_supported._
-Scripts were created to click through the app using tests and record the
-screen.
-
-A simulator with the app in its initial state (or not installed) needs to be
-running.
-
-Optional: set the time and status bar items as described in
-[screenshots for publishing](#screenshots-for-publishing).
-
-The `generate_screendocs/run.sh` script will create screencasts
-and screenshots.
-
-Run the script with `bash generate_screendocs/run.sh`.
-
-### Screencasts
-
-The script uses uses Xcode to record the screencast and
-[`ffmpeg`](https://ffmpeg.org/) to cut the `full.mov` to relevant subsets
-(needs to be installed).
-
-To generate GIFs used in the Tutorial,
-[ImageMagick](https://imagemagick.org/index.php) is used
-(which also needs to be installed).
-
-### Screenshots
-
-The script automatically updates the screenshots in `../docs/screenshots`
-(used in [π App screens](../docs/App-screens.md),
-[π User instructions](../docs/User-instructions.html), and the
-[README](./README.md)).
-
-If the error `The following MissingPluginException was thrown running a test:
-MissingPluginException(No implementation found for method captureScreenshot on
-channel plugins.flutter.io/integration_test)` occurs, the registration in the
-file
-`ios/.symlinks/plugins/integration_test/ios/Classes/IntegrationTestPlugin.m`
-needs to be adapted (see
-[issue](https://github.com/flutter/flutter/issues/91668)):
-
-```m
-+ (void)registerWithRegistrar:(NSObject *)registrar {
- [[IntegrationTestPlugin instance] setupChannels:registrar.messenger];
-}
-```
+_Check `e60efb4f2fc3ba2efa7735ffb06ec5fdb64d7af6` for a rudimentary script_
+_version, removed afterwards due to too many merge conflicts._
## Adapting test data
diff --git a/app/generate_screendocs/run.sh b/app/generate_screendocs/run.sh
deleted file mode 100644
index fb1ce0eb..00000000
--- a/app/generate_screendocs/run.sh
+++ /dev/null
@@ -1,229 +0,0 @@
-#!/bin/bash
-
-output_directory="../docs/screencasts/"
-assets_directory="assets/images/tutorial/"
-cuts_log_path="${output_directory}cuts.log"
-flutter_log_path="${output_directory}flutter.log"
-full_video_path="${output_directory}full.mov"
-
-timestamp_prefix="TIMESTAMP: "
-
-ffmpeg_log_level="warning"
-
-# The following flags are for testing single steps and should be set to true
-redo_recording=true
-redo_cutting=true
-redo_gif_creation=true
-redo_gif_copying=true
-
-log_timestamp() {
- echo "$(date +%s000) $1" >> "$cuts_log_path"
-}
-
-if $redo_recording; then
-
- read -p "Enter username: " username
- read -p "Enter password: " password
-
- # Doing the recording was inspired by
- # https://betterprogramming.pub/how-to-record-flutter-integration-tests-with-github-actions-1ca670eff94a
-
- # Start recording
-
- rm -f "$cuts_log_path"
- rm -f "$flutter_log_path"
- xcrun simctl io booted recordVideo "$full_video_path" -f &
- log_timestamp "recording_start"
- sleep 5
- export RECORDING_PID=${!}
- echo "Recording process up with pid: ${RECORDING_PID}"
-
- # Run sequence in app
-
- echo "Running app"
- flutter drive \
- --driver=generate_screendocs/test_driver.dart \
- --target=generate_screendocs/screendocs_sequence.dart \
- --dart-define=TIMESTAMP_PREFIX="$timestamp_prefix" \
- --dart-define=TEST_USER="$username" \
- --dart-define=TEST_PASSWORD="$password" | tee "$flutter_log_path"
-
- # Write cut timestamps from test.log to cut.log
-
- echo "Finishing recording"
-
- logged_timestamp_prefix="flutter: $timestamp_prefix"
- extracted_timestamps=$(\
- awk -v s="$logged_timestamp_prefix" 'index($0, s) == 1' "$flutter_log_path" | \
- sed -e "s/^$logged_timestamp_prefix//"\
- )
- echo "$extracted_timestamps" >> "$cuts_log_path"
-
- # End recording
-
- log_timestamp "recording_end"
- sleep 5
- kill -SIGINT $RECORDING_PID
- sleep 10
- echo ""
-
-fi
-
-if $redo_cutting; then
-
- # Cut smaller screencasts
-
- echo "Cutting smaller screencasts at keyframes closest before logged times"
-
- timestamps=()
- descriptions=()
- while read cut_info; do
- if [ -z "$cut_info" ]; then
- continue
- fi
- cut_info_array=($cut_info)
- timestamp=${cut_info_array[0]}
- description=${cut_info_array[1]}
- timestamps+=("$timestamp")
- descriptions+=("$description")
- done < "$cuts_log_path"
-
- get_frame_starts() {
- local video_path=$1
- echo $(
- ffprobe -loglevel "$ffmpeg_log_level" \
- -select_streams v \
- -show_entries frame=pts_time \
- -of csv=print_section=0 \
- "$video_path" \
- | awk -F',' '{print $1}'
- )
- }
-
- get_frame_durations() {
- local video_path=$1
- echo $(
- ffprobe -loglevel "$ffmpeg_log_level" \
- -select_streams v \
- -show_entries frame=duration_time \
- -of csv=print_section=0 \
- "$video_path" \
- | awk -F',' '{print $1}'
- )
- }
-
- frame_starts=($(get_frame_starts $full_video_path))
- frame_durations=($(get_frame_durations $full_video_path))
-
- get_difference() {
- local first_float=$1
- local second_float=$2
- local difference=$(echo "$first_float - $second_float" | bc)
- echo ${difference#-}
- }
-
- get_closest_previous_frame_start() {
- local target=$1
- local best_fit_index=0
- local smallest_difference=$(get_difference $target ${frame_starts[0]})
- for ((j=1; j<${#frame_starts[@]}; j++)); do
- local current_value=${frame_starts[j]}
- local current_difference=$(get_difference $target $current_value)
- if (( $(echo "$current_value > $target" | bc) )); then
- break
- fi
- if (( $(echo "$current_difference < $smallest_difference" | bc) )); then
- smallest_difference=$current_difference
- best_fit_index=$j
- fi
- done
- echo "${frame_starts[best_fit_index]}"
- }
-
- get_frame_end() {
- local index=$1
- local frame_start=${frame_starts[index]}
- local frame_duration=${frame_durations[index]}
- echo $(echo "$frame_start + $frame_duration" | bc)
- }
-
- get_closest_previous_frame_end() {
- local target=$1
- local best_fit_index=0
- local smallest_difference=$(get_difference $target $(get_frame_end 0))
- for ((j=1; j<${#frame_starts[@]}; j++)); do
- local current_value=$(get_frame_end $j)
- local current_difference=$(get_difference $target $current_value)
- if (( $(echo "$current_value > $target" | bc) )); then
- break
- fi
- if (( $(echo "$current_difference < $smallest_difference" | bc) )); then
- smallest_difference=$current_difference
- best_fit_index=$j
- fi
- done
- echo "$(get_frame_end $best_fit_index)"
- }
-
- get_seconds_since_start() {
- echo $(printf %.3f "$(($1-${timestamps[0]}))e-3")
- }
-
- cut_video() {
- local description=$1
- local start_seconds=$(get_closest_previous_frame_start $2)
- local end_seconds=$(get_closest_previous_frame_end $3)
-
- echo "Cutting $description $start_seconds β $end_seconds (originally $2 β $3)"
-
- local video_path="${output_directory}${description}.mp4"
-
- ffmpeg -y -loglevel "$ffmpeg_log_level" -an \
- -i "$full_video_path" \
- -ss "$start_seconds" \
- -to "$end_seconds" \
- -pix_fmt yuv420p \
- "$video_path"
- }
-
- cut_video "full_clean" \
- $(get_seconds_since_start ${timestamps[1]}) \
- $(get_seconds_since_start ${timestamps[${#timestamps[@]}-2]})
-
- # Skip first and last entries (recording_start and recording_end)
- for ((i=2; i<${#timestamps[@]}-1; i+=2)); do
- description=${descriptions[i]}
- start_seconds=$(get_seconds_since_start ${timestamps[i-1]})
- end_seconds=$(get_seconds_since_start ${timestamps[i]})
- cut_video $description $start_seconds $end_seconds
- done
-
-fi
-
-if $redo_gif_creation; then
-
- for video_path in `find $output_directory -name "*.mp4" -type f`; do
- video_name=$(basename $video_path)
- if [[ "$video_name" == full*.mp4 ]]; then continue; fi
- gif_name="${video_name%.mp4}.gif"
- gif_path="${output_directory}$gif_name"
- echo "Creating $gif_path"
- # From https://superuser.com/a/556031
- ffmpeg -y -loglevel "$ffmpeg_log_level" \
- -i "$video_path" \
- -vf "fps=10,scale=320:-1:flags=lanczos" -c:v pam -f image2pipe - | \
- magick -delay 10 - -loop 0 -layers optimize "$gif_path"
- done
-
-fi
-
-if $redo_gif_copying; then
-
- for gif_path in `find $output_directory -name "*_loopable.gif" -type f`; do
- gif_name="$(basename $gif_path)"
- assets_path="${assets_directory}$gif_name"
- echo "Copying $gif_name to $assets_directory"
- cp $gif_path $assets_path
- done
-
-fi
diff --git a/app/generate_screendocs/screendocs_sequence.dart b/app/generate_screendocs/screendocs_sequence.dart
deleted file mode 100644
index 2552b144..00000000
--- a/app/generate_screendocs/screendocs_sequence.dart
+++ /dev/null
@@ -1,524 +0,0 @@
-// Clicks though most parts of the app and creates screenshots (based on
-// https://dev.to/mjablecnik/take-screenshot-during-flutter-integration-tests-435k)
-// and screencasts; also outputs timestamp logs for cutting smaller screencasts
-
-import 'dart:io';
-
-import 'package:app/app.dart';
-import 'package:app/common/module.dart';
-import 'package:flutter/cupertino.dart';
-import 'package:flutter_test/flutter_test.dart';
-import 'package:integration_test/integration_test.dart';
-import 'package:provider/provider.dart';
-
-Future takeScreenshot(
- WidgetTester tester,
- IntegrationTestWidgetsFlutterBinding binding,
- String fileName
-) async {
- if (Platform.isAndroid) {
- await binding.convertFlutterSurfaceToImage();
- await tester.pumpAndSettle();
- }
- await binding.takeScreenshot(fileName);
-}
-
-Future logTimeStamp(
- WidgetTester tester,
- String prefix,
- String description,
-) async {
- await tester.pumpAndSettle();
- final timestamp = DateTime.now().millisecondsSinceEpoch;
- // ignore: avoid_print
- print('$prefix$timestamp $description');
- await _waitAndSettle(tester, 1);
-}
-
-Future beginPart(
- WidgetTester tester,
- String timestampPrefix,
- String description,
-) async{
- await logTimeStamp(tester, timestampPrefix, description);
-}
-
-Future endPart(
- WidgetTester tester,
- String timestampPrefix,
- String description,
-) async {
- await logTimeStamp(tester, timestampPrefix, description);
-}
-
-void main() {
- group('click through the app and create screencasts', () {
- final binding = IntegrationTestWidgetsFlutterBinding();
- IntegrationTestWidgetsFlutterBinding.ensureInitialized();
- testWidgets('take screencast', (tester) async {
- const username = String.fromEnvironment('TEST_USER');
- const password = String.fromEnvironment('TEST_PASSWORD');
- const timestampPrefix = String.fromEnvironment('TIMESTAMP_PREFIX');
-
- await _loadApp(tester);
-
- const acceptLoginDescription = '01_accept_and_login';
- const onboardingDescription = '02_onboarding';
- const drugSelectionDescription = '03_drug_selection';
- const tutorialDescription = '04_tutorial';
- const bottomNavigationDescription = '05_bottom_navigation_loopable';
- const drugSearchFilterDescription = '06_drug_search_and_filter_loopable';
- const ibuprofenDescription = '07_ibuprofen_loopable';
- const reportCyp2c9Description = '08_report_and_cyp2c9_loopable';
- const faqMoreDescription = '09_faq_and_more_loopable';
- const deleteDataDescription = '10_delete_data';
-
- await beginPart(
- tester,
- timestampPrefix,
- acceptLoginDescription,
- );
- await _waitAndSettle(tester, 1);
- await takeScreenshot(tester, binding, 'accept-terms');
- await _tapButton(tester, 'Continue');
- await _waitAndSettle(tester, 2);
- await _enterUsername(tester, username);
- await _waitAndSettle(tester, 1);
- await _enterPassword(tester, password);
- await tester.pumpAndSettle();
- await takeScreenshot(tester, binding, 'login');
- await _tapFullWidthButton(tester);
- await _waitAndSettle(tester, 1);
- await endPart(tester, timestampPrefix, acceptLoginDescription);
-
- await beginPart(
- tester,
- timestampPrefix,
- onboardingDescription,
- );
- const onboardingWaitingTime = 1;
- await _waitAndSettle(tester, onboardingWaitingTime);
- await takeScreenshot(tester, binding, 'onboarding-1');
- await _tapButton(tester, 'Next');
- await _waitAndSettle(tester, onboardingWaitingTime);
- await takeScreenshot(tester, binding, 'onboarding-2');
- await _tapButton(tester, 'Next');
- await _waitAndSettle(tester, onboardingWaitingTime);
- await takeScreenshot(tester, binding, 'onboarding-3');
- await _tapButton(tester, 'Next');
- await _waitAndSettle(tester, onboardingWaitingTime);
- await takeScreenshot(tester, binding, 'onboarding-4');
- await _tapButton(tester, 'Next');
- await _waitAndSettle(tester, onboardingWaitingTime);
- await takeScreenshot(tester, binding, 'onboarding-5');
- await _tapButton(tester, 'Get started');
- await _waitAndSettle(tester, 1);
- await endPart(tester, timestampPrefix, onboardingDescription);
-
- await beginPart(tester, timestampPrefix, drugSelectionDescription);
- await _waitAndSettle(tester, 2);
- await takeScreenshot(tester, binding, 'drug-selection-intro');
- await _tapButton(tester, 'Continue');
- await _waitAndSettle(tester, 1);
- await _searchDrug(tester, 'Ibu');
- await _waitAndSettle(tester, 1);
- await _interactWithDrugInSelection(
- tester,
- 'Ibuprofen',
- scroll: false,
- tap: true,
- );
- await _waitAndSettle(tester, 1);
- await _clearDrugSearch(tester);
- await _waitAndSettle(tester, 1);
- await takeScreenshot(tester, binding, 'drug-selection');
- await _tapFullWidthButton(tester);
- await _waitAndSettle(tester, 1);
- await endPart(tester, timestampPrefix, drugSelectionDescription);
-
- await beginPart(tester, timestampPrefix, tutorialDescription);
- const tutorialWaitingTime = 1;
- await Future.delayed(Duration(seconds: tutorialWaitingTime));
- await takeScreenshot(tester, binding, 'tutorial-1');
- await _tapButton(tester, 'Continue');
- await _waitAndSettle(tester, tutorialWaitingTime);
- await takeScreenshot(tester, binding, 'tutorial-2');
- await _tapButton(tester, 'Continue');
- await _waitAndSettle(tester, tutorialWaitingTime);
- await takeScreenshot(tester, binding, 'tutorial-3');
- await _tapButton(tester, 'Continue');
- await _waitAndSettle(tester, tutorialWaitingTime);
- await takeScreenshot(tester, binding, 'tutorial-4');
- await _tapButton(tester, 'Continue');
- await _waitAndSettle(tester, tutorialWaitingTime);
- await takeScreenshot(tester, binding, 'tutorial-5');
- await _tapButton(tester, 'Finish');
- await _waitAndSettle(tester, 1);
- await takeScreenshot(tester, binding, 'setup-complete');
- await _selectDialogAction(tester);
- await _waitAndSettle(tester, 1);
- await endPart(tester, timestampPrefix, tutorialDescription);
-
- await beginPart(tester, timestampPrefix, bottomNavigationDescription);
- await _waitAndSettle(tester, 1);
- await _useBottomNavigation(tester, 'Genes');
- await _waitAndSettle(tester, 1);
- await _useBottomNavigation(tester, 'FAQ');
- await _waitAndSettle(tester, 1);
- await _useBottomNavigation(tester, 'More');
- await _waitAndSettle(tester, 1);
- await _useBottomNavigation(tester, 'Medications');
- await _waitAndSettle(tester, 0);
- await endPart(tester, timestampPrefix, bottomNavigationDescription);
-
- const toggledWarningLevelIndex = 3; // missing data
- await beginPart(tester, timestampPrefix, drugSearchFilterDescription);
- await _waitAndSettle(tester, 1);
- await takeScreenshot(tester, binding, 'drug-search');
- await _openDrugFilters(tester);
- await _waitAndSettle(tester, 1);
- await takeScreenshot(tester, binding, 'drug-search-filter');
- await _toggleNthWarningLevel(tester, toggledWarningLevelIndex);
- await _waitAndSettle(tester, 2);
- await _toggleNthWarningLevel(tester, toggledWarningLevelIndex);
- await _waitAndSettle(tester, 1);
- await _closeDrugFilters(tester);
- await _waitAndSettle(tester, 0);
- await endPart(tester, timestampPrefix, drugSearchFilterDescription);
-
- await beginPart(tester, timestampPrefix, ibuprofenDescription);
- await _waitAndSettle(tester, 1);
- await _tapText(tester, 'Ibuprofen');
- await _waitAndSettle(tester, 1);
- await takeScreenshot(tester, binding, 'ibuprofen');
- await _changeDrugStatus(tester, 'Ibuprofen', 'inactive');
- await _waitAndSettle(tester, 2);
- try {
- await _changeDrugStatus(tester, 'Ibuprofen', 'active');
- await _waitAndSettle(tester, 2);
- } catch (e) {
- // ignore: avoid_print
- print(
- 'π¨ Could not activate Ibuprofen again; video will not be'
- 'loopable'
- );
- }
- await tester.pageBack();
- await _waitAndSettle(tester, 1);
- await endPart(tester, timestampPrefix, ibuprofenDescription);
-
- await _waitAndSettle(tester, 1);
- await _useBottomNavigation(tester, 'Genes');
- await _waitAndSettle(tester, 2);
-
- await beginPart(tester, timestampPrefix, reportCyp2c9Description);
- await _waitAndSettle(tester, 1);
- await takeScreenshot(tester, binding, 'gene-report-current');
- await _toggleNonCurrentList(tester);
- await _waitAndSettle(tester, 1);
- await takeScreenshot(tester, binding, 'gene-report-all');
- await _toggleNonCurrentList(tester, expectExpanded: true);
- await _waitAndSettle(tester, 1);
- await _tapGeneCard(tester, 'CYP2C9');
- await _waitAndSettle(tester, 2);
- await takeScreenshot(tester, binding, 'cyp2c9');
- await _toggleNonCurrentList(tester);
- await _waitAndSettle(tester, 2);
- await takeScreenshot(tester, binding, 'cyp2c9-expanded');
- await _toggleNonCurrentList(tester, expectExpanded: true);
- await _waitAndSettle(tester, 0);
- await tester.pageBack();
- await _waitAndSettle(tester, 1);
- await endPart(tester, timestampPrefix, reportCyp2c9Description);
-
- await _waitAndSettle(tester, 1);
- await _useBottomNavigation(tester, 'FAQ');
- await _waitAndSettle(tester, 1);
- await takeScreenshot(tester, binding, 'faq');
-
- await beginPart(tester, timestampPrefix, faqMoreDescription);
- await _waitAndSettle(tester, 1);
- await _tapFirstFaqItem(tester);
- await _waitAndSettle(tester, 1);
- await takeScreenshot(tester, binding, 'faq-first-item');
- await _tapFirstFaqItem(tester);
- await _waitAndSettle(tester, 1);
- await _useBottomNavigation(tester, 'More');
- await _waitAndSettle(tester, 3);
- await takeScreenshot(tester, binding, 'more');
- await _tapText(tester, 'Contact us', selectLast: true);
- await _waitAndSettle(tester, 2);
- await _selectDialogAction(tester, selectFirst: true);
- await _waitAndSettle(tester, 0);
- await _useBottomNavigation(tester, 'FAQ');
- await _waitAndSettle(tester, 1);
- await endPart(tester, timestampPrefix, faqMoreDescription);
-
-
- await beginPart(tester, timestampPrefix, deleteDataDescription);
- await _useBottomNavigation(tester, 'More');
- await tester.pumpAndSettle();
- await _tapText(tester, 'Delete app data');
- await tester.pumpAndSettle();
- await takeScreenshot(tester, binding, 'delete-app-data');
- await _selectDialogAction(tester, selectFirst: true);
- await tester.pumpAndSettle();
- await endPart(tester, timestampPrefix, deleteDataDescription);
-
- await _cleanupApp();
- });
- });
-}
-
-Future _loadApp(WidgetTester tester) async {
- // Part before runApp in lib/main.dart
- await initServices();
- // Load the app
- await tester.pumpWidget(
- MultiProvider(
- providers: [
- ChangeNotifierProvider(create: (context) => ActiveDrugs()),
- ChangeNotifierProvider(create: (context) => InactivityTimer()),
- ],
- child: PharMeApp(),
- ),
- );
- await tester.pumpAndSettle();
-}
-
-Future _cleanupApp() async {
- // Part after runApp in lib/main.dart
- await cleanupServices();
-}
-
-Future _waitAndSettle(WidgetTester tester, int seconds) async {
- await tester.pumpAndSettle();
- await Future.delayed(Duration(seconds: seconds));
- await tester.pumpAndSettle();
-}
-
-Future _enterText(WidgetTester tester, Finder finder, String text) async {
- // Please note: apparently, this does not actually open the keyboard in the
- // simulator (which is fine I guess)
- await tester.showKeyboard(finder);
- await tester.pump();
- var buildingSearchTerm = '';
- for (final character in text.characters) {
- // ignore: use_string_buffers
- buildingSearchTerm = '$buildingSearchTerm$character';
- await tester.enterText(finder, buildingSearchTerm);
- await tester.pump();
- }
- await _finishTextInput(tester);
-}
-
-Future _enterUsername(WidgetTester tester, String username) async {
- await _enterText(tester, find.byType(TextField).first, username);
-}
-
-Future _enterPassword(WidgetTester tester, String password) async {
- await _enterText(tester, find.byType(TextField).last, password);
-}
-
-Future _searchDrug(WidgetTester tester, String drug) async {
- await _enterText(tester, find.byType(CupertinoSearchTextField).last, drug);
-}
-
-Future _clearDrugSearch(WidgetTester tester) async {
- await tester.tap(find.descendant(
- of: find.byType(CupertinoSearchTextField).first,
- matching: find.byType(Icon),
- ).last);
-}
-
-Future _finishTextInput(WidgetTester tester) async {
- await tester.testTextInput.receiveAction(TextInputAction.done);
-}
-
-Future _tapButton(WidgetTester tester, String label) async {
- await tester.tap(find.bySemanticsLabel(label).first);
-}
-
-Future _toggleNonCurrentList(
- WidgetTester tester,
- { bool expectExpanded = false }
-) async {
- final expectedIcon = expectExpanded
- ? Icons.arrow_drop_up
- : Icons.arrow_drop_down;
- await tester.tap(
- find.ancestor(
- of: find.byIcon(expectedIcon, skipOffstage: false),
- matching: find.byType(ResizedIconButton, skipOffstage: false),
- ).last,
- );
-}
-
-Future _tapFullWidthButton(WidgetTester tester) async {
- await tester.tap(find.byType(FullWidthButton).first);
-}
-
-Finder _findText(String text, {bool selectLast = false}) {
- final exactMatch = find.text(text, skipOffstage: false);
- if (exactMatch.hasFound) {
- return selectLast
- ? exactMatch.last
- : exactMatch.first;
- }
- final fuzzyMatch = find.textContaining(text, skipOffstage: false);
- return selectLast ? fuzzyMatch.last : fuzzyMatch.first;
-}
-
-Future _tapText(
- WidgetTester tester,
- String text,
- {bool selectLast = false}
-) async {
- await tester.tap(_findText(text, selectLast: selectLast));
-}
-
-Future _tapGeneCard(
- WidgetTester tester,
- String gene,
- { String keyPostfix = 'current-medications' }
-) async {
- final geneCard = find.byKey(
- Key('gene-card-$gene-$keyPostfix'),
- skipOffstage: false,
- );
- await tester.tap(geneCard);
-}
-
-// This is a bit hacky, as only some list items can be found currently
-// (not sure why); therefore, the script needs to select one of those.
-// If the interaction could not be executed, a list of available items is
-// printed.
-Future _interactWithDrugListItem(
- WidgetTester tester,
- {
- required String itemKey,
- required String listKey,
- required Type itemType,
- required bool scroll,
- required bool tap,
- required bool raiseException,
- }
-) async {
- final listFinder = find.byKey(Key(listKey), skipOffstage: false);
- final itemFinder = find.descendant(
- of: listFinder,
- matching: find.byKey(Key(itemKey), skipOffstage: false),
- skipOffstage: false,
- );
- final item = itemFinder.first;
- try {
- if (scroll) {
- final list = listFinder.first;
- await tester.dragUntilVisible(item, list, Offset(0, -0.1));
- }
- if (tap) {
- await tester.tap(item);
- }
- } catch (e) {
- var errorMessage = 'π¨ Could not drag drug list';
- if (!raiseException) errorMessage += '\n Error: ${e.toString()}\n';
- // ignore: avoid_print
- print(errorMessage);
- var contextDetails = 'Context details:\n'
- ' With item finder: ${itemFinder.toString()}';
- if (scroll) {
- contextDetails += '\n With list finder: ${listFinder.toString()}\n';
- }
- // ignore: avoid_print
- print(contextDetails);
- // ignore: avoid_print
- print('Available drug items:');
- final availableItems = find.descendant(
- of: listFinder,
- matching: find.byType(itemType, skipOffstage: false),
- skipOffstage: false,
- );
- availableItems.evaluate();
- // ignore: avoid_function_literals_in_foreach_calls
- availableItems.found.forEach(
- // ignore: avoid_print
- (element) => print(' ${element.toString()}')
- );
- if (raiseException) rethrow;
- }
-}
-
-Future _interactWithDrugInSelection(
- WidgetTester tester,
- String drug,
- {
- required bool scroll,
- required bool tap,
- bool raiseException = true,
- }
-) async {
- await _interactWithDrugListItem(
- tester,
- itemKey: 'other-drug-selection-tile-${drug.toLowerCase()}',
- listKey: 'drug-selection',
- itemType: SwitchListTile,
- scroll: scroll,
- tap: tap,
- raiseException: raiseException,
- );
-}
-
-Future _useBottomNavigation(
- WidgetTester tester,
- String destination,
-) async {
- await tester.tap(find.descendant(
- of: find.byType(BottomNavigationBar),
- matching: find.text(destination),
- ).first);
-}
-
-Future _changeDrugStatus(
- WidgetTester tester,
- String drug,
- String activity,
-) async {
- await tester.tap(
- find.byType(Switch).first,
- );
-}
-
-Future _tapFirstFaqItem(WidgetTester tester) async {
- await tester.tap(
- find.descendant(
- of: find.byType(ExpansionTile).first,
- matching: find.byType(Icon),
- ),
- );
-}
-
-Future _toggleNthWarningLevel(WidgetTester tester, int n) async {
- // We are basically testing :shrug:
- // ignore: invalid_use_of_visible_for_testing_member
- await tester.tap(find.byType(WarningLevelFilterChip).at(n));
-}
-
-Future _selectDialogAction(
- WidgetTester tester,
- {bool selectFirst = false}
-) async {
- final actions = find.byType(DialogAction, skipOffstage: false);
- final action = selectFirst ? actions.first : actions.last;
- await tester.tap(action);
-}
-
-Future _openDrugFilters(WidgetTester tester) async {
- await tester.tap(find.ancestor(
- of: find.byIcon(Icons.filter_list),
- matching: find.byType(IconButton),
- ));
-}
-
-Future _closeDrugFilters(WidgetTester tester) async {
- await tester.tapAt(Offset(0, 0));
-}
diff --git a/app/generate_screendocs/test_driver.dart b/app/generate_screendocs/test_driver.dart
deleted file mode 100644
index d7bd66f7..00000000
--- a/app/generate_screendocs/test_driver.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-// Create screenshots from integration tests; from
-// https://dev.to/mjablecnik/take-screenshot-during-flutter-integration-tests-435k
-
-import 'dart:io';
-import 'package:integration_test/integration_test_driver_extended.dart';
-
-Future main() async {
- try {
- await integrationDriver(
- onScreenshot: (screenshotName, screenshotBytes, [_]) async {
- final image =
- await File(
- '../docs/screenshots/$screenshotName.png'
- ).create(recursive: true);
- image.writeAsBytesSync(screenshotBytes);
- return true;
- },
- );
- } catch (e) {
- // ignore: avoid_print
- print('Error occured: $e');
- }
-}
\ No newline at end of file
diff --git a/docs/App-screens.md b/docs/App-screens.md
index 711b17f7..e2d56e28 100644
--- a/docs/App-screens.md
+++ b/docs/App-screens.md
@@ -8,6 +8,10 @@ Actions are usually tapping (π) or scrolling down (β¬).
If no screen number is given, the action refers to the screen in the previous
table row.
+_Please note: as screenshot generation is currently not possible, the screens_
+_you see here are the study version screens. Most screens are the same, but_
+_in the study version some additional content is implemented._
+
| # | Action | Screen | Description |
| - | ------ | ------ | ----------- |
| 1 | App opened the first time |
| Notice that by continuing users agree to terms (see screen 23) |