Skip to content

Commit 091afe1

Browse files
Update Puppeteer tests to use ES modules not window globals
An import map has been added to resolve `govuk-frontend` to `/javascripts/all.bundle.min.mjs` when run inside Puppeteer `page.evaluate()`
1 parent ae60db8 commit 091afe1

File tree

9 files changed

+39
-45
lines changed

9 files changed

+39
-45
lines changed

package-lock.json

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/govuk-frontend-review/src/views/layouts/_generic.njk

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
<link rel="stylesheet" href="/stylesheets/app.min.css">
55

66
{% block styles %}{% endblock %}
7+
8+
<script type="importmap">
9+
{ "imports": { "govuk-frontend": "/javascripts/all.bundle.min.mjs" } }
10+
</script>
711
{% endblock %}
812

913
{% block bodyStart %}

packages/govuk-frontend/src/govuk/components/button/button.test.js

+3-5
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,12 @@ describe('/components/button', () => {
1818
it('does not prevent further JavaScript from running', async () => {
1919
await goTo(page, '/tests/boilerplate')
2020

21-
const result = await page.evaluate((component) => {
22-
const namespace = 'GOVUKFrontend' in window
23-
? window.GOVUKFrontend
24-
: {}
21+
const result = await page.evaluate(async (exportName) => {
22+
const namespace = await import('govuk-frontend')
2523

2624
// `undefined` simulates the element being missing,
2725
// from an unchecked `document.querySelector` for example
28-
new namespace[component](undefined).init()
26+
new namespace[exportName](undefined).init()
2927

3028
// If our component initialisation breaks, this won't run
3129
return true

packages/govuk-frontend/src/govuk/components/character-count/character-count.test.js

+2-5
Original file line numberDiff line numberDiff line change
@@ -648,17 +648,14 @@ describe('Character count', () => {
648648
// Override maxlength to 10
649649
maxlength: 10
650650
},
651-
initialiser ({ config, namespace }) {
652-
const $component = document.querySelector('[data-module]')
653-
651+
initialiser ($module) {
654652
// Set locale to Welsh, which expects translations for 'one', 'two',
655653
// 'few' 'many' and 'other' forms – with the default English strings
656654
// provided we only have translations for 'one' and 'other'.
657655
//
658656
// We want to make sure we handle this gracefully in case users have
659657
// an existing character count inside an incorrect locale.
660-
$component.setAttribute('lang', 'cy')
661-
new namespace.CharacterCount($component, config).init()
658+
$module.setAttribute('lang', 'cy')
662659
}
663660
})
664661

packages/govuk-frontend/src/govuk/components/error-summary/error-summary.test.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const { goToComponent, goToExample, renderAndInitialise } = require('govuk-frontend-helpers/puppeteer')
1+
const { goToComponent, goToExample, renderAndInitialise, goTo } = require('govuk-frontend-helpers/puppeteer')
22
const { getExamples } = require('govuk-frontend-lib/files')
33

44
describe('Error Summary', () => {
@@ -82,14 +82,14 @@ describe('Error Summary', () => {
8282

8383
describe('using JavaScript configuration, with no elements on the page', () => {
8484
it('does not prevent further JavaScript from running', async () => {
85-
const result = await page.evaluate((component) => {
86-
const namespace = 'GOVUKFrontend' in window
87-
? window.GOVUKFrontend
88-
: {}
85+
await goTo(page, '/tests/boilerplate')
86+
87+
const result = await page.evaluate(async (exportName) => {
88+
const namespace = await import('govuk-frontend')
8989

9090
// `undefined` simulates the element being missing,
9191
// from an unchecked `document.querySelector` for example
92-
new namespace[component](undefined).init()
92+
new namespace[exportName](undefined).init()
9393

9494
// If our component initialisation breaks, this won't run
9595
return true

packages/govuk-frontend/src/govuk/components/globals.test.mjs

+7-13
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,17 @@ describe('GOV.UK Frontend', () => {
77
beforeEach(async () => {
88
await goTo(page, '/')
99

10-
// Exported via global (e.g GOVUKFrontend.initAll)
11-
exported = await page.evaluate(() => 'GOVUKFrontend' in window
12-
? Object.keys(window.GOVUKFrontend)
13-
: undefined
10+
// Exports available via browser dynamic import
11+
exported = await page.evaluate(async () =>
12+
Object.keys(await import('govuk-frontend'))
1413
)
1514
})
1615

1716
it('exports `initAll` function', async () => {
1817
await goTo(page, '/')
1918

20-
const typeofInitAll = await page.evaluate((utility) => {
21-
const namespace = 'GOVUKFrontend' in window
22-
? window.GOVUKFrontend
23-
: {}
24-
19+
const typeofInitAll = await page.evaluate(async (utility) => {
20+
const namespace = await import('govuk-frontend')
2521
return typeof namespace[utility]
2622
}, 'initAll')
2723

@@ -53,10 +49,8 @@ describe('GOV.UK Frontend', () => {
5349
const components = exported
5450
.filter(method => !['initAll', 'version'].includes(method))
5551

56-
const componentsWithoutInitFunctions = await page.evaluate((components) => {
57-
const namespace = 'GOVUKFrontend' in window
58-
? window.GOVUKFrontend
59-
: {}
52+
const componentsWithoutInitFunctions = await page.evaluate(async (components) => {
53+
const namespace = await import('govuk-frontend')
6054

6155
return components.filter(component => {
6256
const prototype = namespace[component].prototype

shared/helpers/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"devDependencies": {
1717
"@axe-core/puppeteer": "^4.7.3",
1818
"cheerio": "^1.0.0-rc.12",
19+
"govuk-frontend": "*",
1920
"govuk-frontend-config": "*",
2021
"govuk-frontend-lib": "*",
2122
"jest-axe": "^7.0.1",

shared/helpers/puppeteer.js

+7-15
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,8 @@ async function axe (page, overrides = {}) {
7676
* @param {object} options - Render and initialise options
7777
* @param {object} options.params - Nunjucks macro params
7878
* @param {object} [options.config] - Component instantiation config
79-
* @param {(context: { config?: object, namespace: object }) => void} [options.initialiser] - A function that'll run in the
80-
* browser to execute arbitrary initialisation. Receives an object with the
81-
* passed configuration as `config` and the GOVUKFrontend global as `namespace`
79+
* @param {($module: Element) => void} [options.initialiser] - A function that'll run in the
80+
* browser to execute arbitrary initialisation
8281
* @returns {Promise<import('puppeteer').Page>} Puppeteer page object
8382
*/
8483
async function renderAndInitialise (page, componentName, options) {
@@ -92,22 +91,15 @@ async function renderAndInitialise (page, componentName, options) {
9291
}, html)
9392

9493
// Run a script to init the JavaScript component
95-
await page.evaluate((componentClassName, options) => {
96-
const $component = document.querySelector('[data-module]')
97-
98-
// Check for window global
99-
if (!('GOVUKFrontend' in window) || !window.GOVUKFrontend[componentClassName]) {
100-
throw new Error(`Global 'window.GOVUKFrontend.${componentClassName}' not found`)
101-
}
94+
await page.evaluate(async (exportName, options) => {
95+
const $module = document.querySelector('[data-module]')
10296

10397
if (options.initialiser) {
104-
return options.initialiser({
105-
config: options.config,
106-
namespace: window.GOVUKFrontend
107-
})
98+
options.initialiser($module)
10899
}
109100

110-
new window.GOVUKFrontend[componentClassName]($component, options.config).init()
101+
const namespace = await import('govuk-frontend')
102+
new namespace[exportName]($module, options.config).init()
111103
}, componentNameToClassName(componentName), options)
112104

113105
return page

shared/helpers/tsconfig.json

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
{
22
"extends": "../../tsconfig.base.json",
3-
"include": ["**/*.js", "**/*.mjs", "../config", "../lib"]
3+
"include": [
4+
"**/*.js",
5+
"**/*.mjs",
6+
"../config",
7+
"../lib",
8+
"../../packages/govuk-frontend"
9+
],
10+
"exclude": ["./dist/**", "../../packages/govuk-frontend/dist/**"]
411
}

0 commit comments

Comments
 (0)