Skip to content

Commit 710ebfd

Browse files
run healer
1 parent 786b8fa commit 710ebfd

54 files changed

Lines changed: 461 additions & 226 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env.dev.example

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Development environment template — copy to .env.dev and fill in values
2+
ANGULAR_APP_URL=http://localhost:4200
3+
API_APP_URL=https://localhost:44378/api/v1
4+
IDENTITY_SERVER_URL=https://localhost:44310
5+
6+
TEST_USER_EMPLOYEE_USERNAME=
7+
TEST_USER_EMPLOYEE_PASSWORD=
8+
9+
TEST_USER_MANAGER_USERNAME=
10+
TEST_USER_MANAGER_PASSWORD=
11+
12+
TEST_USER_HRADMIN_USERNAME=
13+
TEST_USER_HRADMIN_PASSWORD=

.env.example

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Test User Credentials
2+
# Copy this file to .env and fill in real values.
3+
# Get values from Azure Key Vault:
4+
# az keyvault secret show --vault-name <vault> --name playwright-employee-username --query value -o tsv
5+
6+
TEST_USER_EMPLOYEE_USERNAME=
7+
TEST_USER_EMPLOYEE_PASSWORD=
8+
9+
TEST_USER_MANAGER_USERNAME=
10+
TEST_USER_MANAGER_PASSWORD=
11+
12+
TEST_USER_HRADMIN_USERNAME=
13+
TEST_USER_HRADMIN_PASSWORD=

.env.prod.example

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Production environment template — copy to .env.prod and fill in values
2+
ANGULAR_APP_URL=https://mango-flower-0ced4011e.4.azurestaticapps.net
3+
API_APP_URL=https://app-talent-api-dev.azurewebsites.net/api/v1
4+
IDENTITY_SERVER_URL=https://app-talent-ids-dev.azurewebsites.net
5+
6+
TEST_USER_EMPLOYEE_USERNAME=
7+
TEST_USER_EMPLOYEE_PASSWORD=
8+
9+
TEST_USER_MANAGER_USERNAME=
10+
TEST_USER_MANAGER_PASSWORD=
11+
12+
TEST_USER_HRADMIN_USERNAME=
13+
TEST_USER_HRADMIN_PASSWORD=

.github/workflows/playwright.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,27 @@ jobs:
3434
- name: Install Playwright Browsers
3535
run: npx playwright install --with-deps ${{ matrix.project }}
3636

37+
- name: Run auth setup (pre-authenticate all roles via PKCE)
38+
run: npx playwright test --project=setup
39+
env:
40+
CI: true
41+
TEST_USER_EMPLOYEE_USERNAME: ${{ secrets.TEST_USER_EMPLOYEE_USERNAME }}
42+
TEST_USER_EMPLOYEE_PASSWORD: ${{ secrets.TEST_USER_EMPLOYEE_PASSWORD }}
43+
TEST_USER_MANAGER_USERNAME: ${{ secrets.TEST_USER_MANAGER_USERNAME }}
44+
TEST_USER_MANAGER_PASSWORD: ${{ secrets.TEST_USER_MANAGER_PASSWORD }}
45+
TEST_USER_HRADMIN_USERNAME: ${{ secrets.TEST_USER_HRADMIN_USERNAME }}
46+
TEST_USER_HRADMIN_PASSWORD: ${{ secrets.TEST_USER_HRADMIN_PASSWORD }}
47+
3748
- name: Run Playwright tests
3849
run: npx playwright test --project=${{ matrix.project }}
3950
env:
4051
CI: true
52+
TEST_USER_EMPLOYEE_USERNAME: ${{ secrets.TEST_USER_EMPLOYEE_USERNAME }}
53+
TEST_USER_EMPLOYEE_PASSWORD: ${{ secrets.TEST_USER_EMPLOYEE_PASSWORD }}
54+
TEST_USER_MANAGER_USERNAME: ${{ secrets.TEST_USER_MANAGER_USERNAME }}
55+
TEST_USER_MANAGER_PASSWORD: ${{ secrets.TEST_USER_MANAGER_PASSWORD }}
56+
TEST_USER_HRADMIN_USERNAME: ${{ secrets.TEST_USER_HRADMIN_USERNAME }}
57+
TEST_USER_HRADMIN_PASSWORD: ${{ secrets.TEST_USER_HRADMIN_PASSWORD }}
4158

4259
- name: Upload HTML Report
4360
uses: actions/upload-artifact@v4

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11

2+
# Credentials — never commit real values (commit only *.example files)
3+
.env
4+
.env.dev
5+
.env.prod
6+
7+
# Playwright auth state — contains JWT tokens, regenerated by auth.setup.ts
8+
/.auth/
9+
210
# Playwright
311
node_modules/
412
/test-results/

.mcp.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"mcpServers": {
3+
"playwright-test": {
4+
"command": "cmd",
5+
"args": [
6+
"/c",
7+
"npx",
8+
"playwright",
9+
"run-test-mcp-server"
10+
]
11+
}
12+
}
13+
}

config/environments.json

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@
1616
"description": "Staging environment for testing"
1717
},
1818
"production": {
19-
"angularUrl": "https://app.example.com",
20-
"apiUrl": "https://api.example.com",
21-
"apiBaseUrl": "https://api.example.com/api/v1",
22-
"identityServerUrl": "https://sts.example.com",
19+
"angularUrl": "https://mango-flower-0ced4011e.4.azurestaticapps.net",
20+
"apiUrl": "https://app-talent-api-dev.azurewebsites.net",
21+
"apiBaseUrl": "https://app-talent-api-dev.azurewebsites.net/api/v1",
22+
"identityServerUrl": "https://app-talent-ids-dev.azurewebsites.net",
23+
"identityServerAdminUrl": "https://app-talent-admin-dev.azurewebsites.net",
2324
"timeout": 45000,
24-
"description": "Production environment (use with caution)"
25+
"description": "Production environment — Azure hosted"
2526
}
2627
}

config/test-config.ts

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,66 @@
55
* Modify these values in one place to affect all tests.
66
*/
77

8+
/**
9+
* Load environment-specific credentials before any constant is evaluated.
10+
*
11+
* Placing dotenv loading here (rather than only in playwright.config.ts) ensures
12+
* that worker processes which import this module directly also pick up the .env
13+
* file, because module imports in playwright.config.ts are evaluated before the
14+
* dotenv.config() call in that file executes.
15+
*
16+
* Select environment with APP_ENV:
17+
* APP_ENV=dev → .env.dev (local development)
18+
* APP_ENV=prod → .env.prod (production)
19+
* (none) → .env (default)
20+
*/
21+
import dotenv from 'dotenv';
22+
import path from 'path';
23+
24+
const _env = process.env.APP_ENV;
25+
const _envFile = _env ? `.env.${_env}` : '.env';
26+
dotenv.config({ path: path.resolve(__dirname, '..', _envFile) });
27+
28+
/**
29+
* Test User Credentials
30+
*
31+
* Loaded from environment variables — never hardcoded.
32+
* Local dev: copy .env.example to .env and fill in values.
33+
* CI: injected automatically via GitHub Secrets.
34+
*/
35+
export const TEST_USERS = {
36+
employee: {
37+
username: process.env.TEST_USER_EMPLOYEE_USERNAME || '',
38+
password: process.env.TEST_USER_EMPLOYEE_PASSWORD || '',
39+
role: 'employee' as const,
40+
},
41+
manager: {
42+
username: process.env.TEST_USER_MANAGER_USERNAME || '',
43+
password: process.env.TEST_USER_MANAGER_PASSWORD || '',
44+
role: 'manager' as const,
45+
},
46+
hradmin: {
47+
username: process.env.TEST_USER_HRADMIN_USERNAME || '',
48+
password: process.env.TEST_USER_HRADMIN_PASSWORD || '',
49+
role: 'hradmin' as const,
50+
},
51+
} as const;
52+
53+
/**
54+
* Fail fast if credentials are missing — prevents cryptic login failures.
55+
*/
56+
export function assertCredentialsLoaded(): void {
57+
const missing = (Object.entries(TEST_USERS) as [string, { username: string; password: string }][])
58+
.filter(([, u]) => !u.username || !u.password)
59+
.map(([role]) => role);
60+
if (missing.length > 0) {
61+
throw new Error(
62+
`Missing credentials for roles: ${missing.join(', ')}. ` +
63+
`Copy .env.example to .env and fill in values, or set GitHub Secrets for CI.`
64+
);
65+
}
66+
}
67+
868
/**
969
* Application URLs
1070
*/
@@ -192,3 +252,16 @@ export function getUrl(path: string): string {
192252
export function getApiUrl(endpoint: string): string {
193253
return `${APP_URLS.api}${endpoint}`;
194254
}
255+
256+
/**
257+
* Returns a RegExp that matches any URL on the Angular app host.
258+
* Use instead of hardcoded /localhost:4200/ so tests work across environments.
259+
*
260+
* @example
261+
* await expect(page).toHaveURL(getAngularUrlPattern());
262+
* await page.waitForURL(getAngularUrlPattern());
263+
*/
264+
export function getAngularUrlPattern(): RegExp {
265+
const host = new URL(APP_URLS.angular).host.replace(/\./g, '\\.');
266+
return new RegExp(host);
267+
}

config/test-users.json

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
{
22
"employee": {
33
"username": "antoinette16",
4-
"password": "Pa$$word123",
5-
"email": "antoinette16@ethereal.email",
64
"role": "Employee",
75
"roles": ["Employee"],
86
"permissions": ["read"],
@@ -13,8 +11,6 @@
1311
},
1412
"manager": {
1513
"username": "rosamond33",
16-
"password": "Pa$$word123",
17-
"email": "rosamond33@ethereal.email",
1814
"role": "Manager",
1915
"roles": ["Employee", "Manager"],
2016
"permissions": ["read", "write"],
@@ -26,8 +22,6 @@
2622
},
2723
"hradmin": {
2824
"username": "ashtyn1",
29-
"password": "Pa$$word123",
30-
"email": "ashtyn1@ethereal.email",
3125
"role": "HRAdmin",
3226
"roles": ["Employee", "Manager", "HRAdmin"],
3327
"permissions": ["read", "write", "delete", "admin"],

fixtures/api.fixtures.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { APIRequestContext, Page, Browser, chromium } from '@playwright/test';
22
import type { EmployeeData, DepartmentData } from './data.fixtures';
33
import { loginAsRole, getTokenFromProfile } from './auth.fixtures';
44
import testUsers from '../config/test-users.json';
5+
import { APP_URLS } from '../config/test-config';
56

67
/**
78
* API Fixtures
@@ -13,7 +14,7 @@ import testUsers from '../config/test-users.json';
1314
* - Token acquisition for roles
1415
*/
1516

16-
const API_BASE_URL = 'https://localhost:44378/api/v1';
17+
const API_BASE_URL = APP_URLS.api;
1718

1819
/**
1920
* Gets an access token for a specific role using browser-based authentication

0 commit comments

Comments
 (0)