Skip to content

Commit

Permalink
Merge branch 'main' into testdata-OL-ZUE
Browse files Browse the repository at this point in the history
  • Loading branch information
Grodien committed Jan 21, 2025
2 parents 04fbb26 + 46d6a05 commit 14fa328
Show file tree
Hide file tree
Showing 93 changed files with 1,118 additions and 434 deletions.
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"webapp":"0.1.0","das_client":"0.6.0"}
{"webapp":"0.1.0","das_client":"0.7.0"}
16 changes: 16 additions & 0 deletions das_client/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# Changelog

## [0.7.0](https://github.com/SchweizerischeBundesbahnen/DAS/compare/das_client-v0.6.0...das_client-v0.7.0) (2025-01-20)


### Features

* add whistle, balise, tram area and levelcrossing ([#224](https://github.com/SchweizerischeBundesbahnen/DAS/issues/224)) ([#485](https://github.com/SchweizerischeBundesbahnen/DAS/issues/485)) ([27379a2](https://github.com/SchweizerischeBundesbahnen/DAS/commit/27379a2bbdd991db8736f57f19eadddfb3dbaf7d))
* added graduated station speed. ([#82](https://github.com/SchweizerischeBundesbahnen/DAS/issues/82)) ([#484](https://github.com/SchweizerischeBundesbahnen/DAS/issues/484)) ([8af6cf9](https://github.com/SchweizerischeBundesbahnen/DAS/commit/8af6cf91a9ea22082f39df2ff73fcce215cfaea9))
* added punctuality display ([#122](https://github.com/SchweizerischeBundesbahnen/DAS/issues/122)) ([#473](https://github.com/SchweizerischeBundesbahnen/DAS/issues/473)) ([f9646b0](https://github.com/SchweizerischeBundesbahnen/DAS/commit/f9646b0a72915d1f6dbc2b57e530c84f14fe5762))


### Bug Fixes

* **deps:** update dependency flutter_bloc to v9 ([#496](https://github.com/SchweizerischeBundesbahnen/DAS/issues/496)) ([1b74d01](https://github.com/SchweizerischeBundesbahnen/DAS/commit/1b74d01697c5401c2cd9f02795eae0948204a9be))
* fix station speed parsing ([#491](https://github.com/SchweizerischeBundesbahnen/DAS/issues/491)) ([00f9a81](https://github.com/SchweizerischeBundesbahnen/DAS/commit/00f9a816c6d0d20140c02a7f37bf85aeb0846457))
* fixed the padding in the punctuality display ([#122](https://github.com/SchweizerischeBundesbahnen/DAS/issues/122)) ([#501](https://github.com/SchweizerischeBundesbahnen/DAS/issues/501)) ([17511ff](https://github.com/SchweizerischeBundesbahnen/DAS/commit/17511ffa1cf48472df2d46a31e912349b181006e))

## [0.6.0](https://github.com/SchweizerischeBundesbahnen/DAS/compare/das_client-v0.5.0...das_client-v0.6.0) (2025-01-06)


Expand Down
18 changes: 16 additions & 2 deletions das_client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,23 @@ fvm flutter test --flavor dev --dart-define=MQTT_USERNAME=${MQTT_USERNAME} --dar

## Architecture

TODO

### Test file structure
To prevent confusion, fictive train numbers with the prefix `T` are used for the test scenarios. It is desired to create new train journeys for different features.
The file structure in [test_resources](test_resources) for a test scenario looks as follows:
* base directory named `<train number>_<optional description>`
* journey profile named `SFERA_JP_<train number>_<optional postfix>`
* corresponding segment profiles named `SFERA_SP_<train number>_<segment number>`
* corresponding train characteristics named `SFERA_TC_<train number>_<tc number>`
An example test scenario for train number T1 could look like this:
* T1_demo_journey/
* SFERA_JP_T1
* SFERA_JP_T1_without_stop
* SFERA_SP_T1_1
* SFERA_SP_T1_2
* SFERA_TC_T1_1
<a name="localization"></a>


## Localization

The app is available in three languages:
Expand Down
175 changes: 159 additions & 16 deletions das_client/integration_test/test/train_journey_table_test.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import 'dart:async';

import 'package:das_client/app/pages/journey/train_journey/widgets/header/header.dart';
import 'package:das_client/app/pages/journey/train_journey/widgets/table/additional_speed_restriction_row.dart';
import 'package:das_client/app/pages/journey/train_journey/widgets/table/balise_row.dart';
import 'package:das_client/app/pages/journey/train_journey/widgets/table/cab_signaling_row.dart';
Expand All @@ -23,6 +26,57 @@ import '../util/test_utils.dart';

void main() {
group('train journey table test', () {
testWidgets('check if update sent is correct', (tester) async {
// Load app widget.
await prepareAndStartApp(tester);

// Select the correct train number
final trainNumberText = findTextFieldByLabel(l10n.p_train_selection_trainnumber_description);
expect(trainNumberText, findsOneWidget);

await enterText(tester, trainNumberText, 'T9999');

// Log into the journey
final primaryButton = find.byWidgetPredicate((widget) => widget is SBBPrimaryButton).first;
await tester.tap(primaryButton);

// Wait for train journey to load
await tester.pumpAndSettle();

// Find the header and check if it is existent
final headerFinder = find.byType(Header);
expect(headerFinder, findsOneWidget);

// Timer logic: increase timer every second, rerun the base every 100 ms and check if the UI changed
int counter = 0;

final completer = Completer<void>();

expect(find.descendant(of: headerFinder, matching: find.text('+00:00')), findsOneWidget);

while (!completer.isCompleted) {
await tester.pumpAndSettle();

if (!find.descendant(of: headerFinder, matching: find.text('+00:00')).evaluate().isNotEmpty) {
expect(find.descendant(of: headerFinder, matching: find.text('+00:30')), findsOneWidget);
completer.complete();
break;
}

// cancel after 10 seconds
if (counter++ > 10 * 10) {
completer
.completeError(Exception('UI did not change from the base value to the updated value (+00:00 -> +00:30)'));
break;
}

await Future.delayed(const Duration(milliseconds: 100));
}

await completer.future;

await tester.pumpAndSettle();
});

testWidgets('test balise multiple level crossings', (tester) async {
await prepareAndStartApp(tester);
Expand Down Expand Up @@ -80,7 +134,8 @@ void main() {
final countText = find.descendant(of: groupOf5BaliseRow, matching: find.text('5'));
expect(countText, findsOneWidget);

final levelCrossingText = find.descendant(of: groupOf5BaliseRow, matching: find.text(l10n.p_train_journey_table_level_crossing));
final levelCrossingText =
find.descendant(of: groupOf5BaliseRow, matching: find.text(l10n.p_train_journey_table_level_crossing));
expect(levelCrossingText, findsOneWidget);

var detailRowBalise = findDASTableRowByText('41.552');
Expand All @@ -99,7 +154,9 @@ void main() {
expect(detailRowBalise, findsOneWidget);

expect(find.descendant(of: detailRowBalise, matching: find.byKey(BaliseRow.baliseIconKey)), findsOneWidget);
expect(find.descendant(of: detailRowLevelCrossing, matching: find.text(l10n.p_train_journey_table_level_crossing)), findsOneWidget);
expect(
find.descendant(of: detailRowLevelCrossing, matching: find.text(l10n.p_train_journey_table_level_crossing)),
findsOneWidget);

// collapse group
await tapElement(tester, groupOf5BaliseRow);
Expand Down Expand Up @@ -317,7 +374,7 @@ void main() {
it is Container &&
it.decoration is BoxDecoration &&
(it.decoration as BoxDecoration).color == AdditionalSpeedRestrictionRow.additionalSpeedRestrictionColor));
expect(coloredCells, findsNWidgets(12));
expect(coloredCells, findsNWidgets(13));
});

testWidgets('test other rows are displayed correctly', (tester) async {
Expand Down Expand Up @@ -540,21 +597,33 @@ void main() {
await tester.dragUntilVisible(find.text('Klammerbahnhof D1'), scrollableFinder, const Offset(0, -50));

final bracketStationD = findDASTableRowByText('Klammerbahnhof D');
final zahnstangenEnde = findDASTableRowByText('Zahnstangen Ende');
final deckungssignal = findDASTableRowByText('Deckungssignal');
final bracketStationD1 = findDASTableRowByText('Klammerbahnhof D1');
expect(bracketStationD, findsOneWidget);
expect(zahnstangenEnde, findsOneWidget);
expect(deckungssignal, findsOneWidget);
expect(bracketStationD1, findsOneWidget);

// check if the bracket station widget is displayed
final bracketStationDWidget =
find.descendant(of: bracketStationD, matching: find.byKey(BracketStationCellBody.bracketStationKey));
final zahnstangenEndeWidget =
find.descendant(of: zahnstangenEnde, matching: find.byKey(BracketStationCellBody.bracketStationKey));
final deckungssignalWidget =
find.descendant(of: deckungssignal, matching: find.byKey(BracketStationCellBody.bracketStationKey));
final bracketStationD1Widget =
find.descendant(of: bracketStationD1, matching: find.byKey(BracketStationCellBody.bracketStationKey));
expect(bracketStationDWidget, findsOneWidget);
expect(zahnstangenEndeWidget, findsOneWidget);
expect(deckungssignalWidget, findsOneWidget);
expect(bracketStationD1Widget, findsOneWidget);

// check that the abbreviation is displayed correctly
expect(find.descendant(of: bracketStationDWidget, matching: find.text('D')), findsNothing);
expect(find.descendant(of: bracketStationD1Widget, matching: find.text('D')), findsOneWidget);
expect(find.descendant(of: bracketStationDWidget, matching: find.text('D')), findsOneWidget);
expect(find.descendant(of: zahnstangenEndeWidget, matching: find.text('D')), findsNothing);
expect(find.descendant(of: deckungssignalWidget, matching: find.text('D')), findsNothing);
expect(find.descendant(of: bracketStationD1Widget, matching: find.text('D')), findsNothing);
});

testWidgets('test halt on request is displayed correctly', (tester) async {
Expand All @@ -566,7 +635,7 @@ void main() {
final scrollableFinder = find.byType(ListView);
expect(scrollableFinder, findsOneWidget);

await tester.dragUntilVisible(find.text('Halt auf Verlangen C'), scrollableFinder, const Offset(0, -50));
await tester.dragUntilVisible(find.text('Klammerbahnhof D'), scrollableFinder, const Offset(0, -50));

final stopOnDemandRow = findDASTableRowByText('Halt auf Verlangen C');
expect(stopOnDemandRow, findsOneWidget);
Expand Down Expand Up @@ -783,51 +852,125 @@ void main() {

final bernStationRow = findDASTableRowByText('Bern');
expect(bernStationRow, findsOneWidget);
final bernIncomingSpeeds = find.descendant(of: bernStationRow, matching: find.byKey(GraduatedSpeedsCellBody.incomingSpeedsKey));
final bernIncomingSpeeds =
find.descendant(of: bernStationRow, matching: find.byKey(GraduatedSpeedsCellBody.incomingSpeedsKey));
expect(bernIncomingSpeeds, findsNWidgets(2));
final bernIncomingSpeedsText = find.descendant(of: bernStationRow, matching: find.text('75-70-60'));
expect(bernIncomingSpeedsText, findsOneWidget);
final bernOutgoingSpeeds = find.descendant(of: bernStationRow, matching: find.byKey(GraduatedSpeedsCellBody.outgoingSpeedsKey));
final bernOutgoingSpeeds =
find.descendant(of: bernStationRow, matching: find.byKey(GraduatedSpeedsCellBody.outgoingSpeedsKey));
expect(bernOutgoingSpeeds, findsNothing);

// check station speeds for Wankdorf, no station speeds given

final wankdorfStationRow = findDASTableRowByText('Wankdorf');
expect(wankdorfStationRow, findsOneWidget);
final wankdorfIncomingSpeeds = find.descendant(of: wankdorfStationRow, matching: find.byKey(GraduatedSpeedsCellBody.incomingSpeedsKey));
final wankdorfIncomingSpeeds =
find.descendant(of: wankdorfStationRow, matching: find.byKey(GraduatedSpeedsCellBody.incomingSpeedsKey));
expect(wankdorfIncomingSpeeds, findsNothing);
final wankdorfOutgoingSpeeds = find.descendant(of: wankdorfStationRow, matching: find.byKey(GraduatedSpeedsCellBody.outgoingSpeedsKey));
final wankdorfOutgoingSpeeds =
find.descendant(of: wankdorfStationRow, matching: find.byKey(GraduatedSpeedsCellBody.outgoingSpeedsKey));
expect(wankdorfOutgoingSpeeds, findsNothing);

// check station speeds for Burgdorf

final burgdorfStationRow = findDASTableRowByText('Burgdorf');
expect(burgdorfStationRow, findsOneWidget);
final burgdorfIncomingSpeeds = find.descendant(of: burgdorfStationRow, matching: find.byKey(GraduatedSpeedsCellBody.incomingSpeedsKey));
final burgdorfIncomingSpeeds =
find.descendant(of: burgdorfStationRow, matching: find.byKey(GraduatedSpeedsCellBody.incomingSpeedsKey));
expect(burgdorfIncomingSpeeds, findsNWidgets(2));
final burgdorfIncomingSpeeds75 = find.descendant(of: burgdorfIncomingSpeeds, matching: find.text('75'));
expect(burgdorfIncomingSpeeds75, findsOneWidget);
final burgdorfIncomingSpeeds70 = find.descendant(of: burgdorfIncomingSpeeds, matching: find.text('70'));
expect(burgdorfIncomingSpeeds70, findsOneWidget);
final burgdorfIncomingSpeeds70Circled = find.ancestor(of: burgdorfIncomingSpeeds70, matching: find.byKey(GraduatedSpeedsCellBody.circledSpeedKey));
final burgdorfIncomingSpeeds70Circled =
find.ancestor(of: burgdorfIncomingSpeeds70, matching: find.byKey(GraduatedSpeedsCellBody.circledSpeedKey));
expect(burgdorfIncomingSpeeds70Circled, findsOneWidget);
final burgdorfOutgoingSpeeds = find.descendant(of: burgdorfStationRow, matching: find.byKey(GraduatedSpeedsCellBody.outgoingSpeedsKey));
final burgdorfOutgoingSpeeds =
find.descendant(of: burgdorfStationRow, matching: find.byKey(GraduatedSpeedsCellBody.outgoingSpeedsKey));
expect(burgdorfOutgoingSpeeds, findsOneWidget);
final burgdorfOutgoingSpeeds60 = find.descendant(of: burgdorfOutgoingSpeeds, matching: find.text('60'));
expect(burgdorfOutgoingSpeeds60, findsOneWidget);
final burgdorfOutgoingSpeeds60Squared = find.ancestor(of: burgdorfOutgoingSpeeds60, matching: find.byKey(GraduatedSpeedsCellBody.squaredSpeedKey));
final burgdorfOutgoingSpeeds60Squared =
find.ancestor(of: burgdorfOutgoingSpeeds60, matching: find.byKey(GraduatedSpeedsCellBody.squaredSpeedKey));
expect(burgdorfOutgoingSpeeds60Squared, findsOneWidget);

// check station speeds for Olten, no graduated speed for train series R

final oltenStationRow = findDASTableRowByText('Olten');
expect(oltenStationRow, findsOneWidget);
final oltenIncomingSpeeds = find.descendant(of: oltenStationRow, matching: find.byKey(GraduatedSpeedsCellBody.incomingSpeedsKey));
final oltenIncomingSpeeds =
find.descendant(of: oltenStationRow, matching: find.byKey(GraduatedSpeedsCellBody.incomingSpeedsKey));
expect(oltenIncomingSpeeds, findsOneWidget);
final oltenOutgoingSpeeds = find.descendant(of: oltenStationRow, matching: find.byKey(GraduatedSpeedsCellBody.outgoingSpeedsKey));
final oltenOutgoingSpeeds =
find.descendant(of: oltenStationRow, matching: find.byKey(GraduatedSpeedsCellBody.outgoingSpeedsKey));
expect(oltenOutgoingSpeeds, findsNothing);

});

testWidgets('find base value when no punctuality update comes', (tester) async {
// Load app widget.
await prepareAndStartApp(tester);

final trainNumberText = findTextFieldByLabel(l10n.p_train_selection_trainnumber_description);
expect(trainNumberText, findsOneWidget);

await enterText(tester, trainNumberText, 'T6');

final primaryButton = find.byWidgetPredicate((widget) => widget is SBBPrimaryButton).first;
await tester.tap(primaryButton);

// wait for train journey to load
await tester.pumpAndSettle();

//find the header and check if it is existent
final headerFinder = find.byType(Header);
expect(headerFinder, findsOneWidget);

//Find the text in the header
expect(find.descendant(of: headerFinder, matching: find.text('+00:00')), findsOneWidget);

await tester.pumpAndSettle();
});

testWidgets('check if the displayed current time is correct', (tester) async {
// Load app widget.
await prepareAndStartApp(tester);

//Select the correct train number
final trainNumberText = findTextFieldByLabel(l10n.p_train_selection_trainnumber_description);
expect(trainNumberText, findsOneWidget);

await enterText(tester, trainNumberText, 'T6');

//Log into the journey
final primaryButton = find.byWidgetPredicate((widget) => widget is SBBPrimaryButton).first;
await tester.tap(primaryButton);

// wait for train journey to load
await tester.pumpAndSettle();

//find the header and check if it is existent
final headerFinder = find.byType(Header);
expect(headerFinder, findsOneWidget);

final DateTime currentTime = DateTime.now();
final String currentHour = currentTime.hour <= 9 ? '0${currentTime.hour}' : (currentTime.hour).toString();
final String currentMinutes = currentTime.minute <= 9 ? '0${currentTime.minute}' : (currentTime.minute).toString();
final String currentSeconds = currentTime.second <= 9 ? '0${currentTime.second}' : (currentTime.second).toString();
final String nextSecond =
currentTime.second <= 9 ? '0${currentTime.second + 1}' : (currentTime.second + 1).toString();
final String currentWholeTime = '$currentHour:$currentMinutes:$currentSeconds';
final String nextSecondWholeTime = '$currentHour:$currentMinutes:$nextSecond';

if (!find.descendant(of: headerFinder, matching: find.text(currentWholeTime)).evaluate().isNotEmpty) {
expect(find.descendant(of: headerFinder, matching: find.text(nextSecondWholeTime)), findsOneWidget);
} else {
expect(find.descendant(of: headerFinder, matching: find.text(currentWholeTime)), findsOneWidget);
}

await tester.pumpAndSettle();
});
});
}

Expand Down
Empty file.
6 changes: 2 additions & 4 deletions das_client/integration_test/test/train_search_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import '../util/test_utils.dart';

void main() {
group('train search screen tests', () {

testWidgets('test default values', (tester) async {
// Load app widget.
await prepareAndStartApp(tester);
Expand Down Expand Up @@ -59,7 +58,6 @@ void main() {
// check that the primary button is disabled
final primaryButton = find.byWidgetPredicate((widget) => widget is SBBPrimaryButton).first;
expect(tester.widget<SBBPrimaryButton>(primaryButton).onPressed, isNull);

});

testWidgets('test can select yesterday', (tester) async {
Expand Down Expand Up @@ -116,7 +114,8 @@ void main() {
final sbbDatePickerFinder = find.byWidgetPredicate((widget) => widget is SBBDatePicker);
final yesterdayFinder = find.descendant(
of: sbbDatePickerFinder,
matching: find.byWidgetPredicate((widget) => widget is Text && widget.data == '${(dayBeforeYesterday.day)}.'));
matching:
find.byWidgetPredicate((widget) => widget is Text && widget.data == '${(dayBeforeYesterday.day)}.'));
await tapElement(tester, yesterdayFinder);

// tap outside dialog
Expand Down Expand Up @@ -154,6 +153,5 @@ void main() {
expect(find.text('${l10n.c_error_code}: ${ErrorCode.sferaJpUnavailable.code}'), findsOneWidget);
expect(find.text(l10n.c_error_sfera_jp_unavailable), findsOneWidget);
});

});
}
2 changes: 1 addition & 1 deletion das_client/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: d9dad56c0cd0b4fd8b4fe3034a53fd42a0b990f6

COCOAPODS: 1.16.1
COCOAPODS: 1.16.2
2 changes: 1 addition & 1 deletion das_client/l10n/strings_de.arb
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"c_error_sfera_handshake_rejected": "Server hat die Verbindung abgelehnt",
"c_error_sfera_request_timeout": "Timeout bei der Anfrage",
"c_error_sfera_jp_unavailable": "Fahrordnung nicht vorhanden",
"c_error_sfera_sp_invalid": "Unvollständige Daten erhalten",
"c_error_sfera_invalid": "Unvollständige Daten erhalten",
"c_connection_track_weiche": "Weiche",
"c_button_confirm": "Übernehmen"
}
2 changes: 1 addition & 1 deletion das_client/lib/app/bloc/train_journey_cubit.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'dart:async';

import 'package:das_client/app/model/ru.dart';
import 'package:das_client/app/model/train_journey_settings.dart';
import 'package:das_client/app/pages/journey/train_journey/widgets/table/config/train_journey_settings.dart';
import 'package:das_client/model/journey/break_series.dart';
import 'package:das_client/model/journey/journey.dart';
import 'package:das_client/sfera/sfera_component.dart';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import 'package:das_client/app/pages/journey/train_journey/widgets/header/header
import 'package:das_client/app/pages/journey/train_journey/widgets/train_journey.dart';
import 'package:flutter/material.dart';

// TODO: handle extraLarge font sizes (diff to figma) globally.
class TrainJourneyOverview extends StatelessWidget {
const TrainJourneyOverview({super.key});

Expand Down
Loading

0 comments on commit 14fa328

Please sign in to comment.