alphagov / govuk-frontend

GOV.UK Frontend contains the code you need to start building a user interface for government platforms and services.
https://frontend.design-system.service.gov.uk/
MIT License
1.18k stars 325 forks source link

Migrate template tests from Cheerio to jsdom #5010

Open 36degrees opened 5 months ago

36degrees commented 5 months ago

What

Update the existing template tests to use jsdom and the matchers provided by @testing-library/jsdom rather than loading the HTML into a Cheerio instance.

Remove the dependency on Cheerio.

Why

We currently render the template to HTML and then load it into a Cheerio instance which we can use to check the state of the HTML by using Cheerio methods like hasClass.

However, if we instead used jsdom (through jest-environment-jsdom) we can make use of the matchers provided by @testing-library/jsdom).

Before:

    it('renders with classes', () => {
      const $ = render('button', examples.classes)

      const $component = $('.govuk-button')
      expect($component.hasClass('app-button--custom-modifier')).toBeTruthy()
    })

After:

    it('renders with classes', () => { 
      document.body.innerHTML = render('button', examples.grey)

      const $component = document.querySelector('.govuk-button')
      expect($component).toHaveClass('app-button--custom-modifier')
    })

It'd also allow us to use other more useful matchers like toHaveAccessibleDescription, toHaveName, toHaveRole which are simpler and better convey intention than checking the association as we currently do:

Before:

    it('associates the input as "described by" the hint', () => {
      const $ = render('input', examples['with hint text'])

      const $input = $('.govuk-input')
      const hintId = $('.govuk-hint').attr('id')

      const describedBy = new RegExp(
        `${WORD_BOUNDARY}${hintId}${WORD_BOUNDARY}`
      )

      expect($input.attr('aria-describedby')).toMatch(describedBy)
    })

After:

    it('associates the input as "described by" the hint', () => {
      document.body.innerHTML = render('input', examples['with hint text'])

      const $input = document.querySelector('.govuk-input')
      expect($input).toHaveAccessibleDescription(
        "It’s on your National Insurance card, benefit letter, payslip or P60. For example, ‘QQ 12 34 56 C’."
      )
    })

Finally, given we aren't using jQuery anywhere else in the codebase, this also means that we only need to remember a single syntax, rather than switching between 'vanilla JavaScript' in our JavaScript and the jQuery-esque Cheerio syntax.

Who needs to work on this

Developers

Who needs to review this

Developers

Done when

## Update the template tests
- [ ] https://github.com/alphagov/govuk-frontend/pull/5025
- [ ] https://github.com/alphagov/govuk-frontend/pull/5026
- [ ] https://github.com/alphagov/govuk-frontend/pull/5027
- [ ] **Button** template tests updated
- [ ] **Character Count** template tests updated
- [ ] **Checkboxes** template tests updated
- [ ] **Cookie Banner** template tests updated
- [ ] **Date Input** template tests updated
- [ ] **Details** template tests updated
- [ ] **Error Message** template tests updated
- [ ] **Error Summary** template tests updated
- [ ] **Exit this Page** template tests updated
- [ ] **Fieldset** template tests updated
- [ ] **File Upload** template tests updated
- [ ] **Footer** template tests updated
- [ ] **Header** template tests updated
- [ ] https://github.com/alphagov/govuk-frontend/pull/5050
- [x] https://github.com/alphagov/govuk-frontend/pull/5017
- [ ] **Inset Text** template tests updated
- [ ] **Label** template tests updated
- [ ] **Notification Banner** template tests updated
- [ ] **Pagination** template tests updated
- [ ] **Panel** template tests updated
- [ ] **Password Input** template tests updated
- [ ] **Phase Banner** template tests updated
- [ ] **Radios** template tests updated
- [ ] **Select** template tests updated
- [ ] **Skip Link** template tests updated
- [ ] **Summary List** template tests updated
- [ ] **Table** template tests updated
- [ ] **Tabs** template tests updated
- [ ] https://github.com/alphagov/govuk-frontend/pull/5049
- [ ] https://github.com/alphagov/govuk-frontend/pull/5045
- [ ] **Textarea** template tests updated
- [ ] https://github.com/alphagov/govuk-frontend/pull/5065
- [ ] https://github.com/alphagov/govuk-frontend/pull/5062
### Tidy up
- [ ] `shared/helpers/nunjucks.js` has been updated to remove unused helpers
- [ ] Cheerio has been removed from our dependencies