Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
94f4f8b
Added screenshots to allure report in case of validation issues and i…
SameenaHMCTS Mar 30, 2026
57009bf
Merge branch 'master' into HDPI-5636-configurable-logging
SameenaHMCTS Mar 30, 2026
c78bd58
Added screenshots to allure report in case of validation issues and i…
SameenaHMCTS Mar 30, 2026
6e6e265
Added screenshots to allure report in case of validation issues and i…
SameenaHMCTS Mar 30, 2026
0d033ab
Added screenshots to allure report in case of validation issues and i…
SameenaHMCTS Mar 30, 2026
d70ba73
Added screenshots to allure report in case of validation issues and i…
SameenaHMCTS Mar 30, 2026
02d5c17
Added few failures
SameenaHMCTS Mar 30, 2026
159587e
Added few failures
SameenaHMCTS Mar 30, 2026
7b3a6b4
Added few failures
SameenaHMCTS Mar 30, 2026
6b5d4c1
Added few failures
SameenaHMCTS Mar 30, 2026
80965e4
Added few failures
SameenaHMCTS Mar 30, 2026
6ae210c
Added few failures
SameenaHMCTS Mar 30, 2026
2710186
Added few failures
SameenaHMCTS Mar 30, 2026
6f572fa
Removed tokens from display
SameenaHMCTS Mar 31, 2026
7572efe
Merge branch 'master' into HDPI-5636-configurable-logging
SameenaHMCTS Mar 31, 2026
b2f96f3
Merge branch 'master' into HDPI-5636-configurable-logging
SameenaHMCTS Apr 8, 2026
318a767
Fix possessive form for claimant's name
SameenaHMCTS Apr 8, 2026
6044c37
Fix error message text for landlord registration
SameenaHMCTS Apr 8, 2026
6e7c8ef
refactored the code
SameenaHMCTS Apr 8, 2026
62a308c
refactored the code
SameenaHMCTS Apr 8, 2026
b9e0d3e
refactored the code
SameenaHMCTS Apr 8, 2026
c2864f3
refactored the code
SameenaHMCTS Apr 8, 2026
ef916b0
refactored the code
SameenaHMCTS Apr 8, 2026
5971d5c
refactored the code
SameenaHMCTS Apr 8, 2026
79c280b
refactored the code
SameenaHMCTS Apr 8, 2026
cd51142
refactored the code
SameenaHMCTS Apr 8, 2026
edac615
refactored the code
SameenaHMCTS Apr 9, 2026
e3fd54b
refactored the code
SameenaHMCTS Apr 9, 2026
c716438
Merge branch 'master' into HDPI-5636-configurable-logging
SameenaHMCTS Apr 9, 2026
6497972
refactored the code
SameenaHMCTS Apr 9, 2026
087228e
Logic to have pages info on main test in failed cse
SameenaHMCTS Apr 9, 2026
4e42cdc
Logic to have pages info on main test in failed cse
SameenaHMCTS Apr 9, 2026
f15b53c
Logic to have pages info on main test in failed cse
SameenaHMCTS Apr 9, 2026
98e354f
Refactored the code
SameenaHMCTS Apr 9, 2026
feeff8e
Refactored the code
SameenaHMCTS Apr 9, 2026
ef19090
Refactored the code
SameenaHMCTS Apr 9, 2026
65fb835
Refactored the code
SameenaHMCTS Apr 9, 2026
d132257
Refactored the code
SameenaHMCTS Apr 9, 2026
7021624
Refactored the code
SameenaHMCTS Apr 9, 2026
a91ee91
Refactored the code
SameenaHMCTS Apr 9, 2026
a4bf5ca
Merge branch 'master' into HDPI-5636-configurable-logging
SameenaHMCTS Apr 10, 2026
b0f0f52
Removed the logs and added only screenshots
SameenaHMCTS Apr 13, 2026
d0c4dd5
Merge branch 'master' into HDPI-5636-configurable-logging
SameenaHMCTS Apr 13, 2026
4998724
Checking the failure
SameenaHMCTS Apr 13, 2026
5a8adca
All tests should pass
SameenaHMCTS Apr 13, 2026
567d2b0
Merge branch 'master' into HDPI-5636-configurable-logging
SameenaHMCTS Apr 13, 2026
9c7950f
All tests should pass
SameenaHMCTS Apr 13, 2026
49422f4
ADDED LOGS
SameenaHMCTS Apr 13, 2026
0c800c8
ADDED CONTENT FAILURE TO freeLegalAdvice, ADDED NAVIGATION FALIRE TO …
SameenaHMCTS Apr 13, 2026
f8b6969
Reverted these injected failures ADDED CONTENT FAILURE TO freeLegalAd…
SameenaHMCTS Apr 13, 2026
fcfc1f3
Updated test read me
SameenaHMCTS Apr 13, 2026
5935ade
export const enable_pft_debug_log = true;
SameenaHMCTS Apr 13, 2026
5cae785
export const enable_pft_debug_log = true;
SameenaHMCTS Apr 13, 2026
069bde6
updated take screenshot
SameenaHMCTS Apr 13, 2026
8a73a52
updated string util
SameenaHMCTS Apr 13, 2026
6a95634
updated string util
SameenaHMCTS Apr 13, 2026
5c0cc2f
lint fix
SameenaHMCTS Apr 13, 2026
7dd159d
set the flag to false for review
SameenaHMCTS Apr 13, 2026
5193e1b
Merge branch 'master' into HDPI-5636-configurable-logging
SameenaHMCTS Apr 14, 2026
24dd419
Merge branch 'master' into HDPI-5636-configurable-logging
SameenaHMCTS Apr 15, 2026
c35bd4a
Merge branch 'master' into HDPI-5636-configurable-logging
SameenaHMCTS Apr 15, 2026
8384db6
Corrected the merge conflict error
SameenaHMCTS Apr 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ if (enable_all_page_functional_tests.toLowerCase() === 'true') {
process.env.ENABLE_NAVIGATION_TESTS = 'true';
}

export const enable_pft_debug_log = false;
export const enable_content_validation = process.env.ENABLE_CONTENT_VALIDATION || 'false';
export const enable_visibility_validation = process.env.ENABLE_VISIBILITY_VALIDATION || 'false';
export const enable_error_message_validation = process.env.ENABLE_ERROR_MESSAGES_VALIDATION || 'false';
Expand Down
4 changes: 3 additions & 1 deletion src/test/ui/e2eTest/dashboard.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@ import config from 'config';

import { createCaseApiData, submitCaseApiData } from '../data/api-data';
import { dashboard } from '../data/page-data';
import { DASHBOARD_BEFORE_EACH_ENV_KEYS, logTestEnvAfterBeforeEach } from '../utils/common/log-test-env';
import { initializeExecutor, performAction, performActions, performValidation } from '../utils/controller';

const home_url = config.get('e2e.testUrl') as string;

test.beforeEach(async ({ page }) => {
test.beforeEach(async ({ page }, testInfo) => {
initializeExecutor(page);
process.env.NOTICE_SERVED = 'NO';
process.env.TENANCY_TYPE = 'INTRODUCTORY_TENANCY';
process.env.GROUNDS = 'RENT_ARREARS_GROUND10';
await performAction('createCaseAPI', { data: createCaseApiData.createCasePayload });
await performAction('submitCaseAPI', { data: submitCaseApiData.submitCasePayload });
logTestEnvAfterBeforeEach(testInfo.title, DASHBOARD_BEFORE_EACH_ENV_KEYS);
await performAction('fetchPINsAPI');
await performAction('createUser', 'citizen', ['citizen']);
await performAction('validateAccessCodeAPI');
Expand Down
2 changes: 2 additions & 0 deletions src/test/ui/e2eTest/respondToAClaim.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
wouldYouHaveSomewhereElseToLiveIfYouHadToLeaveYourHome,
yourCircumstances,
} from '../data/page-data';
import { RESPOND_TO_CLAIM_BEFORE_EACH_ENV_KEYS, logTestEnvAfterBeforeEach } from '../utils/common/log-test-env';
import { getRelativeDate } from '../utils/common/string.utils';
import { finaliseAllValidations, initializeExecutor, performAction, performValidation } from '../utils/controller';

Expand Down Expand Up @@ -150,6 +151,7 @@ test.beforeEach(async ({ page }, testInfo) => {
await performAction('submitCaseAPI', { data: submitCaseApiData.submitCasePayload });
}
console.log(`Case created with case number: ${process.env.CASE_NUMBER}`);
logTestEnvAfterBeforeEach(testInfo.title, RESPOND_TO_CLAIM_BEFORE_EACH_ENV_KEYS);
await performAction('fetchPINsAPI');
await performAction('createUser', 'citizen', ['citizen']);
await performAction('validateAccessCodeAPI');
Expand Down
4 changes: 3 additions & 1 deletion src/test/ui/e2eTest/respondToClaimWales.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,20 @@ import {
writtenTerms,
yourCircumstances,
} from '../data/page-data';
import { RESPOND_TO_CLAIM_WALES_BEFORE_EACH_ENV_KEYS, logTestEnvAfterBeforeEach } from '../utils/common/log-test-env';
import { finaliseAllValidations, initializeExecutor, performAction, performValidation } from '../utils/controller';

const home_url = config.get('e2e.testUrl') as string;
let claimantName: string;

test.beforeEach(async ({ page }) => {
test.beforeEach(async ({ page }, testInfo) => {
initializeExecutor(page);
process.env.WALES_POSTCODE = 'YES';
process.env.CLAIMANT_NAME = submitCaseApiDataWales.submitCasePayload.claimantName;
claimantName = process.env.CLAIMANT_NAME;
await performAction('createCaseAPI', { data: createCaseApiWalesData.createCasePayload });
await performAction('submitCaseAPI', { data: submitCaseApiDataWales.submitCasePayload });
logTestEnvAfterBeforeEach(testInfo.title, RESPOND_TO_CLAIM_WALES_BEFORE_EACH_ENV_KEYS);
await performAction('fetchPINsAPI');
await performAction('createUser', 'citizen', ['citizen']);
await performAction('validateAccessCodeAPI');
Expand Down
8 changes: 8 additions & 0 deletions src/test/ui/test-README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,14 @@ await performValidationGroup(
yarn test:functional
```

### PFT test-env debug logging

In [`playwright.config.ts`](../../../playwright.config.ts), `enable_pft_debug_log` is **`false` by default**. Set it to **`true`** if you want environment variables to be printed in the console while you debug.

```ts
export const enable_pft_debug_log = false;
```

## 8. Troubleshooting

| Issue | Solution |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
enable_navigation_tests,
enable_visibility_validation,
} from '../../../../../../playwright.config';
import { shortUrl, truncateForLog } from '../../common/string.utils';
import { IAction } from '../../interfaces';
import {
ErrorMessageValidation,
Expand All @@ -35,7 +36,15 @@ export class TriggerPageFunctionalTestsAction implements IAction {

private async triggerPageFunctionalTests(page: Page): Promise<void> {
const pageName = await this.getFileNameForPage(page);

if (!pageName) {
if (TriggerPageFunctionalTestsAction.isDashboardUrl(page.url())) {
return;
}
const urlSegment = this.getUrlSegment(page.url());
console.warn(
`[PFT] WARNING mapping missing in urlToFileMapping.config.ts | test="${truncateForLog(test.info().title, 160)}" | url=${shortUrl(page.url())} | key: ${urlSegment}`
);
return;
}

Expand Down Expand Up @@ -214,6 +223,15 @@ export class TriggerPageFunctionalTestsAction implements IAction {
}
}

/** Dashboard is not in url mapping; skip PFT warn. */
private static isDashboardUrl(url: string): boolean {
try {
return new URL(url).pathname.split('/').filter(Boolean)[0] === 'dashboard';
} catch {
return /\/dashboard(\/|$)/.test(url);
}
}

private async runVisibilityValidation(page: Page, pageName: string, pftFilePath: string): Promise<void> {
delete require.cache[require.resolve(pftFilePath)];
const pftModule = require(pftFilePath);
Expand Down
29 changes: 29 additions & 0 deletions src/test/ui/utils/common/log-test-env.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { enable_pft_debug_log } from '../../../../../playwright.config';

/** Env keys set in `respondToAClaim.spec.ts` `beforeEach` (plus `CASE_NUMBER` from submit). */
export const RESPOND_TO_CLAIM_BEFORE_EACH_ENV_KEYS = [
'CASE_NUMBER',
'CLAIMANT_NAME',
'CLAIMANT_NAME_OVERRIDDEN',
'CORRESPONDENCE_ADDRESS',
'GROUNDS',
'NOTICE_DATE_PROVIDED',
'NOTICE_DETAILS_NO_NOTSURE',
'NOTICE_SERVED',
'RENT_NON_RENT',
'TENANCY_START_DATE_KNOWN',
'TENANCY_TYPE',
] as const;

export const DASHBOARD_BEFORE_EACH_ENV_KEYS = ['CASE_NUMBER', 'GROUNDS', 'NOTICE_SERVED', 'TENANCY_TYPE'] as const;

export const RESPOND_TO_CLAIM_WALES_BEFORE_EACH_ENV_KEYS = ['CASE_NUMBER', 'CLAIMANT_NAME', 'WALES_POSTCODE'] as const;

export function logTestEnvAfterBeforeEach(testTitle: string, keys: readonly string[]): void {
if (!enable_pft_debug_log) {
return;
}
const kv = keys.map(key => `${key}=${process.env[key] ?? ''}`).join(' ');
console.log(`\n📊 TEST ENVIRONMENT VARIABLES\n`);
console.log(`[test env] ${testTitle} | ${kv}`);
}
20 changes: 20 additions & 0 deletions src/test/ui/utils/common/pft-validation-screenshot.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { Page } from '@playwright/test';
import { test } from '@playwright/test';

export async function takeValidationFailureScreenshot(
page: Page,
category: 'error-messages' | 'page-content' | 'page-navigation',
pageName: string
): Promise<void> {
try {
const body = await page.screenshot({ fullPage: true });
await test
.info()
.attach(`Validation failure (${category.replace(/-/g, ' ')}): ${(pageName.trim() || 'page').slice(0, 80)}`, {
body,
contentType: 'image/png',
});
} catch (err) {
console.warn('[PFT] screenshot attach failed:', err instanceof Error ? err.message : String(err));
}
}
15 changes: 15 additions & 0 deletions src/test/ui/utils/common/string.utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
export function truncateForLog(text: string, maxLen = 200): string {
return text.length <= maxLen ? text : `${text.slice(0, maxLen)}…`;
}

export function shortUrl(url: string, maxLen = 120): string {
let s = url;
try {
const u = new URL(url);
s = u.pathname + u.search;
} catch {
/* keep raw string when URL is relative or invalid */
}
return s.length <= maxLen ? s : `${s.slice(0, maxLen)}…`;
}

export function escapeForRegex(text: string): string {
return text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as path from 'path';

import { Page } from '@playwright/test';

import { takeValidationFailureScreenshot } from '../../common/pft-validation-screenshot';
import { IValidation, validationData, validationRecord } from '../../interfaces';

type ValidationResult = {
Expand Down Expand Up @@ -106,6 +107,10 @@ export class ErrorMessageValidation implements IValidation {
const pageUrl = page.url();
const pageName = await ErrorMessageValidation.getPageNameFromUrl(pageUrl, page);

if (!passed) {
await takeValidationFailureScreenshot(page, 'error-messages', pageName);
}

ErrorMessageValidation.results.push({
pageUrl,
pageName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as path from 'path';
import { Page } from '@playwright/test';

import { contactUs } from '../../../data/section-data/contactUs.section.data';
import { takeValidationFailureScreenshot } from '../../common/pft-validation-screenshot';
import { escapeForRegex, exactTextWithOptionalWhitespaceRegex } from '../../common/string.utils';
import { performAction } from '../../controller';
import { IValidation } from '../../interfaces';
Expand Down Expand Up @@ -165,7 +166,11 @@ export class PageContentValidation implements IValidation {
}

PageContentValidation.validationResults.set(pageUrl, pageResults);
if (pageResults.some(r => r.status === 'fail')) {
await takeValidationFailureScreenshot(page, 'page-content', pageName);
}
} catch (error) {
await takeValidationFailureScreenshot(page, 'page-content', pageName);
// Add the error as a validation failure
pageResults.push({
element: 'SectionData',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as path from 'path';

import { Page, expect } from '@playwright/test';

import { takeValidationFailureScreenshot } from '../../common/pft-validation-screenshot';
import { performAction } from '../../controller';
import { IValidation, validationRecord } from '../../interfaces';

Expand Down Expand Up @@ -161,8 +162,13 @@ export class PageNavigationValidation implements IValidation {

const pageName = await PageNavigationValidation.getPageNameFromUrl(page.url(), page);
const hasPFTFile = await PageNavigationValidation.hasPFTFile(pageName);

const overallPassed = elementPassed && urlPassed;

if (!overallPassed) {
await takeValidationFailureScreenshot(page, 'page-navigation', pageName);
}

if (!elementPassed) {
PageNavigationValidation.navigationResults.push({
pageUrl: page.url(),
Expand Down Expand Up @@ -213,6 +219,7 @@ export class PageNavigationValidation implements IValidation {
}
} catch (error) {
const pageName = await PageNavigationValidation.getPageNameFromUrl(page.url(), page);
await takeValidationFailureScreenshot(page, 'page-navigation', pageName);
const actualText = await page
.locator('h1')
.first()
Expand Down
Loading