tests: show fullscreen, info
This commit is contained in:
parent
8e13625192
commit
55c6209bee
7 changed files with 68 additions and 21 deletions
|
@ -186,7 +186,7 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
||||||
)),
|
)),
|
||||||
Builder(
|
Builder(
|
||||||
builder: (context) => PopupMenuButton<CollectionAction>(
|
builder: (context) => PopupMenuButton<CollectionAction>(
|
||||||
key: Key('menu-button'),
|
key: Key('appbar-menu-button'),
|
||||||
itemBuilder: (context) {
|
itemBuilder: (context) {
|
||||||
final hasSelection = collection.selection.isNotEmpty;
|
final hasSelection = collection.selection.isNotEmpty;
|
||||||
return [
|
return [
|
||||||
|
|
|
@ -499,6 +499,7 @@ class _FullscreenVerticalPageViewState extends State<FullscreenVerticalPageView>
|
||||||
child: child,
|
child: child,
|
||||||
),
|
),
|
||||||
child: PageView(
|
child: PageView(
|
||||||
|
key: Key('vertical-pageview'),
|
||||||
scrollDirection: Axis.vertical,
|
scrollDirection: Axis.vertical,
|
||||||
controller: widget.verticalPager,
|
controller: widget.verticalPager,
|
||||||
physics: PhotoViewPageViewScrollPhysics(parent: PageScrollPhysics()),
|
physics: PhotoViewPageViewScrollPhysics(parent: PageScrollPhysics()),
|
||||||
|
|
|
@ -37,6 +37,7 @@ class MultiImagePageState extends State<MultiImagePage> with AutomaticKeepAliveC
|
||||||
return PhotoViewGestureDetectorScope(
|
return PhotoViewGestureDetectorScope(
|
||||||
axis: [Axis.horizontal, Axis.vertical],
|
axis: [Axis.horizontal, Axis.vertical],
|
||||||
child: PageView.builder(
|
child: PageView.builder(
|
||||||
|
key: Key('horizontal-pageview'),
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
controller: widget.pageController,
|
controller: widget.pageController,
|
||||||
physics: PhotoViewPageViewScrollPhysics(parent: BouncingScrollPhysics()),
|
physics: PhotoViewPageViewScrollPhysics(parent: BouncingScrollPhysics()),
|
||||||
|
@ -45,6 +46,7 @@ class MultiImagePageState extends State<MultiImagePage> with AutomaticKeepAliveC
|
||||||
final entry = entries[index];
|
final entry = entries[index];
|
||||||
return ClipRect(
|
return ClipRect(
|
||||||
child: ImageView(
|
child: ImageView(
|
||||||
|
key: Key('imageview'),
|
||||||
entry: entry,
|
entry: entry,
|
||||||
heroTag: widget.collection.heroTag(entry),
|
heroTag: widget.collection.heroTag(entry),
|
||||||
onScaleChanged: widget.onScaleChanged,
|
onScaleChanged: widget.onScaleChanged,
|
||||||
|
|
|
@ -20,12 +20,13 @@ class ImageView extends StatelessWidget {
|
||||||
final List<Tuple2<String, IjkMediaController>> videoControllers;
|
final List<Tuple2<String, IjkMediaController>> videoControllers;
|
||||||
|
|
||||||
const ImageView({
|
const ImageView({
|
||||||
|
Key key,
|
||||||
this.entry,
|
this.entry,
|
||||||
this.heroTag,
|
this.heroTag,
|
||||||
this.onScaleChanged,
|
this.onScaleChanged,
|
||||||
this.onTap,
|
this.onTap,
|
||||||
this.videoControllers,
|
this.videoControllers,
|
||||||
});
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
|
@ -133,6 +133,7 @@ class _TopOverlayRow extends StatelessWidget {
|
||||||
OverlayButton(
|
OverlayButton(
|
||||||
scale: scale,
|
scale: scale,
|
||||||
child: PopupMenuButton<EntryAction>(
|
child: PopupMenuButton<EntryAction>(
|
||||||
|
key: Key('entry-menu-button'),
|
||||||
itemBuilder: (context) => [
|
itemBuilder: (context) => [
|
||||||
...inAppActions.map(_buildPopupMenuItem),
|
...inAppActions.map(_buildPopupMenuItem),
|
||||||
PopupMenuDivider(),
|
PopupMenuDivider(),
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:aves/model/source/enums.dart';
|
import 'package:aves/model/source/enums.dart';
|
||||||
import 'package:flutter_driver/flutter_driver.dart';
|
import 'package:flutter_driver/flutter_driver.dart';
|
||||||
import 'package:path/path.dart' as path;
|
import 'package:path/path.dart' as path;
|
||||||
|
@ -14,6 +12,7 @@ void main() {
|
||||||
FlutterDriver driver;
|
FlutterDriver driver;
|
||||||
|
|
||||||
setUpAll(() async {
|
setUpAll(() async {
|
||||||
|
print('adb=${[adb, ...adbDeviceParam].join(' ')}');
|
||||||
await copyContent(sourcePicturesDir, targetPicturesDir);
|
await copyContent(sourcePicturesDir, targetPicturesDir);
|
||||||
await grantPermissions('deckers.thibault.aves.debug', [
|
await grantPermissions('deckers.thibault.aves.debug', [
|
||||||
'android.permission.READ_EXTERNAL_STORAGE',
|
'android.permission.READ_EXTERNAL_STORAGE',
|
||||||
|
@ -30,8 +29,6 @@ void main() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
final appBarTitleFinder = find.byValueKey('appbar-title');
|
|
||||||
|
|
||||||
test('agree to terms and reach home', () async {
|
test('agree to terms and reach home', () async {
|
||||||
await driver.scroll(find.text('Terms of Service'), 0, -300, Duration(milliseconds: 500));
|
await driver.scroll(find.text('Terms of Service'), 0, -300, Duration(milliseconds: 500));
|
||||||
|
|
||||||
|
@ -39,16 +36,17 @@ void main() {
|
||||||
expect(await isEnabled(driver, buttonFinder), equals(false));
|
expect(await isEnabled(driver, buttonFinder), equals(false));
|
||||||
|
|
||||||
await driver.tap(find.byValueKey('agree-checkbox'));
|
await driver.tap(find.byValueKey('agree-checkbox'));
|
||||||
await driver.waitUntilNoTransientCallbacks();
|
await Future.delayed(Duration(seconds: 1));
|
||||||
expect(await isEnabled(driver, buttonFinder), equals(true));
|
expect(await isEnabled(driver, buttonFinder), equals(true));
|
||||||
|
|
||||||
await driver.tap(buttonFinder);
|
await driver.tap(buttonFinder);
|
||||||
await driver.waitUntilNoTransientCallbacks();
|
await driver.waitUntilNoTransientCallbacks();
|
||||||
expect(await driver.getText(appBarTitleFinder), 'Aves');
|
|
||||||
|
expect(await driver.getText(find.byValueKey('appbar-title')), 'Aves');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('sort and group', () async {
|
test('sort collection', () async {
|
||||||
await driver.tap(find.byValueKey('menu-button'));
|
await driver.tap(find.byValueKey('appbar-menu-button'));
|
||||||
await driver.waitUntilNoTransientCallbacks();
|
await driver.waitUntilNoTransientCallbacks();
|
||||||
|
|
||||||
await driver.tap(find.byValueKey('menu-sort'));
|
await driver.tap(find.byValueKey('menu-sort'));
|
||||||
|
@ -56,8 +54,10 @@ void main() {
|
||||||
|
|
||||||
await driver.tap(find.byValueKey(SortFactor.date.toString()));
|
await driver.tap(find.byValueKey(SortFactor.date.toString()));
|
||||||
await driver.tap(find.byValueKey('apply-button'));
|
await driver.tap(find.byValueKey('apply-button'));
|
||||||
|
});
|
||||||
|
|
||||||
await driver.tap(find.byValueKey('menu-button'));
|
test('group collection', () async {
|
||||||
|
await driver.tap(find.byValueKey('appbar-menu-button'));
|
||||||
await driver.waitUntilNoTransientCallbacks();
|
await driver.waitUntilNoTransientCallbacks();
|
||||||
|
|
||||||
await driver.tap(find.byValueKey('menu-group'));
|
await driver.tap(find.byValueKey('menu-group'));
|
||||||
|
@ -81,7 +81,32 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('show fullscreen', () async {
|
test('show fullscreen', () async {
|
||||||
sleep(Duration(seconds: 5));
|
await driver.tap(find.byType('DecoratedThumbnail'));
|
||||||
|
await driver.waitUntilNoTransientCallbacks();
|
||||||
|
await Future.delayed(Duration(seconds: 2));
|
||||||
|
|
||||||
|
final imageViewFinder = find.byValueKey('imageview');
|
||||||
|
|
||||||
|
print('* hide overlay');
|
||||||
|
await driver.tap(imageViewFinder);
|
||||||
|
await Future.delayed(Duration(seconds: 1));
|
||||||
|
|
||||||
|
print('* show overlay');
|
||||||
|
await driver.tap(imageViewFinder);
|
||||||
|
await Future.delayed(Duration(seconds: 1));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('show info', () async {
|
||||||
|
final verticalPageViewFinder = find.byValueKey('vertical-pageview');
|
||||||
|
|
||||||
|
print('* scroll to info');
|
||||||
|
await driver.scroll(verticalPageViewFinder, 0, -600, Duration(milliseconds: 400));
|
||||||
|
await Future.delayed(Duration(seconds: 1));
|
||||||
|
|
||||||
|
// TODO TLAD find.pageBack
|
||||||
|
// print('* back to image');
|
||||||
|
// await driver.tap(find.pageBack());
|
||||||
|
// await Future.delayed(Duration(seconds: 5));
|
||||||
});
|
});
|
||||||
}, timeout: Timeout(Duration(seconds: 10)));
|
}, timeout: Timeout(Duration(seconds: 10)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,18 +3,40 @@ import 'dart:io';
|
||||||
import 'package:flutter_driver/flutter_driver.dart';
|
import 'package:flutter_driver/flutter_driver.dart';
|
||||||
import 'package:path/path.dart' as path;
|
import 'package:path/path.dart' as path;
|
||||||
|
|
||||||
|
// conditions
|
||||||
|
|
||||||
|
Future<bool> isEnabled(FlutterDriver driver, SerializableFinder widgetFinder) async {
|
||||||
|
Map widgetDiagnostics = await driver.getWidgetDiagnostics(widgetFinder);
|
||||||
|
return widgetDiagnostics['properties'].firstWhere((property) => property['name'] == 'enabled')['value'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// ADB
|
||||||
|
|
||||||
String get adb {
|
String get adb {
|
||||||
final env = Platform.environment;
|
final env = Platform.environment;
|
||||||
final sdkDir = env['ANDROID_SDK_ROOT'] ?? env['ANDROID_SDK'];
|
final sdkDir = env['ANDROID_SDK_ROOT'] ?? env['ANDROID_SDK'];
|
||||||
return path.join(sdkDir, 'platform-tools', Platform.isWindows ? 'adb.exe' : 'adb');
|
return path.join(sdkDir, 'platform-tools', Platform.isWindows ? 'adb.exe' : 'adb');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
If there's only one emulator running or only one device connected,
|
||||||
|
the adb command is sent to that device by default.
|
||||||
|
If multiple emulators are running and/or multiple devices are attached,
|
||||||
|
you need to use the -d, -e, or -s option to specify the target device
|
||||||
|
to which the command should be directed.
|
||||||
|
*/
|
||||||
|
const List<String> adbDeviceParam = ['-e']; // '[-d]', '[-e]', or '[-s, <serial_number>]'
|
||||||
|
|
||||||
|
Future<void> runAdb(List<String> args) async {
|
||||||
|
await Process.runSync(adb, [...adbDeviceParam, ...args]);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> createDirectory(String dir) async {
|
Future<void> createDirectory(String dir) async {
|
||||||
await Process.run(adb, ['shell', 'mkdir -p', dir.replaceAll(' ', '\\ ')]);
|
await runAdb(['shell', 'mkdir -p', dir.replaceAll(' ', '\\ ')]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> removeDirectory(String dir) async {
|
Future<void> removeDirectory(String dir) async {
|
||||||
await Process.run(adb, ['shell', 'rm -r', dir.replaceAll(' ', '\\ ')]);
|
await runAdb(['shell', 'rm -r', dir.replaceAll(' ', '\\ ')]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> copyContent(String sourceDir, String targetDir) async {
|
Future<void> copyContent(String sourceDir, String targetDir) async {
|
||||||
|
@ -22,14 +44,9 @@ Future<void> copyContent(String sourceDir, String targetDir) async {
|
||||||
// `push source/* target/` works only when the target directory exists, and fails when `target` contains spaces
|
// `push source/* target/` works only when the target directory exists, and fails when `target` contains spaces
|
||||||
// `push source/ target/` works only when the target directory does not exist
|
// `push source/ target/` works only when the target directory does not exist
|
||||||
await removeDirectory(targetDir);
|
await removeDirectory(targetDir);
|
||||||
await Process.run(adb, ['push', sourceDir, targetDir]);
|
await runAdb(['push', sourceDir, targetDir]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> grantPermissions(String packageName, Iterable<String> permissions) async {
|
Future<void> grantPermissions(String packageName, Iterable<String> permissions) async {
|
||||||
await Future.forEach(permissions, (permission) => Process.run(adb, ['shell', 'pm', 'grant', packageName, permission]));
|
await Future.forEach(permissions, (permission) => runAdb(['shell', 'pm', 'grant', packageName, permission]));
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool> isEnabled(FlutterDriver driver, SerializableFinder widgetFinder) async {
|
|
||||||
Map widgetDiagnostics = await driver.getWidgetDiagnostics(widgetFinder);
|
|
||||||
return widgetDiagnostics['properties'].firstWhere((property) => property['name'] == 'enabled')['value'];
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue