diff --git a/lib/ui/app/forms/decorated_form_field.dart b/lib/ui/app/forms/decorated_form_field.dart new file mode 100644 index 000000000..1a0a3eb1d --- /dev/null +++ b/lib/ui/app/forms/decorated_form_field.dart @@ -0,0 +1,29 @@ +import 'package:flutter/material.dart'; + +class DecoratedFormField extends StatelessWidget { + const DecoratedFormField({ + @required this.controller, + @required this.label, + this.validator, + this.keyboardType, + }); + + final TextEditingController controller; + final String label; + final Function(String) validator; + final TextInputType keyboardType; + + @override + Widget build(BuildContext context) { + return TextFormField( + key: ValueKey(label), + autocorrect: false, + controller: controller, + decoration: InputDecoration( + labelText: label, + ), + validator: validator, + keyboardType: null, + ); + } +} diff --git a/lib/ui/client/client_screen.dart b/lib/ui/client/client_screen.dart index 4a75dc504..7821016c7 100644 --- a/lib/ui/client/client_screen.dart +++ b/lib/ui/client/client_screen.dart @@ -1,7 +1,6 @@ import 'package:invoiceninja_flutter/ui/app/app_scaffold.dart'; import 'package:invoiceninja_flutter/ui/app/list_filter.dart'; import 'package:invoiceninja_flutter/ui/app/list_filter_button.dart'; -import 'package:invoiceninja_flutter/utils/keys.dart'; import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/redux/app/app_state.dart'; import 'package:flutter/material.dart'; @@ -63,7 +62,6 @@ class ClientScreen extends StatelessWidget { ), floatingActionButton: user.canCreate(EntityType.client) ? FloatingActionButton( - key: Key(ClientKeys.fab), backgroundColor: Theme.of(context).primaryColorDark, onPressed: () => store.dispatch( EditClient(client: ClientEntity(), context: context)), diff --git a/lib/ui/client/edit/client_edit_details.dart b/lib/ui/client/edit/client_edit_details.dart index 8c1c05c86..420a894b9 100644 --- a/lib/ui/client/edit/client_edit_details.dart +++ b/lib/ui/client/edit/client_edit_details.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:invoiceninja_flutter/data/models/entities.dart'; import 'package:invoiceninja_flutter/ui/app/forms/custom_field.dart'; +import 'package:invoiceninja_flutter/ui/app/forms/decorated_form_field.dart'; import 'package:invoiceninja_flutter/ui/client/edit/client_edit_vm.dart'; import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/ui/app/form_card.dart'; @@ -95,44 +96,29 @@ class ClientEditDetailsState extends State { children: [ FormCard( children: [ - TextFormField( - autocorrect: false, + DecoratedFormField( + label: localization.name, controller: _nameController, - decoration: InputDecoration( - labelText: localization.name, - ), validator: (String val) => !viewModel.client.hasNameSet ? AppLocalization.of(context).pleaseEnterAClientOrContactName : null, ), - TextFormField( - autocorrect: false, + DecoratedFormField( + label: localization.idNumber, controller: _idNumberController, - decoration: InputDecoration( - labelText: localization.idNumber, - ), ), - TextFormField( - autocorrect: false, + DecoratedFormField( + label: localization.vatNumber, controller: _vatNumberController, - decoration: InputDecoration( - labelText: localization.vatNumber, - ), ), - TextFormField( - autocorrect: false, + DecoratedFormField( + label: localization.website, controller: _websiteController, - decoration: InputDecoration( - labelText: localization.website, - ), keyboardType: TextInputType.url, ), - TextFormField( - autocorrect: false, + DecoratedFormField( + label: localization.phone, controller: _phoneController, - decoration: InputDecoration( - labelText: localization.phone, - ), keyboardType: TextInputType.phone, ), CustomField( diff --git a/lib/utils/keys.dart b/lib/utils/keys.dart deleted file mode 100644 index ea5502cdc..000000000 --- a/lib/utils/keys.dart +++ /dev/null @@ -1,5 +0,0 @@ -class ClientKeys { - static const String screen = 'ClientScreen'; - static const String fab = 'clientFab'; - static const String drawer = 'clientDrawer'; -} \ No newline at end of file diff --git a/test_driver/clients_it_test.dart b/test_driver/clients_it_test.dart index 7ca4e90bc..a1b76a1c9 100644 --- a/test_driver/clients_it_test.dart +++ b/test_driver/clients_it_test.dart @@ -1,22 +1,27 @@ import 'package:flutter_driver/flutter_driver.dart'; import 'package:test/test.dart'; -import 'package:invoiceninja_flutter/utils/keys.dart'; - +import 'package:faker/faker.dart'; import 'utils/common_actions.dart'; import 'utils/localizations.dart'; void main() { - group('CLIENTS TEST', () { - + group('Client Tests', () { TestLocalization localization; FlutterDriver driver; + final name = makeUnique(faker.company.name()); + + final updatedName = makeUnique(faker.company.name()); + setUpAll(() async { localization = TestLocalization('en'); - driver = await FlutterDriver.connect(); - //await loginAndOpenClients(driver); + print('Login to app'); + await login(driver); + + print('View clients'); + viewSection(driver: driver, name: localization.clients); }); tearDownAll(() async { @@ -29,14 +34,71 @@ void main() { // Create an empty client test('Try to add an empty client', () async { - await driver.tap(find.byValueKey(ClientKeys.fab)); + print('Tap new client'); + await driver.tap(find.byTooltip(localization.newClient)); + print('Tap save'); await driver.tap(find.text(localization.save)); + print('Check for error'); await driver.waitFor(find.text(localization.pleaseEnterAClientOrContactName)); - await driver.tap(find.pageBack()); + if (await isMobile(driver)) { + print('Click back'); + await driver.tap(find.pageBack()); + await driver.waitFor(find.byTooltip(localization.newClient)); + } else { + print('Click cancel'); + await driver.tap(find.text(localization.cancel)); + } }); + // Create a new client + test('Add a new client', () async { + print('Tap new client'); + await driver.tap(find.byTooltip(localization.newClient)); + + print('Fill form: $name'); + await fillAndSaveForm(driver, { + localization.name: name, + }); + + if (await isMobile(driver)) { + print('Click back'); + await driver.tap(find.pageBack()); + await driver.waitFor(find.byTooltip(localization.newClient)); + } + }); + + // Edit the newly created client + test('Edit an existing client', () async { + if (await isMobile(driver)) { + print('Select client: $name'); + await driver.scrollUntilVisible( + find.byType('ListView'), find.text(name), + dyScroll: -300); + await driver.tap(find.text(name)); + } + + print('Tap edit'); + await driver.tap(find.text(localization.edit)); + + await fillAndSaveForm(driver, { + localization.name: updatedName, + }); + }); + + // Archive the edited client + test('Archieve/delete client test', () async { + await testArchiveAndDelete( + driver: driver, + archivedMessage: localization.archivedClient, + deletedMessage: localization.deletedClient, + restoredMessage: localization.restoredClient); + + if (await isMobile(driver)) { + await driver.tap(find.pageBack()); + } + }); }); }