From 391a878f135c90c45d96a5373751527d2e3ba2f7 Mon Sep 17 00:00:00 2001 From: kitttang Date: Wed, 20 Aug 2025 09:29:54 +0100 Subject: [PATCH 1/4] patch: Align with GDS and Accessibility --- e2e/cypress/e2e/runner/dateValidation.js | 4 ++-- .../common/i_see_the_error_string_for_string.js | 2 +- .../plugins/engine/pageControllers/PageControllerBase.ts | 6 +++--- .../engine/pluginHandlers/exit/prehandlers/utils.ts | 2 +- runner/src/server/plugins/engine/types.ts | 2 +- .../plugins/engine/views/components/fileuploadfield.html | 4 ++-- runner/src/server/services/upload/uploadService.ts | 8 ++++++-- runner/src/server/views/layout.html | 1 + .../cases/server/plugins/engine/datepartsfield.test.ts | 2 +- .../engine/pageControllers/PageControllerBase.test.ts | 2 +- runner/test/cases/server/upload.test.js | 2 +- 11 files changed, 20 insertions(+), 15 deletions(-) diff --git a/e2e/cypress/e2e/runner/dateValidation.js b/e2e/cypress/e2e/runner/dateValidation.js index d0080e1a78..61b7a26119 100644 --- a/e2e/cypress/e2e/runner/dateValidation.js +++ b/e2e/cypress/e2e/runner/dateValidation.js @@ -22,7 +22,7 @@ Then("I see the date parts error {string}", (error) => { /** * Date parts only show one error at a time. */ - cy.findByText("Fix the following errors"); + cy.findByText("There is a problem"); cy.findByRole("link", { name: error, exact: false }); }); @@ -32,7 +32,7 @@ Then( /** * Date parts only show one error at a time. */ - cy.findByText("Fix the following errors"); + cy.findByText("There is a problem"); cy.get(`#${fieldName}-error`).within(() => { cy.findByText(error, { exact: false }); }); diff --git a/e2e/cypress/support/step_definitions/common/i_see_the_error_string_for_string.js b/e2e/cypress/support/step_definitions/common/i_see_the_error_string_for_string.js index b1c0e2a70e..5ed4d1f281 100644 --- a/e2e/cypress/support/step_definitions/common/i_see_the_error_string_for_string.js +++ b/e2e/cypress/support/step_definitions/common/i_see_the_error_string_for_string.js @@ -1,7 +1,7 @@ import { When } from "@badeball/cypress-cucumber-preprocessor"; When("I see the error {string} for {string}", (error, fieldName) => { - cy.findByText("Fix the following errors"); + cy.findByText("There is a problem"); cy.findByRole("link", { name: error }); cy.findByRole("group", { description: `Error: ${error}` }); }); diff --git a/runner/src/server/plugins/engine/pageControllers/PageControllerBase.ts b/runner/src/server/plugins/engine/pageControllers/PageControllerBase.ts index d21fb54cd8..6885745b51 100644 --- a/runner/src/server/plugins/engine/pageControllers/PageControllerBase.ts +++ b/runner/src/server/plugins/engine/pageControllers/PageControllerBase.ts @@ -611,7 +611,7 @@ export class PageControllerBase { }); formResult.errors = Object.is(formResult.errors, null) - ? { titleText: "Fix the following errors" } + ? { titleText: "There is a problem" } : formResult.errors; formResult.errors.errorList = reformattedErrors; } @@ -638,7 +638,7 @@ export class PageControllerBase { }); formResult.errors = Object.is(formResult.errors, null) - ? { titleText: "Fix the following errors" } + ? { titleText: "There is a problem" } : formResult.errors; formResult.errors.errorList = reformattedErrors; } @@ -841,7 +841,7 @@ export class PageControllerBase { } get errorSummaryTitle() { - return "Fix the following errors"; + return "There is a problem"; } /** diff --git a/runner/src/server/plugins/engine/pluginHandlers/exit/prehandlers/utils.ts b/runner/src/server/plugins/engine/pluginHandlers/exit/prehandlers/utils.ts index 19229333a8..4eb911ca12 100644 --- a/runner/src/server/plugins/engine/pluginHandlers/exit/prehandlers/utils.ts +++ b/runner/src/server/plugins/engine/pluginHandlers/exit/prehandlers/utils.ts @@ -19,7 +19,7 @@ export function errorListFromValidationResult( const errorList = errors.details.map(errorListItemToErrorVM); return { - titleText: "Fix the following errors", + titleText: "There is a problem", errorList: errorList.filter( ({ text }, index) => index === errorList.findIndex((err) => err.text === text) diff --git a/runner/src/server/plugins/engine/types.ts b/runner/src/server/plugins/engine/types.ts index af24b5e51c..0da5951902 100644 --- a/runner/src/server/plugins/engine/types.ts +++ b/runner/src/server/plugins/engine/types.ts @@ -61,7 +61,7 @@ export type FormSubmissionState = { }; export type FormSubmissionErrors = { - titleText: string; // e.b: "Fix the following errors" + titleText: string; // e.b: "There is a problem" errorList: { path: string; // e.g: "firstName" href: string; // e.g: "#firstName" diff --git a/runner/src/server/plugins/engine/views/components/fileuploadfield.html b/runner/src/server/plugins/engine/views/components/fileuploadfield.html index 085a0a2e86..9bcf102a0c 100644 --- a/runner/src/server/plugins/engine/views/components/fileuploadfield.html +++ b/runner/src/server/plugins/engine/views/components/fileuploadfield.html @@ -5,8 +5,8 @@

You previously uploaded the file ‘{{component.model.value}}’

{% endif %} {% endmacro %} diff --git a/runner/src/server/services/upload/uploadService.ts b/runner/src/server/services/upload/uploadService.ts index 9990ab7eb1..a1e3122f56 100644 --- a/runner/src/server/services/upload/uploadService.ts +++ b/runner/src/server/services/upload/uploadService.ts @@ -47,10 +47,14 @@ export class UploadService { validFiletypesString(customAcceptedTypes?: string[]) { const acceptedTypes = customAcceptedTypes ?? this.validContentTypes; - const acceptedTypeNames = acceptedTypes + let acceptedTypeNames = acceptedTypes .map((type) => contentTypeToName[type]) - .filter(Boolean); + .filter(Boolean) + .map((type) => type.toUpperCase()); + const namesSet = new Set(acceptedTypeNames); + acceptedTypeNames = Array.from(namesSet); + const acceptedTypesNameWithoutLast = acceptedTypeNames .slice(0, -1) .join(", "); diff --git a/runner/src/server/views/layout.html b/runner/src/server/views/layout.html index 062592c4d1..6c838beef9 100644 --- a/runner/src/server/views/layout.html +++ b/runner/src/server/views/layout.html @@ -180,6 +180,7 @@

Default page template

GOVUKFrontend.modalDialog.init() {% endif %} }); + {% if BROWSER_REFRESH_URL %} diff --git a/runner/test/cases/server/plugins/engine/datepartsfield.test.ts b/runner/test/cases/server/plugins/engine/datepartsfield.test.ts index 2b7b8a09d6..3a7d75e4e2 100644 --- a/runner/test/cases/server/plugins/engine/datepartsfield.test.ts +++ b/runner/test/cases/server/plugins/engine/datepartsfield.test.ts @@ -62,7 +62,7 @@ suite("Date parts field", () => { type: "DatePartsField", }; const errors = { - titleText: "Fix the following errors", + titleText: "There is a problem", errorList: [ { path: "approximate__day", diff --git a/runner/test/cases/server/plugins/engine/pageControllers/PageControllerBase.test.ts b/runner/test/cases/server/plugins/engine/pageControllers/PageControllerBase.test.ts index 18fbdb9bd9..da5cd4317d 100644 --- a/runner/test/cases/server/plugins/engine/pageControllers/PageControllerBase.test.ts +++ b/runner/test/cases/server/plugins/engine/pageControllers/PageControllerBase.test.ts @@ -63,7 +63,7 @@ suite("PageControllerBase", () => { }; expect(page.getErrors(error)).to.equal({ - titleText: "Fix the following errors", + titleText: "There is a problem", errorList: [ { path: "approximate", diff --git a/runner/test/cases/server/upload.test.js b/runner/test/cases/server/upload.test.js index 0d025deb24..981a16b305 100644 --- a/runner/test/cases/server/upload.test.js +++ b/runner/test/cases/server/upload.test.js @@ -150,7 +150,7 @@ suite("uploads", () => { const $ = cheerio.load(response.payload); expect($("[href='#file1']").text().trim()).to.contain( - 'The selected file for "Passport photo" must be a jpg, jpeg, png or pdf' + 'The selected file for "Passport photo" must be a JPG, JPEG, PNG or PDF' ); }); From 39a3211c5cd0f32d5682e46e6ed8f73f54dd03aa Mon Sep 17 00:00:00 2001 From: kitttang Date: Mon, 15 Sep 2025 10:06:35 +0100 Subject: [PATCH 2/4] Update layout.html --- runner/src/server/views/layout.html | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/runner/src/server/views/layout.html b/runner/src/server/views/layout.html index 6c838beef9..744cb69382 100644 --- a/runner/src/server/views/layout.html +++ b/runner/src/server/views/layout.html @@ -181,6 +181,14 @@

Default page template

{% endif %} }); + document.addEventListener('DOMContentLoaded', function (event) { + const navType = performance.getEntriesByType('navigation')[0].type; + if ((navType === 'navigate' || navType === 'back_forward') && + !document.querySelector('.govuk-error-summary') && + window.location.hash === "#main-content") { + history.replaceState(null, "", window.location.pathname); + } + }, true) {% if BROWSER_REFRESH_URL %} From e71e5277d6b6597bc496cb031aca2b510ab6c77d Mon Sep 17 00:00:00 2001 From: kitttang Date: Mon, 15 Sep 2025 10:30:33 +0100 Subject: [PATCH 3/4] Update initialiseSession.feature --- e2e/cypress/e2e/runner/initialiseSession.feature | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/e2e/cypress/e2e/runner/initialiseSession.feature b/e2e/cypress/e2e/runner/initialiseSession.feature index cce8ccda7c..a63732ed4d 100644 --- a/e2e/cypress/e2e/runner/initialiseSession.feature +++ b/e2e/cypress/e2e/runner/initialiseSession.feature @@ -6,7 +6,7 @@ Feature: Initialise session - prepopulate a session | form | callbackUrl | redirectPath | message | htmlMessage | title | | initialiseSession | https://61bca17e-fe74-40e0-9c15-a901ad120eca.mock.pstmn.io | /summary | | | | And I go to the initialised session URL - Then I see "Summary" + Then I see the heading "Summary" Scenario: The configured message is displayed @@ -15,7 +15,7 @@ Feature: Initialise session - prepopulate a session | form | callbackUrl | redirectPath | message | htmlMessage | title | | initialiseSession | https://61bca17e-fe74-40e0-9c15-a901ad120eca.mock.pstmn.io | /summary | your favourite egg is wrong | | | And I go to the initialised session URL - Then I see "Summary" + Then I see the heading "Summary" And I see "your favourite egg is wrong" Scenario: The configured htmlMessage is displayed @@ -24,7 +24,7 @@ Feature: Initialise session - prepopulate a session | form | callbackUrl | redirectPath | message | htmlMessage | title | | initialiseSession | https://61bca17e-fe74-40e0-9c15-a901ad120eca.mock.pstmn.io | /summary | |

This is not a type of egg

| | And I go to the initialised session URL - Then I see "Summary" + Then I see the heading "Summary" And I see "This is not a type of egg" And I don't see "

" @@ -46,4 +46,4 @@ Feature: Initialise session - prepopulate a session And I declare and continue Then I see "Cookies are files saved on your phone" When I revisit the status page - Then I see "Cookies are files saved on your phone" \ No newline at end of file + Then I see "Cookies are files saved on your phone" From ec71384232469523ef74f4a3e6047521a291493f Mon Sep 17 00:00:00 2001 From: kitttang Date: Tue, 16 Sep 2025 15:43:59 +0100 Subject: [PATCH 4/4] Update layout.html moving out skip to main content change --- runner/src/server/views/layout.html | 9 --------- 1 file changed, 9 deletions(-) diff --git a/runner/src/server/views/layout.html b/runner/src/server/views/layout.html index 744cb69382..062592c4d1 100644 --- a/runner/src/server/views/layout.html +++ b/runner/src/server/views/layout.html @@ -180,15 +180,6 @@

Default page template

GOVUKFrontend.modalDialog.init() {% endif %} }); - - document.addEventListener('DOMContentLoaded', function (event) { - const navType = performance.getEntriesByType('navigation')[0].type; - if ((navType === 'navigate' || navType === 'back_forward') && - !document.querySelector('.govuk-error-summary') && - window.location.hash === "#main-content") { - history.replaceState(null, "", window.location.pathname); - } - }, true) {% if BROWSER_REFRESH_URL %}