From 65f364f42ce0e6ada54c54cdb47d5f14bcd141f6 Mon Sep 17 00:00:00 2001
From: Jon Mulhern <81927768+curlyfriesplease@users.noreply.github.com>
Date: Mon, 24 Mar 2025 16:42:29 +0000
Subject: [PATCH 1/8] Adds additional postcode validation
---
src/pages/GiftAid/SubmitForm/SubmitForm.js | 6 ++++--
src/pages/GiftAid/UpdateForm/UpdateForm.js | 2 ++
src/pages/GiftAid/utils/Utils.js | 6 ++++++
3 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/src/pages/GiftAid/SubmitForm/SubmitForm.js b/src/pages/GiftAid/SubmitForm/SubmitForm.js
index d7c45b21..a32fba14 100644
--- a/src/pages/GiftAid/SubmitForm/SubmitForm.js
+++ b/src/pages/GiftAid/SubmitForm/SubmitForm.js
@@ -9,6 +9,7 @@ import FormHeader from '../../../components/FormHeader/FormHeader';
import FormButton from '../../../components/Buttons/FormButton/index';
import InputFields from '../../../components/InputFields/InputFields';
import JustInTime from '../../../components/JustInTime/index';
+import { postcodeRegex } from '../utils/Utils';
// fields data
import { submitFormFields } from './SubmitFormFields';
@@ -103,6 +104,7 @@ function SubmitForm(props) {
Object.keys(validation).map(key => setFieldValidity(validation[key], key));
}
}
+ postcodeValidation={postcodeRegex}
/>
- submitForm(e)}
- text="Gift Aid your donation"
+ text="Gift Aid your donation"
/>
diff --git a/src/pages/GiftAid/UpdateForm/UpdateForm.js b/src/pages/GiftAid/UpdateForm/UpdateForm.js
index f834a3eb..a1dfdaf3 100644
--- a/src/pages/GiftAid/UpdateForm/UpdateForm.js
+++ b/src/pages/GiftAid/UpdateForm/UpdateForm.js
@@ -11,6 +11,7 @@ import JustInTime from '../../../components/JustInTime/index';
// fields data
import { updateFormFields, giftAidButtonChoices } from './UpdateFormFields';
+import { postcodeRegex } from '../utils/Utils';
// import context
import FormContext from '../../../context/FormContext';
@@ -67,6 +68,7 @@ function UpdateForm(props) {
Object.keys(validation).map(key => setFieldValidity(validation[key], key));
}
}
+ postcodeValidation={postcodeRegex}
/>
diff --git a/src/pages/GiftAid/utils/Utils.js b/src/pages/GiftAid/utils/Utils.js
index fccc5697..c9c9c993 100644
--- a/src/pages/GiftAid/utils/Utils.js
+++ b/src/pages/GiftAid/utils/Utils.js
@@ -51,6 +51,12 @@ export const getPathParams = (update = false) => {
};
};
+export const postcodeRegex = {
+ GB: {
+ pattern: '^[a-z]{1,2}\\d[a-z\\d]?\\s*\\d[a-z]{2}$',
+ errorMsg: 'Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.',
+ },
+};
/**
* Function to Create form fields
From 380499f904002d6258664a340331fb747dcc2e93 Mon Sep 17 00:00:00 2001
From: Jon Mulhern <81927768+curlyfriesplease@users.noreply.github.com>
Date: Mon, 24 Mar 2025 16:48:47 +0000
Subject: [PATCH 2/8] Updates upload-artifact version from v3 to v4
---
.github/workflows/main.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index c7970a9d..d7c38524 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -44,7 +44,7 @@ jobs:
# Test run video was always captured, so this action uses "always()" condition
- name: Upload videos
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
From 7c920975a018708ae69d0015833e8138b4781beb Mon Sep 17 00:00:00 2001
From: Jon Mulhern <81927768+curlyfriesplease@users.noreply.github.com>
Date: Mon, 24 Mar 2025 17:05:31 +0000
Subject: [PATCH 3/8] Update tests
---
.../tests/submit/addressValidation.spec.js | 18 +-
.../tests/update/formValidation.spec.js | 161 +++++++++---------
.../tests/submit/addressValidation.spec.js | 18 +-
.../tests/update/formValidation.spec.js | 53 +++---
4 files changed, 132 insertions(+), 118 deletions(-)
diff --git a/playwright-local/tests/submit/addressValidation.spec.js b/playwright-local/tests/submit/addressValidation.spec.js
index bea38bb2..9779e779 100644
--- a/playwright-local/tests/submit/addressValidation.spec.js
+++ b/playwright-local/tests/submit/addressValidation.spec.js
@@ -5,29 +5,31 @@ test.describe('Address validation', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/', { timeout: 30000 });
-
+
await page.waitForLoadState('domcontentloaded');
await page.locator('#field-label--giftaid').click();
await page.locator('#field-input--mobile').fill('07123456789');
await page.locator('input#field-input--firstname').fill('test');
await page.locator('input#field-input--lastname').fill('user');
});
-
+
test('empty postcode should show error message', async ({ page }) => {
await page.locator('input#field-input--postcode').fill('');
await page.locator('button[type=submit]').click();
await expect(page.locator('div#field-error--postcode > span')).toHaveText('Please enter your postcode');
await page.close();
});
-
+
test('invalid postcodes should show error messages', async ({ page }) => {
await page.locator('input#field-input--postcode').fill('12SE17TP');
await expect(page.locator('div#field-error--postcode > span')).toHaveText('Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.');
await page.locator('input#field-input--postcode').fill('comic relief');
await expect(page.locator('div#field-error--postcode > span')).toHaveText('Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.');
+ await page.locator('input#field-input--postcode').fill('cro 7tp');
+ await expect(page.locator('div#field-error--postcode > span')).toHaveText('Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.');
await page.close();
});
-
+
test('enter postcode but submit without selecting address should show error message', async ({ page }) => {
await page.locator('input#field-input--postcode').fill('SE1 7TP');
await page.locator('#postcode_button').click();
@@ -36,7 +38,7 @@ test.describe('Address validation', () => {
await expect(page.locator('div#field-error--addressSelect > span')).toHaveText('Please select your address');
await page.close();
});
-
+
test('clicking on manual address link should show address fields', async ({ page }) => {
await page.locator('input#field-input--postcode').fill('SE1 7TP');
await expect(page.locator('a[aria-describedby=field-error--addressDetails]')).toBeVisible();
@@ -48,17 +50,17 @@ test.describe('Address validation', () => {
await expect(page.locator('select#field-select--country')).toBeVisible();
await page.close();
});
-
+
test('validate address fields', async ({ page }) => {
await page.locator('input#field-input--postcode').fill('SE1 7TP');
await page.locator('a[aria-describedby=field-error--addressDetails]').click();
-
+
// Should see error message for address1 when inout with special characters is entered
await page.locator('#field-input--address1').fill('@£%3dComic Relief');
await expect(page.locator('#field-error--address1 > span')).toHaveText("This field only accepts alphanumeric characters and ' . - & _ /");
await page.locator('#field-input--town').fill(' Comic Relief');
await expect(page.locator('#field-error--town > span')).toHaveText("This field only accepts alphanumeric characters and ' . - & _ /");
-
+
await page.close();
});
});
diff --git a/playwright-local/tests/update/formValidation.spec.js b/playwright-local/tests/update/formValidation.spec.js
index 900070dc..41b801ee 100644
--- a/playwright-local/tests/update/formValidation.spec.js
+++ b/playwright-local/tests/update/formValidation.spec.js
@@ -7,15 +7,15 @@ const chance = new Chance();
const email = `giftaid-staging-${Date.now().toString()}@email.sls.comicrelief.com`;
test.describe('Giftaid update form validation', () => {
-
+
test.beforeEach(async ({ page }) => {
await page.goto('/update', { timeout: 30000 });
-
+
await page.waitForLoadState('domcontentloaded');
});
-
+
test('empty input fields should show error messages', async ({ page }) => {
-
+
// submit the form
await page.locator('button[type=submit]').click();
@@ -23,145 +23,145 @@ test.describe('Giftaid update form validation', () => {
await expect(page.locator('div#field-error--lastname > span')).toContainText('Please fill in your last name');
await expect(page.locator('div#field-error--postcode > span')).toContainText('Please enter your postcode');
await expect(page.locator('div#field-error--addressDetails > span')).toContainText('Please fill in your address');
-
+
// click on manual address link to show address fields error messages
await page.locator('a[aria-describedby=field-error--addressDetails]').click();
await expect(page.locator('div#field-error--address1 > span')).toContainText('Please fill in your address line 1');
await expect(page.locator('div#field-error--town > span')).toContainText('Please fill in your town/city');
-
+
// giftaid declaration error message
await expect(page.locator('div#field-error--giftAidClaimChoice > span')).toContainText('This field is required');
await page.close();
});
-
-
+
+
test('validate first name field on giftaid update form', async ({ page }) => {
-
+
const commands = new Commands(page);
-
+
await page.locator('#field-input--firstname').fill('test');
await page.locator('#field-input--firstname').fill('');
await expect(page.locator('#field-error--firstname')).toContainText('Please fill in your first name');
-
+
// enter firstname field with special chars should show error message
await page.locator('#field-input--firstname').type('Test^$%£');
await expect(page.locator('#field-error--firstname')).toContainText('This field only accepts alphabetic characters and \' -\n');
-
+
// firstname with just a space should show error message
await page.keyboard.press('Backspace');
await page.locator('#field-input--firstname').type(' ');
await expect(page.locator('#field-error--firstname')).toContainText('This field only accepts alphabetic characters and \' -\n');
-
+
// firstname with a mixture of alphanumeric chars should show error message
await page.locator('#field-input--firstname').fill(''); // clear the first-name field
await page.locator('#field-input--firstname').type('123Test');
await expect(page.locator('#field-error--firstname')).toContainText('This field only accepts alphabetic characters and \' -\n');
-
+
// clear the first name field
await page.locator('#field-input--firstname').fill('');
-
+
// entering valid input fields should be able to submit the form
await commands.populateUpdateFormFields(page);
// select giftaid declaration
await page.locator('#giftAidClaimChoice>div:nth-child(2)>label').click();
-
+
// submit the form
await page.locator('button[type=submit]').click();
-
+
await expect(page.locator('div > h1')).toContainText('Thank you,\n' +
'test!');
-
+
await page.close();
});
-
+
test('validate last name field on giftaid update form', async ({ page }) => {
-
+
const commands = new Commands(page);
-
+
await page.locator('#field-input--lastname').fill('test lastname');
await page.locator('#field-input--lastname').fill('');
await expect(page.locator('div#field-error--lastname > span')).toContainText('Please fill in your last name');
-
+
// enter lastname field with special chars should show error message
await page.locator('#field-input--lastname').type('Test^$%£');
await expect(page.locator('div#field-error--lastname > span')).toContainText('This field only accepts alphanumeric characters and , . ( ) / & \' -');
-
+
// lastname with just a space should show error message
await page.keyboard.press('Backspace');
await page.locator('#field-input--lastname').type(' ');
await expect(page.locator('div#field-error--lastname > span')).toContainText('This field only accepts alphanumeric characters and , . ( ) / & \' -');
-
+
// lastname with a mixture of alphanumeric chars should not show error message
await page.locator('#field-input--lastname').fill(''); // clear the last-name field
await page.locator('#field-input--lastname').type('123Test');
// should not show error message
expect(await page.locator('div#field-error--lastname > span').count()).toEqual(0);
-
+
// clear the last name field
await page.locator('#field-input--lastname').fill('');
-
+
// entering valid input fields should be able to submit the form
await commands.populateUpdateFormFields(page);
-
+
// select giftaid declaration
await page.locator('#giftAidClaimChoice>div:nth-child(2)>label').click();
-
+
// submit the form
await page.locator('button[type=submit]').click();
-
+
await expect(page.locator('div > h1')).toContainText('Thank you,\n' +
'test!');
-
+
await page.close();
-
+
});
-
+
test('validate email field on giftaid update form', async ({ page }) => {
-
+
const commands = new Commands(page);
-
+
// email validation
// email that has $ after the domian name should show error message
await page.locator('input#field-input--email').fill('test@comic$relief.com');
await expect(page.locator('div#field-error--email > span')).toContainText('Please fill in a valid email address');
-
+
// email that has @ after the domian name should show error message
await page.locator('input#field-input--email').fill(''); // clear the email field
await page.locator('input#field-input--email').type('test@c{(micrelief.com');
await expect(page.locator('div#field-error--email > span')).toContainText('Please fill in a valid email address');
-
+
// email that has % after the domian name should show error message
await page.locator('input#field-input--email').fill('');
await page.locator('input#field-input--email').type('test@comic%relief.com');
await expect(page.locator('div#field-error--email > span')).toContainText('Please fill in a valid email address');
-
+
// email that has special chars $%^ before domain name should not show error message
await page.locator('input#field-input--email').fill('');
await page.locator('input#field-input--email').type('te$%^st@comicrelief.com');
await expect(page.locator('div#field-error--email > span')).not.toBeVisible();
-
+
// email that has mix of special chars that's valid and not valid should show error message
await page.locator('input#field-input--email').fill('');
await page.locator('input#field-input--email').type('Test0-9!#$%&\'*+/=?^_{|}~-@comicrelief_9-8.com.uk');
await expect(page.locator('div#field-error--email > span')).toContainText('Please fill in a valid email address');
-
+
// clear the email field
await page.locator('input#field-input--email').fill('');
-
+
// entering valid input fields should be able to submit the form
await commands.populateUpdateFormFields(page);
// select giftaid declaration
await page.locator('#giftAidClaimChoice>div:nth-child(2)>label').click();
-
+
// submit the form
await page.locator('button[type=submit]').click();
-
+
await expect(page.locator('div > h1')).toContainText('Thank you,\n' +
'test!');
-
+
await page.close();
});
@@ -174,7 +174,7 @@ test.describe('Giftaid update form validation', () => {
// Generate the remaining 8 digits randomly
const mobile = `${prefix}${chance.string({ pool: '0123456789', length: 8 })}`;
console.log('mobile number generated', mobile);
-
+
// Test cases for various mobile number validations
const mobileTestCases = [
{ input: '0712345678', error: 'Please enter a valid mobile phone number - it must be the same number associated with your donation.' },
@@ -182,13 +182,13 @@ test.describe('Giftaid update form validation', () => {
{ input: '0712 345 6789', error: 'Please enter a valid mobile phone number - it must be the same number associated with your donation.' },
{ input: '0780ab5694245', error: 'Please enter a valid mobile phone number - it must be the same number associated with your donation.' },
];
-
+
for (let testCase of mobileTestCases) {
await page.locator('#field-input--mobile').fill(''); // Clear the field before each test
await page.locator('#field-input--mobile').type(testCase.input, { delay: 100 });
await expect(page.locator('div#field-error--mobile > span')).toHaveText(testCase.error);
}
-
+
// Validate correct mobile number
await page.locator('#field-input--mobile').fill(''); // Ensure the field is cleared before filling with valid data
@@ -200,93 +200,102 @@ test.describe('Giftaid update form validation', () => {
await page.locator('button[type=submit]').click();
await expect(page.locator('div > h1')).toHaveText('Thank you, test!');
});
-
+
test('postcode entered with extra spaces should show error message', async ({ page }) => {
-
+
await page.locator('input#field-input--postcode').type('S E 1 7 T P');
await expect(page.locator('div#field-error--postcode > span')).toBeVisible();
await expect(page.locator('div#field-error--postcode > span')).toContainText('Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.');
-
+
await page.close();
});
-
+
test('postcode entered in lowercase should show error message', async ({ page }) => {
-
+
await page.locator('input#field-input--postcode').type('se17tp');
await expect(page.locator('div#field-error--postcode > span')).toBeVisible();
await expect(page.locator('div#field-error--postcode > span')).toContainText('Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.');
-
+
await page.close();
});
-
+
test('postcode entered with no spaces should show error message', async ({ page }) => {
-
+
await page.locator('input#field-input--postcode').type('SE17TP');
await expect(page.locator('div#field-error--postcode > span')).toBeVisible();
await expect(page.locator('div#field-error--postcode > span')).toContainText('Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.');
-
+
await page.close();
});
-
+
test('postcode entered with special characters should show error message', async ({ page }) => {
-
+
await page.locator('input#field-input--postcode').type('SE$%TP');
await expect(page.locator('div#field-error--postcode > span')).toBeVisible();
await expect(page.locator('div#field-error--postcode > span')).toContainText('Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.');
-
+
await page.close();
});
-
+
+ test('postcode with incorrect format like "cro 7tp" should show error message', async ({ page }) => {
+
+ await page.locator('input#field-input--postcode').type('cro 7tp');
+ await expect(page.locator('div#field-error--postcode > span')).toBeVisible();
+ await expect(page.locator('div#field-error--postcode > span')).toContainText('Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.');
+
+ await page.close();
+ });
+
test('enter valid UK postcode on giftaid update form using postcode lookup should be able to submit the form', async ({ page }) => {
-
+
// fill in all input fields
await page.locator('#field-input--firstname').fill('test');
await page.locator('#field-input--lastname').fill('test lastname');
await page.locator('input#field-input--email').fill('giftaid-staging-@email.sls.comicrelief.com');
-
+
// enter postcode
await page.locator('input#field-input--postcode').fill('SE1 7TP');
// click on postcode lookup button
await page.locator('#postcode_button').click();
-
+
if (await page.locator('#field-select--addressSelect').isVisible()) {
console.log('postcode lookup address dropdown present select the address');
-
+
await expect(page.locator('#field-select--addressSelect')).toBeVisible();
-
+
await page.waitForSelector('select#field-select--addressSelect');
-
+
const optionToSelect = await page.locator('option', { hasText: 'COMIC RELIEF, CAMELFORD HOUSE 87-90' }).textContent();
console.log('selected option: ', optionToSelect);
-
+
// Use option text to select
await page.locator('select#field-select--addressSelect').selectOption({ label: optionToSelect });
-
+
// expect pre-enetered se17tp postcode to change to SE1 7TP when address is selected by removing the extra spaces
await expect(page.locator('input#field-input--postcode')).toHaveValue('SE1 7TP');
-
+
const addressLine1 = await page.evaluate(() => document.querySelector('#field-input--address1').getAttribute('value'));
console.log('Address line 1 field value is : ', addressLine1);
-
+
const addressLine2 = await page.evaluate(() => document.querySelector('#field-input--address2').getAttribute('value'));
console.log('Address line 1 field value is : ', addressLine2);
-
+
const addressLine3 = await page.evaluate(() => document.querySelector('#field-input--address3').getAttribute('value'));
console.log('Address line 1 field value is : ', addressLine3);
-
+
const town = await page.evaluate(() => document.querySelector('input#field-input--town').getAttribute('value'));
console.log('Address line 1 field value is : ', town);
// select giftaid declaration
await page.locator('#giftAidClaimChoice>div:nth-child(2)>label').click();
-
+
// clicking on submit button should show error on address lookup
await page.locator('button[type=submit]').click();
-
+
await expect(page.locator('div > h1')).toContainText('Thank you,\n' +
'test!');
} else {
-
+
// click on manual address link
await page.locator('a[aria-describedby=field-error--addressDetails]').click();
await page.locator('#field-input--address1').type('COMIC RELIEF');
@@ -296,10 +305,10 @@ test.describe('Giftaid update form validation', () => {
// select giftaid declaration
await page.locator('#giftAidClaimChoice>div:nth-child(2)>label').click();
-
+
// clicking on submit button should show error on address lookup
await page.locator('button[type=submit]').click();
-
+
await expect(page.locator('div > h1')).toContainText('Thank you,\n' +
'test!');
}
diff --git a/playwright-staging/tests/submit/addressValidation.spec.js b/playwright-staging/tests/submit/addressValidation.spec.js
index d2a7915b..1a574546 100644
--- a/playwright-staging/tests/submit/addressValidation.spec.js
+++ b/playwright-staging/tests/submit/addressValidation.spec.js
@@ -3,7 +3,7 @@ const { expect } = require('@playwright/test');
const { test } = require('../../browserstack');
test.describe('Address validation @sanity @nightly-sanity', () => {
-
+
test.beforeEach(async ({ page }) => {
// Navigate to the giftaid page
await page.goto(process.env.BASE_URL, { timeout: 30000 });
@@ -13,22 +13,24 @@ test.describe('Address validation @sanity @nightly-sanity', () => {
await page.locator('input#field-input--firstname').fill('test');
await page.locator('input#field-input--lastname').fill('user');
});
-
+
test('empty postcode should show error message', async ({ page }) => {
await page.locator('input#field-input--postcode').fill('');
await page.locator('button[type=submit]').click();
await expect(page.locator('div#field-error--postcode > span')).toHaveText('Please enter your postcode');
await page.close();
});
-
+
test('invalid postcodes should show error messages', async ({ page }) => {
await page.locator('input#field-input--postcode').fill('12SE17TP');
await expect(page.locator('div#field-error--postcode > span')).toHaveText('Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.');
await page.locator('input#field-input--postcode').fill('comic relief');
await expect(page.locator('div#field-error--postcode > span')).toHaveText('Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.');
+ await page.locator('input#field-input--postcode').fill('cro 7tp');
+ await expect(page.locator('div#field-error--postcode > span')).toHaveText('Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.');
await page.close();
});
-
+
test('enter postcode but submit without selecting address should show error message', async ({ page }) => {
await page.locator('input#field-input--postcode').fill('SE1 7TP');
await page.locator('#postcode_button').click();
@@ -37,7 +39,7 @@ test.describe('Address validation @sanity @nightly-sanity', () => {
await expect(page.locator('div#field-error--addressSelect > span')).toHaveText('Please select your address');
await page.close();
});
-
+
test('clicking on manual address link should show address fields', async ({ page }) => {
await page.locator('input#field-input--postcode').fill('SE1 7TP');
await expect(page.locator('a[aria-describedby=field-error--addressDetails]')).toBeVisible();
@@ -49,17 +51,17 @@ test.describe('Address validation @sanity @nightly-sanity', () => {
await expect(page.locator('select#field-select--country')).toBeVisible();
await page.close();
});
-
+
test('validate address fields', async ({ page }) => {
await page.locator('input#field-input--postcode').fill('SE1 7TP');
await page.locator('a[aria-describedby=field-error--addressDetails]').click();
-
+
// Should see error message for address1 when inout with special characters is entered
await page.locator('#field-input--address1').fill('@£%3dComic Relief');
await expect(page.locator('#field-error--address1 > span')).toHaveText("This field only accepts alphanumeric characters and ' . - & _ /");
await page.locator('#field-input--town').fill(' Comic Relief');
await expect(page.locator('#field-error--town > span')).toHaveText("This field only accepts alphanumeric characters and ' . - & _ /");
-
+
await page.close();
});
});
diff --git a/playwright-staging/tests/update/formValidation.spec.js b/playwright-staging/tests/update/formValidation.spec.js
index 529c1c8e..4763de6c 100644
--- a/playwright-staging/tests/update/formValidation.spec.js
+++ b/playwright-staging/tests/update/formValidation.spec.js
@@ -8,18 +8,18 @@ const chance = new Chance();
test.describe('Giftaid Update form validation @sanity @nightly-sanity', () => {
let commands;
-
+
test.beforeEach(async ({ page }) => {
- commands = new Commands(page);
+ commands = new Commands(page);
// Navigate to the Giftaid Update form
await page.goto(`${process.env.BASE_URL}update`, { timeout: 30000 });
await page.waitForLoadState('domcontentloaded');
});
-
+
test('empty input fields should show error messages', async ({ page }) => {
// Submit the form without filling out any fields
await page.click('button[type=submit]');
-
+
// Check for the error messages associated with each field
await expect(page.locator('div#field-error--firstname > span')).toHaveText('Please fill in your first name');
await expect(page.locator('div#field-error--lastname > span')).toHaveText('Please fill in your last name');
@@ -29,17 +29,17 @@ test.describe('Giftaid Update form validation @sanity @nightly-sanity', () => {
await expect(page.locator('div#field-error--giftAidClaimChoice > span')).toHaveText('This field is required');
await page.close();
});
-
+
test('Validate first name field on Giftaid update form', async ({ page }) => {
const commands = new Commands(page);
-
+
// Set up different first name test cases
const firstNameTestCases = [
{ input: 'Test^$%£', error: "This field only accepts alphabetic characters and ' -" }, // Test for invalid characters
{ input: ' ', error: "This field only accepts alphabetic characters and ' -" }, // Test for space as input
{ input: '123Test', error: "This field only accepts alphabetic characters and ' -" } // Test for alphanumeric input
];
-
+
for (let testCase of firstNameTestCases) {
await page.fill('#field-input--firstname', testCase.input);
if (testCase.input) {
@@ -47,20 +47,20 @@ test.describe('Giftaid Update form validation @sanity @nightly-sanity', () => {
}
await expect(page.locator('#field-error--firstname')).toHaveText(testCase.error);
}
-
+
// Test for a valid first name
await page.fill('#field-input--firstname', ''); // clear firstname field
await commands.populateUpdateFormFields(page, { firstName: 'John' });
await page.click('#giftAidClaimChoice>div:nth-child(2)>label'); // Select yes for declaration
await page.click('button[type=submit]'); // Submit the form
-
+
await expect(page.locator('div.success-wrapper--inner h1')).toHaveText('Thank you, John!');
await page.close();
});
-
+
test('Validate email field on giftaid update form', async ({ page }) => {
const commands = new Commands(page);
-
+
// Set up different email test cases
const emailTestCases = [
{ input: 'test@comic$relief.com', error: 'Please fill in a valid email address', visible: true },
@@ -69,7 +69,7 @@ test.describe('Giftaid Update form validation @sanity @nightly-sanity', () => {
{ input: 'te$%^st@comicrelief.com', error: '', visible: false },
{ input: 'Test0-9!#$%&\'*+/=?^_{|}~-@comicrelief_9-8.com.uk', error: 'Please fill in a valid email address', visible: true }
];
-
+
for (let testCase of emailTestCases) {
await page.fill('input#field-input--email', ''); // clear the email field before entering the test cases input
await page.fill('input#field-input--email', testCase.input);
@@ -81,18 +81,18 @@ test.describe('Giftaid Update form validation @sanity @nightly-sanity', () => {
await expect(page.locator('div#field-error--email > span')).not.toBeVisible();
}
}
-
+
// Test for a valid email
const validEmail = `giftaid-update-staging-${chance.email()}`;
await page.fill('input#field-input--email', ''); // clear email field
await commands.populateUpdateFormFields(page, { email: validEmail });
await page.click('#giftAidClaimChoice>div:nth-child(3)>label'); // Select no for declaration
await page.click('button[type=submit]'); // Submit the form
-
+
await expect(page.locator('div.success-wrapper--inner h1')).toHaveText('Thanks for letting us know');
await page.close();
});
-
+
test('Validate mobile number field on giftaid update form', async ({ page }) => {
const commands = new Commands(page);
// List of allowed prefixes for UK mobile numbers
@@ -102,7 +102,7 @@ test.describe('Giftaid Update form validation @sanity @nightly-sanity', () => {
// Generate the remaining 8 digits randomly
const mobile = `${prefix}${chance.string({ pool: '0123456789', length: 8 })}`;
console.log('mobile number generated', mobile);
-
+
// Test cases for various mobile number validations
const mobileTestCases = [
{ input: '0712345678', error: 'Please enter a valid mobile phone number - it must be the same number associated with your donation.' },
@@ -110,31 +110,32 @@ test.describe('Giftaid Update form validation @sanity @nightly-sanity', () => {
{ input: '0712 345 6789', error: 'Please enter a valid mobile phone number - it must be the same number associated with your donation.' },
{ input: '0780ab5694245', error: 'Please enter a valid mobile phone number - it must be the same number associated with your donation.' },
];
-
+
for (let testCase of mobileTestCases) {
await page.locator('#field-input--mobile').fill(''); // Clear the field before each test
await page.locator('#field-input--mobile').type(testCase.input, { delay: 100 });
await expect(page.locator('div#field-error--mobile > span')).toHaveText(testCase.error);
}
-
+
// Validate correct mobile number
await page.locator('#field-input--mobile').fill(''); // Ensure the field is cleared and filled with valid data
await commands.populateUpdateFormFields(page, { lastName: 'test', mobile: mobile });
await page.click('#giftAidClaimChoice>div:nth-child(2)>label'); // Select yes for declaration
await page.click('button[type=submit]'); // Submit the form
-
+
await expect(page.locator('div.success-wrapper--inner h1')).toHaveText('Thank you, test!');
});
-
+
test('Postcode validation and form submission', async ({ page }) => {
// Define postcodes and expected error messages
const postcodes = [
{ input: 'S E 1 7 T P', error: 'Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.' },
{ input: 'se17tp', error: 'Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.' },
{ input: 'SE17TP', error: 'Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.' },
- { input: 'SE$%TP', error: 'Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.' }
+ { input: 'SE$%TP', error: 'Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.' },
+ { input: 'cro 7tp', error: 'Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.' }
];
-
+
// Test for each invalid postcode
for (const postcode of postcodes) {
await page.fill('input#field-input--postcode', '');
@@ -142,11 +143,11 @@ test.describe('Giftaid Update form validation @sanity @nightly-sanity', () => {
await expect(page.locator('div#field-error--postcode > span')).toBeVisible();
await expect(page.locator('div#field-error--postcode > span')).toHaveText(postcode.error);
}
-
+
// Test for a valid postcode and subsequent form submission
await page.fill('input#field-input--postcode', 'SE1 7TP');
await page.click('#postcode_button');
-
+
// Checking whether address selection is available or if manual entry is needed
if (await page.locator('#field-select--addressSelect').isVisible()) {
// Select the first address if available
@@ -162,14 +163,14 @@ test.describe('Giftaid Update form validation @sanity @nightly-sanity', () => {
await page.fill('input#field-input--town', 'LONDON');
await page.click('button[type=submit]');
}
-
+
await page.locator('input#field-input--firstname').fill('test');
await page.locator('input#field-input--lastname').fill(chance.last());
await page.locator('input#field-input--email').fill(`giftaid-update-staging-${chance.email()}`);
await page.fill('input#field-input--postcode', 'SE1 7TP');
await page.click('#giftAidClaimChoice>div:nth-child(2)>label'); // Select yes for declaration
await page.click('button[type=submit]'); // Submit the form
-
+
await expect(page.locator('div.success-wrapper--inner h1')).toHaveText('Thank you, test!');
await page.close();
});
From d88cce164db820caa0b29c1fac7f524b84de2447 Mon Sep 17 00:00:00 2001
From: Jon Mulhern <81927768+curlyfriesplease@users.noreply.github.com>
Date: Mon, 24 Mar 2025 17:43:01 +0000
Subject: [PATCH 4/8] Attempt to resolve libasound missing installation
candidate error
---
.github/workflows/main.yml | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index d7c38524..f53dc3a8 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -31,6 +31,11 @@ jobs:
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
+ - name: Install system dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y libasound2
+
- name: Install playwright browsers
run: yarn playwright install --with-deps chromium
From d46bc97eb6d12864c8587bd73ae66088ec88ec5f Mon Sep 17 00:00:00 2001
From: Jon Mulhern <81927768+curlyfriesplease@users.noreply.github.com>
Date: Mon, 24 Mar 2025 17:44:53 +0000
Subject: [PATCH 5/8] Reversing last commit which had no effect
---
.github/workflows/main.yml | 5 -----
1 file changed, 5 deletions(-)
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index f53dc3a8..d7c38524 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -31,11 +31,6 @@ jobs:
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- - name: Install system dependencies
- run: |
- sudo apt-get update
- sudo apt-get install -y libasound2
-
- name: Install playwright browsers
run: yarn playwright install --with-deps chromium
From 78c27831cbca5001b4c660387c25a606ec7148ef Mon Sep 17 00:00:00 2001
From: Krupa Pammi
Date: Tue, 25 Mar 2025 11:15:30 +0000
Subject: [PATCH 6/8] install playwright chromium without deps
---
.github/workflows/main.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index d7c38524..721fe861 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -32,7 +32,7 @@ jobs:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Install playwright browsers
- run: yarn playwright install --with-deps chromium
+ run: yarn playwright install chromium
- name: Run end-to-end tests
run: yarn test:playwright-local:ci
From cf164f04cdc4b4a32d797cf9f85609d254090a64 Mon Sep 17 00:00:00 2001
From: Jon Mulhern <81927768+curlyfriesplease@users.noreply.github.com>
Date: Fri, 10 Apr 2026 15:44:17 +0100
Subject: [PATCH 7/8] Match regex rule with data-models
---
src/pages/GiftAid/utils/Utils.js | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/pages/GiftAid/utils/Utils.js b/src/pages/GiftAid/utils/Utils.js
index c9c9c993..bbdcebf1 100644
--- a/src/pages/GiftAid/utils/Utils.js
+++ b/src/pages/GiftAid/utils/Utils.js
@@ -51,9 +51,10 @@ export const getPathParams = (update = false) => {
};
};
+// Regex matches what we use in data-models, which the backend uses to validate postcodes.
export const postcodeRegex = {
GB: {
- pattern: '^[a-z]{1,2}\\d[a-z\\d]?\\s*\\d[a-z]{2}$',
+ pattern: '^[A-Za-z]{1,2}\\d[A-Za-z\\d]?\\s*\\d[A-Za-z]{2}$',
errorMsg: 'Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.',
},
};
From 73c6ce5824f795c32afca9678433a217a50f7a64 Mon Sep 17 00:00:00 2001
From: Jon Mulhern <81927768+curlyfriesplease@users.noreply.github.com>
Date: Fri, 10 Apr 2026 16:11:02 +0100
Subject: [PATCH 8/8] Update tests now that regex has changed
---
.../tests/submit/postcodeLookup.spec.js | 2 --
.../tests/update/formValidation.spec.js | 20 +++++--------------
.../tests/submit/postcodeLookup.spec.js | 2 --
.../tests/update/formValidation.spec.js | 2 --
4 files changed, 5 insertions(+), 21 deletions(-)
diff --git a/playwright-local/tests/submit/postcodeLookup.spec.js b/playwright-local/tests/submit/postcodeLookup.spec.js
index 229981ac..63959b33 100644
--- a/playwright-local/tests/submit/postcodeLookup.spec.js
+++ b/playwright-local/tests/submit/postcodeLookup.spec.js
@@ -16,8 +16,6 @@ test.describe('Postcode validation', () => {
test('Postcode formatting errors', async ({ page }) => {
const postcodes = [
{ code: 'S E 1 7 T P', message: 'Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.' },
- { code: 'se17tp', message: 'Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.' },
- { code: 'SE17TP', message: 'Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.' },
{ code: 'SE$%TP', message: 'Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.' }
];
diff --git a/playwright-local/tests/update/formValidation.spec.js b/playwright-local/tests/update/formValidation.spec.js
index c12347b8..7fee95a5 100644
--- a/playwright-local/tests/update/formValidation.spec.js
+++ b/playwright-local/tests/update/formValidation.spec.js
@@ -216,21 +216,11 @@ test.describe('Giftaid update form validation', () => {
await page.close();
});
- test('postcode entered in lowercase should show error message', async ({ page }) => {
-
- await page.locator('input#field-input--postcode').type('se17tp');
- await expect(page.locator('div#field-error--postcode > span')).toBeVisible();
- await expect(page.locator('div#field-error--postcode > span')).toContainText('Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.');
-
- await page.close();
- });
-
- test('postcode entered with no spaces should show error message', async ({ page }) => {
-
- await page.locator('input#field-input--postcode').type('SE17TP');
- await expect(page.locator('div#field-error--postcode > span')).toBeVisible();
- await expect(page.locator('div#field-error--postcode > span')).toContainText('Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.');
-
+ test('compact lowercase and no-space UK postcodes do not show format error (aligned with data-models / postcode)', async ({ page }) => {
+ await page.locator('input#field-input--postcode').fill('se17tp');
+ await expect(page.locator('div#field-error--postcode > span')).not.toBeVisible();
+ await page.locator('input#field-input--postcode').fill('SE17TP');
+ await expect(page.locator('div#field-error--postcode > span')).not.toBeVisible();
await page.close();
});
diff --git a/playwright-staging/tests/submit/postcodeLookup.spec.js b/playwright-staging/tests/submit/postcodeLookup.spec.js
index 79d71b8e..740c4b52 100644
--- a/playwright-staging/tests/submit/postcodeLookup.spec.js
+++ b/playwright-staging/tests/submit/postcodeLookup.spec.js
@@ -16,8 +16,6 @@ test.describe('Postcode validation @sanity @nightly-sanity', () => {
test('Postcode formatting errors', async ({ page }) => {
const postcodes = [
{ code: 'S E 1 7 T P', message: 'Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.' },
- { code: 'se17tp', message: 'Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.' },
- { code: 'SE17TP', message: 'Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.' },
{ code: 'SE$%TP', message: 'Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.' }
];
diff --git a/playwright-staging/tests/update/formValidation.spec.js b/playwright-staging/tests/update/formValidation.spec.js
index 6f1aad18..0c71fe80 100644
--- a/playwright-staging/tests/update/formValidation.spec.js
+++ b/playwright-staging/tests/update/formValidation.spec.js
@@ -136,8 +136,6 @@ test.describe('Giftaid Update form validation @sanity @nightly-sanity', () => {
// Define postcodes and expected error messages
const postcodes = [
{ input: 'S E 1 7 T P', error: 'Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.' },
- { input: 'se17tp', error: 'Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.' },
- { input: 'SE17TP', error: 'Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.' },
{ input: 'SE$%TP', error: 'Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.' },
{ input: 'cro 7tp', error: 'Please enter a valid UK postcode, using a space. For non-UK addresses, please use manual entry below.' }
];