Front-End Web & Mobile

Running end-to-end Cypress tests for your fullstack CI/CD deployment with Amplify Console

This article was written by Nikhil Swaminathan, Sr. Technical Product Manager, AWS.

Amplify Console now officially supports end-to-end (E2E) testing as part of your continuous deployment pipeline. E2E tests allow you to test your whole application from start to finish. Writing unit tests for the separate components of your app (e.g. product search flow, checkout flow) while useful, does not verify that the different components work together properly. E2E tests simulate real user scenarios and ensure all the pieces work together (e.g. searching for a product and purchasing it).

In this blog post, we are going to build a React app using Amplify’s Authentication UI, and add Cypress tests to verify the login flow.

Set up project locally

To get set up, create a new React app, install the Amplify CLI and Amplify JS libraries.

create-react-app amplify-cypress 
cd amplify-cypress
npm i @aws-amplify/cli
npm install aws-amplify @aws-amplify/ui-react

Initialize your Amplify project and accept all defaults.

amplify init
? Enter a name for the environment: dev

Add authentication to your backend.

amplify add auth
amplify push

Copy and paste the following code to your App.js

 import Amplify from "aws-amplify";
import { Authenticator } from '@aws-amplify/ui-react';
import '@aws-amplify/ui-react/styles.css';

import awsExports from "./aws-exports";
Amplify.configure(awsExports);

export default function App() {
  return (
    <Authenticator signUpAttributes={['email']}>
      {({ signOut, user }) => (
        <main>
          <h1>Hello {user.username}</h1>
          <button onClick={signOut}>Sign out</button>
        </main>
      )}
    </Authenticator>
  );
}

Run your project locally by running yarn start. You should see the Amplify Auth UI. Go ahead and create a dummy user (record the login information as we will use it later!).

Add E2E tests to your app with Cypress

Cypress is a popular JavaScript-based testing framework for running E2E tests in the browser. Install Cypress locally, and then run yarn run cypress open. This command launches the Cypress app which bootstraps a cypress folder in your repository with all the test spec files.

cd myapp && yarn add cypress --dev 
yarn run cypress open

Let’s add a test spec called authenticator_spec.js to test our sign-in flow. You’ll want to have two terminal instances or panes: one running your app and one running Cypress.

touch cypress/integration/authenticator_spec.js

All tests cover three phases, for each phase we will test different functionality:

  1. Set up the application state: Visit the sign-in page.
  2. Take an action: Enter the information for the dummy user created above and click on Sign-in.
  3. Make an assertion:  If the resulting page contains the Sign-out button, then the user successfully signed-in.

Copy and paste the following code to the authenticator_spec.js. Please replace DUMMY_USERNAME and DUMMY_PASSWORD with the login details for the user you created above.

describe('Authenticator:', function() {
  // Step 1: setup the application state
  beforeEach(function() {
    cy.visit('/');
  });
  
  describe('Sign In:', () => {
    it('allows a user to signin', () => {
      // Step 2: Take an action (Sign in)
      cy.get(selectors.usernameInput).type("testuser");
      cy.get(selectors.signInPasswordInput).type("1234uiop");
      cy.get(selectors.signInButton).contains('Sign in').click();

      cy.wait(3000);

      // Step 3: Make an assertion (Check for sign-out text)
        cy.get(selectors.signOutButton).contains('Sign out');
    });
  });

});
export const selectors = {
  // Auth component classes
  usernameInput: '[data-amplify-usernamealias="true"]',
  signInPasswordInput: '[data-amplify-password="true"]',
  signInButton: '[data-variation="primary"]',
  signOutButton: 'button'
}

Update the cypress.json file with { "baseUrl": "http://localhost:3000/" } to ensure the tests are run against your localhost port. Launch the Cypress app (yarn run cypress open) and run the test. This will launch a Chrome browser which executes the authenticator_spec.js. If you wrote the test correctly, you should see a screen with 1 success and 0 errors.

Set up continuous delivery with the Amplify Console

The Amplify Console provides a continuous deployment and hosting service for your fullstack app. Amplify Console hosting is fully managed offering features such as instant cache invalidation, atomic deployments, easy custom domain setup, and password protection. To get started, first push your code to a Git provider of your choice.

git commit -am 'Added auth ui'
git push origin master

Log in to the Amplify Console, pick your Git provider, repository and branch, and choose Next. The Amplify Console automatically detects your build settings by inspecting your repository and finding React, Cypress, and Amplify.

Amplify Console detects the existing backend you created with the Amplify CLI – connect the dev backend you created in the CLI to automatically deploy fullstack changes on every git push. Create a service role so Amplify Console can access your backend resources.

Review the build settings – you should notice a test phase with Cypress commands that are automatically detected by Amplify Console to execute tests. You can now save and deploy your app.

 

The Amplify Console deploys your app to an amplifyapp.com domain. When the build completes, you should see a successful pipeline, and be able to access your deployed site.

Choosing the Test icon will take you to the test report dashboard. This report contains a list of all the executed specs, with links to a recording for each test spec. These recordings are particularly useful when tests fail and you want to investigate the failure. The screenshot below shows a more comprehensive set of tests we run on our Amplify UI component.

Your app is now setup with CI/CD and E2E tests! You can build new features with E2E tests, and deploy updates with a git push. Every commit is regression tested – if your E2E tests fail for any reason, the Amplify Console will fail the deployment preventing regressions from being released to production.

Conclusion

This post showed you how to add backend functionality to your app with the Amplify CLI, write E2E tests with Cypress to test fullstack functionality, and finally set up continuous deployment and hosting for your app with the Amplify Console.