diff --git a/README.md b/README.md index 0848423f0..829c1b869 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,7 @@ The architecture is based off these two projects: - Press "Register App" button. - Download "google-services.json" and put it in `android/app` directory. - Run `flutter run` while you have a device connected to the computer or an emulator running and now you can run it. +- Run `flutter drive --target=test_driver/products_it.dart` to run the tests ## Contributions diff --git a/lib/redux/auth/auth_middleware.dart b/lib/redux/auth/auth_middleware.dart index 6a077493c..4a39359e3 100644 --- a/lib/redux/auth/auth_middleware.dart +++ b/lib/redux/auth/auth_middleware.dart @@ -38,11 +38,11 @@ void _saveAuthLocal(dynamic action) async { void _loadAuthLocal(Store store, dynamic action) async { final SharedPreferences prefs = await SharedPreferences.getInstance(); - final String email = prefs.getString(kSharedPrefEmail) ?? Config.LOGIN_EMAIL; + final String email = prefs.getString(kSharedPrefEmail) ?? ''; final String url = - formatApiUrlMachine(prefs.getString(kSharedPrefUrl) ?? Config.LOGIN_URL); + formatApiUrlMachine(prefs.getString(kSharedPrefUrl) ?? ''); final String secret = - prefs.getString(kSharedPrefSecret) ?? Config.LOGIN_SECRET; + prefs.getString(kSharedPrefSecret) ?? ''; store.dispatch(UserLoginLoaded(email, url, secret)); final bool enableDarkMode = prefs.getBool(kSharedPrefEnableDarkMode) ?? false; @@ -136,7 +136,7 @@ Middleware _createRefreshRequest(AuthRepository repository) { final SharedPreferences prefs = await SharedPreferences.getInstance(); final String url = formatApiUrlMachine( - prefs.getString(kSharedPrefUrl) ?? Config.LOGIN_URL); + prefs.getString(kSharedPrefUrl) ?? Config.TEST_URL); final String token = prefs.getString(getKeychainTokenKey()); repository diff --git a/lib/ui/auth/login_view.dart b/lib/ui/auth/login_view.dart index 860ccf281..9c6b8d352 100644 --- a/lib/ui/auth/login_view.dart +++ b/lib/ui/auth/login_view.dart @@ -31,12 +31,12 @@ class _LoginState extends State { static const String OTP_ERROR = 'OTP_REQUIRED'; - static final ValueKey _emailKey = Key(LoginKeys.emailKeyString); - static final ValueKey _passwordKey = Key(LoginKeys.passwordKeyString); - static final ValueKey _urlKey = Key(LoginKeys.urlKeyString); - static final ValueKey _secretKey = Key(LoginKeys.secretKeyString); + static final ValueKey _emailKey = Key(LoginKeys.email); + static final ValueKey _passwordKey = Key(LoginKeys.password); + static final ValueKey _urlKey = Key(LoginKeys.url); + static final ValueKey _secretKey = Key(LoginKeys.secret); static final ValueKey _oneTimePasswordKey = - Key(LoginKeys.oneTimePasswordKeyString); + Key(LoginKeys.oneTimePassword); final FocusNode _focusNode1 = new FocusNode(); @@ -227,6 +227,7 @@ class _LoginState extends State { setState(() => _isSelfHosted = false), child: Text(localization.hostedLogin)) : FlatButton( + key: Key(LoginKeys.loginSelfHost), onPressed: () => setState(() => _isSelfHosted = true), child: Text(localization.selfhostLogin)), diff --git a/lib/ui/product/edit/product_edit.dart b/lib/ui/product/edit/product_edit.dart index 150003d28..7e00ed905 100644 --- a/lib/ui/product/edit/product_edit.dart +++ b/lib/ui/product/edit/product_edit.dart @@ -148,7 +148,7 @@ class _ProductEditState extends State { FormCard( children: [ TextFormField( - key: Key(ProductKeys.productEditProductFieldKeyString), + key: Key(ProductKeys.productKey), controller: _productKeyController, autocorrect: false, decoration: InputDecoration( @@ -160,7 +160,7 @@ class _ProductEditState extends State { autovalidate: autoValidate, ), TextFormField( - key: Key(ProductKeys.productEditNotesFieldKeyString), + key: Key(ProductKeys.notes), controller: _notesController, maxLines: 4, decoration: InputDecoration( @@ -182,7 +182,7 @@ class _ProductEditState extends State { company.getCustomFieldValues(CustomFieldType.product2), ), TextFormField( - key: Key(ProductKeys.productEditCostFieldKeyString), + key: Key(ProductKeys.cost), controller: _costController, keyboardType: TextInputType.number, decoration: InputDecoration( diff --git a/lib/ui/product/product_screen.dart b/lib/ui/product/product_screen.dart index d37a3406f..f41d6726b 100644 --- a/lib/ui/product/product_screen.dart +++ b/lib/ui/product/product_screen.dart @@ -69,7 +69,7 @@ class ProductScreen extends StatelessWidget { floatingActionButtonLocation: FloatingActionButtonLocation.endDocked, floatingActionButton: user.canCreate(EntityType.product) ? FloatingActionButton( - key: Key(ProductKeys.productScreenFABKeyString), + key: Key(ProductKeys.fab), backgroundColor: Theme.of(context).primaryColorDark, onPressed: () { store.dispatch( diff --git a/lib/utils/keys.dart b/lib/utils/keys.dart index 18f8a8219..311038dd9 100644 --- a/lib/utils/keys.dart +++ b/lib/utils/keys.dart @@ -1,16 +1,15 @@ -// Keys for Login Screen class LoginKeys { - static const String emailKeyString = 'loginEmail'; - static const String passwordKeyString = 'loginPassword'; - static const String urlKeyString = 'loginUrl'; - static const String secretKeyString = 'loginSecret'; - static const String oneTimePasswordKeyString = 'loginOneTimePassword'; + static const String email = 'loginEmail'; + static const String password = 'loginPassword'; + static const String url = 'loginUrl'; + static const String loginSelfHost = 'loginSelfHost'; + static const String secret = 'loginSecret'; + static const String oneTimePassword = 'loginOneTimePassword'; } -// Keys for Product Screen class ProductKeys { - static const String productScreenFABKeyString = 'productScreenFAB'; - static const String productEditProductFieldKeyString = 'productEditProductField'; - static const String productEditNotesFieldKeyString = 'productEditNotesField'; - static const String productEditCostFieldKeyString = 'productEditCostField'; + static const String fab = 'productFab'; + static const String productKey = 'productKey'; + static const String notes = 'productNotes'; + static const String cost = 'productCost'; } \ No newline at end of file diff --git a/test_driver/login_it_test.dart b/test_driver/login_it_test.dart index 0767b4274..f90d19a8a 100644 --- a/test_driver/login_it_test.dart +++ b/test_driver/login_it_test.dart @@ -14,10 +14,10 @@ void main() { driver = await FlutterDriver.connect(); // read config file - loginEmail = Config.LOGIN_EMAIL; - loginPassword = Config.LOGIN_PASSWORD; - loginUrl = Config.LOGIN_URL; - loginSecret = Config.LOGIN_SECRET; + loginEmail = Config.TEST_EMAIL; + loginPassword = Config.TEST_PASSWORD; + loginUrl = Config.TEST_URL; + loginSecret = Config.TEST_SECRET; }); tearDown(() async { @@ -28,16 +28,16 @@ void main() { test('No input provided by user test', () async { - await driver.tap(find.byValueKey(LoginKeys.emailKeyString)); + await driver.tap(find.byValueKey(LoginKeys.email)); await driver.enterText(''); - await driver.tap(find.byValueKey(LoginKeys.passwordKeyString)); + await driver.tap(find.byValueKey(LoginKeys.password)); await driver.enterText(''); - await driver.tap(find.byValueKey(LoginKeys.urlKeyString)); + await driver.tap(find.byValueKey(LoginKeys.url)); await driver.enterText(''); - await driver.tap(find.byValueKey(LoginKeys.secretKeyString)); + await driver.tap(find.byValueKey(LoginKeys.secret)); await driver.enterText(''); await driver.tap(find.text('LOGIN')); @@ -47,16 +47,16 @@ void main() { test('Details filled by user and login', () async { - await driver.tap(find.byValueKey(LoginKeys.emailKeyString)); + await driver.tap(find.byValueKey(LoginKeys.email)); await driver.enterText(loginEmail); - await driver.tap(find.byValueKey(LoginKeys.passwordKeyString)); + await driver.tap(find.byValueKey(LoginKeys.password)); await driver.enterText(loginPassword); - await driver.tap(find.byValueKey(LoginKeys.urlKeyString)); + await driver.tap(find.byValueKey(LoginKeys.url)); await driver.enterText(loginUrl); - await driver.tap(find.byValueKey(LoginKeys.secretKeyString)); + await driver.tap(find.byValueKey(LoginKeys.secret)); await driver.enterText(loginSecret); await driver.tap(find.text('LOGIN')); diff --git a/test_driver/products_it_test.dart b/test_driver/products_it_test.dart index f34e51b72..2f9744b15 100644 --- a/test_driver/products_it_test.dart +++ b/test_driver/products_it_test.dart @@ -46,10 +46,10 @@ void main() { driver = await FlutterDriver.connect(); // read config file - loginEmail = Config.LOGIN_EMAIL; - loginPassword = Config.LOGIN_PASSWORD; - loginUrl = Config.LOGIN_URL; - loginSecret = Config.LOGIN_SECRET; + loginEmail = Config.TEST_EMAIL; + loginPassword = Config.TEST_PASSWORD; + loginUrl = Config.TEST_URL; + loginSecret = Config.TEST_SECRET; }); tearDown(() async { @@ -60,18 +60,19 @@ void main() { // Login into the app with details from .env.dart test('Login into the app and switch to products screen', () async { - - await driver.tap(find.byValueKey(LoginKeys.emailKeyString), timeout: new Duration(seconds: 60)); + + await driver.tap(find.byValueKey(LoginKeys.loginSelfHost)); + await driver.tap(find.byValueKey(LoginKeys.email), timeout: new Duration(seconds: 60)); await driver.enterText(loginEmail); - await driver.tap(find.byValueKey(LoginKeys.passwordKeyString)); + await driver.tap(find.byValueKey(LoginKeys.password)); await driver.enterText(loginPassword); - await driver.tap(find.byValueKey(LoginKeys.urlKeyString)); + await driver.tap(find.byValueKey(LoginKeys.url)); await driver.enterText(loginUrl); - await driver.tap(find.byValueKey(LoginKeys.secretKeyString)); + await driver.tap(find.byValueKey(LoginKeys.secret)); await driver.enterText(loginSecret); await driver.tap(find.text(Constants.loginButton)); - await driver.waitUntilNoTransientCallbacks(); + await driver.waitUntilNoTransientCallbacks(timeout: Duration(minutes: 1)); await driver.waitFor(find.byType(Constants.dashboardScreen)); @@ -89,13 +90,13 @@ void main() { // Create a new product test('Add a new product', () async { - await driver.tap(find.byValueKey(ProductKeys.productScreenFABKeyString)); + await driver.tap(find.byValueKey(ProductKeys.fab)); - await driver.tap(find.byValueKey(ProductKeys.productEditProductFieldKeyString)); + await driver.tap(find.byValueKey(ProductKeys.productKey)); await driver.enterText(Constants.newProductKey); - await driver.tap(find.byValueKey(ProductKeys.productEditNotesFieldKeyString)); + await driver.tap(find.byValueKey(ProductKeys.notes)); await driver.enterText(Constants.newProductNotes); - await driver.tap(find.byValueKey(ProductKeys.productEditCostFieldKeyString)); + await driver.tap(find.byValueKey(ProductKeys.cost)); await driver.enterText(Constants.newProductCost); await driver.tap(find.byTooltip(Constants.saveToolTip)); @@ -118,11 +119,11 @@ void main() { test('Edit an existing product', () async { await driver.tap(find.text(Constants.newProductKey)); - await driver.tap(find.byValueKey(ProductKeys.productEditProductFieldKeyString)); + await driver.tap(find.byValueKey(ProductKeys.productKey)); await driver.enterText(Constants.updatedProductKey); - await driver.tap(find.byValueKey(ProductKeys.productEditNotesFieldKeyString)); + await driver.tap(find.byValueKey(ProductKeys.notes)); await driver.enterText(Constants.updatedProductNotes); - await driver.tap(find.byValueKey(ProductKeys.productEditCostFieldKeyString)); + await driver.tap(find.byValueKey(ProductKeys.cost)); await driver.enterText(Constants.updatedProductCost); await driver.tap(find.byTooltip(Constants.saveToolTip));