This README contains a setup guide for setting up your dev environment (Copied from Confluence).
- HMCTS.NET account
- GitHub account with HMCTS.NET account linked
- Git installed
- Access to repos in GitHub (see GitHub page)
- Code editor/IDE of choice installed (Eclipse, VS Code, IntelliJ, etc.)
- OpenJDK 21 (for this setup example we used Adoptium Temurin as our source but most JDKs should work)
- Azure CLI
- Certificate store in NPM (for ZScaler to work with yarn install). See https://intranet.ent.cgi.com/browse/cio/global/Documents/CGI-SASE_Wave1-FAQ_EN.pdf Section 21.
You can either run a provided script or install manually.
- Clone the Git repo
- Run the
appreg-env-setup.shscript in your terminal (ensure you are in the root directory of the repo)
- This script runs through the steps of the manual installation
- If the script fails, attempt installation manually
- If you get
permission deniederrors, run:
sudo chmod +x appreg-env-setup.sh-
Ensure Git repo is cloned
-
Install NVM from: https://github.com/nvm-sh/nvm
-
After installation, add to your shell config:
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
-
Verify installation:
nvm --version
-
Install Node.js version 20.19.4 and set it:
nvm install 20.19.4 nvm use 20.19.4
-
Check Node.js version:
node --version # should be v20.19.4 -
Navigate to root of
appreg-frontenddirectory and run:corepack enable yarn install yarn build -
Run a local dev version:
yarn start:dev
-
Curl should come preinstalled on Linux and MacOS
-
Verify with:
which curl
It should return
/usr/bin/curl. If missing, install manually:Linux:
sudo apt-get update && sudo apt-get upgrade sudo apt-get install curlMacOS:
-
Install Homebrew from brew.sh
-
Run:
brew install curl echo 'export PATH="$(brew --prefix)/opt/curl/bin:$PATH"' >> ~/.zshrc source ~/.zshrc
-
-
Restart terminal:
exec $SHELL
-
See troubleshooting: https://github.com/nvm-sh/nvm
-
Ensure you are inside the
appreg-frontenddirectory -
Restart terminal, then:
exec $SHELL corepack enable
-
If
node_modulesandyarn.lockexist, delete them and run:yarn cache clear yarn install && yarn build
- Follow the MacOS & Linux steps (since WSL is a Linux environment)
- Clone Git repo
- Install Node.js version 20.19.4:
- Option 1 (simpler): Install from Node.js site
- Option 2: Install
nvm-windowsfrom nvm-windows Github
nvm install 20.19.4
nvm use 20.19.4-
Verify installation:
node --version -
In the
appreg-frontenddirectory, run:corepack enable yarn install && yarn build
Once yarn/node has been installed, run below to generate openapi files
yarn api:all:forceRun below to run code using Wiremock/Stub
yarn dev:stubIf you do not have Azure SSO onboarding yet, run the local SSO bypass mode:
yarn dev:stub:no-ssoThis mode also injects a local dummy bearer token for API proxy calls so WireMock auth-header matchers pass. You can override it with DEV_BYPASS_BEARER_TOKEN.
Run below to run code using Staging connectivity (VPN required)
yarn dev:stgRun the following command to setup pre-commit & pre-push checks
yarn prepare
Frontend browser telemetry is configured at runtime from GET /app/config.
The browser SDK is enabled automatically outside local/test environments when
secrets.appreg.app-insights-connection-string-fe is available.
For local development, telemetry stays off by default even if the connection string exists. To opt in locally, set:
APPINSIGHTS_ENABLED=trueImplementation notes:
- Browser exceptions are sent through the Angular
ErrorHandleroverride. - Failed Angular
HttpClientrequests are logged from the error interceptor. - Route changes are logged as page views.
- Telemetry payloads only include route and request paths, status data, and correlation IDs when present. Query strings and response bodies are excluded.
-
Restart PowerShell
-
Verify install:
node --version && npm --version
-
If not found, add Node.js install path to PATH (usually
C:\Program Files\nodejs\):- Press
Win + R, typesysdm.cpl, press Enter - Go to Advanced → Environment Variables
- Under System variables, edit
Path→ Add new entry:C:\Program Files\nodejs\ - Restart PowerShell
- Press
-
Ensure you are inside
appreg-frontenddirectory -
Restart PowerShell, then:
corepack enable
-
If
node_modulesandyarn.lockexist, delete them and run:yarn cache clear yarn install && yarn build
This mock service simulates the AppReg API so you can run the UI and SSR server without a live backend. It ships with hand-crafted fixtures and generated mappings, plus easy ways to force specific error codes for each endpoint.
yarn start:mockyarn stop:mock- Start:
yarn start:mock(exposes WireMock at http://localhost:4550) - Stop:
yarn stop:mock
Curated JSON & CSV fixtures used by mappings are under:
wiremock/__files/fixtures/** # JSON bodies per endpoint/status
wiremock/__files/reports/sample.csv # CSV used by report download endpoint
wiremock/__files/errors/**
Fixture files are named:
wiremock/__files/fixtures/<group>/<kebab(operationId)>-<status>.json
Mappings will automatically use these when available. Feel free to update or add new ones as needed.
yarn mock:gen:errors
# -> runs: node scripts/gen-error-bodies.cjs
# Writes wiremock/__files/errors/*.json (hard-coded JSON, no templating)yarn mock:gen
# -> runs: node scripts/gen-wiremock-mappings.mjs
# Reads the OpenAPI spec, creates one 2xx mapping per endpoint,
# and one mapping per error code (401/403/404/… as defined).
# If a curated fixture exists, it’s used via "bodyFileName".
# Error mappings are emitted as WireMock "scenarios" for forcing errors.yarn mock:sync
# -> runs: yarn api:fetch-unpack:force && yarn mock:gen:errors && yarn mock:gen- OpenAPI ingest:
gen-wiremock-mappings.mjsreadstools/openapi/vendor/openapi/openapi.yaml(and local$refs). - Grouping: Each operation is grouped by its first OpenAPI tag (e.g.,
court-locations). - One success mapping per endpoint:
- Prefers the curated fixture at
wiremock/__files/fixtures/<group>/<opId-kebab>-<2xx>.json. - Otherwise, generates a JSON body from the response schema.
- Special-case: if the OpenAPI
content-typeistext/csv, it serveswiremock/__files/reports/sample.csv.
- Prefers the curated fixture at
- Error mappings:
- For each 4xx/5xx listed in the spec, a mapping is emitted with a scenario named after the operationId (or a readable fallback) and a
requiredScenarioStatelikeFORCE_401,FORCE_403,FORCE_500, etc. - Body payloads are reused from
wiremock/__files/errors/*.json.
- For each 4xx/5xx listed in the spec, a mapping is emitted with a scenario named after the operationId (or a readable fallback) and a
Two options:
- Global delay at generation time
Set STUB_DELAY_MS before running yarn mock:gen:
STUB_DELAY_MS=250 yarn mock:genThis adds fixedDelayMilliseconds: 250 to all generated mappings.
- Per-mapping tweak
Manually add "fixedDelayMilliseconds": to any mapping JSON under wiremock/mappings/**.
Every endpoint’s error mappings are part of a WireMock scenario. To make a specific endpoint return (say) HTTP 500, set the scenario state to FORCE_500.
Put scenario into a 500 state
curl -i -X PUT http://localhost:4550/__admin/scenarios/getCourtLocations/state \
-H 'Content-Type: application/json' \
-d '{"state":"FORCE_500"}'Verify it took:
curl -s http://localhost:4550/__admin/scenarios \
| jq '.scenarios[] | select(.id=="getCourtLocations" or .name=="getCourtLocations") | {id, name, state, possibleStates}'Now any request that matches that mapping (correct method, path, and headers) will return 500 until you reset the scenario.
- Reset a single scenario to Started:
curl -i -X PUT http://localhost:4550/__admin/scenarios/<ScenarioName>/state \
-H 'Content-Type: application/json' \
-d '{"state":"Started"}'- Reset all scenarios:
curl -i -X POST http://localhost:4550/__admin/scenarios/reset- Full reset:
curl -i -X POST http://localhost:4550/__admin/resetThis section documents all test types, how to run them, and how to add new cases.
Tests live under test/ and are split by purpose to keep suites fast and focused.
| Script | What it runs | Config |
|---|---|---|
yarn test |
Alias for unit tests locally. In CI (CI=true) this script no-ops (exits 0) because CI jobs invoke suites explicitly. |
— |
yarn test:unit |
Jest unit tests under test/unit. Fast, isolated. |
jest.config.js (default) |
yarn test:coverage |
Same as unit, with coverage output. | jest.config.js |
yarn test:routes |
Route-render checks under test/routes. |
jest.routes.config.js |
yarn test:a11y |
Accessibility tests with Pa11y under test/a11y. Spins up a temp HTTP server. |
jest.a11y.config.js |
yarn test:smoke |
High-level smoke tests under test/smoke. Disables TLS verification for test envs that use self-signed certs. |
jest.smoke.config.js |
- Location:
test/unit/ - Purpose: Validate functions, components, and services in isolation.
- Run:
yarn test:unit
- With coverage:
-
yarn test:coverage
- Tips:
-
Prefer pure tests without network or timers.
-
Use jest.mock(...) for dependencies.
-
Keep them fast (<100ms each).
-
- Location:
test/routes/ - Purpose: Verifies that key application routes function correctly within the Server-Side Rendering (SSR) layer.
- Run:
yarn test:routesAccessibility checks run against the built app served via a temporary local server. This is required to support Angular’s client-side routing (e.g., /applications-list/:id).
- Location:
test/a11y/ - Key files:
a11y.server.ts– starts a static SPA server that:- serves
dist/appreg-frontend/browser - falls back to index.html for unknown paths
a11y.spec.ts– defines the list of routes and Pa11y expectations
- Run:
yarn build yarn test:a11y
Edit test/a11y/a11y.spec.ts and append routes:
describe('Accessibility', () => {
testAccessibility('/login');
testAccessibility('/applications-list');
testAccessibility('/applications-list/123'); // dynamic route example (use a stable test ID)
});
- Location:
test/smoke/ - Purpose: High-level end-to-end tests simulating user journeys.
- Run:
yarn test:smoke- Note:
NODE_TLS_REJECT_UNAUTHORIZED=0is set in the script to allow self-signed local certs; do not rely on this outside test environments.
End-to-end tests using Cypress 15.11.0 with Cucumber BDD. Tests are organized in cypress/e2e/features/ by type: smoke/, regression/, apiTests/.
-
Configure credentials in
config/development.json:{ "secrets": { "rpx": { "test": { "user1": { "email": "...", "password": "..." }, "admin1": { "email": "...", "password": "..." } } } } } -
Run tests:
# Interactive mode yarn cypress:open # Headless (all tests) yarn cypress:run # Smoke tests yarn cypress:run:smoke:chrome # Regression (parallel, recommended) yarn test:parallel:regression:chrome
-
Target an environment:
TEST_URL='https://appreg.demo.apps.hmcts.net' yarn cypress:run
| Command | Description |
|---|---|
yarn cypress:open |
Open Cypress UI |
yarn cypress:run |
Run all tests headlessly |
yarn cypress:run:smoke:chrome |
Run smoke tests |
yarn cypress:run:regression:chrome |
Run regression tests |
yarn test:parallel:regression:chrome |
Run regression in parallel (4 threads) |
yarn cypress:clean:reports |
Clean test reports |
Filter tests using TAGS environment variable:
TAGS='@smoke' yarn cypress:run
TAGS='@regression and @applicationsList' yarn cypress:run
TAGS='@regression and not @ignore and not @broken' yarn cypress:run
TEST_URL='https://appreg.demo.apps.hmcts.net' TAGS='(@applicationsList or @referenceData or @authentication) and not @ignore and not @broken' yarn test:parallel:regression:chromeNote: Use TAGS (not CYPRESS_TAGS) with the scripts above, as they pass tags via --env TAGS which overrides CYPRESS_TAGS. For interactive mode without tags, use:
CYPRESS_TAGS='@smoke' yarn cypress:openAvailable tags: @smoke, @regression, @ignore, @broken, feature tags (@applicationsList), story tags (@ARCPOC-214)
After execution, reports are in:
cypress/reports/cucumber-html/– HTML reportscypress/reports/screenshots/– Failure screenshotsfunctional-output/– CI artifacts
In this section, we will document how you generate the required services and models using @openapitools/openapi-generator-cli.
These are the scripts needed:
yarn api:fetch-unpack- Fetches and decompresses OpenAPI spec held in Azure Artifacts (scripts/fetch-unpack-openapi.cjs). Skips fetch if there is a spec exists and is less than a week old.yarn api:fetch-unpack:force- Force fetches and decompresses OpenAPI spec held in Azure Artifacts. Use this command if you want to fetch the current latest spec file in Azure Artifacts.yarn api:validate- Validates the OpenAPI spec (tools/openapi/vendor/openapi/openapi.yaml)yarn api:clear- Recursively deletes current OpenAPI generated files held atsrc/generated/openapiyarn api:generate- Generates files based on the OpenAPI spec and the config file attools/openapi/generator-config.yamlyarn api:bundle- Bundles the OpenAPI spec, schemas, responses intotools/dist/openapi.bundled.yamlyarn api:all- Runs all API scripts (api:validate -> api:clear -> api:bundle -> api:generate)yarn api:all:force- Force fetch spec and runs all API scripts (api:validate -> api:clear -> api:bundle -> api:generate)
If you want to use a specific OpenAPI spec version, you can edit scripts/fetch-unpack-openapi.cjs and change the following:
let SPEC_VERSION = envOr('SPEC_VERSION', '**ENTER SPEC VERSION HERE AS A STRING**');
This repository includes an automated policy to keep old/inactive branches tidy. It runs in two stages:
- Dry Run: scans branches and opens a GitHub Issue with candidates, no deletions.
- Enforce: re-checks eligibility and deletes branches that still qualify; then comments on and closes the Issue.
- A Node script scans via the GitHub API, excluding protected names and branches with open PRs or a “do-not-delete” marker.
- Run creates an Issue labeled
branch-cleanup+ a marker label (defaultdry-run) containing a table and a machine-readable ```json block. - Enforce reads that Issue’s JSON (not the runner artifacts), applies the grace period and re-checks exclusions, then deletes eligible branches and posts a deletion summary.
- Policy (config):
.github/branch-retention/branch-retention.yml - Script:
.github/branch-retention/branch-retention.mjs - Workflow:
.github/workflows/branch-retention.yml - Artifacts (optional, for download):
.github/branch-retention/out/*.json
Edit .github/branch-retention/branch-retention.yml:
# Example production-ish values (adjust to taste)
inactivityDays: 60 # candidates must be inactive for >= this many days
graceDays: 7 # wait this many days after “Run” before deletion
protectedPatterns: - 'master'
- 'develop'
- 'release/*'
doNotDelete: label: 'do-not-delete' # if an open PR has this label, branch is skipped
namePatterns: ['do-not-delete/*', '*[do-not-delete]*'] # name-based skip
notify: githubIssueLabel: 'branch-cleanup'
# (optional) markerLabels: ['dry-run', 'run', 'pending'] # accepted markers# Authenticate with GitHub CLI (if not already done):
gh auth login
# Preview run (creates batch Issue):
yarn branch:run
# Enforce (deletes eligible branches for the latest batch):
yarn branch:enforce