From 95043563747eb46fec11753660dba5befab3783e Mon Sep 17 00:00:00 2001 From: Oliver Byford Date: Fri, 31 May 2024 16:38:27 +0100 Subject: [PATCH 1/3] Rename breadcrumbs template tests to .jsdom.test.js The next commit will refactor the tests to make use of jsdom which requires us to update the filename so that we get the jsdom test environment. Doing this in two commits so that git shows the changes to the file rather than treating it as an addition and a deletion. --- .../breadcrumbs/{template.test.js => template.jsdom.test.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/govuk-frontend/src/govuk/components/breadcrumbs/{template.test.js => template.jsdom.test.js} (100%) diff --git a/packages/govuk-frontend/src/govuk/components/breadcrumbs/template.test.js b/packages/govuk-frontend/src/govuk/components/breadcrumbs/template.jsdom.test.js similarity index 100% rename from packages/govuk-frontend/src/govuk/components/breadcrumbs/template.test.js rename to packages/govuk-frontend/src/govuk/components/breadcrumbs/template.jsdom.test.js From b08770e98a58a9a71e89963de2ea16e9beec0858 Mon Sep 17 00:00:00 2001 From: Oliver Byford Date: Fri, 31 May 2024 17:22:11 +0100 Subject: [PATCH 2/3] Remove redundant test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The template has no option for inverse colours – the example just passes an additional class, so the test has no value over the existing test for additional classes. --- .../govuk/components/breadcrumbs/template.jsdom.test.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/packages/govuk-frontend/src/govuk/components/breadcrumbs/template.jsdom.test.js b/packages/govuk-frontend/src/govuk/components/breadcrumbs/template.jsdom.test.js index 9ac6ad2a2b..a6cd93d071 100644 --- a/packages/govuk-frontend/src/govuk/components/breadcrumbs/template.jsdom.test.js +++ b/packages/govuk-frontend/src/govuk/components/breadcrumbs/template.jsdom.test.js @@ -98,12 +98,5 @@ describe('Breadcrumbs', () => { $component.hasClass('govuk-breadcrumbs--collapse-on-mobile') ).toBeTruthy() }) - - it('renders with inverted colours if specified', () => { - const $ = render('breadcrumbs', examples.inverse) - - const $component = $('.govuk-breadcrumbs') - expect($component.hasClass('govuk-breadcrumbs--inverse')).toBeTruthy() - }) }) }) From 4e53a39b7cbd3c02138f1ef4e1d44dbba7609640 Mon Sep 17 00:00:00 2001 From: Oliver Byford Date: Fri, 31 May 2024 17:23:23 +0100 Subject: [PATCH 3/3] Update breadcrumbs template tests to use jsdom --- .../components/breadcrumbs/breadcrumbs.yaml | 4 +- .../breadcrumbs/template.jsdom.test.js | 170 ++++++++++++------ 2 files changed, 116 insertions(+), 58 deletions(-) diff --git a/packages/govuk-frontend/src/govuk/components/breadcrumbs/breadcrumbs.yaml b/packages/govuk-frontend/src/govuk/components/breadcrumbs/breadcrumbs.yaml index 934691dced..012a5703bd 100644 --- a/packages/govuk-frontend/src/govuk/components/breadcrumbs/breadcrumbs.yaml +++ b/packages/govuk-frontend/src/govuk/components/breadcrumbs/breadcrumbs.yaml @@ -124,10 +124,12 @@ examples: options: items: - text: Section 1 + href: /section-1 + - text: Section 2 - name: html hidden: true options: items: - html: Section 1 + href: /section-1 - html: Section 2 - href: /section-2 diff --git a/packages/govuk-frontend/src/govuk/components/breadcrumbs/template.jsdom.test.js b/packages/govuk-frontend/src/govuk/components/breadcrumbs/template.jsdom.test.js index a6cd93d071..12e9a02f04 100644 --- a/packages/govuk-frontend/src/govuk/components/breadcrumbs/template.jsdom.test.js +++ b/packages/govuk-frontend/src/govuk/components/breadcrumbs/template.jsdom.test.js @@ -1,5 +1,4 @@ -const { render } = require('@govuk-frontend/helpers/nunjucks') -const { getExamples } = require('@govuk-frontend/lib/components') +const { getExamples, render } = require('@govuk-frontend/lib/components') describe('Breadcrumbs', () => { let examples @@ -9,94 +8,151 @@ describe('Breadcrumbs', () => { }) describe('default example', () => { - it('renders with items', () => { - const $ = render('breadcrumbs', examples.default) + let $component, $list, $listItems - const $items = $('.govuk-breadcrumbs__list-item') - expect($items).toHaveLength(2) - }) + beforeAll(() => { + document.body.innerHTML = render('breadcrumbs', examples.default) - it('renders 2 items', () => { - const $ = render('breadcrumbs', examples.default) - const $items = $('.govuk-breadcrumbs__list-item') - expect($items).toHaveLength(2) + $component = document.querySelector('.govuk-breadcrumbs') + $list = document.querySelector('ol.govuk-breadcrumbs__list') + $listItems = document.querySelectorAll('li.govuk-breadcrumbs__list-item') }) - it('renders item with anchor', () => { - const $ = render('breadcrumbs', examples.default) + it('includes an ordered list', () => { + expect($component).toContainElement($list) + }) - const $anchor = $('.govuk-breadcrumbs__list-item a').first() - expect($anchor.get(0).tagName).toBe('a') - expect($anchor.attr('class')).toBe('govuk-breadcrumbs__link') - expect($anchor.attr('href')).toBe('/section') - expect($anchor.text()).toBe('Section') + it('includes 2 list items within the list', () => { + expect($listItems).toHaveLength(2) }) + + describe.each([ + { index: 0, expectedText: 'Section', expectedHref: '/section' }, + { + index: 1, + expectedText: 'Sub-section', + expectedHref: '/section/sub-section' + } + ])( + 'the "$expectedText" breadcrumb', + ({ index, expectedText, expectedHref }) => { + it(`includes the text "${expectedText}"`, () => { + expect($listItems[index]).toHaveTextContent(expectedText) + }) + + it(`includes a link with the class govuk-breadcrumbs__link`, () => { + expect($listItems[index].querySelector('a')).toHaveClass( + 'govuk-breadcrumbs__link' + ) + }) + + it(`includes a link with the href "${expectedHref}"`, () => { + expect($listItems[index].querySelector('a')).toHaveAttribute( + 'href', + expectedHref + ) + }) + } + ) }) - describe('custom options', () => { - it('renders item with text', () => { - const $ = render( + describe('when the last breadcrumb is the current page', () => { + let $lastItem + + beforeAll(() => { + document.body.innerHTML = render( 'breadcrumbs', examples['with last breadcrumb as current page'] ) - const $item = $('.govuk-breadcrumbs__list-item').last() - expect($item.text()).toBe('Travel abroad') + $lastItem = document.querySelector( + '.govuk-breadcrumbs__list-item:last-child' + ) + }) + + it('includes the current page as the last list item', () => { + expect($lastItem).toHaveTextContent('Travel abroad') + }) + + it('does not link the last list item', () => { + expect($lastItem.querySelector('a')).toBeNull() + }) + + it('sets the aria-current attribute to "page"', () => { + expect($lastItem).toHaveAttribute('aria-current', 'page') }) + }) + + describe('custom options', () => { + it('escapes HTML when using the `text` option', () => { + document.body.innerHTML = render('breadcrumbs', examples['html as text']) + const $item = document.querySelector('.govuk-breadcrumbs__list-item') - it('renders item with escaped entities in text', () => { - const $ = render('breadcrumbs', examples['html as text']) + expect($item).toHaveTextContent('Section 1') + }) + + it('escapes HTML when using the `text` option without a link', () => { + document.body.innerHTML = render('breadcrumbs', examples['html as text']) + const $item = document.querySelector( + '.govuk-breadcrumbs__list-item:nth-child(2)' + ) - const $item = $('.govuk-breadcrumbs__list-item') - expect($item.html()).toBe('<span>Section 1</span>') + expect($item).toHaveTextContent('Section 2') }) - it('renders item with html', () => { - const $ = render('breadcrumbs', examples.html) + it('does not escape HTML when using the `html` option', () => { + document.body.innerHTML = render('breadcrumbs', examples.html) + const $item = document.querySelector('.govuk-breadcrumbs__list-item') - const $item = $('.govuk-breadcrumbs__list-item').first() - expect($item.html()).toBe('Section 1') + expect($item).toContainHTML('Section 1') }) - it('renders item with html inside anchor', () => { - const $ = render('breadcrumbs', examples.html) + it('does not escape HTML when using the `html` option without a link', () => { + document.body.innerHTML = render('breadcrumbs', examples.html) + const $item = document.querySelector( + '.govuk-breadcrumbs__list-item:nth-child(2)' + ) - const $anchor = $('.govuk-breadcrumbs__list-item a').last() - expect($anchor.html()).toBe('Section 2') + expect($item).toContainHTML('Section 2') }) - it('renders item anchor with attributes', () => { - const $ = render('breadcrumbs', examples['item attributes']) + it('sets any additional attributes on the link based on the `item.attributes` option', () => { + document.body.innerHTML = render( + 'breadcrumbs', + examples['item attributes'] + ) + const $breadcrumbLink = document.querySelector('.govuk-breadcrumbs__link') - const $breadcrumbLink = $('.govuk-breadcrumbs__link') - expect($breadcrumbLink.attr('data-attribute')).toBe('my-attribute') - expect($breadcrumbLink.attr('data-attribute-2')).toBe('my-attribute-2') + expect($breadcrumbLink).toHaveAttribute('data-attribute', 'my-attribute') + expect($breadcrumbLink).toHaveAttribute( + 'data-attribute-2', + 'my-attribute-2' + ) }) - it('renders with classes', () => { - const $ = render('breadcrumbs', examples.classes) + it('includes additional classes from the `classes` option', () => { + document.body.innerHTML = render('breadcrumbs', examples.classes) - const $component = $('.govuk-breadcrumbs') - expect( - $component.hasClass('app-breadcrumbs--custom-modifier') - ).toBeTruthy() + const $component = document.querySelector('.govuk-breadcrumbs') + expect($component).toHaveClass('app-breadcrumbs--custom-modifier') }) - it('renders with attributes', () => { - const $ = render('breadcrumbs', examples.attributes) + it('adds the `--collapse-on-mobile` modifier class if `collapseOnMobile` is true', () => { + document.body.innerHTML = render( + 'breadcrumbs', + examples['with collapse on mobile'] + ) - const $component = $('.govuk-breadcrumbs') - expect($component.attr('id')).toBe('my-navigation') - expect($component.attr('role')).toBe('navigation') + const $component = document.querySelector('.govuk-breadcrumbs') + expect($component).toHaveClass('govuk-breadcrumbs--collapse-on-mobile') }) - it('renders item as collapse on mobile if specified', () => { - const $ = render('breadcrumbs', examples['with collapse on mobile']) + it('sets any additional attributes based on the `attributes` option', () => { + document.body.innerHTML = render('breadcrumbs', examples.attributes) - const $component = $('.govuk-breadcrumbs') - expect( - $component.hasClass('govuk-breadcrumbs--collapse-on-mobile') - ).toBeTruthy() + const $component = document.querySelector('.govuk-breadcrumbs') + expect($component).toHaveAttribute('id', 'my-navigation') + expect($component).toHaveAttribute('role', 'navigation') }) }) })