Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions lib/constants.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import 'dart:core';

const instrumentsScreenTitleKey = 'instruments_screen_title';
const accelerometerScreenTitleKey = 'accelerometer_screen_title';
const powerSourceScreenTitleKey = 'power_source_screen_title';
const multimeterScreenTitleKey = 'multimeter_screen_title';
const waveGeneratorScreenTitleKey = 'wave_generator_screen_title';
const oscilloscopeScreenTitleKey = 'oscilloscope_screen_title';

List<String> instrumentHeadings = [
'OSCILLOSCOPE',
'MULTIMETER',
Expand Down
6 changes: 3 additions & 3 deletions lib/providers/accelerometer_state_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ class AccelerometerStateProvider extends ChangeNotifier {
final List<double> _yData = [];
final List<double> _zData = [];

final List<FlSpot> xData = [];
final List<FlSpot> yData = [];
final List<FlSpot> zData = [];
final List<FlSpot> xData = [const FlSpot(0, 0)];
final List<FlSpot> yData = [const FlSpot(0, 0)];
final List<FlSpot> zData = [const FlSpot(0, 0)];

final int _maxLength = 50;
double _xMin = 0, _xMax = 0;
Expand Down
3 changes: 2 additions & 1 deletion lib/view/accelerometer_screen.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:pslab/constants.dart';
import 'package:pslab/l10n/app_localizations.dart';
import 'package:pslab/providers/locator.dart';
import 'package:pslab/view/widgets/guide_widget.dart';
Expand All @@ -11,7 +12,6 @@ import 'package:pslab/view/logged_data_screen.dart';

import '../providers/accelerometer_config_provider.dart';
import '../theme/colors.dart';
import '../constants.dart';
import 'accelerometer_config_screen.dart';

class AccelerometerScreen extends StatefulWidget {
Expand Down Expand Up @@ -229,6 +229,7 @@ class _AccelerometerScreenState extends State<AccelerometerScreen> {
builder: (context, provider, child) {
return CommonScaffold(
title: appLocalizations.accelerometerTitle,
key: const Key(accelerometerScreenTitleKey),
onGuidePressed: _showInstrumentGuide,
onOptionsPressed: _showOptionsMenu,
onRecordPressed: _toggleRecording,
Expand Down
3 changes: 1 addition & 2 deletions lib/view/instruments_screen.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:pslab/constants.dart';
import 'package:pslab/l10n/app_localizations.dart';
import 'package:pslab/providers/locator.dart';
Expand Down Expand Up @@ -253,7 +252,6 @@ class _InstrumentsScreenState extends State<InstrumentsScreen> {
_setOrientation();
SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
});
Permission.microphone.request();
}

void _setOrientation() {
Expand All @@ -267,6 +265,7 @@ class _InstrumentsScreenState extends State<InstrumentsScreen> {
Widget build(BuildContext context) {
return MainScaffold(
index: 0,
scaffoldKey: const Key(instrumentsScreenTitleKey),
title: appLocalizations.instrumentsTitle,
showSearch: true,
onSearchChanged: _filterInstruments,
Expand Down
2 changes: 2 additions & 0 deletions lib/view/multimeter_screen.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:pslab/constants.dart';
import 'package:pslab/l10n/app_localizations.dart';
import 'package:pslab/providers/locator.dart';
import 'package:pslab/providers/multimeter_state_provider.dart';
Expand Down Expand Up @@ -47,6 +48,7 @@ class _MultimeterScreenState extends State<MultimeterScreen> {
children: [
CommonScaffold(
title: appLocalizations.multimeterTitle,
key: const Key(multimeterScreenTitleKey),
body: SafeArea(
child: LayoutBuilder(
builder: (context, constraints) {
Expand Down
2 changes: 2 additions & 0 deletions lib/view/oscilloscope_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import 'package:pslab/communication/science_lab.dart';
import 'package:pslab/constants.dart';
import 'package:pslab/l10n/app_localizations.dart';
import 'package:pslab/providers/locator.dart';
import 'package:pslab/view/widgets/channel_parameters_widget.dart';
Expand Down Expand Up @@ -117,6 +118,7 @@ class _OscilloscopeScreenState extends State<OscilloscopeScreen> {
children: [
CommonScaffold(
title: appLocalizations.oscilloscope,
key: const Key(oscilloscopeScreenTitleKey),
body: SafeArea(
minimum: const EdgeInsets.only(right: 0, bottom: 0),
child: LayoutBuilder(
Expand Down
2 changes: 2 additions & 0 deletions lib/view/power_source_screen.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:pslab/constants.dart';
import 'package:pslab/l10n/app_localizations.dart';
import 'package:pslab/providers/locator.dart';
import 'package:pslab/providers/power_source_state_provider.dart';
Expand Down Expand Up @@ -492,6 +493,7 @@ class _PowerSourceScreenState extends State<PowerSourceScreen> {
children: [
CommonScaffold(
title: appLocalizations.powerSourceTitle,
key: const Key(powerSourceScreenTitleKey),
body: ScrollConfiguration(
behavior: ScrollBehavior(),
child: LayoutBuilder(
Expand Down
2 changes: 2 additions & 0 deletions lib/view/wave_generator_screen.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:pslab/communication/science_lab.dart';
import 'package:pslab/constants.dart';
import 'package:pslab/l10n/app_localizations.dart';
import 'package:pslab/providers/locator.dart';
import 'package:pslab/providers/wave_generator_state_provider.dart';
Expand Down Expand Up @@ -81,6 +82,7 @@ class _WaveGeneratorScreenState extends State<WaveGeneratorScreen> {
children: [
CommonScaffold(
title: appLocalizations.waveGenerator,
key: const Key(waveGeneratorScreenTitleKey),
body: SafeArea(
child: Container(
margin:
Expand Down
4 changes: 3 additions & 1 deletion lib/view/widgets/channel_parameters_widget.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';
import 'package:pslab/l10n/app_localizations.dart';
import 'package:pslab/providers/locator.dart';
Expand Down Expand Up @@ -246,7 +247,8 @@ class _ChannelParametersState extends State<ChannelParametersWidget> {
RadioGroup(
groupValue:
oscilloscopeStateProvider.isInBuiltMICSelected,
onChanged: (bool? value) {
onChanged: (bool? value) async {
await Permission.microphone.request();
setState(
() {
if (value == null) {
Expand Down
2 changes: 1 addition & 1 deletion lib/view/widgets/main_scaffold_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ class _MainScaffoldState extends State<MainScaffold>
cursorColor: appBarContentColor,
)
: Text(
key: ValueKey('title_${widget.title}'),
key: widget.scaffoldKey,
widget.title,
style: TextStyle(
color: appBarContentColor,
Expand Down
2 changes: 2 additions & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,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
Expand Down
150 changes: 150 additions & 0 deletions test_integration/screenshots.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:pslab/constants.dart';
import 'package:pslab/main.dart' as app;
import 'utils.dart';

void main() async {
final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized();
setUpAll(() {
return Future(() async {
WidgetsApp.debugAllowBannerOverride = false; // Hide the debug banner
if (Platform.isAndroid) {
await binding.convertFlutterSurfaceToImage();
}
});
});

group('E2E Group', () {
testWidgets('Take Screenshots', (tester) async {
app.main();
await tester.pumpAndSettle();

final instrumentsScreenTitle =
find.byKey(const ValueKey(instrumentsScreenTitleKey));
final powerSourceScreenTitle =
find.byKey(const ValueKey(powerSourceScreenTitleKey));
final multimeterScreenTitle =
find.byKey(const ValueKey(multimeterScreenTitleKey));
final waveGeneratorScreenTitle =
find.byKey(const ValueKey(waveGeneratorScreenTitleKey));
final oscilloscopeScreenTitle =
find.byKey(const ValueKey(oscilloscopeScreenTitleKey));

final notConnectedText = find.text('Not Connected');
final backButton = find.byIcon(Icons.arrow_back);

await pumpUntilFound(tester, instrumentsScreenTitle);
await binding.takeScreenshot('1_instruments_screen');

ScaffoldState state = tester.firstState(find.byType(Scaffold));
state.openDrawer();
await pumpUntilFound(tester, notConnectedText);
await tester.pump(const Duration(seconds: 5));
await tester.pumpAndSettle();
await tester.pump(const Duration(seconds: 5));
await tester.pumpAndSettle();
await binding.takeScreenshot('2_nav_drawer');

state.closeDrawer();
await pumpUntilFound(tester, instrumentsScreenTitle);
await tester.pumpAndSettle();

final accelerometerCard = find.text('ACCELEROMETER');
await tester.scrollUntilVisible(
accelerometerCard,
200.0,
scrollable: find.byType(Scrollable),
);
await tester.pumpAndSettle();
await tester.tap(accelerometerCard);
await tester.pump(const Duration(seconds: 5));

final infoIcon = find.byIcon(Icons.info);
await tester.tap(infoIcon);
await tester.pump(const Duration(seconds: 5));
await binding.takeScreenshot('3_accelerometer');

final hideGuideText = find.text('Hide Guide');
await tester.tap(hideGuideText);
await tester.pump(const Duration(seconds: 5));

await tester.tap(backButton);
await pumpUntilFound(tester, instrumentsScreenTitle);

final powerSourceCard = find.text('POWER SOURCE');
await tester.scrollUntilVisible(
powerSourceCard,
200.0,
scrollable: find.byType(Scrollable),
);
await tester.pumpAndSettle();
await tester.tap(powerSourceCard);
await pumpUntilFound(tester, powerSourceScreenTitle);
await tester.pump(const Duration(seconds: 5));
await tester.pumpAndSettle();
await tester.pump(const Duration(seconds: 5));
await tester.pumpAndSettle();
await binding.takeScreenshot('4_power_source');

await tester.tap(backButton);
await pumpUntilFound(tester, instrumentsScreenTitle);

final multimeterCard = find.text('MULTIMETER');
await tester.scrollUntilVisible(
multimeterCard,
200.0,
scrollable: find.byType(Scrollable),
);
await tester.pumpAndSettle();
await tester.tap(multimeterCard);
await pumpUntilFound(tester, multimeterScreenTitle);
await tester.pump(const Duration(seconds: 5));
await tester.pumpAndSettle();
await tester.pump(const Duration(seconds: 5));
await tester.pumpAndSettle();
await binding.takeScreenshot('5_multimeter');

await tester.tap(backButton);
await pumpUntilFound(tester, instrumentsScreenTitle);

final waveGeneratorCard = find.text('WAVE GENERATOR');
await tester.scrollUntilVisible(
waveGeneratorCard,
200.0,
scrollable: find.byType(Scrollable),
);
await tester.pumpAndSettle();
await tester.tap(waveGeneratorCard);
await pumpUntilFound(tester, waveGeneratorScreenTitle);

final freqText = find.text('Freq');
await tester.tap(freqText);
await tester.pump(const Duration(seconds: 5));
await tester.pumpAndSettle();
await tester.pump(const Duration(seconds: 5));
await tester.pumpAndSettle();
await binding.takeScreenshot('6_wave_generator');

await tester.tap(backButton);
await pumpUntilFound(tester, instrumentsScreenTitle);

final oscilloscopeCard = find.text('OSCILLOSCOPE');
await tester.scrollUntilVisible(
oscilloscopeCard,
200.0,
scrollable: find.byType(Scrollable),
);
await tester.pumpAndSettle();
await tester.tap(oscilloscopeCard);
await pumpUntilFound(tester, oscilloscopeScreenTitle);
await tester.pump(const Duration(seconds: 5));
await tester.pumpAndSettle();
await tester.pump(const Duration(seconds: 5));
await tester.pumpAndSettle();
await binding.takeScreenshot('7_oscilloscope');
});
});
}
20 changes: 20 additions & 0 deletions test_integration/test_driver.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// ignore_for_file: avoid_print

import 'dart:io';
import 'package:integration_test/integration_test_driver_extended.dart';

Future<void> main() async {
final deviceName = Platform.environment['DEVICE_NAME'] ?? 'unknown_device';
final formattedDeviceName = deviceName.replaceAll(RegExp(r'\s+'), '_');
await integrationDriver(
onScreenshot: (String screenshotName, List<int> screenshotBytes,
[Map<String, Object?>? args]) async {
final filePath = 'screenshots/$formattedDeviceName-$screenshotName.png';
print('Writing screenshot to $filePath');

final File image = await File(filePath).create(recursive: true);
image.writeAsBytesSync(screenshotBytes);
return true;
},
);
}
21 changes: 21 additions & 0 deletions test_integration/utils.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import 'dart:async';

import 'package:flutter_test/flutter_test.dart';

Future<void> pumpUntilFound(
WidgetTester tester,
Finder finder, {
Duration timeout = const Duration(seconds: 10),
}) async {
bool timerDone = false;
final timer = Timer(timeout, () => timerDone = true);
while (timerDone != true) {
await tester.pumpAndSettle();

final found = tester.any(finder);
if (found) {
timerDone = true;
}
}
timer.cancel();
}
Loading