diff --git a/packages/govuk-frontend/.htmlvalidate.js b/packages/govuk-frontend/.htmlvalidate.js index ac4c9aee0a..e73bbd7e38 100644 --- a/packages/govuk-frontend/.htmlvalidate.js +++ b/packages/govuk-frontend/.htmlvalidate.js @@ -15,9 +15,15 @@ module.exports = { // Allow pattern attribute on input type="number" 'input-attributes': 'off', + // Require input to have a label + 'input-missing-label': 'error', + // Allow inline styles for testing purposes 'no-inline-style': 'off', + // Require all form field and ARIA references to exist + 'no-missing-references': 'error', + // Allow for explicit roles on regions that have implict roles // We do this to better support AT with older versions of IE that // have partial support for HTML5 semantic elements diff --git a/packages/govuk-frontend/src/govuk/components/button/button.yaml b/packages/govuk-frontend/src/govuk/components/button/button.yaml index c2423d98bc..fa5437d2b2 100644 --- a/packages/govuk-frontend/src/govuk/components/button/button.yaml +++ b/packages/govuk-frontend/src/govuk/components/button/button.yaml @@ -186,7 +186,7 @@ examples: element: button text: Submit attributes: - aria-controls: content + aria-controls: test-target-element data-tracking-dimension: 123 - name: link attributes hidden: true @@ -194,7 +194,7 @@ examples: element: a text: Submit attributes: - aria-controls: content + aria-controls: test-target-element data-tracking-dimension: 123 - name: input attributes hidden: true @@ -202,7 +202,7 @@ examples: element: input text: Submit attributes: - aria-controls: content + aria-controls: test-target-element data-tracking-dimension: 123 - name: classes hidden: true diff --git a/packages/govuk-frontend/src/govuk/components/button/template.test.js b/packages/govuk-frontend/src/govuk/components/button/template.test.js index 02fc91b9c8..4a359720e6 100644 --- a/packages/govuk-frontend/src/govuk/components/button/template.test.js +++ b/packages/govuk-frontend/src/govuk/components/button/template.test.js @@ -23,7 +23,7 @@ describe('Button', () => { const $ = render('button', examples.attributes) const $component = $('.govuk-button') - expect($component.attr('aria-controls')).toEqual('content') + expect($component.attr('aria-controls')).toEqual('test-target-element') expect($component.attr('data-tracking-dimension')).toEqual('123') }) @@ -123,7 +123,7 @@ describe('Button', () => { const $ = render('button', examples['link attributes']) const $component = $('.govuk-button') - expect($component.attr('aria-controls')).toEqual('content') + expect($component.attr('aria-controls')).toEqual('test-target-element') expect($component.attr('data-tracking-dimension')).toEqual('123') }) @@ -148,7 +148,7 @@ describe('Button', () => { const $ = render('button', examples['input attributes']) const $component = $('.govuk-button') - expect($component.attr('aria-controls')).toEqual('content') + expect($component.attr('aria-controls')).toEqual('test-target-element') expect($component.attr('data-tracking-dimension')).toEqual('123') }) diff --git a/packages/govuk-frontend/src/govuk/components/checkboxes/checkboxes.yaml b/packages/govuk-frontend/src/govuk/components/checkboxes/checkboxes.yaml index 2a6fda8fa5..d7b444dbb2 100644 --- a/packages/govuk-frontend/src/govuk/components/checkboxes/checkboxes.yaml +++ b/packages/govuk-frontend/src/govuk/components/checkboxes/checkboxes.yaml @@ -696,7 +696,7 @@ examples: options: name: example-name fieldset: - describedBy: content + describedBy: test-target-element legend: text: Which option? items: @@ -804,7 +804,7 @@ examples: errorMessage: text: Please select an option fieldset: - describedBy: content + describedBy: test-target-element legend: text: What is your nationality? hint: @@ -858,7 +858,7 @@ examples: - name: with single option set 'aria-describedby' on input, and describedBy hidden: true options: - describedBy: content + describedBy: test-target-element name: t-and-c errorMessage: text: Please accept the terms and conditions @@ -868,7 +868,7 @@ examples: - name: with single option (and hint) set 'aria-describedby' on input, and describedBy hidden: true options: - describedBy: content + describedBy: test-target-element name: t-and-c-with-hint errorMessage: text: Please accept the terms and conditions @@ -894,7 +894,7 @@ examples: errorMessage: text: Please select an option fieldset: - describedBy: content + describedBy: test-target-element legend: text: What is your nationality? items: diff --git a/packages/govuk-frontend/src/govuk/components/checkboxes/template.test.js b/packages/govuk-frontend/src/govuk/components/checkboxes/template.test.js index 4dae256f0e..2723bb8ff0 100644 --- a/packages/govuk-frontend/src/govuk/components/checkboxes/template.test.js +++ b/packages/govuk-frontend/src/govuk/components/checkboxes/template.test.js @@ -82,7 +82,7 @@ describe('Checkboxes', () => { const $ = render('checkboxes', examples['with fieldset describedBy']) const $fieldset = $('.govuk-fieldset') - expect($fieldset.attr('aria-describedby')).toMatch('content') + expect($fieldset.attr('aria-describedby')).toMatch('test-target-element') }) it('render attributes', () => { @@ -404,7 +404,7 @@ describe('Checkboxes', () => { const errorMessageId = $('.govuk-error-message').attr('id') const describedBy = new RegExp( - `${WORD_BOUNDARY}content${WHITESPACE}${errorMessageId}${WORD_BOUNDARY}` + `${WORD_BOUNDARY}test-target-element${WHITESPACE}${errorMessageId}${WORD_BOUNDARY}` ) expect($fieldset.attr('aria-describedby')).toMatch(describedBy) @@ -461,7 +461,7 @@ describe('Checkboxes', () => { const hintId = $('.govuk-hint').attr('id') const describedBy = new RegExp( - `${WORD_BOUNDARY}content${WHITESPACE}${hintId}${WORD_BOUNDARY}` + `${WORD_BOUNDARY}test-target-element${WHITESPACE}${hintId}${WORD_BOUNDARY}` ) expect($fieldset.attr('aria-describedby')).toMatch(describedBy) @@ -495,7 +495,7 @@ describe('Checkboxes', () => { const errorMessageId = $('.govuk-error-message').attr('id') const describedByCombined = new RegExp( - `${WORD_BOUNDARY}content${WHITESPACE}${hintId}${WHITESPACE}${errorMessageId}${WORD_BOUNDARY}` + `${WORD_BOUNDARY}test-target-element${WHITESPACE}${hintId}${WHITESPACE}${errorMessageId}${WORD_BOUNDARY}` ) expect($fieldset.attr('aria-describedby')).toMatch(describedByCombined) @@ -548,7 +548,9 @@ describe('Checkboxes', () => { const $ = render('checkboxes', examples[exampleName]) const $input = $('input') - expect($input.attr('aria-describedby')).toMatch('content t-and-c-error') + expect($input.attr('aria-describedby')).toMatch( + 'test-target-element t-and-c-error' + ) }) }) @@ -573,7 +575,7 @@ describe('Checkboxes', () => { const $input = $('input') expect($input.attr('aria-describedby')).toMatch( - 'content t-and-c-with-hint-error t-and-c-with-hint-item-hint' + 'test-target-element t-and-c-with-hint-error t-and-c-with-hint-item-hint' ) }) }) diff --git a/packages/govuk-frontend/src/govuk/components/components.template.test.js b/packages/govuk-frontend/src/govuk/components/components.template.test.js index 633d54eaaa..25b3f2a31e 100644 --- a/packages/govuk-frontend/src/govuk/components/components.template.test.js +++ b/packages/govuk-frontend/src/govuk/components/components.template.test.js @@ -9,6 +9,7 @@ const { } = require('@govuk-frontend/lib/components') const validatorConfig = require('govuk-frontend/.htmlvalidate.js') const { HtmlValidate } = require('html-validate') +const { outdent } = require('outdent') describe('Components', () => { let nunjucksEnvCustom @@ -65,10 +66,18 @@ describe('Components', () => { // Validate component examples for (const { component: componentName, fixtures } of componentsFixtures) { const fixtureTasks = fixtures.map(async (fixture) => { - const html = render(componentName, { - context: fixture.options, - fixture - }) + const html = outdent` + ${render(componentName, { + context: fixture.options, + fixture + })} + + +
+ ` // Validate HTML return expect({ diff --git a/packages/govuk-frontend/src/govuk/components/date-input/date-input.yaml b/packages/govuk-frontend/src/govuk/components/date-input/date-input.yaml index e2b16bfbde..97e2086cc1 100644 --- a/packages/govuk-frontend/src/govuk/components/date-input/date-input.yaml +++ b/packages/govuk-frontend/src/govuk/components/date-input/date-input.yaml @@ -349,7 +349,7 @@ examples: options: id: dob-errors fieldset: - describedBy: content + describedBy: test-target-element legend: text: What is your date of birth? hint: @@ -359,7 +359,7 @@ examples: options: id: dob-errors fieldset: - describedBy: content + describedBy: test-target-element legend: text: What is your date of birth? errorMessage: diff --git a/packages/govuk-frontend/src/govuk/components/date-input/template.test.js b/packages/govuk-frontend/src/govuk/components/date-input/template.test.js index 874c3def76..a216bffb1f 100644 --- a/packages/govuk-frontend/src/govuk/components/date-input/template.test.js +++ b/packages/govuk-frontend/src/govuk/components/date-input/template.test.js @@ -206,7 +206,7 @@ describe('Date input', () => { const hintId = $('.govuk-hint').attr('id') const describedBy = new RegExp( - `${WORD_BOUNDARY}content${WHITESPACE}${hintId}${WORD_BOUNDARY}` + `${WORD_BOUNDARY}test-target-element${WHITESPACE}${hintId}${WORD_BOUNDARY}` ) expect($fieldset.attr('aria-describedby')).toMatch(describedBy) @@ -246,7 +246,7 @@ describe('Date input', () => { const $fieldset = $('.govuk-fieldset') expect($fieldset.attr('aria-describedby')).toMatch( - 'content dob-errors-error' + 'test-target-element dob-errors-error' ) }) diff --git a/packages/govuk-frontend/src/govuk/components/fieldset/fieldset.yaml b/packages/govuk-frontend/src/govuk/components/fieldset/fieldset.yaml index 529884bfd8..f7591a8853 100644 --- a/packages/govuk-frontend/src/govuk/components/fieldset/fieldset.yaml +++ b/packages/govuk-frontend/src/govuk/components/fieldset/fieldset.yaml @@ -113,7 +113,7 @@ examples: - name: with describedBy hidden: true options: - describedBy: content + describedBy: test-target-element legend: text: Which option? - name: html as text diff --git a/packages/govuk-frontend/src/govuk/components/fieldset/template.test.js b/packages/govuk-frontend/src/govuk/components/fieldset/template.test.js index d5ee48d5a9..042fa0244f 100644 --- a/packages/govuk-frontend/src/govuk/components/fieldset/template.test.js +++ b/packages/govuk-frontend/src/govuk/components/fieldset/template.test.js @@ -40,7 +40,7 @@ describe('fieldset', () => { const $ = render('fieldset', examples['with describedBy']) const $component = $('.govuk-fieldset') - expect($component.attr('aria-describedby')).toEqual('content') + expect($component.attr('aria-describedby')).toEqual('test-target-element') }) it('escapes HTML in the text argument', () => { diff --git a/packages/govuk-frontend/src/govuk/components/file-upload/file-upload.yaml b/packages/govuk-frontend/src/govuk/components/file-upload/file-upload.yaml index 4955d90e89..5c7805a6c8 100644 --- a/packages/govuk-frontend/src/govuk/components/file-upload/file-upload.yaml +++ b/packages/govuk-frontend/src/govuk/components/file-upload/file-upload.yaml @@ -126,7 +126,7 @@ examples: name: file-upload-describedby label: text: Upload a file - describedBy: content + describedBy: test-target-element - name: with hint and describedBy hidden: true options: @@ -134,7 +134,7 @@ examples: name: file-upload-hint-describedby label: text: Upload a file - describedBy: content + describedBy: test-target-element hint: text: Your photo may be in your Pictures, Photos, Downloads or Desktop folder. Or in an app like iPhoto. - name: error @@ -153,7 +153,7 @@ examples: name: file-upload-error-describedby label: text: Upload a file - describedBy: content + describedBy: test-target-element errorMessage: text: Error message - name: with error, describedBy and hint @@ -163,7 +163,7 @@ examples: name: file-upload-error-describedby-hint label: text: Upload a file - describedBy: content + describedBy: test-target-element errorMessage: text: Error message hint: diff --git a/packages/govuk-frontend/src/govuk/components/file-upload/template.test.js b/packages/govuk-frontend/src/govuk/components/file-upload/template.test.js index b9e1534c27..fa5e028cdb 100644 --- a/packages/govuk-frontend/src/govuk/components/file-upload/template.test.js +++ b/packages/govuk-frontend/src/govuk/components/file-upload/template.test.js @@ -56,7 +56,7 @@ describe('File upload', () => { const $ = render('file-upload', examples['with describedBy']) const $component = $('.govuk-file-upload') - expect($component.attr('aria-describedby')).toMatch('content') + expect($component.attr('aria-describedby')).toMatch('test-target-element') }) it('renders with attributes', () => { @@ -104,7 +104,7 @@ describe('File upload', () => { const hintId = $('.govuk-hint').attr('id') const describedBy = new RegExp( - `${WORD_BOUNDARY}content${WHITESPACE}${hintId}${WORD_BOUNDARY}` + `${WORD_BOUNDARY}test-target-element${WHITESPACE}${hintId}${WORD_BOUNDARY}` ) expect($component.attr('aria-describedby')).toMatch(describedBy) @@ -138,7 +138,7 @@ describe('File upload', () => { const errorMessageId = $('.govuk-error-message').attr('id') const describedBy = new RegExp( - `${WORD_BOUNDARY}content${WHITESPACE}${errorMessageId}${WORD_BOUNDARY}` + `${WORD_BOUNDARY}test-target-element${WHITESPACE}${errorMessageId}${WORD_BOUNDARY}` ) expect($component.attr('aria-describedby')).toMatch(describedBy) @@ -175,7 +175,7 @@ describe('File upload', () => { }) it('associates the input as described by the hint, error message and parent fieldset', () => { - const describedById = 'content' + const describedById = 'test-target-element' const $ = render( 'file-upload', diff --git a/packages/govuk-frontend/src/govuk/components/input/input.yaml b/packages/govuk-frontend/src/govuk/components/input/input.yaml index ef7b84425a..ec2a858033 100644 --- a/packages/govuk-frontend/src/govuk/components/input/input.yaml +++ b/packages/govuk-frontend/src/govuk/components/input/input.yaml @@ -351,7 +351,7 @@ examples: name: with-describedby label: text: With describedBy - describedBy: content + describedBy: test-target-element - name: attributes hidden: true options: @@ -368,7 +368,7 @@ examples: name: with-hint-describedby label: text: With hint describedBy - describedBy: content + describedBy: test-target-element hint: text: It’s on your National Insurance card, benefit letter, payslip or P60. For example, ‘QQ 12 34 56 C’. - name: error with describedBy @@ -378,7 +378,7 @@ examples: name: with-error-describedby label: text: With error describedBy - describedBy: content + describedBy: test-target-element errorMessage: text: Error message - name: with error and hint @@ -403,7 +403,7 @@ examples: text: Error message hint: text: Hint - describedBy: content + describedBy: test-target-element - name: inputmode hidden: true options: diff --git a/packages/govuk-frontend/src/govuk/components/input/template.test.js b/packages/govuk-frontend/src/govuk/components/input/template.test.js index b755b68fdb..d854a16caf 100644 --- a/packages/govuk-frontend/src/govuk/components/input/template.test.js +++ b/packages/govuk-frontend/src/govuk/components/input/template.test.js @@ -75,7 +75,7 @@ describe('Input', () => { const $ = render('input', examples['with describedBy']) const $component = $('.govuk-input') - expect($component.attr('aria-describedby')).toMatch('content') + expect($component.attr('aria-describedby')).toMatch('test-target-element') }) it('renders with attributes', () => { @@ -127,7 +127,7 @@ describe('Input', () => { const hintId = $('.govuk-hint').attr('id') const describedBy = new RegExp( - `${WORD_BOUNDARY}content${WHITESPACE}${hintId}${WORD_BOUNDARY}` + `${WORD_BOUNDARY}test-target-element${WHITESPACE}${hintId}${WORD_BOUNDARY}` ) expect($input.attr('aria-describedby')).toMatch(describedBy) @@ -161,7 +161,7 @@ describe('Input', () => { const errorMessageId = $('.govuk-error-message').attr('id') const describedBy = new RegExp( - `${WORD_BOUNDARY}content${WHITESPACE}${errorMessageId}${WORD_BOUNDARY}` + `${WORD_BOUNDARY}test-target-element${WHITESPACE}${errorMessageId}${WORD_BOUNDARY}` ) expect($input.attr('aria-describedby')).toMatch(describedBy) @@ -228,7 +228,7 @@ describe('Input', () => { const hintId = $('.govuk-hint').attr('id') const describedByCombined = new RegExp( - `${WORD_BOUNDARY}content${WHITESPACE}${hintId}${WHITESPACE}${errorMessageId}${WORD_BOUNDARY}` + `${WORD_BOUNDARY}test-target-element${WHITESPACE}${hintId}${WHITESPACE}${errorMessageId}${WORD_BOUNDARY}` ) expect($component.attr('aria-describedby')).toMatch(describedByCombined) diff --git a/packages/govuk-frontend/src/govuk/components/label/label.yaml b/packages/govuk-frontend/src/govuk/components/label/label.yaml index a8f45d49e1..567150ce7f 100644 --- a/packages/govuk-frontend/src/govuk/components/label/label.yaml +++ b/packages/govuk-frontend/src/govuk/components/label/label.yaml @@ -93,7 +93,7 @@ examples: - name: for hidden: true options: - for: content + for: test-target-element text: National Insurance number - name: attributes hidden: true diff --git a/packages/govuk-frontend/src/govuk/components/label/template.test.js b/packages/govuk-frontend/src/govuk/components/label/template.test.js index 8ffc4a1fbc..4e63667ae1 100644 --- a/packages/govuk-frontend/src/govuk/components/label/template.test.js +++ b/packages/govuk-frontend/src/govuk/components/label/template.test.js @@ -58,7 +58,7 @@ describe('Label', () => { const $ = render('label', examples.for) const labelForAttr = $('.govuk-label').attr('for') - expect(labelForAttr).toEqual('content') + expect(labelForAttr).toEqual('test-target-element') }) it('can be nested inside an H1 using isPageHeading', () => { diff --git a/packages/govuk-frontend/src/govuk/components/radios/radios.yaml b/packages/govuk-frontend/src/govuk/components/radios/radios.yaml index 2b639a3936..c4b526b25e 100644 --- a/packages/govuk-frontend/src/govuk/components/radios/radios.yaml +++ b/packages/govuk-frontend/src/govuk/components/radios/radios.yaml @@ -689,7 +689,7 @@ examples: options: name: example-name fieldset: - describedBy: content + describedBy: test-target-element legend: text: Which option? items: @@ -767,7 +767,7 @@ examples: options: name: example-hint-describedby fieldset: - describedBy: content + describedBy: test-target-element legend: text: Have you changed your name? hint: @@ -823,7 +823,7 @@ examples: errorMessage: text: Please select an option fieldset: - describedBy: content + describedBy: test-target-element legend: text: Have you changed your name? hint: @@ -882,7 +882,7 @@ examples: errorMessage: text: Please select an option fieldset: - describedBy: content + describedBy: test-target-element legend: text: Have you changed your name? items: diff --git a/packages/govuk-frontend/src/govuk/components/radios/template.test.js b/packages/govuk-frontend/src/govuk/components/radios/template.test.js index 59b59d6ad3..922a056ae0 100644 --- a/packages/govuk-frontend/src/govuk/components/radios/template.test.js +++ b/packages/govuk-frontend/src/govuk/components/radios/template.test.js @@ -47,7 +47,7 @@ describe('Radios', () => { }) it('renders initial aria-describedby on fieldset', () => { - const describedById = 'content' + const describedById = 'test-target-element' const $ = render('radios', examples['fieldset with describedBy']) @@ -309,7 +309,7 @@ describe('Radios', () => { const $ = render('radios', examples['with describedBy and hint']) const $fieldset = $('.govuk-fieldset') - expect($fieldset.attr('aria-describedby')).toMatch('content') + expect($fieldset.attr('aria-describedby')).toMatch('test-target-element') }) }) @@ -358,7 +358,7 @@ describe('Radios', () => { const errorMessageId = $('.govuk-error-message').attr('id') const describedBy = new RegExp( - `${WORD_BOUNDARY}content${WHITESPACE}${errorMessageId}${WORD_BOUNDARY}` + `${WORD_BOUNDARY}test-target-element${WHITESPACE}${errorMessageId}${WORD_BOUNDARY}` ) expect($fieldset.attr('aria-describedby')).toMatch(describedBy) @@ -398,7 +398,7 @@ describe('Radios', () => { const hintId = $('.govuk-hint').attr('id') const describedByCombined = new RegExp( - `${WORD_BOUNDARY}content${WHITESPACE}${hintId}${WHITESPACE}${errorMessageId}${WORD_BOUNDARY}` + `${WORD_BOUNDARY}test-target-element${WHITESPACE}${hintId}${WHITESPACE}${errorMessageId}${WORD_BOUNDARY}` ) expect($fieldset.attr('aria-describedby')).toMatch(describedByCombined) diff --git a/packages/govuk-frontend/src/govuk/components/select/select.yaml b/packages/govuk-frontend/src/govuk/components/select/select.yaml index 871f6a52d8..c18056e408 100644 --- a/packages/govuk-frontend/src/govuk/components/select/select.yaml +++ b/packages/govuk-frontend/src/govuk/components/select/select.yaml @@ -197,7 +197,7 @@ examples: text: GOV.UK frontend option 1 - value: 2 text: GOV.UK frontend option 2 - describedBy: content + describedBy: test-target-element - name: attributes hidden: true options: @@ -262,7 +262,7 @@ examples: name: select-with-hint label: text: Label text goes here - describedBy: content + describedBy: test-target-element hint: text: Hint text goes here items: @@ -291,7 +291,7 @@ examples: name: select-with-error label: text: Label text goes here - describedBy: content + describedBy: test-target-element errorMessage: text: Error message items: diff --git a/packages/govuk-frontend/src/govuk/components/select/template.test.js b/packages/govuk-frontend/src/govuk/components/select/template.test.js index d82939c103..354303c620 100644 --- a/packages/govuk-frontend/src/govuk/components/select/template.test.js +++ b/packages/govuk-frontend/src/govuk/components/select/template.test.js @@ -146,7 +146,7 @@ describe('Select', () => { const $ = render('select', examples['with describedBy']) const $component = $('.govuk-select') - expect($component.attr('aria-describedby')).toMatch('content') + expect($component.attr('aria-describedby')).toMatch('test-target-element') }) it('renders with attributes', () => { @@ -196,7 +196,7 @@ describe('Select', () => { const $select = $('.govuk-select') - expect($select.attr('aria-describedby')).toMatch('content') + expect($select.attr('aria-describedby')).toMatch('test-target-element') }) }) @@ -225,7 +225,7 @@ describe('Select', () => { const $input = $('.govuk-select') - expect($input.attr('aria-describedby')).toMatch('content') + expect($input.attr('aria-describedby')).toMatch('test-target-element') }) it('adds the error class to the select', () => { diff --git a/packages/govuk-frontend/src/govuk/components/skip-link/skip-link.puppeteer.test.js b/packages/govuk-frontend/src/govuk/components/skip-link/skip-link.puppeteer.test.js index 8901acac35..76dac5d04c 100644 --- a/packages/govuk-frontend/src/govuk/components/skip-link/skip-link.puppeteer.test.js +++ b/packages/govuk-frontend/src/govuk/components/skip-link/skip-link.puppeteer.test.js @@ -20,11 +20,11 @@ describe('Skip Link', () => { () => document.activeElement.id ) - expect(activeElementId).toBe('content') + expect(activeElementId).toBe('test-target-element') }) it('adds the tabindex attribute to the linked element', async () => { - const tabindex = await page.$eval('#content', (el) => + const tabindex = await page.$eval('#test-target-element', (el) => el.getAttribute('tabindex') ) @@ -32,7 +32,7 @@ describe('Skip Link', () => { }) it('adds the class for removing the native focus style to the linked element', async () => { - const cssClass = await page.$eval('#content', (el) => + const cssClass = await page.$eval('#test-target-element', (el) => el.classList.contains('govuk-skip-link-focused-element') ) @@ -41,11 +41,11 @@ describe('Skip Link', () => { it('removes the tabindex attribute from the linked element on blur', async () => { await page.$eval( - '#content', + '#test-target-element', (el) => el instanceof window.HTMLElement && el.blur() ) - const tabindex = await page.$eval('#content', (el) => + const tabindex = await page.$eval('#test-target-element', (el) => el.getAttribute('tabindex') ) @@ -54,11 +54,11 @@ describe('Skip Link', () => { it('removes the class for removing the native focus style from the linked element on blur', async () => { await page.$eval( - '#content', + '#test-target-element', (el) => el instanceof window.HTMLElement && el.blur() ) - const cssClass = await page.$eval('#content', (el) => + const cssClass = await page.$eval('#test-target-element', (el) => el.getAttribute('class') ) diff --git a/packages/govuk-frontend/src/govuk/components/skip-link/skip-link.yaml b/packages/govuk-frontend/src/govuk/components/skip-link/skip-link.yaml index 58fa1f7ef1..2f56120adb 100644 --- a/packages/govuk-frontend/src/govuk/components/skip-link/skip-link.yaml +++ b/packages/govuk-frontend/src/govuk/components/skip-link/skip-link.yaml @@ -24,14 +24,14 @@ examples: - name: default options: text: Skip to main content - href: '#content' + href: '#test-target-element' - name: with focus description: Simulate triggering the :focus CSS pseudo-class, not available in the production build. options: classes: :focus text: Skip to main content - href: '#content' + href: '#test-target-element' # Hidden examples are not shown in the review app, but are used for tests and HTML fixtures - name: no href diff --git a/packages/govuk-frontend/src/govuk/components/textarea/template.test.js b/packages/govuk-frontend/src/govuk/components/textarea/template.test.js index f3b75d0c09..b45c11d8f2 100644 --- a/packages/govuk-frontend/src/govuk/components/textarea/template.test.js +++ b/packages/govuk-frontend/src/govuk/components/textarea/template.test.js @@ -68,7 +68,7 @@ describe('Textarea', () => { const $ = render('textarea', examples['with describedBy']) const $component = $('.govuk-textarea') - expect($component.attr('aria-describedby')).toMatch('content') + expect($component.attr('aria-describedby')).toMatch('test-target-element') }) it('renders with rows', () => { @@ -136,7 +136,7 @@ describe('Textarea', () => { const hintId = $('.govuk-hint').attr('id') const describedBy = new RegExp( - `${WORD_BOUNDARY}content${WHITESPACE}${hintId}${WORD_BOUNDARY}` + `${WORD_BOUNDARY}test-target-element${WHITESPACE}${hintId}${WORD_BOUNDARY}` ) expect($textarea.attr('aria-describedby')).toMatch(describedBy) @@ -173,7 +173,7 @@ describe('Textarea', () => { const errorMessageId = $('.govuk-error-message').attr('id') const describedBy = new RegExp( - `${WORD_BOUNDARY}content${WHITESPACE}${errorMessageId}${WORD_BOUNDARY}` + `${WORD_BOUNDARY}test-target-element${WHITESPACE}${errorMessageId}${WORD_BOUNDARY}` ) expect($component.attr('aria-describedby')).toMatch(describedBy) @@ -220,7 +220,7 @@ describe('Textarea', () => { const hintId = $('.govuk-hint').attr('id') const describedByCombined = new RegExp( - `${WORD_BOUNDARY}content${WHITESPACE}${hintId}${WHITESPACE}${errorMessageId}${WORD_BOUNDARY}` + `${WORD_BOUNDARY}test-target-element${WHITESPACE}${hintId}${WHITESPACE}${errorMessageId}${WORD_BOUNDARY}` ) expect($component.attr('aria-describedby')).toMatch(describedByCombined) diff --git a/packages/govuk-frontend/src/govuk/components/textarea/textarea.yaml b/packages/govuk-frontend/src/govuk/components/textarea/textarea.yaml index 82bb4f6e74..866386e533 100644 --- a/packages/govuk-frontend/src/govuk/components/textarea/textarea.yaml +++ b/packages/govuk-frontend/src/govuk/components/textarea/textarea.yaml @@ -175,7 +175,7 @@ examples: name: with-describedby label: text: With describedBy - describedBy: content + describedBy: test-target-element - name: with hint and described by hidden: true options: @@ -183,7 +183,7 @@ examples: name: with-hint-describedby label: text: With hint and describedBy - describedBy: content + describedBy: test-target-element hint: text: It’s on your National Insurance card, benefit letter, payslip or P60. For example, ‘QQ 12 34 56 C’. - name: with error message and described by @@ -192,7 +192,7 @@ examples: name: textarea-with-error label: text: Textarea with error - describedBy: content + describedBy: test-target-element id: textarea-with-error errorMessage: text: Error message @@ -214,7 +214,7 @@ examples: name: with-hint-error-describedby label: text: With hint, error and describedBy - describedBy: content + describedBy: test-target-element errorMessage: text: Error message hint: diff --git a/packages/govuk-frontend/src/govuk/template.test.js b/packages/govuk-frontend/src/govuk/template.test.js index 6b323a7424..f16473e675 100644 --- a/packages/govuk-frontend/src/govuk/template.test.js +++ b/packages/govuk-frontend/src/govuk/template.test.js @@ -1,5 +1,7 @@ const crypto = require('crypto') +require('html-validate/jest') + const { renderTemplate } = require('@govuk-frontend/helpers/nunjucks') const { nunjucksEnv } = require('@govuk-frontend/lib/components') @@ -53,6 +55,16 @@ describe('Template', () => { expect($('html').hasClass('my-custom-class')).toBeTruthy() }) + + it('renders valid HTML', () => { + expect(renderTemplate('govuk/template.njk').html()).toHTMLValidate({ + extends: ['html-validate:document'], + rules: { + // Allow optional subresource integrity (SRI) + 'require-sri': 'off' + } + }) + }) }) describe('', () => { diff --git a/shared/lib/components.js b/shared/lib/components.js index 81408d27ab..fc7d42b23f 100644 --- a/shared/lib/components.js +++ b/shared/lib/components.js @@ -213,6 +213,12 @@ function renderPreview(componentName, options) {
${componentName ? render(componentName, options) : ''}
+ + +
`, bodyEnd: outdent`