Skip to content

Guide to Creating Citizen Users

Abigail Smith edited this page Sep 17, 2025 · 1 revision

Creating Citizen Users for Test Automation

Setting up realistic and isolated users is crucial for effective end-to-end testing. This wiki page walks you through how to dynamically create and log in citizen users for your test automation suite using the @hmcts/playwright-common library.

This library provides built-in support for using IDAM testing endpoints and a convenient login helper method. By centralizing these functionalities in a common library, we can all reuse these endpoints with different payloads, which is particularly useful for HMCTS services that rely on IDAM for authentication.


1. Install the Playwright Common Library

First, add the library to your project using Yarn. It's recommended to use v1.0.29 or later, as this version includes the latest IDAM changes.

yarn add @hmcts/playwright-common@^1.0.29

2. Configure Environment Variables

Add the following environment variables to your project. You can use a dedicated config utility or add them to your .env file. These URLs are essential; without them, the IDAM utilities will not function.

  • IDAM_SECRET: Specific to your service. Ask your team if you're unsure what it is.
  • IDAM_CITIZEN_USER_PASSWORD: A secure password for the test users.
  • IDAM_WEB_URL: https://idam-web-public.aat.platform.hmcts.net
  • IDAM_TESTING_SUPPORT_URL: https://idam-testing-support-api.aat.platform.hmcts.net

⚠️ Note: The IDAM_SECRET and IDAM_CITIZEN_USER_PASSWORD should be securely stored in Azure Key Vault. You must also be connected to the F5 VPN to access the IDAM test support API, as these endpoints are not publicly accessible.


3. Map Secrets in Jenkins

If your tests run in a Jenkins pipeline, ensure these secrets are correctly mapped in your pipeline configuration.

def secrets = [
    'prl-${env}': [
        secret('prl-cos-idam-client-secret', 'IDAM_SECRET'),
        secret('idam-citizen-password', 'IDAM_CITIZEN_USER_PASSWORD')
    ]
]

💡 Tip: If you're using a get.secrets script, ensure you add the correct tags and update the Key Vault name for your service.


4. Retrieve a Bearer Token at Test Startup

To programmatically create users, you need an IDAM bearer token. It's best practice to retrieve this token once at the start of your test run in a global.setup.ts file. This reduces the number of API calls and the load on the IDAM service, as the token is valid for 8 hours and can be used to create multiple users.

Token setup in global.setup.ts:

setup.describe("Set up users and retrieve tokens", () => {
    setup.beforeAll("Retrieve IDAM token for citizen user creation", async ({ idamUtils }) => {
        const token = await idamUtils.generateIdamToken({
            grantType: "client_credentials",
            clientId: "prl-cos-api", // Replace with your service’s client ID
            clientSecret: process.env.IDAM_SECRET as string,
            scope: "profile roles",
        });
        process.env.CREATE_USER_BEARER_TOKEN = token;
    });
});

To ensure the setup runs before your tests, configure it as a dependency in your playwright.config.ts.

Configuration in playwright.config.ts:

import { CommonConfig, ProjectsConfig } from "@hmcts/playwright-common";
import { defineConfig } from "@playwright/test";

export default defineConfig({
    testDir: "./playwright-e2e",
    snapshotDir: "./playwright-e2e/snapshots",
    ...CommonConfig.recommended,

    projects: [
        {
            name: "setup",
            testMatch: /global\.setup\.ts/,
        },
        {
            ...ProjectsConfig.chrome,
            dependencies: ["setup"],
        },
        {
            ...ProjectsConfig.chromium,
            dependencies: ["setup"],
        },
    ],
});

5. Create a Utility Class for User Generation

Create a helper class to dynamically generate new, uniquely named citizen users. This avoids conflicts (409 errors) with existing users. A good place to store this is under playwright-e2e/utils/citizenUserUtils.ts, as shown in the TCoE example repo.

import { IdamUtils } from "@hmcts/playwright-common";
import { v4 as uuidv4 } from "uuid";

type UserInfo = {
    email: string;
    password: string;
    forename: string;
    surname: string;
    sessionFile?: string;
};

export class CitizenUserUtils {
    constructor(private idamUtils: IdamUtils) {}

    public async createUser(): Promise<UserInfo> {
        const token = process.env.CREATE_USER_BEARER_TOKEN as string;
        const password = process.env.IDAM_CITIZEN_USER_PASSWORD as string;
        const uniqueId = uuidv4();
        const email = `TEST_PRL_USER_citizen.${uniqueId}@test.local`;
        const forename = "fn_" + uniqueId.split("-")[0];
        const surname = "sn_" + uniqueId.split("-")[1];

        const user = await this.idamUtils.createUser({
            bearerToken: token,
            password,
            user: {
                email,
                forename,
                surname,
                roleNames: ["citizen"],
            },
        });

        return {
            email: user.email,
            password: user.password,
            forename,
            surname,
        };
    }
}

🔧 Tip: You can expose this utility via a custom fixture in fixtures.ts to make it easily accessible in your tests.


6. Automatically Log In Users Before Each Test

Use a test.beforeEach hook to automatically log in the newly created user before each test using the idamPage.login helper method from @hmcts/playwright-common. This helper streamlines the entire login process, handling redirects and credential input.

test.beforeEach(async ({ page, config, citizenUserUtils, idamPage }) => {
    const user = await citizenUserUtils.createUser();
    await page.goto(config.urls.citizenUrl);

    // Provided by @hmcts/playwright-common
    await idamPage.login({
        username: user.email,
        password: user.password,
    });
});

Clearing Down Test Users

You do not need to manually clear down users created through the idam-testing-support-api. These test users are automatically removed after a set period. The cleanup process uses the bearer token as its key, so all users created with the same token are deleted as a single batch.