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

chore(authenticator_test): Updated Golden tests to run on any screen #3655

Merged
merged 7 commits into from
Sep 8, 2023

Conversation

Equartey
Copy link
Member

@Equartey Equartey commented Aug 30, 2023

Description of changes:

  • Updated Golden tests to run on any screen & expands the golden test suite to test every screen, except for AuthenticatorStep.loading.
  • Fixed Beta channel failures
  • Golden test failures are now saved as artifacts for download
  • amplify_authenticator.ymal workflow uses a MacOS runner to ensure more consistent testing

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@Equartey Equartey requested a review from a team as a code owner August 30, 2023 20:45
@Equartey Equartey force-pushed the chore/authenticator-totp-goldens branch 7 times, most recently from f10f0ce to 9bc8dae Compare September 1, 2023 17:43

aft:
github:
custom: true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure this is the best way to handle this. It means taking responsibility for updating the authenticator workflow file for any changes in the future. And the goldens thing may pop up in other packages if we add UI components. Can we handle this in generate_workflows instead? Basically, add a check for the existence of goldens and make flutter_vm.yaml take a boolean flag for whether there are goldens or not?

@@ -437,6 +438,9 @@ class Authenticator extends StatefulWidget {
/// {@macro amplify_authenticator_dial_code_options}
final DialCodeOptions dialCodeOptions;

@visibleForTesting
final AuthenticatorState? mockAuthenticatorState;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this and setState?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These were added to populate the state with required properties depending on the desired authenticator step during testing. For example, some screens such as the TOTP setup screen expect TotpDetails to be non-null.

Perhaps naming it authenticatorStateOverride would make its purpose more explicit?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need setState as well though? Did setting the initial state via the mocked AuthenticatorState and state machine not work, or is there a need to change the state inside a test?

Copy link
Member Author

@Equartey Equartey Sep 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need setState as well though? is there a need to change the state inside a test?

Yes -- setState is required. The step continueSignInWithMfaSelection requires the actual state to be typed as ContinueSignInWithMfaSelection in order to retrieve it's required values.

Additionally, having one state for all tests was brittle. Any changes to the business logic of state inputs would need to be duplicated in tests and the bloc, ie transforming the Cognito provided TotpSetupDetails into a setupURI string. Instead, we only need to supply the required inputs for a given state. Then we are able to reuse the business logic in the bloc and discretely represent the proper state of each screen of the application.

Copy link
Contributor

@dnys1 dnys1 Sep 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather make stateMachineBloc visible for testing and call setState on it than expose a parameter like this

.github/workflows/flutter_vm.yaml Outdated Show resolved Hide resolved
@@ -437,6 +438,9 @@ class Authenticator extends StatefulWidget {
/// {@macro amplify_authenticator_dial_code_options}
final DialCodeOptions dialCodeOptions;

@visibleForTesting
final AuthenticatorState? mockAuthenticatorState;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need setState as well though? Did setting the initial state via the mocked AuthenticatorState and state machine not work, or is there a need to change the state inside a test?

Comment on lines 249 to 250
${hasGoldens ? 'runner-os: macos-latest' : ''}
${hasGoldens ? 'has-goldens: true' : ''}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This creates empty lines in other generated workflows when running the generate command.

Couldn't find a simple way to trim the extra lines when not needed...

@dnys1 would it be better to have them always defined?

@@ -9,46 +9,10 @@ on:
paths:
- '.github/workflows/amplify_authenticator.yaml'
- '.github/workflows/flutter_vm.yaml'
- 'packages/amplify/amplify_flutter/lib/**/*.dart'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happened here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Running the generate workflows command removes several paths in all the workflow files. I only included this one though.

@@ -244,6 +246,8 @@ jobs:
with:
package-name: ${package.name}
working-directory: $repoRelativePath
${hasGoldens ? 'runner-os: macos-latest' : ''}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove, it's not a parameter you can pass anyway. But only has-goldens is needed to know which runner to use.

@Equartey Equartey force-pushed the chore/authenticator-totp-goldens branch from 9733d28 to db69ffc Compare September 7, 2023 20:28
.github/workflows/flutter_vm.yaml Outdated Show resolved Hide resolved
@@ -437,6 +438,9 @@ class Authenticator extends StatefulWidget {
/// {@macro amplify_authenticator_dial_code_options}
final DialCodeOptions dialCodeOptions;

@visibleForTesting
final AuthenticatorState? mockAuthenticatorState;
Copy link
Contributor

@dnys1 dnys1 Sep 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather make stateMachineBloc visible for testing and call setState on it than expose a parameter like this

dnys1
dnys1 previously approved these changes Sep 8, 2023
@@ -214,6 +214,8 @@ $groupPubPackages
// TODO(dnys1): Enable E2E runs for Dart packages
final needsE2ETest = package.flavor == PackageFlavor.flutter &&
package.integrationTestDirectory != null;
final hasGoldens = package.flavor == PackageFlavor.flutter &&
package.goldensTestDirectory != null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An alternative to checking for a directory would be to look for a dev dep of golden_toolkit. It isn't required to run golden tests, but I think we would be likely to use it in any future packages that have golden tests. Looking for a ui directory is fine too. If this is still in place when future UI components are built, we will just have to confirm to that dir.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood, this for sure could be different. Since we don't have any other UI packages or other established conventions, we can readdress this down the road.

import 'package:amplify_flutter/amplify_flutter.dart';
import 'package:amplify_integration_test/amplify_integration_test.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

/// Use for testing the [MockAuthenticatorApp] widget locally.
void main() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you would like to commit this, can you move it to an /example dir and add all the platforms (not just iOS)

@Equartey Equartey merged commit 9bcac40 into main Sep 8, 2023
117 of 122 checks passed
@Equartey Equartey deleted the chore/authenticator-totp-goldens branch September 8, 2023 18:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants