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.' } ];