Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: Attempt to fix flaky tests for Windows & Android #1441

Merged
merged 44 commits into from
Sep 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
7b4a3c8
test: increase timeout on complete (for Windows)
Gustl22 Mar 18, 2023
f030f81
Merge branch 'main' into gustl22/increase-timeout-windows
Gustl22 Mar 18, 2023
dee2b72
Revert "test: increase timeout on complete (for Windows)"
Gustl22 Mar 18, 2023
2db92c1
ci: take screenshot on failure and print as base64
Gustl22 Mar 18, 2023
0854965
ci: disable some tests for faster debugging
Gustl22 Mar 18, 2023
22c61fa
reenable controlsTab
Gustl22 Mar 18, 2023
9fed5ab
Merge branch 'main' into gustl22/increase-timeout-windows
Gustl22 Mar 20, 2023
1cde87b
test: reenable lib test, before app test
Gustl22 Mar 20, 2023
eab27fe
Merge branch 'main' into gustl22/increase-timeout-windows
Gustl22 Mar 20, 2023
0bfb592
use another screenshot api
Gustl22 Mar 20, 2023
51d26c4
Merge branch 'main' into gustl22/increase-timeout-windows
Gustl22 Apr 4, 2023
6252aa3
Merge branch 'main' into gustl22/increase-timeout-windows
Gustl22 Apr 5, 2023
5598359
Merge branch 'main' into gustl22/increase-timeout-windows
Gustl22 Apr 20, 2023
68b65a6
Merge branch 'main' into gustl22/increase-timeout-windows
Gustl22 May 14, 2023
ebae0c2
tests: decrease stop duration, increase timeout
Gustl22 May 24, 2023
11e8640
Merge branch 'main' into gustl22/increase-timeout-windows
Gustl22 May 24, 2023
2b69264
Merge branch 'main' into gustl22/increase-timeout-windows
Gustl22 May 24, 2023
5b31f71
revert screenshot feature
Gustl22 May 24, 2023
028e2d2
feat(windows): set same source twice
Gustl22 May 25, 2023
612b4db
revert timeout
Gustl22 May 25, 2023
b1517d6
feat(windows): set same source twice
Gustl22 May 25, 2023
dbfc405
fix: set same source twice
Gustl22 May 25, 2023
c341ab0
revert unrelated changes from other branch
Gustl22 May 25, 2023
53eb47c
Merge branch 'gustl22/fix-same-source' into gustl22/increase-timeout-…
Gustl22 May 25, 2023
9ec5864
add debug logs
Gustl22 May 25, 2023
e610199
ci: disable all irrelevant tests
Gustl22 May 25, 2023
4ad2324
Merge branch 'main' into gustl22/increase-timeout-windows
Gustl22 May 28, 2023
ce5e302
debug on android, too
Gustl22 May 28, 2023
ffec283
Merge branch 'main' into gustl22/increase-timeout-windows
Gustl22 Jun 14, 2023
2cc8e89
Merge branch 'main' into gustl22/increase-timeout-windows
Gustl22 Aug 31, 2023
8810790
Merge branch 'gustl22/increase-timeout-windows' of https://github.com…
Gustl22 Aug 31, 2023
7800ae4
disable android tests, reduce amount of players, disable getDuration
Gustl22 Aug 31, 2023
8172085
Add logs
Gustl22 Aug 31, 2023
7f14132
Avoid redundant logs
Gustl22 Aug 31, 2023
8c5daa4
Merge branch 'main' into gustl22/increase-timeout-windows
Gustl22 Sep 5, 2023
cdcbd26
add prints
Gustl22 Sep 5, 2023
beea434
test non strict position
Gustl22 Sep 5, 2023
be90a08
stop after testing position
Gustl22 Sep 7, 2023
524d0d0
remove debugging lines
Gustl22 Sep 7, 2023
242a08c
test short samples
Gustl22 Sep 7, 2023
7f3820b
test: exclude tests for android samples smaller than 1s
Gustl22 Sep 7, 2023
615afeb
Merge branch 'main' into gustl22/increase-timeout-windows
Gustl22 Sep 7, 2023
66fee38
attempt to fix null check
Gustl22 Sep 7, 2023
e6bf4d4
fix tests
Gustl22 Sep 7, 2023
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
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_test/flutter_test.dart';

import '../../platform_features.dart';
Expand All @@ -19,19 +19,19 @@ Future<void> testControlsTab(
await tester.pumpAndSettle();

// Sources take some time to get initialized
const timeout = Duration(seconds: 8);
const stopDuration = Duration(seconds: 5);

if (features.hasVolume) {
await tester.testVolume('0.5', timeout: timeout);
await tester.testVolume('0.0', timeout: timeout);
await tester.testVolume('1.0', timeout: timeout);
await tester.testVolume('0.5', stopDuration: stopDuration);
await tester.testVolume('0.0', stopDuration: stopDuration);
await tester.testVolume('1.0', stopDuration: stopDuration);
// No tests for volume > 1
}

if (features.hasBalance) {
await tester.testBalance('-1.0', timeout: timeout);
await tester.testBalance('1.0', timeout: timeout);
await tester.testBalance('0.0', timeout: timeout);
await tester.testBalance('-1.0', stopDuration: stopDuration);
await tester.testBalance('1.0', stopDuration: stopDuration);
await tester.testBalance('0.0', stopDuration: stopDuration);
}

if (features.hasPlaybackRate && !audioSourceTestData.isLiveStream) {
Expand All @@ -48,17 +48,15 @@ Future<void> testControlsTab(

// Linux cannot complete seek if duration is not present.
await tester.testSeek('0.5', isResume: false);
await tester.tap(find.byKey(const Key('streamsTab')));
await tester.pumpAndSettle();

if (isImmediateDurationSupported) {
await tester.testPosition(
Duration(seconds: audioSourceTestData.duration!.inSeconds ~/ 2),
matcher: greaterThanOrEqualTo,
);
}
await tester.tap(find.byKey(const Key('controlsTab')));
await tester.pumpAndSettle();
await tester.doInStreamsTab((tester) async {
if (isImmediateDurationSupported) {
await tester.testPosition(
Duration(seconds: audioSourceTestData.duration!.inSeconds ~/ 2),
matcher: (Object? value) =>
greaterThanOrEqualTo(value ?? Duration.zero),
);
}
});

await tester.pump(const Duration(seconds: 1));
await tester.testSeek('1.0');
Expand Down Expand Up @@ -100,9 +98,23 @@ Future<void> testControlsTab(

if (!audioSourceTestData.isLiveStream &&
audioSourceTestData.duration! < const Duration(seconds: 2)) {
if (features.hasReleaseModeLoop) {
final isAndroid =
!kIsWeb && defaultTargetPlatform == TargetPlatform.android;
// FIXME(gustl22): Android provides no position for samples shorter
// than 0.5 seconds.
if (features.hasReleaseModeLoop &&
!(isAndroid &&
audioSourceTestData.duration! < const Duration(seconds: 1))) {
await tester.testReleaseMode(ReleaseMode.loop);
await tester.pump(const Duration(seconds: 3));
// Check if sound has started playing.
await tester.doInStreamsTab((tester) async {
await tester.testPosition(
Duration.zero,
matcher: (Duration? position) =>
greaterThan(position ?? Duration.zero),
);
});
await tester.stop();
await tester.testReleaseMode(ReleaseMode.stop, isResume: false);
await tester.pumpAndSettle();
Expand All @@ -111,8 +123,11 @@ Future<void> testControlsTab(
if (features.hasReleaseModeRelease) {
await tester.testReleaseMode(ReleaseMode.release);
await tester.pump(const Duration(seconds: 3));
// No need to call stop, as it should be released by now
// TODO(Gustl22): test if source was released
// No need to call stop, as it should be released by now.
// Ensure source was released by checking `position == null`.
await tester.doInStreamsTab((tester) async {
await tester.testPosition(null);
});

// Reinitialize source
await tester.tap(find.byKey(const Key('sourcesTab')));
Expand Down Expand Up @@ -146,34 +161,34 @@ extension ControlsWidgetTester on WidgetTester {

Future<void> testVolume(
String volume, {
Duration timeout = const Duration(seconds: 1),
Duration stopDuration = const Duration(seconds: 1),
}) async {
printWithTimeOnFailure('Test Volume: $volume');
await scrollToAndTap(Key('control-volume-$volume'));
await resume();
await pump(timeout);
await pump(stopDuration);
await stop();
}

Future<void> testBalance(
String balance, {
Duration timeout = const Duration(seconds: 1),
Duration stopDuration = const Duration(seconds: 1),
}) async {
printWithTimeOnFailure('Test Balance: $balance');
await scrollToAndTap(Key('control-balance-$balance'));
await resume();
await pump(timeout);
await pump(stopDuration);
await stop();
}

Future<void> testRate(
String rate, {
Duration timeout = const Duration(seconds: 2),
Duration stopDuration = const Duration(seconds: 2),
}) async {
printWithTimeOnFailure('Test Rate: $rate');
await scrollToAndTap(Key('control-rate-$rate'));
await resume();
await pump(timeout);
await pump(stopDuration);
await stop();
}

Expand Down Expand Up @@ -223,4 +238,16 @@ extension ControlsWidgetTester on WidgetTester {
await resume();
}
}

Future<void> doInStreamsTab(
Future<void> Function(WidgetTester tester) foo,
) async {
await tap(find.byKey(const Key('streamsTab')));
await pump();

await foo(this);

await tap(find.byKey(const Key('controlsTab')));
await pump();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ extension PropertiesWidgetTester on WidgetTester {
}

Future<void> testPosition(
Duration position, {
Matcher Function(Duration) matcher = equals,
Duration? position, {
Matcher Function(Duration?) matcher = equals,
Duration timeout = const Duration(seconds: 4),
}) async {
printWithTimeOnFailure('Test Position: $position');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Future<void> testStreamsTab(
if (features.hasPositionEvent) {
await tester.testPosition(
Duration.zero,
matcher: greaterThan,
matcher: (Duration? position) => greaterThan(position ?? Duration.zero),
timeout: timeout,
);
await tester.testOnPosition(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:flutter_test/flutter_test.dart';

extension LibWidgetTester on WidgetTester {
Future<void> pumpLinux() async {
if (!kIsWeb && Platform.isLinux) {
if (!kIsWeb && defaultTargetPlatform == TargetPlatform.linux) {
// FIXME(gustl22): Linux needs additional pump (#1556)
await pump();
}
Expand Down
4 changes: 1 addition & 3 deletions packages/audioplayers/example/integration_test/lib_test.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import 'dart:io';

import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_test/flutter_test.dart';
Expand All @@ -13,7 +11,7 @@ import 'test_utils.dart';
void main() async {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
final features = PlatformFeatures.instance();
final isAndroid = !kIsWeb && Platform.isAndroid;
final isAndroid = !kIsWeb && defaultTargetPlatform == TargetPlatform.android;
final audioTestDataList = await getAudioTestDataList();

group('play multiple sources', () {
Expand Down
60 changes: 36 additions & 24 deletions packages/audioplayers/example/integration_test/platform_test.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'dart:async';
import 'dart:io';

import 'package:audioplayers/audioplayers.dart';
import 'package:audioplayers_platform_interface/audioplayers_platform_interface.dart';
Expand All @@ -16,7 +15,8 @@ import 'test_utils.dart';
void main() async {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
final features = PlatformFeatures.instance();
final isLinux = !kIsWeb && Platform.isLinux;
final isLinux = !kIsWeb && defaultTargetPlatform == TargetPlatform.linux;
final isAndroid = !kIsWeb && defaultTargetPlatform == TargetPlatform.android;
final audioTestDataList = await getAudioTestDataList();

group('Platform method channel', () {
Expand Down Expand Up @@ -352,30 +352,42 @@ void main() async {
}

for (final td in audioTestDataList) {
if (features.hasPositionEvent &&
(td.isLiveStream || td.duration! > const Duration(seconds: 2))) {
testWidgets('#positionEvent ${td.source}', (tester) async {
await tester.prepareSource(
playerId: playerId,
platform: platform,
testData: td,
);
if (features.hasPositionEvent) {
testWidgets(
'#positionEvent ${td.source}',
(tester) async {
await tester.prepareSource(
playerId: playerId,
platform: platform,
testData: td,
);

final eventStream = platform.getEventStream(playerId);
Duration? position;
final onPositionSub = eventStream
.where((event) => event.eventType == AudioEventType.position)
.listen(
(event) => position = event.position,
);
final eventStream = platform.getEventStream(playerId);
Duration? position;
final onPositionSub = eventStream.where(
(event) {
return event.eventType == AudioEventType.position &&
event.position != null &&
event.position! > Duration.zero;
},
).listen(
(event) => position = event.position,
);

await platform.resume(playerId);
await tester.pumpAndSettle(const Duration(seconds: 1));
expect(position, greaterThan(Duration.zero));
await platform.stop(playerId);
await onPositionSub.cancel();
await tester.pumpLinux();
});
await platform.resume(playerId);
await tester.pumpAndSettle(const Duration(seconds: 1));
expect(position, isNotNull);
expect(position, greaterThan(Duration.zero));
await platform.stop(playerId);
await onPositionSub.cancel();
await tester.pumpLinux();
},
// FIXME(gustl22): Android provides no position for samples shorter
// than 0.5 seconds.
skip: isAndroid &&
!td.isLiveStream &&
td.duration! < const Duration(seconds: 1),
);
}
}

Expand Down