Test Against FusionAuth

On this page

You can download FusionAuth and run an instance next to your tests. Your tests log real users in through the real login pages, with no mocks. When a test run changes data, you reset the instance to a known state.

The examples on this page come from the example app, a Node.js and Express app with Playwright tests. The app uses Kickstart to create its users, roles, and application on startup.

Write an End-to-End Test#

The simplest test confirms that FusionAuth is running. The test requests the Admin UI and checks the title of the login page:

test('FA has title', async ({ page }) => {
  await page.goto('http://localhost:9011/admin');

  // Expect a title "to contain" a substring.
  await expect(page).toHaveTitle(/Login | FusionAuth/);
});

A complete login test drives the browser through the same steps as a user:

test('log in', async ({ page }) => {
  // #1
  await page.goto('http://localhost:8080/');

  // #2
  const login = page.getByRole('link', { name: 'Login' });
  await login.click();

  // #3
  await expect(page).toHaveTitle(/Login | FusionAuth/);
  await expect(page.locator('#loginId')).toBeVisible();
  await expect(page.locator('#password')).toBeVisible();

  // #4
  const loginId = await page.locator('#loginId');
  await loginId.fill("richard@example.com");
  const pw = await page.locator('#password');
  await pw.fill("password");

  // #5
  const button = await page.locator('.button.blue');
  await button.click();

  // #6
  await expect(page).toHaveTitle(/FusionAuth Start Here Application | Home/);

  // #7
  await expect(page.getByText('richard@example.com')).toBeVisible();
});

The login test does the following:

  • Opens the app homepage and clicks the login button.
  • Checks that the browser lands on the FusionAuth login page.
  • Fills in the credentials for a test user and submits the form.
  • Checks that the browser returns to the app with the user logged in.

Reset FusionAuth Between Runs#

Tests that create or delete users change the state of the instance. To start the next run from a clean state, delete the database and restart FusionAuth. On startup, FusionAuth runs your Kickstart file again.

The -v flag removes the database volume:

$ docker compose down -v
$ docker compose up

Stop FusionAuth, drop the database, and start FusionAuth again. The exact commands depend on your platform and database:

$ bin/shutdown.sh
$ psql -U postgres -c 'drop database fusionauth;'
$ bin/startup.sh

Run the Tests in CI#

The FusionAuth GitHub Action starts an instance inside a GitHub Actions workflow. The following step starts FusionAuth with a Kickstart file from the kickstart directory:

- name: Start FusionAuth
  uses: fusionauth/fusionauth-github-action@v1
  with:
    FUSIONAUTH_VERSION: latest
    FUSIONAUTH_APP_KICKSTART_DIRECTORY_PATH: kickstart

Later steps install dependencies, start the app, and run Playwright:

- name: Install npm dependencies
  run: |
    npm install
    npx playwright install-deps
    npx playwright install

- name: Start app
  run: npm run dev &

- name: Run Playwright tests
  run: npx playwright test --project=chromium

Each CI run starts a new instance, so CI runs don't need a reset step. Other CI systems need the same steps: start FusionAuth with Kickstart, start the app, and run the tests.

For a complete workflow that also covers updating FusionAuth and deploying your app, see Test and Deploy with GitHub Actions.