diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index 3071725..029d026 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -5,11 +5,13 @@ // gestures. You can also use WidgetTester to find child widgets in the widget // tree, read text, and verify that the values of widget properties are correct. +import 'dart:io'; + import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; -import 'package:flutter_app/main.dart' as app; +import 'package:flutter_app/main_test.dart' as app; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); @@ -17,21 +19,35 @@ void main() { } void _testMain() { - testWidgets('New profile pane smoke test', (WidgetTester tester) async { + testWidgets('Blocked message rejection test', (WidgetTester tester) async { + final String testerProfile = "mr roboto"; + final String blockedProfile = "rudey"; + + // start the app and render a few frames app.main(); + await tester.pump(); await tester.pump(); await tester.pump(); + //await tester.pumpAndSettle(); - await tester.pump(); - await tester.pump(); - await tester.pump(); - //await tester.pumpAndSettle(Duration(seconds: 3), EnginePhase.sendSemanticsUpdate, Duration(seconds: 30)); + for (var i = 0; i < 30; i++) { + print("$i pump"); + await tester.pump(); + } - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - await tester.pump(); - await tester.pump(); + // log in to a profile with a blocked contact + await tester.tap(find.text(testerProfile)); + await tester.pump(); await tester.pump(); await tester.pump(); + expect(find.byIcon(Icons.block), findsOneWidget); - // Verify that our counter has incremented. - // expect(find.text('0'), findsNothing); - expect(find.byKey(Key('addprofile')), findsOneWidget); + // use the debug control to inject a message from the contact + await tester.tap(find.byIcon(Icons.bug_report)); + await tester.pump(); await tester.pump(); await tester.pump(); + + + // screenshot test + print(Directory.current); + //Directory.current = "/home/erinn/AndroidStudioProjects/flwtch/integration_test"; + await expectLater(find.byKey(Key('app')), matchesGoldenFile('blockedcontact.png')); + // any active message badges? + expect(find.text('1'), findsNothing); }); } diff --git a/integration_test/blockedcontact.png b/integration_test/blockedcontact.png new file mode 100644 index 0000000..6a9feef Binary files /dev/null and b/integration_test/blockedcontact.png differ diff --git a/integration_test/failures/blockedcontact_isolatedDiff.png b/integration_test/failures/blockedcontact_isolatedDiff.png new file mode 100644 index 0000000..6dc7a98 Binary files /dev/null and b/integration_test/failures/blockedcontact_isolatedDiff.png differ diff --git a/integration_test/failures/blockedcontact_maskedDiff.png b/integration_test/failures/blockedcontact_maskedDiff.png new file mode 100644 index 0000000..440fb66 Binary files /dev/null and b/integration_test/failures/blockedcontact_maskedDiff.png differ diff --git a/integration_test/failures/blockedcontact_masterImage.png b/integration_test/failures/blockedcontact_masterImage.png new file mode 100644 index 0000000..6a9feef Binary files /dev/null and b/integration_test/failures/blockedcontact_masterImage.png differ diff --git a/integration_test/failures/blockedcontact_testImage.png b/integration_test/failures/blockedcontact_testImage.png new file mode 100644 index 0000000..98c4a29 Binary files /dev/null and b/integration_test/failures/blockedcontact_testImage.png differ diff --git a/lib/main.dart b/lib/main.dart index 3a259ed..5b94d7b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -80,6 +80,7 @@ class FlwtchState extends State { Provider.of(context).initPackageInfo(); return Consumer( builder: (context, opaque, child) => MaterialApp( + key: Key('app'), locale: Provider.of(context).locale, localizationsDelegates: AppLocalizations.localizationsDelegates, supportedLocales: AppLocalizations.supportedLocales, diff --git a/lib/main_test.dart b/lib/main_test.dart new file mode 100644 index 0000000..b62f734 --- /dev/null +++ b/lib/main_test.dart @@ -0,0 +1,71 @@ +import 'dart:convert'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_app/errorHandler.dart'; +import 'package:flutter_app/settings.dart'; +import 'licenses.dart'; +import 'main.dart'; +import 'opaque.dart'; + +import 'dart:convert'; +import 'dart:io'; +import 'dart:typed_data'; + +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:glob/glob.dart'; +import 'package:glob/list_local_fs.dart'; + +var globalSettings = Settings(Locale("en", ''), Opaque.dark); +var globalErrorHandler = ErrorHandler(); + +void main() { + LicenseRegistry.addLicense(() => licenses()); + DiskAssetBundle.loadGlob(['profiles/*.png']).then((assetBundle) { + runApp(DefaultAssetBundle( + bundle: assetBundle, + child: Flwtch(), + )); + }); +} + +class DiskAssetBundle extends CachingAssetBundle { + static const _assetManifestDotJson = 'AssetManifest.json'; + + /// Creates a [DiskAssetBundle] by loading [globs] of assets under `assets/`. + static Future loadGlob( + Iterable globs, { + String from = 'assets', + }) async { + final cache = {}; + for (final pattern in globs) { + await for (final path in Glob(pattern).list(root: from)) { + if (path is File) { + final bytes = await (path as File).readAsBytes() as Uint8List; + cache[path.path] = ByteData.view(bytes.buffer); + } + } + } + final manifest = >{}; + cache.forEach((key, _) { + manifest[key] = [key]; + }); + + cache[_assetManifestDotJson] = ByteData.view( + Uint8List.fromList(jsonEncode(manifest).codeUnits).buffer, + ); + + return DiskAssetBundle._(cache); + } + + final Map _cache; + + DiskAssetBundle._(this._cache); + + @override + Future load(String key) async { + return _cache[key]; + } +} \ No newline at end of file diff --git a/lib/views/contactsview.dart b/lib/views/contactsview.dart index 1792428..f51556b 100644 --- a/lib/views/contactsview.dart +++ b/lib/views/contactsview.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_app/widgets/contactrow.dart'; import 'package:provider/provider.dart'; +import '../main.dart'; import 'addcontactview.dart'; import '../model.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -23,6 +24,10 @@ class _ContactsViewState extends State { icon: Icon(Icons.copy), onPressed: _copyOnion, ), + IconButton( + icon: Icon(Icons.bug_report), + onPressed: _debugFakeMessage, + ) ], ), floatingActionButton: FloatingActionButton( @@ -63,4 +68,8 @@ class _ContactsViewState extends State { // Find the Scaffold in the widget tree and use it to show a SnackBar. ScaffoldMessenger.of(context).showSnackBar(snackBar); } + + void _debugFakeMessage() { + Provider.of(context, listen:false).contactList.getContact("44pknjvf4ju46nbuyn5getuayb6dj6z6zoppl56syn7pmscptoahlaid").unreadMessages++; + } } diff --git a/lib/views/messageview.dart b/lib/views/messageview.dart index b1e024f..6570ed5 100644 --- a/lib/views/messageview.dart +++ b/lib/views/messageview.dart @@ -93,11 +93,12 @@ class _MessageViewState extends State { child: Row( children: [ Expanded( - child: TextField( - controller: ctrlrCompose, - focusNode: focusNode, - textInputAction: TextInputAction.send, - onSubmitted: _sendMessage, + child: TextField( + key: Key('txtCompose'), + controller: ctrlrCompose, + focusNode: focusNode, + textInputAction: TextInputAction.send, + onSubmitted: _sendMessage, )), SizedBox( width: 90, diff --git a/pubspec.lock b/pubspec.lock index 78cf820..aa13d17 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -115,6 +115,13 @@ packages: description: flutter source: sdk version: "0.0.0" + glob: + dependency: "direct main" + description: + name: glob + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" http: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 3343752..691ce52 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -35,6 +35,7 @@ dependencies: ffi: ^1.0.0 path_provider: ^2.0.0 + glob: any # todo: flutter_driver causes version conflict. eg https://github.com/flutter/flutter/issues/44829 # testing-related deps integration_test: ^1.0.0 diff --git a/test/textfield_test.dart b/test/textfield_test.dart index 1b4a1e4..06d50cd 100644 --- a/test/textfield_test.dart +++ b/test/textfield_test.dart @@ -125,8 +125,10 @@ void main() { await tester.pumpAndSettle(); // empty string - formKey.currentState.validate(); + formKey.currentState.validate(); //(ctrlr1.clear() doesn't trigger validate like keypress does) await tester.pumpAndSettle(); await expectLater(find.byWidget(testHarness), matchesGoldenFile(file('form_final'))); + expect(find.text(strFail1), findsOneWidget); + expect(find.text(strFail2), findsNothing); }); }